首页
论坛
课程
招聘
[原创]C++函数反汇编实验
2021-12-20 14:59 11129

[原创]C++函数反汇编实验

2021-12-20 14:59
11129

测试代码(见下方)

main初始化部分反汇编代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
000C3C20  push        ebp 
000C3C21  mov         ebp,esp 
000C3C23  sub         esp,308h 
000C3C29  push        ebx 
000C3C2A  push        esi 
000C3C2B  push        edi 
000C3C2C  lea         edi,[ebp+FFFFFCF8h] 
000C3C32  mov         ecx,0C2h 
000C3C37  mov         eax,0CCCCCCCCh 
000C3C3C  rep stos    dword ptr es:[edi] 
000C3C3E  mov         eax,dword ptr ds:[000C9088h
000C3C43  xor         eax,ebp 
000C3C45  mov         dword ptr [ebp-4],eax

功能函数代码分析

无参函数

  1. 带返回值

    1. 反汇编代码

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      int IntSize()
      {
      000C1650  push        ebp 
      000C1651  mov         ebp,esp 
      000C1653  sub         esp,0C0h 
      000C1659  push        ebx 
      000C165A  push        esi 
      000C165B  push        edi 
      000C165C  lea         edi,[ebp+FFFFFF40h] 
      000C1662  mov         ecx,30h 
      000C1667  mov         eax,0CCCCCCCCh 
      000C166C  rep stos    dword ptr es:[edi] 
       return sizeof(int);
      000C166E  mov         eax,4 
      }
      000C1673  pop         edi 
      000C1674  pop         esi 
      000C1675  pop         ebx 
      000C1676  mov         esp,ebp 
      000C1678  pop         ebp 
      000C1679  ret

      分析

      返回值在eax中

  2. 不带返回值

    1. 反汇编代码

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      void print()
      {
      00C11410  push        ebp 
      00C11411  mov         ebp,esp 
      00C11413  sub         esp,0C0h 
      00C11419  push        ebx 
      00C1141A  push        esi 
      00C1141B  push        edi 
      00C1141C  lea         edi,[ebp+FFFFFF40h] 
      00C11422  mov         ecx,30h 
      00C11427  mov         eax,0CCCCCCCCh 
      00C1142C  rep stos    dword ptr es:[edi] 
       printf("No params\n");
      00C1142E  mov         esi,esp 
      00C11430  push        0C16CA8h 
      00C11435  call        dword ptr ds:[00C1C2BCh
      00C1143B  add         esp,4 
      00C1143E  cmp         esi,esp 
      00C11440  call        00C11159 
      }
      00C11445  pop         edi 
      00C11446  pop         esi 
      00C11447  pop         ebx 
      00C11448  add         esp,0C0h 
      00C1144E  cmp         ebp,esp 
      00C11450  call        00C11159 
      00C11455  mov         esp,ebp 
      00C11457  pop         ebp 
      00C11458  ret
    2. 分析

      EBP+4是函数返回的IP寄存器的值


  1. 有参函数

    1. 基本类型变量

      1. 一个参数

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
          print("THINCT");
        00E13C52  push        0E16C94h 
        00E13C57  call        00E11226 
        00E13C5C  add         esp,4 
         
        ;------------------------
        void print(const char* name)
        {
        00E11520  push        ebp 
        00E11521  mov         ebp,esp 
        00E11523  sub         esp,0C0h 
        00E11529  push        ebx 
        00E1152A  push        esi 
        00E1152B  push        edi 
        00E1152C  lea         edi,[ebp+FFFFFF40h] 
        00E11532  mov         ecx,30h 
        00E11537  mov         eax,0CCCCCCCCh 
        00E1153C  rep stos    dword ptr es:[edi] 
          printf("name: %s", name);
        00E1153E  mov         esi,esp 
        00E11540  mov         eax,dword ptr [ebp+8
        00E11543  push        eax 
        00E11544  push        0E16B98h 
        00E11549  call        dword ptr ds:[00E1C2BCh
        00E1154F  add         esp,8 
        00E11552  cmp         esi,esp 
        00E11554  call        00E11159 
        }
        00E11559  pop         edi 
        00E1155A  pop         esi 
        00E1155B  pop         ebx 
        00E1155C  add         esp,0C0h 
        00E11562  cmp         ebp,esp 
        00E11564  call        00E11159 
        00E11569  mov         esp,ebp 
        00E1156B  pop         ebp 
        00E1156C  ret

      2. 两个参数

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
          add(3, 4);
        00E13C5F  push        4 
        00E13C61  push        3 
        00E13C63  call        00E11203 
        00E13C68  add         esp,8 
         
        ;---------------------------------
         
        int add(int a, int b)
        {
        00E11570  push        ebp 
        00E11571  mov         ebp,esp 
        00E11573  sub         esp,0C0h 
        00E11579  push        ebx 
        00E1157A  push        esi 
        00E1157B  push        edi 
        00E1157C  lea         edi,[ebp+FFFFFF40h] 
        00E11582  mov         ecx,30h 
        00E11587  mov         eax,0CCCCCCCCh 
        00E1158C  rep stos    dword ptr es:[edi] 
          return a + b;
        00E1158E  mov         eax,dword ptr [ebp+8
        00E11591  add         eax,dword ptr [ebp+0Ch
        }
        00E11594  pop         edi 
        00E11595  pop         esi 
        00E11596  pop         ebx 
        00E11597  mov         esp,ebp 
        00E11599  pop         ebp 
        00E1159A  ret

        1. 参数压栈顺序和函数调用约定有关
        2. 返回值在eax中
    2. 指针变量

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
        add(4, 5, &result);
      00E13C72  lea         eax,[ebp-0Ch
      00E13C75  push        eax 
      00E13C76  push        5 
      00E13C78  push        4 
      00E13C7A  call        00E11217 
      00E13C7F  add         esp,0Ch 
       
      ;---------------------------
       
      void add(int a, int b, int* result)
      {
      00E13AB0  push        ebp 
      00E13AB1  mov         ebp,esp 
      00E13AB3  sub         esp,0C0h 
      00E13AB9  push        ebx 
      00E13ABA  push        esi 
      00E13ABB  push        edi 
      00E13ABC  lea         edi,[ebp+FFFFFF40h] 
      00E13AC2  mov         ecx,30h 
      00E13AC7  mov         eax,0CCCCCCCCh 
      00E13ACC  rep stos    dword ptr es:[edi] 
        *result = a + b;
      00E13ACE  mov         eax,dword ptr [ebp+8
      00E13AD1  add         eax,dword ptr [ebp+0Ch
      00E13AD4  mov         ecx,dword ptr [ebp+10h
      00E13AD7  mov         dword ptr [ecx],eax

    3. 结构体变量

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
        print(stu);
      00E13CA0  sub         esp,104h 
      00E13CA6  mov         ecx,41h 
      00E13CAB  lea         esi,[ebp+FFFFFEE8h] 
      00E13CB1  mov         edi,esp 
      00E13CB3  rep movs    dword ptr es:[edi],dword ptr [esi] 
      00E13CB5  call        00E1121C 
      00E13CBA  add         esp,104h
       
      ;-----------------------------
      void print(student stu)
      {
      00E139F0  push        ebp 
      00E139F1  mov         ebp,esp 
      00E139F3  sub         esp,0CCh

      结构体传值是内存副本。是edi寄存器的值,而非原本变量所在内存。

    4. 结构体指针变量

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      00E13CC0  lea         eax,[ebp+FFFFFEE8h] 
      00E13CC6  push        eax 
      00E13CC7  call        00E1122B 
      00E13CCC  add         esp,4 
      ;------------------------------
       
      void print(student* stu)
      {
      00E13720  push        ebp 
      00E13721  mov         ebp,esp 
      00E13723  sub         esp,0C0h 
      00E13729  push        ebx 
      00E1372A  push        esi 
      00E1372B  push        edi 
      00E1372C  lea         edi,[ebp+FFFFFF40h] 
      00E13732  mov         ecx,30h 
      00E13737  mov         eax,0CCCCCCCCh 
      00E1373C  rep stos    dword ptr es:[edi] 
        printf("name: %s, age: %d\n", stu->name, stu->age);

      直接取对象的内存地址

结构体返回值(拓展)

  1. 普通变量返回值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    student stuData = printStructData();
    00B74128  lea         eax,[ebp-634h
    00B7412E  push        eax 
    00B7412F  call        printStructData (0B7124Eh
    00B74134  add         esp,4 
    00B74137  mov         ecx,41h 
    00B7413C  mov         esi,eax 
    00B7413E  lea         edi,[ebp-84Ch
    00B74144  rep movs    dword ptr es:[edi],dword ptr [esi] 
    00B74146  mov         ecx,41h 
    00B7414B  lea         esi,[ebp-84Ch
    00B74151  lea         edi,[stuData] 
    00B74157  rep movs    dword ptr es:[edi],dword ptr [esi] 
     
    ;----------------------------
    student printStructData()
    {
    00B73C20  push        ebp 
    00B73C21  mov         ebp,esp 
    00B73C23  sub         esp,1D0h 
    00B73C29  push        ebx 
    00B73C2A  push        esi 
    00B73C2B  push        edi 
    00B73C2C  lea         edi,[ebp-1D0h
    00B73C32  mov         ecx,74h 
    00B73C37  mov         eax,0CCCCCCCCh 
    00B73C3C  rep stos    dword ptr es:[edi] 
    00B73C3E  mov         eax,dword ptr [__security_cookie (0B79088h)] 
    00B73C43  xor         eax,ebp 
    00B73C45  mov         dword ptr [ebp-4],eax 
     student stu;
     stu.age = 30;
    00B73C48  mov         dword ptr [stu],1Eh 
     strcpy(stu.name, "THINCT");
    00B73C52  push        offset string "THINCT" (0B769B0h
    00B73C57  lea         eax,[ebp-108h
    00B73C5D  push        eax 
    00B73C5E  call        _strcpy (0B71230h
    00B73C63  add         esp,8 
     return stu;
    00B73C66  mov         ecx,41h 
    00B73C6B  lea         esi,[stu] 
    00B73C71  mov         edi,dword ptr [ebp+8
    00B73C74  rep movs    dword ptr es:[edi],dword ptr [esi] 
    00B73C76  mov         eax,dword ptr [ebp+8
    }


    如果是结构体变量,会取结构体地址作为函数的第一个参数传入函数

  2. 指针变量返回值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
  student* stuDataPtr = printStructDataPtr();
00B74179  call        printStructDataPtr (0B71249h
00B7417E  mov         dword ptr [stuDataPtr],eax 
;----------------------
 
student* printStructDataPtr()
{
00B73D30  push        ebp 
00B73D31  mov         ebp,esp 
00B73D33  sub         esp,0D8h 
00B73D39  push        ebx 
00B73D3A  push        esi 
00B73D3B  push        edi 
00B73D3C  lea         edi,[ebp-0D8h
00B73D42  mov         ecx,36h 
00B73D47  mov         eax,0CCCCCCCCh 
00B73D4C  rep stos    dword ptr es:[edi] 
  student* stu = new student;
00B73D4E  push        104h 
00B73D53  call        operator new (0B71253h
00B73D58  add         esp,4 
00B73D5B  mov         dword ptr [ebp-0D4h],eax 
00B73D61  mov         eax,dword ptr [ebp-0D4h
00B73D67  mov         dword ptr [stu],eax 
  stu->age = 30;
00B73D6A  mov         eax,dword ptr [stu] 
00B73D6D  mov         dword ptr [eax],1Eh 
  strcpy(stu->name, "THINCT");
00B73D73  push        offset string "THINCT" (0B769B0h
00B73D78  mov         eax,dword ptr [stu] 
00B73D7B  add         eax,4 
00B73D7E  push        eax 
00B73D7F  call        _strcpy (0B71230h
00B73D84  add         esp,8 
  return stu;
00B73D87  mov         eax,dword ptr [stu]

简要分析

00B7417E mov dword ptr [stuDataPtr],eax

00B73D87 mov eax,dword ptr [stu]

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
void print()
{
  printf("No params\n");
}
 
void print(const char* name)
{
  printf("name: %s", name);
}
 
int add(int a, int b)
{
  return a + b;
}
 
void add(int a, int b, int* result)
{
  *result = a + b;
}
 
struct student
{
  int age;
  char name[256];
};
 
void print(student stu)
{
  printf("name: %s, age: %d\n", stu.name, stu.age);
}
 
void print2(student stu1, student stu2)
{
  printf("student 1 name: %s, age: %d\n", stu1.name, stu1.age);
  printf("student 2 name: %s, age: %d\n", stu2.name, stu2.age);
}
 
void print(student* stu)
{
  printf("name: %s, age: %d\n", stu->name, stu->age);
}
 
void print2(student* stu1, student* stu2)
{
  printf("student 1 name: %s, age1 %d\n", stu1->name, stu1->age);
  printf("student 2 name: %s, age: %d\n", stu2->name, stu2->age);
}
 
 
int main()
{
  print();
  print("THINCT");
  a
  dd(3, 4);
 
  int result = 0;
  add(4, 5, &result);
 
  student stu;
  stu.age = 30;
  strcpy(stu.name, "THINCT");
 
  print(stu);
  print(&stu);
 
  student stu2;
  stu2.age = 27;
  strcpy(stu2.name, "CallMe");
  print2(stu, stu2);
  print2(&stu, &stu2);

【公告】 [2022大礼包]《看雪论坛精华22期》发布!收录近1000余篇精华优秀文章!

最后于 2022-3-7 16:57 被_THINCT编辑 ,原因:
收藏
点赞1
打赏
分享
最新回复 (1)
雪    币: 427
活跃值: 活跃值 (2394)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
glopen 活跃值 2021-12-29 10:37
2
0
有心人
游客
登录 | 注册 方可回帖
返回