首页
社区
课程
招聘
[原创]逆向C++之一 基本数据类型
发表于: 2008-12-6 11:40 16968

[原创]逆向C++之一 基本数据类型

2008-12-6 11:40
16968

【文章标题】: 逆向C++之一 基本数据类型
【文章作者】: kanghtta
【作者邮箱】: kanghtta@hotmail.com
【作者主页】: http://kanghtta.cublog.cn
--------------------------------------------------------------------------------
【详细过程】
   
   
  
  #include<iostream>
  using namespace std;
  
  int main()
  {
          int a=2,
                  b=4;
          float        c=2.0f;
          bool        v=1;
          char        x=2;
          return        0;
  }
  
   我们知道,上面定于的几个基本数据类型的局部变量,一共占用8+4+1+1 = 14字节;  编译链接后生成exe文件,用OD载入之,
   由于main函数实际要压入三个参数,故在GetCommandlineA函数下不远处可找到main函数的调用;
  
  004083FB  |.  E8 E05F0000   call    0040E3E0
  00408400  |.  FF15 60F14300 call    dword ptr [<&KERNEL32.GetCommand>; [GetCommandLineA
  00408406  |.  A3 A4E64300   mov     dword ptr [43E6A4], eax
  0040840B  |.  E8 B05D0000   call    0040E1C0
  00408410  |.  A3 8CCC4300   mov     dword ptr [43CC8C], eax
  00408415  |.  E8 96580000   call    0040DCB0
  0040841A  |.  E8 41570000   call    0040DB60
  0040841F  |.  E8 7C430000   call    0040C7A0
  00408424  |.  8B0D D8CC4300 mov     ecx, dword ptr [43CCD8]
  0040842A  |.  890D DCCC4300 mov     dword ptr [43CCDC], ecx
  00408430  |.  8B15 D8CC4300 mov     edx, dword ptr [43CCD8]
  00408436  |.  52            push    edx
  00408437  |.  A1 D0CC4300   mov     eax, dword ptr [43CCD0]
  0040843C  |.  50            push    eax
  0040843D  |.  8B0D CCCC4300 mov     ecx, dword ptr [43CCCC]
  00408443  |.  51            push    ecx
  00408444  |.  E8 C68BFFFF   call    0040100F  ;main函数入口地址
  00408449  |.  83C4 0C       add     esp, 0C
  
  
  
  我们知道 call 指令执行的操作是: push eip 即将子程序的返回地址(也就是call指令的下一条指令的地址)存入堆栈中;
  F7跟进,在堆栈窗口中的esp此时指向00408449,也就是call 0040100F的后条指令的地址
  ESP ==>  > 00408449  返回到 class.<模块入口点>+0E9 来自 class.0040100F
  
  
  
  
  
  00401030  /> \55            push    ebp                    ;main的反汇编代码
  00401031  |.  8BEC          mov     ebp, esp
  00401033  |.  83EC 54       sub     esp, 54
  00401036  |.  53            push    ebx
  00401037  |.  56            push    esi
  00401038  |.  57            push    edi
  00401039  |.  8D7D AC       lea     edi, dword ptr [ebp-54]
  0040103C  |.  B9 15000000   mov     ecx, 15
  00401041  |.  B8 CCCCCCCC   mov     eax, CCCCCCCC
  00401046  |.  F3:AB         rep     stos dword ptr es:[edi]
  00401048  |.  C745 FC 02000>mov     dword ptr [ebp-4], 2        ; a=2
  0040104F  |.  C745 F8 04000>mov     dword ptr [ebp-8], 4        ;b=4;
  00401056  |.  C745 F4 00000>mov     dword ptr [ebp-C], 40000000 ;c=2.0f;
  0040105D  |.  C645 F0 01    mov     byte ptr [ebp-10], 1        ;v=1;
  00401061  |.  C645 EC 02    mov     byte ptr [ebp-14], 2        ;x=2;
  00401065  |.  33C0          xor     eax, eax                   ;return        0;
  00401067  |.  5F            pop     edi
  00401068  |.  5E            pop     esi
  00401069  |.  5B            pop     ebx
  0040106A  |.  8BE5          mov     esp, ebp
  0040106C  |.  5D            pop     ebp
  0040106D  \.  C3            retn
  
  我们知道,c函数调用的参数入栈顺序是从右到左,而在汇编中学过,ebp的默认段也是ss段,也就是说,ebp寄存器是配合
  堆栈段使用的,而他往往被用来作为存取局部变量的指针基址,同时也起着保存 原始esp指针的作用,以便在函数执行完后能
  让ret指令从堆栈中读到正确的返回地址; 我们看到 ,在子程序开始时有一 push ebp  mov ebp,esp指令,
  而在结束时有mov esp,ebp  pop ebp 指令;它们成对出现,在80386中也可以用leave指令来代替后两条指令;
  指令,他们成对出现,
  
  这里有一点我不大明白,局部变量一共只需要14字节就能保存,加上ebx,esi,edi等寄存器也才24字节,而C++编译器却初始化
  了54字节,并用CCCCCCCC初始化堆栈空间,而当mov esp ebp 执行后,堆栈被清空,可以说有点浪费空间了,但不知道多初始化
  这一部分空间有什么用途;
  
  F8跟到初始化完后,堆栈中数据如下;
  
  EBP-54   > CCCCCCCC
  EBP-50   > CCCCCCCC
  EBP-4C   > CCCCCCCC
  EBP-48   > CCCCCCCC
  EBP-44   > CCCCCCCC
  EBP-40   > CCCCCCCC
  EBP-3C   > CCCCCCCC
  EBP-38   > CCCCCCCC
  EBP-34   > CCCCCCCC
  EBP-30   > CCCCCCCC
  EBP-2C   > CCCCCCCC
  EBP-28   > CCCCCCCC
  EBP-24   > CCCCCCCC
  EBP-20   > CCCCCCCC
  EBP-1C   > CCCCCCCC
  EBP-18   > CCCCCCCC
  EBP-14   > CCCCCC02   ;char x
  EBP-10   > CCCCCC01   ;bool v
  EBP-C    > 40000000   ;float c
  EBP-8    > 00000004   ;int b
  EBP-4    > 00000002   ;int a
  
  
  
  
--------------------------------------------------------------------------------
【经验总结】
    我们知道,了解子程序调用的栈变化情况,是利用栈溢出的基础; 故,通过一个简单的C程序来加深对c语言的理解;也
  为进一步学习shellcode打下基础;
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2008年12月06日 11:36:52


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (11)
雪    币: 385
活跃值: (144)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
希望可以继续往下写啊!
2008-12-6 18:54
0
雪    币: 199
活跃值: (27)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
希望以后多一点逆向分析技术资料供学习。。。
2009-1-13 23:44
0
雪    币: 212
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感觉楼主是写书的。
2009-1-17 20:55
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
谢谢,学习一下了!!!
2009-1-19 08:35
0
雪    币: 561
活跃值: (124)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
学习下
2009-1-19 23:40
0
雪    币: 102
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
win7 用od载入控制台程序,完全不是这样啊!
01341490 >  55              PUSH EBP
01341491    8BEC            MOV EBP,ESP
01341493    81EC 10010000   SUB ESP,110
01341499    53              PUSH EBX
0134149A    56              PUSH ESI
0134149B    57              PUSH EDI
0134149C    8DBD F0FEFFFF   LEA EDI,DWORD PTR SS:[EBP-110]
013414A2    B9 44000000     MOV ECX,44
013414A7    B8 CCCCCCCC     MOV EAX,CCCCCCCC
013414AC    F3:AB           REP STOS DWORD PTR ES:[EDI]
013414AE    C745 F8 0200000>MOV DWORD PTR SS:[EBP-8],2
013414B5    C745 EC 0400000>MOV DWORD PTR SS:[EBP-14],4
013414BC    D905 3C783401   FLD DWORD PTR DS:[__real@40000000]
013414C2    D95D E0         FSTP DWORD PTR SS:[EBP-20]
013414C5    C645 D7 01      MOV BYTE PTR SS:[EBP-29],1
013414C9    C645 CB 02      MOV BYTE PTR SS:[EBP-35],2
013414CD    C745 BC 3078340>MOV DWORD PTR SS:[EBP-44],OFFSET test.??_C@_07DJMAIOHN@lengxue?$AA@                                                ; lengxue
013414D4    8BF4            MOV ESI,ESP

部分代码如上:第一个变量偏移8字节,第二个竟然偏移12个字节。
2013-4-15 11:07
0
雪    币: 291
活跃值: (213)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
8
不奇怪,有对齐什么的。
2013-4-15 11:18
0
雪    币: 2939
活跃值: (2768)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
9
ls正解,有对齐。另外LZ这个是debug版
2013-4-15 12:38
0
雪    币: 69
活跃值: (30)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
那一堆CC是用来作错误侦测的吗
我猜写入那边的话程式结束时会报记忆体泄漏
2013-4-15 12:49
0
雪    币: 102
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
对齐怎么理解?有什么规律吗?而且这个地址也奇怪 不是004开头
2013-4-15 14:44
0
雪    币: 420
活跃值: (77)
能力值: ( LV13,RANK:500 )
在线值:
发帖
回帖
粉丝
12
首先呢,看看自己的系统平台和编译环境,不同的编译器编译出来的东西,C++的内存布局上不相同的,其次呢,多用google,或者还+ #pragma pack(n) 试试,一般写struct 或class 的时候,小字节在前,大字节在后,
等有时间在来篇文章补充下。
2013-4-16 16:07
0
游客
登录 | 注册 方可回帖
返回
//