gmh5225 发表于 2014-12-25 17:08

汇编逆向(三)

本帖最后由 gmh5225 于 2014-12-25 17:11 编辑

写这个纯属就是自己记录下自己的学习经历,没有其他的意思。




局部变量,参数,全局变量


无脑记法:
局部变量:第一个 第二个,类推
参数:第一个参数,第二个,类推
全局变量:一般都是 mov eax,dword ptr ds:之类的
局部变量需要使用subesp,xx 开辟空间xx个字节空间,有几个局部变量就开几个
举例:
003C1040 >55            push    ebp                              ;保存原来ebp指针
003C1041    8BEC            mov   ebp, esp                         ;ebp指向esp,即堆栈
003C1043    83EC 0C         sub   esp, 0xC                         ; 开辟12个字节空间供3个变量
003C1046    C745 FC 0300000>mov   dword ptr , 0x3         ; int a
003C104D    C745 F8 0400000>mov   dword ptr , 0x4         ; int b
003C1054    C745 F4 0000000>mov   dword ptr , 0x0         ; int c
////////////////////////////////////////////////////////////////////////
003C10A9    83C4 04         add   esp, 0x4
003C10AC    33C0            xor   eax, eax                                     ;清空eax
003C10AE    8BE5            mov   esp, ebp                                 ;esp指向当前ebp,同步跟进
003C10B0    5D            pop   ebp                                             ;还原原来ebp指针
003C10B1    C3            retn
可以看到我的第一个局部变量是 ,初值是3,第二个是b,第三个是c


而参数因为之前的压栈导致esp的减少,一般如果是int型,就每次减4个字节,进行call的时候还会减4字节,在ret时返回4字节平衡,所以第一个参数就是ebp+8,注意堆栈的存储方式
,第二个就是ebp+c
举例:
003C1000 >55            push    ebp
003C1001    8BEC            mov   ebp, esp
003C1003    8B45 08         mov   eax, dword ptr     //这里是第一个参数
003C1006    0345 0C         add   eax, dword ptr    // b
003C1009    5D            pop   ebp
003C100A    C3            retn
此外,编译器还会用其他的寄存器来代替开辟局部变量的操作,以此来节省二进制的大小
C源代码:
int add(int a,int b)
{
      int c=a+b;
      return c;
}
int main()
{   
      int a=3,b=4,c=0;
      c=add(a,b);
      printf("%d",c);
      system("pause");
      return 0;
}OD反汇编:
主要看add这个函数内部:
010E1000 >55            push    ebp
010E1001    8BEC            mov   ebp, esp
010E1003    51            push    ecx //这里就是运用了节省空间的方法,达到同样开辟4字节的效果
010E1004    8B45 08         mov   eax, dword ptr
010E1007    0345 0C         add   eax, dword ptr
010E100A    8945 FC         mov   dword ptr , eax
010E100D    8B45 FC         mov   eax, dword ptr
010E1010 >8BE5            mov   esp, ebp
010E1012    5D            pop   ebp
010E1013    C3            retn
上面的代码可以看到,push ecx这命令,相当于是subesp,4 不过这样写二进制编码就是51,节省了很大的空间,提高效率



全局变量:一般都是 mov eax,dword ptr ds:之类的,里面的内容是一个4字节的内存地址
C源代码:
int x=0;
int add(int a,int b)
{

      return a+b+x;
}
int main()
{   
      int a=3,b=4,c=0;
      x=5;
      c=add(a,b);
      printf("%d",c);
      system("pause");
      return 0;
}OD反汇编: 01071020 >55            push    ebp
01071021    8BEC            mov   ebp, esp
01071023    83EC 0C         sub   esp, 0xC                         ; 开辟12个字节的空间
01071026    C745 FC 0300000>mov   dword ptr , 0x3         ; int a=3
0107102D    C745 F8 0400000>mov   dword ptr , 0x4         ; int b=4
01071034    C745 F4 0000000>mov   dword ptr , 0x0         ; int c=0
0107103B    C705 6C330701 0>mov   dword ptr , 0x5               ; 全局变量x=5
01071045    8B45 F8         mov   eax, dword ptr
01071048    50            push    eax                              ; 压b
01071049    8B4D FC         mov   ecx, dword ptr
0107104C    51            push    ecx                              ; 压a
0107104D    E8 AEFFFFFF   call    testtest.add                     ; 调用add函数
01071052    83C4 08         add   esp, 0x8                         ; 堆栈平衡
01071055    8945 F4         mov   dword ptr , eax
01071058    8B55 F4         mov   edx, dword ptr
0107105B    52            push    edx
0107105C    68 F4200701   push    testtest.010720F4                ; ASCII "%d"
01071061    FF15 9C200701   call    dword ptr [<&MSVCR100.printf>]   ; msvcr100.printf
01071067    83C4 08         add   esp, 0x8
0107106A    68 F8200701   push    testtest.010720F8                ; ASCII "pause"
0107106F    FF15 A4200701   call    dword ptr [<&MSVCR100.system>]   ; msvcr100.system
01071075    83C4 04         add   esp, 0x4                         ; 压 a
01071078    33C0            xor   eax, eax
0107107A    8BE5            mov   esp, ebp
0107107C    5D            pop   ebp
0107107D    C3            retn


看下add函数
01071000 >55            push    ebp
01071001    8BEC            mov   ebp, esp
01071003    8B45 08         mov   eax, dword ptr          ; 参数1 a
01071006    0345 0C         add   eax, dword ptr          ; 参数2 ba=a+b
01071009    0305 6C330701   add   eax, dword ptr                ; 全局变量x   a=a+x
0107100F    5D            pop   ebp
01071010 >C3            retn

变量到此结束!







Scar-疤痕 发表于 2014-12-25 17:39

很详细的教程,学习了!

geekcat 发表于 2014-12-25 19:48

希望这个系列一直做下去!

sndncel 发表于 2014-12-25 20:49

{:5_117:}谢谢分享。这个要支持一下,对于新手来说,非常的有用呀。。。。

Desire 发表于 2014-12-25 23:29

不会c语言怎么破

=天天= 发表于 2015-1-2 23:21




教程不错学习一下

fcguo800 发表于 2017-11-30 14:51

感谢楼主教程,继续学习中。

别管我了行 发表于 2022-2-25 02:25

weiran324 发表于 2022-3-31 18:27

学习学习

4957465 发表于 2022-5-20 02:05

页: [1] 2
查看完整版本: 汇编逆向(三)