ff 15 调用函数与e8调用函数的区别 call的两种二进制命令

ff 15 和e8都是用来调用函数的机器码,看一个例子:
218 f9ebc53a 6a00                  push    0
218 f9ebc53c ff1500c9ebf9    call    dword ptr [APC!PspExitThread_Addr (f9ebc900)]
219 f9ebc542 a100c9ebf9      mov     eax,dword ptr [APC!PspExitThread_Addr (f9ebc900)]
219 f9ebc547 50                      push    eax
219 f9ebc548 68f0c4ebf9     push    offset APC!GetPspExitThreadAddr+0xee (f9ebc4f0)
219 f9ebc54d e872020000     call    APC!DbgPrint (f9ebc7c4)
219 f9ebc552 83c408              add     esp,8
220 f9ebc555 e870020000     call    APC!KeGetCurrentThread (f9ebc7ca)
220 f9ebc55a 8945fc               mov     dword ptr [ebp-4],eax
221 f9ebc55d 8b4dfc               mov     ecx,dword ptr [ebp-4]
221 f9ebc560 51                      push    ecx
221 f9ebc561 680cc5ebf9      push    offset APC!GetPspExitThreadAddr+0x10a (f9ebc50c)
221 f9ebc566 e859020000    call    APC!DbgPrint (f9ebc7c4)
221 f9ebc56b 83c408             add     esp,8

222 f9ebc56e 6a00                 push    0
222 f9ebc570 8b5508             mov     edx,dword ptr [ebp+8]
222 f9ebc573 52                     push    edx
222 f9ebc574 ff1508c8ebf9   call    dword ptr [APC!_imp__ExFreePoolWithTag (f9ebc808)]

APC!KillThreadRoutine+0x4d [f:/dvs/apc/apc.c @ 224]:
224 f9ebc57a 8be5                mov     esp,ebp
224 f9ebc57c 5d                     pop     ebp
224 f9ebc57d c21400            ret     14h
看上面的代码得到的结果是:
ff 15 调用时后面直接跟的是函数地址,并且不需要主调函数来平衡堆栈(即不需要在主调函数中使用add esp,xxh)
e8调用时后面跟的是函数地址相对于当前地址的偏移量,并且需要主调函数来实现堆栈平衡(即需要在主调函数中添加add esp,xxh),这个xxh当然是等于调用函数前push了多少字节的参数)
但是不知道还有没有其他的区别了...

 

 

 

PS:

call 一个near过程,只把偏移地址压入堆栈,过程返回时用retn返回
call一个far过程,把偏移地址和段地址入栈,过程返回时用retf返回

在过程中的ret指令根据near和far的不同,分别编译成retn和 retf
retn和retf的机器码是不同的,你也可以不定义过程,直接用retn和retf

好的,下面是二进制炸弹第一阶段的`strings_not_equal`函数比较字符串是否相等的反汇编代码及逐条解释: ```assembly 08048c4b <strings_not_equal>: 8048c4b: 55 push ebp 8048c4c: 89 e5 mov ebp,esp 8048c4e: 83 ec 18 sub esp,0x18 8048c51: 8b 45 08 mov eax,DWORD PTR [ebp+0x8] 8048c54: 8b 55 0c mov edx,DWORD PTR [ebp+0xc] 8048c57: 89 04 24 mov DWORD PTR [esp],eax 8048c5a: e8 71 ff ff ff call 8048bd0 <strcmp@plt> 8048c5f: 85 c0 test eax,eax 8048c61: 0f 94 c0 sete al 8048c64: 0f b6 c0 movzx eax,al 8048c67: c9 leave 8048c68: c3 ret ``` 1. `push ebp`:将当前函数的栈底指针 `ebp` 压入栈中,为当前函数建立栈帧。 2. `mov ebp, esp`:将当前栈顶指针 `esp` 的值赋给栈底指针 `ebp`,为当前函数建立栈帧。 3. `sub esp, 0x18`:在栈上分配 `0x18` 字节的空间,用于存储局部变量。 4. `mov eax, DWORD PTR [ebp+0x8]`:将第一个参数的值(即调用该函数时传入的第一个字符串)存储在寄存器 `eax` 中。 5. `mov edx, DWORD PTR [ebp+0xc]`:将第二个参数的值(即调用该函数时传入的第二个字符串)存储在寄存器 `edx` 中。 6. `mov DWORD PTR [esp], eax`:将第一个字符串的指针存储在栈顶指针 `esp` 指向的位置上。 7. `call 8048bd0 <strcmp@plt>`:调用 `strcmp` 函数,比较两个字符串是否相等。 8. `test eax, eax`:将 `eax` 寄存器的值自身进行按位操作,用于判断 `eax` 是否为零。 9. `sete al`:将 `al` 寄存器的值设置为 `1` 或 `0`,表示比较的结果是否相等。 10. `movzx eax, al`:将 `al` 寄存器的值(即比较结果)零拓展,存储到 `eax` 寄存器中。 11. `leave`:撤销当前函数的栈帧。 12. `ret`:从当前函数返回,并弹出栈顶元素。 以上是二进制炸弹第一阶段的`strings_not_equal`函数比较字符串是否相等的反汇编代码及逐条解释。该函数的作用是比较两个字符串是否相等,如果相等则返回0,否则返回非零值。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值