0%

汇编2-标志寄存器、jcc语句、堆栈、堆栈图

汇编2-标志寄存器、jcc语句、堆栈、堆栈图

杂项

EIP寄存器是记录程序运行到哪个寄存器就指向哪个寄存器。

cmp语句是用来看前后两个参数的值是否相等的,当然可以指定某个内存中的数据进行比较。比较结果会放到Zf里面去,也就是下图所示的寄存器中。

image-20231228225203726

0XCCCCCCCC 在汇编中是int 3

od

F2 在OD的反汇编视图中使用F2进行下断
F4 程序执行到当前光标位置
F5 缩小、还原当前窗口
F7 单步步入,进入函数内,跟进到CALL地址处
F8 单步步过,越过函数实现,不会进入CALL地址处
F9 直接运行程序,遇到断点程序暂停

标志寄存器

image-20231228225350448

image-20231228225609644

下面这张图是eflag寄存器需要我们掌握的位数,一般都有八个,下面是一些介绍。

image-20231228225849576

image-20231228230924204

堆栈

image-20231228231149048

上图,一个exe程序可以分为这几个区域,
其中代码区就是存储一些代码,他是可读可可执行(rx)权限
堆,这个里面就是c语言里面的malloc函数申请的内存空间就是申请在这里面的。

ESP EBP

esp和ebp分别是栈顶和栈底,值得注意的是,这个堆栈是从高字节往第四节存储的。

在进入程序和退出程序的时候,esp和ebp的值是不能变的,也就是堆栈平衡。

jcc语句

jmp,跳转到指定地址 硬编码:e9
jmp是不会引起esp和ebp的变化的。(其本质就是修改EIP,但是你自己直接mov eip是不行的)

call,跳转到指定地址并返回到当前指令的下一行(调用函数之后回来),硬编码 e8
call是会涉及到堆栈的变化的,esp提升4字节,将返回地址压入堆栈。
值得注意的是,由于esp和ebp是从高字节往低字节存储的,所以提升4也就是减4.

ret,返回到指定地址(和retn是一个东西)
ret会esp会降低4字节,并且会从堆栈中提出返回地址传给eip

cmp指令,比较两 个操作数是否相等,如果相等则ZF为1(但是不能比较两个立即数)

test指令,对两个操作数进行相与操作,通常都是用于判断一个寄存器是否为0,test eax eax

而jcc语句大多都是通过不同的情况,进行跳转

image-20231229151423853

堆栈

压入数据

压入数据一般就可以大致分为下面两个

1.先把数据存到堆栈-4的那个地址,随后将堆栈提升4字节,从而存入

1
2
3
代码实现如下:
mov dword ptr ds:[0x19FF70],0x123456
sub esp,0x4

2.也可以先提栈再存入。

读取数据

可以直接从栈顶和栈底来读取数据,esp和ebp

移除数据

和压入数据差不多,可以先压栈再去除数据,或者先取出数据之后在压栈。

当然上述指令都不常用,我们一般用push和pop,只不过讲解上面的内容是方便理解原理。

push

向堆栈中存入数据,只有一个参数,那个参数就是数据。

pop

压栈之后将数据存入寄存器中,只有一个参数,那个参数就是寄存器。

堆栈图

stos指令,循环执行将eax的值存储到[edi]指定的内存,执行ecx中存储的次数,每执行一次ecx的值减1。

保留环境:esp ebp在进入函数的时候是什么样,出来的时候就是什么样子。