逆向入门(4)汇编篇-常用指令的学习

0x01 常用汇编指令

mov就比较熟悉了,前面练习使用的都是这个指令,支持以下用法

mov r,imm	立即数到寄存器
mov r,m	内存到寄存器
mov r,r	寄存器到寄存器
mov m,r	寄存器到内存
mov m,imm 立即数到内存

r是寄存器,m是内存,imm是立即数

这个就不再演示了

add 加法

先将eax值设置为1,然后给eax寄存器的值增加4

add eax,4

运行结果如下
在这里插入图片描述

sub 减法

基于上一部操作,给eax寄存器的值减少2

sub eax,2

运算结果如下
在这里插入图片描述

and 与运算

ecx设置为1,和上一步操作的的eax进行与运算

and eax,ecx

运算结果如下
在这里插入图片描述
这里其实是00110001的与运算,结果肯定为1

or 或运算

ecx设置为3,和上一步操作的eax进行或运算

or eax,ecx

运行结果如下
在这里插入图片描述
实际就是00010011进行或运算,结果为3

not 非运算

直接对上一步的eax取非

not eax

运行结果如下
在这里插入图片描述
3转为000 0000 0000 0000 0000 0000 0000 0011二进制,取非就是1111 1111 1111 1111 1111 1111 1111 1100FFFFFFFC

movs 移动数据

mov指令不能完成内存到内存的操作,但是movs指令可以。由于内存需要指令数据宽度,所以一共有下面3种写法

movs byte ptr es:[edi],byte ptr ds:[esi]						简写:movsb
movs word ptr es:[edi],word ptr ds:[esi]						简写:movsw
movs dword ptr es:[edi],dword ptr ds:[esi]						简写:movsd

这里的esiedi两个寄存器用来存放需要调整数据的内存地址。

举个例子,这里我将0012FFC8的值改为1,然后将这个值移动到0012FFF0

mov edi,0012FFF0
mov esi,0012FFC8
movs dword ptr es:[edi],dword ptr ds:[esi]

运行指令结果如下
在这里插入图片描述
0012fff0值已成功修改,这里除了内存的值移动修改外,还有一个需要注意的点,就是寄存器的值。
在这里插入图片描述
可以发现这两个寄存器的值和之前设置的都不一样了,全部都增加了4,这个增加4或者2或者1取决于数据宽度,是增加还是减少取决于EFL寄存器中DF(第10位)的取值,当DF0时,进行增加,当DF1时,进行减少。
在这里插入图片描述
这里将EFL第十位更改为1后,值为00000606再次进行测试
在这里插入图片描述
此时0012FFCC的值为1A2B,再次运行指令

movs dword ptr es:[edi],dword ptr ds:[esi]

在这里插入图片描述
可以看到值已经修改完成,同时再次观察esiedi寄存器的值
在这里插入图片描述
发现已经减少4,完成实验。

stos,将al/ax/eax的值存储到[edi]指定的内存单元

在学习了一上一个指令后,看完解释,应该可以理解此命令等同于下面两条指令

    mov [edi], eax
    add edi, 4       ;或者 sub edi, 4 

同样也是存到内存中,所以和数据宽度也有关系

stos byte ptr es:[edi]			简写为stosb,对应的就是al寄存器
stos word ptr es:[edi]			简写为stosw,对应的就是ax寄存器
stos dword ptr es:[edi]			简写为stosd,对应的就是eax寄存器

目前DF位为1,则存储后会减少,这里使用ax做测试,先将eax设置为0,此时[edi]0012fff0,然后运行以下指令

mov ax,1a2b
stos word ptr es:[edi]

运行后结果如下
在这里插入图片描述
运行结果如期,同时观察edi寄存器
在这里插入图片描述
确实也是在之前的寄存器的值上减少了2,因为用的是word,所以只减少2

rep,按计数寄存器ecx中指定的次数重复执行字符串指令

比如可以重复使用stosmovs等命令。比如重复10stos,当前ax4444edi0012FFEE,运行以下代码

mov ecx,0xa
rep stos word ptr es:[edi]

运行结果如下
在这里插入图片描述
同时的edi也减少了10*2
在这里插入图片描述


0x02 堆栈常用指令

堆栈是什么?

其实我现在还没太理解清楚,还挺模糊的,按教程老师讲的话就是,程序运行时操作系统为程序分配好的内存,供程序使用。

可以通过FS位查看到堆栈的信息,
在这里插入图片描述
在内存窗口中输入dd 7ffde000
在这里插入图片描述
可以看到栈底是0012d000,栈顶是00130000,堆栈是从大往小用的。

ESP寄存器

esp栈指针寄存器,存放当前的栈用到哪了。
在这里插入图片描述

push指令

用于向栈中压入数据的同时修改(减少)esp寄存器,可以支持以下命令

push r
push m
pusm imm

运行命令push 1111
在这里插入图片描述
可以看到,直接基于栈指针之上的内存地址写入了1111,同时将原本ESP的值0012ffc4改为了0012ffc0,减少了4

pop指令

将栈当前数据存入到寄存器或者内存中,同时ESP的值增加,感觉就和push是相反的。

pop ebp

运行指令后,结果如下
在这里插入图片描述
ebp中已存入1111,同时也将esp的值增加至0012ffc4


0x03 修改eip的指令

eip寄存器存放着是cpu下一次会执行的指令,是不可以通过mov指令来进行修改的。

jmp指令

jmp命令相当于 mov eip,1 ,专用于修改eip寄存器。可以支持两种方式

jmp r
jmp imm

立即数要写成内存地址的格式,并且此内存地址需要使用,当然也可以使用寄存器。

mov eax,0040ef57
jmp eax

按第一个f8
在这里插入图片描述
可以看到,多出了个红色箭头指向了下一次要执行命令的地方,再按第二个f8
在这里插入图片描述
eip已经成功修改。

call指令

call指令功能和jmp基本一样,在此基础上,还在堆栈中存储call指令的下一行地址

CALL 0040EF35

使用f7进行调试
在这里插入图片描述
可以看到eip成功修改,同时esp指针也减少了4,并且将call指令的下一行地址进行存储。

ret指令

相当于下列两条指令

jmp [esp]
add esp,4

在这里插入图片描述
可以看到将栈顶的值存入了eip中,同时将esp的值增加4指向下一个值。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值