第七周学习心得

初识reverse

一、进制转换
1.r进制转换为十进制
r进制转换为十进制的方法其实很简单,就是把r进制按该数×r的该数所在数位的次方求得(如二进制10101转换为十进制就是12^4+02的3次+12的2次+02的1次+1*2的0次)
2.十进制转换为r进制
十进制转换为r进制就是拿十进制的数去除r取余然后在拿商去除r再取余,最后逆序排列
二、字长与端序
1.字长:字长就是字的长度,一个字(word)长度为两个字节,一个字节长度为8个比特位,两个字即为四个字节(dword),同理四个字为八个字节(qword)。
2.端序:端序就是字节排列的通用规则。一般分为小端序和大端序,大端序。
大端序:将低位字节存放在高位地址处,将高位字节存放在低位地址处。比较符合人类的阅读习惯。
小端序:将数据的低位字节放在较小的地址处,高位放在较大的地址处.比较符合计算机的阅读习惯。
三、汇编基础指令
1.标志寄存器
(1)什么是标志寄存器
标志寄存器是一种特殊的寄存器,对于不同的主机,该寄存器的个数和结构不同
(2)标志寄存器的作用
a.用来储存相关指令的某些执行结果。
b. 用来为CPU执行相关指令提供行为依据。
c.用来控制CPU的相关工作方式。
2.关于堆栈
(1)堆栈是什么:栈(stack)又名堆栈是操作系统在建立某个进程时或者线程,为这个线程建立的存储区域,在编译的时候可以指定需要的栈的大小,堆是一种数据结构,控制一段自己的储存空间,叫做堆空间,可以理解为在程序运行时给自己申请的内存。
(2)进栈和出栈:进栈(push)是指将一个元素从栈顶放入栈中,出栈(pop)是指从栈顶上拿出一个元素
(3)堆栈操作原理: 栈在程序运行中的作用非常重要,它保存了一个函数调用所需要维护的信息,称为现场保护,当函数调用结束后需要返回主函数,这时候就需要现场信息,要保护的现场信息包括:ebp :是栈底指针,esp是栈顶指针。
操作原理:就是堆是一个很大的操作空间,然后我们使用申请到它的使用权以后,在里面存放一些信息,比如c的函数的参数名,然后这个存放的方式就是使用类似于数据结构中栈的方式
3.寄存器简单指令
(1)add:加法指令,此指令描述两个操作数相加,结果送到dest,即dest+src→dest
(2)sub:减法指令,此指令描述两个操作数相减,结果送到dest
(3)inc:加1指令,对操作数加以,结果送到dest
(4)dec:减一指令,对操作数减一,结果送到dest
(5)neg:取补指令,堆操作数进行取补,就是用0-操作数opro,在送回opro
4.堆栈的操作指令
(1)push:进栈指令,该指令把源操作数src压入堆栈。
(2)pop:出栈指令,该指令从栈顶弹出一个双字或者字数据到目的操作数dest
.5.字符串指令

  1. 字符串装入指令(LOAD String)
    格式:
    LODSB ;装入字节
    LODSW ;装入字
    LODSD ;装入双字
  2. 字符串存储指令(STOre String)
    格式:
    STOSB ;存储字节
    STOSW ;存储字
    STOSD ;存储双字
  3. 字符串传送指令(MOVe String)
    格式:
    MOVSB ;字节传送
    MOVSW ;字传送
    MOVSD ;双字传送
  4. 字符串扫描指令(SCAn String)
    格式:
    SCASB ;串字节扫描
    SCASW ;串字扫描
    SCASD ;串双字扫描
  5. 字符串比较指令(CoMPare String)
    格式:
    CMPSB ;串字节比较
    CMPSW ;串字比较
    CMPSD ;串双字比较
    6.例题
    有了上面的指令,我们就可以初步的做一些题目来熟悉语言了,以下为给出的样例
    .text:000011B1 var_4= dword ptr -4
    .text:000011B1 arg_0= dword ptr 8
    .text:000011B1 55 push ebp
    .text:000011B2 89 E5 mov ebp, esp
    .text:000011B4 83 EC 10 sub esp, 10h
    .text:000011C1 C7 45 FC 00 00 00 00 mov [ebp+var_4], 0
    .text:000011C8 83 7D 08 00 cmp [ebp+arg_0], 0
    .text:000011CC 79 09 jns short loc_11D7
    .text:000011CC
    .text:000011CE C7 45 FC 01 00 00 00 mov [ebp+var_4], 1
    .text:000011D5 EB 34 jmp short loc_120B
    .text:000011D5
    .text:000011D7 loc_11D7:
    .text:000011D7 83 7D 08 00 cmp [ebp+arg_0], 0
    .text:000011DB 75 09 jnz short loc_11E6
    .text:000011DB
    .text:000011DD C7 45 FC 02 00 00 00 mov [ebp+var_4], 2
    .text:000011E4 EB 25 jmp short loc_120B
    .text:000011E4
    .text:000011E6 loc_11E6:
    .text:000011E6 83 7D 08 1D cmp [ebp+arg_0], 1Dh
    .text:000011EA 7F 09 jg short loc_11F5
    .text:000011EA
    .text:000011EC C7 45 FC 03 00 00 00 mov [ebp+var_4], 3
    .text:000011F3 EB 16 jmp short loc_120B
    .text:000011F3
    .text:000011F5 loc_11F5:
    .text:000011F5 83 7D 08 45 cmp [ebp+arg_0], 45h
    .text:000011F9 7F 09 jg short loc_1204
    .text:000011F9
    .text:000011FB C7 45 FC 04 00 00 00 mov [ebp+var_4], 4
    .text:00001202 EB 07 jmp short loc_120B
    .text:00001202
    .text:00001204 loc_1204:
    .text:00001204 C7 45 FC 05 00 00 00 mov [ebp+var_4], 5
    .text:00001204
    .text:0000120B loc_120B:
    .text:0000120B 8B 45 FC mov eax, [ebp+var_4]
    .text:0000120E C9 leave
    .text:0000120F C3 retn

main 函数按照如下方式进行调用:

.text:00001221 6A 3C						push 3Ch
.text:00001223 E8 85 FF FF FF				call test1
.text:00001228 83 C4 04 					add esp, 4
  1. 该函数有几个参数
  2. 该函数使用了什么函数调用约定
  3. 当程序执行到 0x1228 时,eax 的值是多少
  4. 你能还原出 C 代码吗

1.由该函数所知,进栈了一个3ch参数,所以该函数的参数数目为一
2.由函数第三行add esp,4可知该函数对堆栈进行了清除,所以是 cdecl调用约定
3.先还原其c代码,根据观察上述内容,我们可以知道他是拿输入进去的数去和0做比较,然后分别进行操作,所以应该使用判断语句去写,还原代码如下
– int test1(int arg_0) {
int var_4 = 0;

if (arg_0 < 0) {
    var_4 = 1;
} else if (arg_0 == 0) {
    var_4 = 2;
} else if (arg_0 <= 0x1D) {
    var_4 = 3;
} else if (arg_0 <= 0x45) {
    var_4 = 4;
} else {
    var_4 = 5;
}
return var_4;

}

int main() {
int result = test1(0x3C);
return 0;
}
然后程序执行到0时因为0=0,所以 结果为2.
三、buuctf
1.下载zip导入ida后打开字符串界面第一个就是flag,这里不做过多赘述。
2.reverse1
导入exe后打开查找字符串,找到与flag有关的点击进入在这里插入图片描述
进去以后按x会出来一个流程图,f5查看伪代码在这里插入图片描述
可以发现,它对我们输入的 str1 与程序里的 str2 做比较,str2 是{hello_world},而在开始前会将 str2 中的字母 o 替换为数字 0,于是得到 flag
3.reverse2
IDA 载入,找到 main 函数,F5 查看伪代码,查看&flag,&flag 为 "hacking_for_fun}"往上看有一段对&flag变换的操作是将其中的 i 和 r 换成 1,于是得到 flag
四、初步了解x86架构
X86架构(The X86 architecture)是微处理器执行的计算机语言指令集,指一个intel通用计算机系列的标准编号缩写,也标识一套通用的计算机指令集合。
1.冯·诺依曼体系结构
1946年,第一台计算机ENIAC诞生,人类进入计算机时代,后来,美籍匈牙利数学家:冯.诺依曼提出了计算机“存储程序”的计算机设计理念,即将计算机指令进行编码后存储在计算机的存储器中,需要的时候可以顺序地执行程序代码,从而控制计算机运行,这就是冯.诺依曼计算机体系的开端。
一.冯.诺依曼结构的灵魂
早期的计算机是由各种门电路组成的,这些门电路通过组装出一个固定的电路板,来执行一个特定的程序,一旦需要修改程序功能,就要重新组装电路板,所以早期的计算机程序是硬件化的!
然而,祖师爷的出现将最初的硬件化程序变为可编程、可存储编码,放在存储器中,随意使用,下面大体介绍一下冯.诺依曼结构的灵魂。
要知道,早期的计算机设计中,程序和数据是俩个截然不同的概念,数据放在存储器中,而程序作为控制器的一部分,这样的计算机计算效率低,灵活性较差。冯.诺依曼结构中,将程序和数据一样看待,将程序编码为数据,然后与数据一同存放在存储器中,这样计算机就可以调用存储器中的程序来处理数据了。意味着,无论什么程序,最终都是会转换为数据的形式存储在存储器中,要执行相应的程序只需要从存储器中依次取出指令、执行,冯.诺依曼结构的灵魂所在正是这里:减少了硬件的连接,这种设计思想导致了硬件和软件的分离,即硬件设计和程序设计可以分开执行!!!这就催生了程序员这个职业的诞生!!!
概括的来讲,冯.诺依曼结构消除了原始计算机体系中,只能依靠硬件控制程序的状况(程序作为控制器的一部分,作为硬件存在),将程序编码存储在存储器中,实现了可编程的计算机功能,实现了硬件设计和程序设计的分离,大大促进了计算机的发展。
灵魂就是将程序从硬件实现转换为软件实现(存储程序控制原理)!!!
计算机的基本工作原理就是:存储程序控制原理!
二.冯.诺依曼结构的核心设计思想
核心设计思想主要体现在如下三个方面:
程序、数据的最终形态都是二进制编码,程序和数据都是以二进制方式存储在存储器中的,二进制编码也是计算机能够所识别和执行的编码。(可执行二进制文件:.bin文件)
程序、数据和指令序列,都是事先存在主(内)存储器中,以便于计算机在工作时能够高速地从存储器中提取指令并加以分析和执行。
确定了计算机的五个基本组成部分:运算器、控制器、存储器、输入设备、输出设备
三.冯诺依曼结构的五个主要组成部分
冯.诺依曼在秘密开发的 EDVAC 写了一篇报告First Draft of a Report on the EDVAC,描述了他心目中的一台计算机应该长什么样。这篇报告在历史上有个很特殊的简称,叫First Draft,翻译成中文,其实就是《第一份草案》。这样,现代计算机的发展就从祖师爷写的一份草案开始了。
First Draft里面说了一台计算机应该有哪些部分组成,我们一起来看看。
冯.诺依曼确定了”计算机结构“中的5大部件:
运算器
控制器
存储器
输入设备
输出设备
现在看来,运算器和控制器单元集成在CPU中实现,存储器的容量不断扩大、输入输出设备不断更新,这些部件构成了当代计算机硬件系统的基本组成。
我们手机里只有 SD 卡(Secure Digital Memory Card)这样类似硬盘功能的存储卡插槽,并没有内存插槽、CPU 插槽这些东西。没错,因为手机尺寸的原因,手机制造商们选择把 CPU、内存、网络通信,乃至摄像头芯片,都封装到一个芯片,然后再嵌入到手机主板上。这种方式叫SoC,也就是 System on a Chip(系统芯片)。
1.运算器
首先计算机要有运算处理数据的能力,所以需要一个处理单元来完成各种算数运算和逻辑运算,这就是算术逻辑单元(Arithmetic Logic Unit,ALU)。ALU的主要功能就是在控制信号的作用下,完成加、减、乘、除等算术运算以及与、或、非、异或等逻辑运算以及移位、补位等运算。
运算器的主要部件就是ALU,运算器的处理对象是数据,所以数据的长度以及数据的表示方法,对运算器的影响很大。大多数通用计算机是以16、32、64位数据作为运算器一次处理数据的长度。能够对一个数据的所有位同时处理运算器称为并行运算器,一次只能对数据的一个位处理的运算器称为串行运算器
运算器与其他部分的关系:
计算机运算时,运算器的操作对象和操作种类由控制器决定。运算器操作的数据从内存中读取,处理的结果再写入内存(或者暂时存放在内部寄存器中),而且运算器对内存数据的读写是由控制器来进行的。
2.控制器
控制器又称为控制单元(Control Unit),是计算机的神经中枢和指挥中心,只有在控制器的控制下,整个计算机才能够有条不紊地工作、自动执行程序。
控制器的工作流程为:从内存中取指令、翻译指令、分析指令,然后根据指令的内存向有关部件发送控制命令,控制相关部件执行指令所包含的操作。
控制器和运算器共同组成中央处理器(Central Processing Unit),CPU是一块超大规模集成电路,是计算机运算核心和控制核心,CPU的主要功能是解释计算机指令以及处理数据。
3.存储器
存储器的主要功能是存储程序和各种数据,并且能够在计算机运行过程高速、自动地完成程序或者数据的存储,存储器是有记忆的设备,而且采用俩种稳定状态的物理器件来记录存储信息,所以计算机中的程序和数据都要转换为二进制代码才可以存储和操作。
存储器可以分为内部存储器(内存)和外部存储器,俩者在计算机系统中各有用处,下面大概介绍一下俩种存储器的特点:

Ⅰ.内部存储器
内部存储器称为内存或者主存,是用来存放欲执行的程序和数据。
在计算机内部,程序和数据都是以二进制代码的形式存储的,它们均以字节为单位(8位)存储在存储器中,一个字节占用一个存储单元,并且每个存储单元都有唯一的地址号。这里以字节(8位)为存储单元,就与上面运算器的操作数据的大小联系起来了,16、32、64都是8的倍数
CPU可以直接使用指令对内部存储器按照地址进行读写俩种操作,读:将内存中某个存储单元的内容读出,送入CPU的某个寄存器中;写:在控制器的控制下,将CPU中某寄存器内容传到某个存储单元中。
要注意,内存中的数据和地址码都是二进制数,但是俩者是不同的,一个地址可以指向一个存储单元,地址是存储单元的位置,数据是存储单元的内容,数据可以是操作码、可以是CPU要处理阿数据、也可以是数据的地址,地址码的长度由内存单元的个数确定。内存的存取速度会直接影响计算机的运算速度,由于CPU是高速器件,但是CPU的速度是受制于内存的存取速度的,所以为了解决CPU和内存速度不匹配的问题,在CPU和内存直接设置了一种高速缓冲存储器Cache。 Cache是计算机中的一个高速小容量存储器,其中存放的是CPU近期要执行的指令和数据,其存取速度可以和CPU的速度匹配,一般采用静态RAM充当Cach
内存按工作方式的不同又可以分为俩部分:
RAM:随机存储器,可以被CPU随机读取,一般存放CPU将要执行的程序、数据,断电丢失数据
ROM:只读存储器,只能被CPU读,不能轻易被CPU写,用来存放永久性的程序和数据,比如:系统引导程序、监控程序等。具有掉电非易失性。
Ⅱ.外部存储器
外部存储器主要来存放”暂时“用不着的程序和数据,可以和内存交换数据。
一般是磁盘、光盘、U盘、硬盘等。
4.输入输出设备
实际上我们操作计算机都是与输入输出设备在打交道。
鼠标键盘是输入设备、显示器是输出设备;
手机触摸屏即时输入设备又是输出设备;
服务器中网卡既是输入设备又是输出设备;
所有的计算机程序都可以抽象为输入设备读取信息,通过CPU来执行存储在存储器中的程序,结果通过输出设备反馈给用户。
五、进程的空间布局
程序段(Text):程序代码在内存中的映射,存放函数体的二进制代码。

初始化过的数据(Data):在程序运行初已经对变量进行初始化的数据。

未初始化过的数据(BSS):在程序运行初未对变量进行初始化的数据。

栈 (Stack):存储局部、临时变量,函数调用时,存储函数的返回指针,用于控制函数的调用和返回。在程序块开始时自动分配内存,结束时自动释放内存,其操作方式类似于数据结构中的栈。

堆 (Heap):存储动态内存分配,需要程序员手工分配,手工释放.注意它与数据结构中的堆是两回事,分配方式类似于链表。

注:1.Text, BSS, Data段在编译时已经决定了进程将占用多少VM

  • 28
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值