反汇编深入分析函数调用

来源:互联网 发布:飘谁翻译的最好 知乎 编辑:程序博客网 时间:2024/04/28 19:19

文章来源:http://club.xasoft.org/?uid-356-action-viewspace-itemid-4408

函数:

intfun(inta,intb) {

  charvar[128] = "A";

  a = 0x4455;

  b = 0x6677;

  returna + b;

}

intmain() {

   fun(0x8899,0x1100);

   return0;

}

F11跟踪fun,alt+8看反汇编代码:

//参数压栈,遵循__cdecl调用规范,参数由右向左

00401078  push       1100h//第一个参数压栈

0040107D  push       8899h//第二个参数压栈

00401082  call       @ILT+0(_fun) (00401005)//调用函数

00401087  add        esp,8//被调用函数的堆栈由主调函数来清空堆栈,使堆栈平衡。

由上图的EIP可以看到0040B500就是下条要执行的指令,在Memory窗口中可以看到内存数据9988000011000000,实质上是0x8899,0x1100,(intel处理器一般都是小端存储),还可以看到有内存数据87104000,实质上是00401087,在主调函数中,可以很清楚的看到00401087被调函数返回以后执行的第一条指令,也就是堆栈清空指令(遵循__cdecl调用规范)Call指令隐含做了一个操作:就是把函数返回后执行的第一条指令压入堆栈(push)。

1:   int fun(int a, int b) {

0040B500  push       ebp

0040B501  mov        ebp,esp //调用函数通常的做法,通过ebp基址寄存器来操作堆//栈数据

0040B503  sub        esp,0C0h//为什么是C0h(不是因为堆栈保护,TKX;2NvU_d'O

防止缓冲区overflow,而是DEBUG选项造成的)

0040B509  push       ebx

0040B50A  push       esi

0040B50B  push       edi

0040B50C  lea        edi,[ebp-0C0h]

0040B512  mov        ecx,30h //C0h除以4,就是30h,因为rep stos用的是dword

0040B517  mov        eax,0CCCCCCCCh

0040B51C  rep stos   dword ptr [edi] //0CCCCCCCCh初始化堆栈

2:      char var[128] = "A";

0040B51E  mov        ax,[string "A" (0041f10c)] //此时EBP = 0012FF24

0040B524  mov        word ptr [ebp-80h],ax //80h也就是128,写了一个字

0040B528  mov        ecx,1Fh              //1Fh31

0040B52D  xor        eax,eax              //清零

0040B52F  lea        edi,[ebp-7Eh]

0040B532  rep stos   dword ptr [edi]      //一共是32个双字,开始写了一个字,rep stos

0040B534  stos       word ptr [edi]       //写入了31个双字,还剩下一个字由stos完成

//var的地址是:0x0012fea4

3:      a = 0x4455;

0040B536  mov        dword ptr [ebp+8],4455h

4:      b = 0x6677;

0040B53D  mov        dword ptr [ebp+0Ch],6677h

5:      return a + b;

0040B544  mov        eax,dword ptr [ebp+8]

0040B547  add        eax,dword ptr [ebp+0Ch] //返回值通过eax保存

6:   }

0040B54A  pop        edi

0040B54B  pop        esi

0040B54C  pop        ebx //弹栈(windowsAPI都会有这三个寄存器的保存,回复工作)

0040B54D  mov        esp,ebp

0040B54F  pop        ebp //恢复ebp寄存器

0040B550  ret             //默认操作,D网管2jTKg4h_OC=育管`Ok发达 地专%X2|p.x1QcZ_U恢复EIP:将堆栈中的00401087popEIP

 

执行完:0040B50B  push       edi如下图:

ESP0012FE58与刚进入函数的时候的ESP0012FF28之间的堆栈图如下:

执行完:0040B51C  rep stos   dword ptr [edi]EDI为:0012FF24,如下图: