反汇编函数(C)

裸函数(无参无返空实现)

void _declspec(naked) Function(){
   __asm{
       push ebp
       mov ebp,esp
       sub esp,0x40
       
 push ebx
 push esi
 push edi
           
 lea edi,dword ptr ds:[ebp-0x40]
       mov eax,0xCCCCCCCC
 mov ecx,0x10
       rep stosd
       
       pop edi
       pop esi
       pop ebx
       
       mov esp,ebp
       pop ebp
       ret
   }
}

int main(){
   
   Function();
}

函数返回值

函数返回值是通过EAX传出去的(在函数ret之前如果有返回,他会先将要返回的地址的值放在EAX寄存器中,之后EAX保持不变,返回。)

示例代码如下:

;int a=1;
;int b=2;
;int c=a+b;
mov dword ptr [ebp-8],1
mov dword ptr [ebp-14h],2
mov eax,dword ptr [ebp-8]
add eax,dword ptr [ebp-14h]
mov dword ptr [ebp-20h],eax
;eax = result
;此处就是将结果c所在地址的值给到EAX寄存器中返回
mov eax,dword ptr [ebp-20h]

注意:mov dword ptr ds:[ebp-8],1和mov dword ptr [ebp-8],1的区别,第一种指定了段寄存器ds,第二种则使用默认寄存器,默认为ds。

函数传参

函数的第一个参数位置为[ebp+8],第二个参数位置为[ebp+C],因为[ebp+0]位置为原ebp位置,[ebp+4]位置为函数调用后的下一步的地址,所以第一个参数的位置为[ebp+8]。

在调用之前原函数会将每个参数从右往左依次压入堆栈,然后再执行call命令,在call命令执行结束之后需要将原来堆栈加 4×参数数。

调用约定

调用约定参数压栈顺序平衡堆栈
__cdecl从右至左入栈调用者清理栈
__stdcall从右至左入栈自身清理堆栈
__fastcallECX/EDX传送前两个 剩下:从右至左入栈自身清理堆栈

1、add esp,10h

2、ret 10h

3、先把前两参数传给ECX和EDX,然后ECX和EDX再将值放到变量堆栈区,就是自己弄出来到缓冲区。ret 8h

堆栈回溯(EBP)

int Fun1(){
   int Addr1=0;
   int Addr2=0;
   
   __asm{
       mov eax,dword ptr ds:[ebp+4]
       mov dword ptr ds:[Addr1],eax
       
       mov eax,dword ptr ds:[ebp]
       mov eax,dword ptr ds:[eax+4]
       mov dword ptr ds:[Addr2],eax
   }
   
   printf("%x \n",Addr1 - 5);
   printf("%x \n",Addr2 - 5);
}

EBP 回溯过程

  • 确定当前栈帧的底部:EBP 寄存器指向当前函数栈帧的底部。当开始回溯时,首先读取当前 EBP 的值。假设这个值为ebp_value

  • 获取返回地址:在栈帧中,返回地址通常存储在相对于 EBP 的一个固定偏移量位置。在 32 位系统中,返回地址一般位于ebp_value + 4处。通过读取这个位置的值,可以得到当前函数的返回地址,这个返回地址指向调用当前函数的下一条指令的地址,从而知道是从哪里调用到当前函数的。

  • 获取上一栈帧的 EBP:上一栈帧的 EBP 值通常存储在当前栈帧底部的位置(即当前 EBP 所指向的位置)。通过读取这个位置的值,可以得到上一栈帧的 EBP,这是回溯到上一个函数栈帧的关键。

  • 重复上述步骤:不断重复获取上一栈帧的 EBP、返回地址的操作,就可以沿着栈向上回溯,逐步构建出函数调用链。每次获取新的 EBP 值后,就可以在新的栈帧中找到对应的返回地址和其他相关信息(如函数参数等)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值