首页
社区
课程
招聘
[原创]从逆向工程的角度来看C++ (三)
发表于: 2009-5-1 12:16 7316

[原创]从逆向工程的角度来看C++ (三)

2009-5-1 12:16
7316
进入本次正题:

                                 (三)[  C++ 之 构造与析构  ]

//来CPP:

//stack3.h
#ifndef STACK_H_
#define STACK_H_

class stack
{
struct link
{
   void *data;
   link *next;
   void initialize(void *Data, link *Next);
} *head;
public:
   stack();
   stack(int);
   ~stack();
   void push(void *Data);
   void* peek(void *Data);
   void* pop();
};

#endif

//stack3.cpp
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "stack3.h"

void stack::link::initialize(void *Data, link *Next)
{
data = Data;
next = Next;
}

stack::stack()
{
printf("stack::stack() called . \n");
head = 0;
}
stack::stack(int){}

void stack::push(void *Data)
{
link *newLink = (link*)malloc(sizeof(link));
assert(newLink);
newLink->initialize(Data,head);
head = newLink ;
}

void* stack::peek(void *Data){return head->data;}

void* stack::pop()
{
if (0 == head) return 0;
void *result =head->data;
link *oldHead = head;
head = head->next;
free(oldHead);
return result;
}

stack::~stack()
{
printf("stack::~stack() called . \n");
link *cursor = head;
while(head)
{
   cursor = cursor->next;
   free(head);
   head = cursor;
}
}

// lesson3.cpp : Defines the entry point for the console application.
//

//#include "stdafx.h"
#include "stack3.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#pragma warning(disable:4005)
#pragma warning(disable:4700)

#define PPATH "c:\\test.txt"
#define BUFSIZE 100

int main(int argc, char* argv[])
{
__asm int 3
assert(2 == argc) ;
FILE *file = fopen(PPATH,"r");
assert(file);
printf("1\n");

{printf("2\n"); stack test;   printf("3\n");}
printf("4\n");
printf("sizeof stack :%d",sizeof(stack));

char buf[BUFSIZE];
buf[9] += 9 ;
stack textline; //Constuctor called.
while (fgets(buf,BUFSIZE,file))
{
   char *str = (char *)malloc(strlen(buf)+1);
   assert(str);
   strcpy(str,buf);
   textline.push(str);
}
//Pop lines from the stack and print them
char *s;
while(0 != (s = (char*)textline.pop()))
{
   printf("%s",s);
   free(s);
}
buf[8] += 8;
return 0;
} //Destructor called here .

////来反汇编:

00410BE0 > 55              push ebp
00410BE1    8BEC            mov ebp,esp
00410BE3    6A FF           push -1
00410BE5    68 99594100     push lesson3.00415999
00410BEA    64:A1 00000000 mov eax,dword ptr fs:[0]
00410BF0    50              push eax
00410BF1    64:8925 0000000>mov dword ptr fs:[0],esp
00410BF8    81EC BC000000   sub esp,0BC
00410BFE    53              push ebx
00410BFF    56              push esi
00410C00    57              push edi
00410C01    8DBD 38FFFFFF   lea edi,dword ptr ss:[ebp-C8]
00410C07    B9 2F000000     mov ecx,2F
00410C0C    B8 CCCCCCCC     mov eax,CCCCCCCC
00410C11    F3:AB           rep stos dword ptr es:[edi]
00410C13    90              nop
00410C14    837D 08 02      cmp dword ptr ss:[ebp+8],2                 ; assert (2==argc) 相当于if(..) 弹错!
00410C18    74 1D           je short lesson3.00410C37                  ; 跳过去继续正常执行
00410C1A    0FBF05 409C4200 movsx eax,word ptr ds:[`main'::`2'::__LINE>
00410C21    83C0 02         add eax,2
00410C24    50              push eax                                   ; assert有三个参数了
00410C25    68 94824200     push lesson3.00428294                      ; ASCII "d:\reverse\c++\lesson3\lesson3.cpp"
00410C2A    68 38704200     push lesson3.00427038                      ; ASCII "2 == argc"
00410C2F    E8 8C2BFFFF     call lesson3._assert
00410C34    83C4 0C         add esp,0C                                 ; 恢复堆栈
00410C37    68 34704200     push lesson3.00427034
00410C3C    68 88824200     push lesson3.00428288                      ; ASCII "c:\test.txt"
00410C41    E8 EA2FFFFF     call lesson3.fopen                         ; fopen
00410C46    83C4 08         add esp,8
00410C49    8945 F0         mov dword ptr ss:[ebp-10],eax              ; 打开后文件的指针
00410C4C    837D F0 00      cmp dword ptr ss:[ebp-10],0
00410C50    75 1D           jnz short lesson3.00410C6F                 ; 不为NULL则继续.
00410C52    0FBF15 409C4200 movsx edx,word ptr ds:[`main'::`2'::__LINE>
00410C59    83C2 04         add edx,4
00410C5C    52              push edx
00410C5D    68 94824200     push lesson3.00428294                      ; ASCII "d:\reverse\c++\lesson3\lesson3.cpp"
00410C62    68 48824200     push lesson3.00428248                      ; ASCII "file"
00410C67    E8 542BFFFF     call lesson3._assert
00410C6C    83C4 0C         add esp,0C
00410C6F    68 30704200     push lesson3.00427030                      ; ASCII "1",LF
00410C74    E8 2728FFFF     call lesson3.printf                        ; {的外面打印1
00410C79    83C4 04         add esp,4
00410C7C    68 68704200     push lesson3.00427068                      ; ASCII "2",LF
00410C81    E8 1A28FFFF     call lesson3.printf                        ; 进去之后打印2
00410C86    83C4 04         add esp,4
00410C89    8D4D EC         lea ecx,dword ptr ss:[ebp-14]
00410C8C    E8 7403FFFF     call lesson3.00401005                      ; 定义类对象时,构造函数执行.
00410C91    68 58704200     push lesson3.00427058                      ; ASCII "3",LF
00410C96    E8 0528FFFF     call lesson3.printf                        ; }的左边打印3
00410C9B    83C4 04         add esp,4
00410C9E    8D4D EC         lea ecx,dword ptr ss:[ebp-14]
00410CA1    E8 6903FFFF     call lesson3.0040100F                      ; 出}析构了.
00410CA6    68 2C704200     push lesson3.0042702C                      ; ASCII "4",LF
00410CAB    E8 F027FFFF     call lesson3.printf                        ; 刚出}的时候来打印4
00410CB0    83C4 04         add esp,4
00410CB3    6A 04           push 4
00410CB5    68 44704200     push lesson3.00427044                      ; ASCII "sizeof stack :%d"
00410CBA    E8 E127FFFF     call lesson3.printf
00410CBF    83C4 08         add esp,8
00410CC2    8A4D 91         mov cl,byte ptr ss:[ebp-6F]
00410CC5    80C1 09         add cl,9
00410CC8    884D 91         mov byte ptr ss:[ebp-6F],cl
00410CCB    8D4D 84         lea ecx,dword ptr ss:[ebp-7C]
00410CCE    E8 3203FFFF     call lesson3.00401005                      ; 构造函数
00410CD3    C745 FC 0000000>mov dword ptr ss:[ebp-4],0
00410CDA    8B55 F0         mov edx,dword ptr ss:[ebp-10]
00410CDD    52              push edx                                   ; 文件句柄.
00410CDE    6A 64           push 64                                    ; size
00410CE0    8D45 88         lea eax,dword ptr ss:[ebp-78]              ; 缓冲区
00410CE3    50              push eax
00410CE4    E8 A729FFFF     call lesson3.fgets
00410CE9    83C4 0C         add esp,0C
00410CEC    85C0            test eax,eax
00410CEE    74 5C           je short lesson3.00410D4C                  ; fgets得到空则玩完
00410CF0    8D4D 88         lea ecx,dword ptr ss:[ebp-78]
00410CF3    51              push ecx
00410CF4    E8 1729FFFF     call lesson3.strlen
00410CF9    83C4 04         add esp,4
00410CFC    83C0 01         add eax,1
00410CFF    50              push eax
00410D00    E8 1B08FFFF     call lesson3.malloc                        ; 申请一段内存放buff
00410D05    83C4 04         add esp,4
00410D08    8945 80         mov dword ptr ss:[ebp-80],eax
00410D0B    837D 80 00      cmp dword ptr ss:[ebp-80],0
00410D0F    75 1D           jnz short lesson3.00410D2E                 ; 没申请到下面就玩完
00410D11    0FBF15 409C4200 movsx edx,word ptr ds:[`main'::`2'::__LINE>
00410D18    83C2 11         add edx,11
00410D1B    52              push edx
00410D1C    68 94824200     push lesson3.00428294                      ; ASCII "d:\reverse\c++\lesson3\lesson3.cpp"
00410D21    68 20704200     push lesson3.00427020                      ; ASCII "str"
00410D26    E8 952AFFFF     call lesson3._assert
00410D2B    83C4 0C         add esp,0C
00410D2E    8D4D 88         lea ecx,dword ptr ss:[ebp-78]
00410D31    51              push ecx
00410D32    8B55 80         mov edx,dword ptr ss:[ebp-80]
00410D35    52              push edx
00410D36    E8 E527FFFF     call lesson3.strcpy                        ; 放到缓冲区中
00410D3B    83C4 08         add esp,8
00410D3E    8B45 80         mov eax,dword ptr ss:[ebp-80]
00410D41    50              push eax                                   ; 刚刚堆上的字符串
00410D42    8D4D 84         lea ecx,dword ptr ss:[ebp-7C]              ; this
00410D45    E8 DE02FFFF     call lesson3.00401028                      ; 成员函数 stack::push
00410D4A ^ EB 8E           jmp short lesson3.00410CDA                 ; 继续循环.
00410D4C    8D4D 84         lea ecx,dword ptr ss:[ebp-7C]
00410D4F    E8 CF02FFFF     call lesson3.00401023                      ; 成员函数.跟了一下发现是pop
00410D54    8985 7CFFFFFF   mov dword ptr ss:[ebp-84],eax
00410D5A    83BD 7CFFFFFF 0>cmp dword ptr ss:[ebp-84],0
00410D61    74 25           je short lesson3.00410D88                  ; 为0则读完,玩完
00410D63    8B8D 7CFFFFFF   mov ecx,dword ptr ss:[ebp-84]
00410D69    51              push ecx
00410D6A    68 1C704200     push lesson3.0042701C                      ; ASCII "%s"
00410D6F    E8 2C27FFFF     call lesson3.printf
00410D74    83C4 08         add esp,8
00410D77    8B95 7CFFFFFF   mov edx,dword ptr ss:[ebp-84]              ; char *s 指针
00410D7D    52              push edx
00410D7E    E8 1D12FFFF     call lesson3.free                          ; 释放
00410D83    83C4 04         add esp,4
00410D86 ^ EB C4           jmp short lesson3.00410D4C
00410D88    8A45 90         mov al,byte ptr ss:[ebp-70]
00410D8B    04 08           add al,8
00410D8D    8845 90         mov byte ptr ss:[ebp-70],al
00410D90    C785 78FFFFFF 0>mov dword ptr ss:[ebp-88],0
00410D9A    C745 FC FFFFFFF>mov dword ptr ss:[ebp-4],-1
00410DA1    8D4D 84         lea ecx,dword ptr ss:[ebp-7C]
00410DA4    E8 6602FFFF     call lesson3.0040100F                      ; 调用析构函数.
00410DA9    8B85 78FFFFFF   mov eax,dword ptr ss:[ebp-88]              ; return 0
00410DAF    8B4D F4         mov ecx,dword ptr ss:[ebp-C]
00410DB2    64:890D 0000000>mov dword ptr fs:[0],ecx
00410DB9    5F              pop edi                                    ; 00241FE4
00410DBA    5E              pop esi
00410DBB    5B              pop ebx
00410DBC    81C4 C8000000   add esp,0C8
00410DC2    3BEC            cmp ebp,esp
00410DC4    E8 6732FFFF     call lesson3._chkesp                       ; 就是看ebp esp了..
00410DC9    8BE5            mov esp,ebp
00410DCB    5D              pop ebp
00410DCC    C3              retn

////来看看Release版本的:

00401000 /$ 55            push ebp
00401001 |. 8BEC          mov ebp,esp
00401003 |. 6A FF         push -1
00401005 |. 68 58744000   push lesson3.00407458                              ; SE 处理程序安装
0040100A |. 64:A1 0000000>mov eax,dword ptr fs:[0]
00401010 |. 50            push eax
00401011 |. 64:8925 00000>mov dword ptr fs:[0],esp
00401018 |. 83EC 6C       sub esp,6C
0040101B |. 53            push ebx
0040101C |. 56            push esi
0040101D |. 90            nop
0040101E |. 68 74904000   push lesson3.00409074
00401023 |. 68 68904000   push lesson3.00409068                              ; ASCII "c:\test.txt"
00401028 |. E8 A6030000   call lesson3.004013D3
0040102D |. 68 64904000   push lesson3.00409064                              ; ASCII "1",LF
00401032 |. 8BD8          mov ebx,eax
00401034 |. E8 49030000   call lesson3.00401382
00401039 |. 68 60904000   push lesson3.00409060                              ; ASCII "2",LF
0040103E |. E8 3F030000   call lesson3.00401382
00401043 |. 83C4 10       add esp,10
00401046 |. 8D4D EC       lea ecx,[local.5]
00401049 |. E8 22010000   call lesson3.00401170                              ; instructor called
0040104E |. 68 5C904000   push lesson3.0040905C                              ; ASCII "3",LF
00401053 |. E8 2A030000   call lesson3.00401382
00401058 |. 83C4 04       add esp,4
0040105B |. 8D4D EC       lea ecx,[local.5]
0040105E |. E8 7D010000   call lesson3.004011E0                              ; destructor called
00401063 |. 68 58904000   push lesson3.00409058                              ; ASCII "4",LF
00401068 |. E8 15030000   call lesson3.00401382
0040106D |. 6A 04         push 4
0040106F |. 68 44904000   push lesson3.00409044                              ; ASCII "sizeof stack :%d"
00401074 |. E8 09030000   call lesson3.00401382
00401079 |. 8A4D 91       mov cl,byte ptr ss:[ebp-6F]
0040107C |. 83C4 0C       add esp,0C
0040107F |. 80C1 09       add cl,9
00401082 |. 884D 91       mov byte ptr ss:[ebp-6F],cl
00401085 |. 8D4D F0       lea ecx,[local.4]
00401088 |. E8 E3000000   call lesson3.00401170                              ; instructor
0040108D |. 53            push ebx
0040108E |. 8D45 88       lea eax,[local.30]
00401091 |. 6A 64         push 64
00401093 |. 50            push eax
00401094 |. C745 FC 00000>mov [local.1],0
0040109B |. E8 8B020000   call lesson3.0040132B                              ; fgets
004010A0 |. 83C4 0C       add esp,0C
004010A3 |. 85C0          test eax,eax
004010A5 |. 74 55         je short lesson3.004010FC
004010A7 |. 57            push edi
004010A8 |> 8D7D 88       /lea edi,[local.30]
004010AB |. 83C9 FF       |or ecx,FFFFFFFF
004010AE |. 33C0          |xor eax,eax
004010B0 |. F2:AE         |repne scas byte ptr es:[edi]
004010B2 |. F7D1          |not ecx                                           ; 直接把strlen inline进来了, 呵呵
004010B4 |. 51            |push ecx
004010B5 |. E8 BF010000   |call lesson3.00401279                             ; malloc
004010BA |. 8BD0          |mov edx,eax
004010BC |. 8D7D 88       |lea edi,[local.30]
004010BF |. 83C9 FF       |or ecx,FFFFFFFF
004010C2 |. 33C0          |xor eax,eax
004010C4 |. 83C4 04       |add esp,4
004010C7 |. F2:AE         |repne scas byte ptr es:[edi]
004010C9 |. F7D1          |not ecx
004010CB |. 2BF9          |sub edi,ecx
004010CD |. 52            |push edx
004010CE |. 8BC1          |mov eax,ecx
004010D0 |. 8BF7          |mov esi,edi
004010D2 |. 8BFA          |mov edi,edx
004010D4 |. C1E9 02       |shr ecx,2
004010D7 |. F3:A5         |rep movs dword ptr es:[edi],dword ptr ds:[esi]
004010D9 |. 8BC8          |mov ecx,eax
004010DB |. 83E1 03       |and ecx,3
004010DE |. F3:A4         |rep movs byte ptr es:[edi],byte ptr ds:[esi]      ; strcpy也融入进来了
004010E0 |. 8D4D F0       |lea ecx,[local.4]
004010E3 |. E8 A8000000   |call lesson3.00401190                             ; push
004010E8 |. 53            |push ebx
004010E9 |. 8D4D 88       |lea ecx,[local.30]
004010EC |. 6A 64         |push 64
004010EE |. 51            |push ecx
004010EF |. E8 37020000   |call lesson3.0040132B                             ; fgets
004010F4 |. 83C4 0C       |add esp,0C
004010F7 |. 85C0          |test eax,eax
004010F9 |.^ 75 AD         \jnz short lesson3.004010A8
004010FB |. 5F            pop edi
004010FC |> 8D4D F0       lea ecx,[local.4]
004010FF |. E8 BC000000   call lesson3.004011C0                              ; pop
00401104 |. 8BF0          mov esi,eax
00401106 |. 85F6          test esi,esi
00401108 |. 74 22         je short lesson3.0040112C
0040110A |> 56            /push esi
0040110B |. 68 40904000   |push lesson3.00409040                             ; ASCII "%s"
00401110 |. E8 6D020000   |call lesson3.00401382                             ; 打印
00401115 |. 56            |push esi
00401116 |. E8 F5000000   |call lesson3.00401210                             ; free
0040111B |. 83C4 0C       |add esp,0C
0040111E |. 8D4D F0       |lea ecx,[local.4]
00401121 |. E8 9A000000   |call lesson3.004011C0                             ; 又是pop
00401126 |. 8BF0          |mov esi,eax
00401128 |. 85F6          |test esi,esi
0040112A |.^ 75 DE         \jnz short lesson3.0040110A
0040112C |> 8A45 90       mov al,byte ptr ss:[ebp-70]
0040112F |. 8D4D F0       lea ecx,[local.4]
00401132 |. 04 08         add al,8
00401134 |. C745 FC FFFFF>mov [local.1],-1
0040113B |. 8845 90       mov byte ptr ss:[ebp-70],al
0040113E |. E8 9D000000   call lesson3.004011E0                              ; 析构
00401143 |. 8B4D F4       mov ecx,[local.3]
00401146 |. 5E            pop esi
00401147 |. 33C0          xor eax,eax
00401149 |. 5B            pop ebx
0040114A |. 64:890D 00000>mov dword ptr fs:[0],ecx
00401151 |. 8BE5          mov esp,ebp
00401153 |. 5D            pop ebp
00401154 \. C3            retn

看来Release版本的变化还真是大, 编译器做了很多的优化, 一定要注意.

还有注意构造函数与析构函数的执行时机, 构造函数实在对象定义的位置执行的, 析构函数是在离开右边的大括号的时候执行的.

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

收藏
免费 7
支持
分享
最新回复 (14)
雪    币: 332
活跃值: (30)
能力值: ( LV12,RANK:460 )
在线值:
发帖
回帖
粉丝
2
杀你一个发
2009-5-1 22:44
0
雪    币: 152
活跃值: (106)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
3
你发出来的东西,完全没有价值
2009-5-1 23:33
0
雪    币: 1450
活跃值: (35)
能力值: (RANK:680 )
在线值:
发帖
回帖
粉丝
4
我想你也是一路从新手走过来的,我不保证所有内容都对任何人有帮助,
但是肯定有部分内容是对新手有益的。
既然你是高手那你可以不看,我在(一)里面已经说的很清楚了,主要是想让新手更快的入门。

你觉得没有价值的话你可以发一个更有价值的系列出来为新手们做一做贡献。

另外  本来我这个系列是全部发在初学者论坛的,承蒙看雪大哥看得起,移到了这个板块。

不说什么了,大家各取所需吧 ...
2009-5-2 10:13
0
雪    币: 197
活跃值: (52)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
5
c++难分析的是类之间的关系,不是成员,函数的关系,一个实际的c++写的软件不可能就一个类
2009-5-2 13:41
0
雪    币: 1450
活跃值: (35)
能力值: (RANK:680 )
在线值:
发帖
回帖
粉丝
6
多谢LS指点,谨记于心
2009-5-2 16:19
0
雪    币: 1667
活跃值: (286)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
7
....LZ我大体上看了一下,关键的没说~!
我希望LZ补RELEASE,变化大,就不补了?
哎~~!
因为现在release的逆向,多于debug,主要是取决个头,运行速度,等等
所以,程序都是release,希望LZ以后出一下,release的系列,debug的不太容易见到~!
希望LZ下会补一下,静态LIB的区分,我就不写了,哈哈~~!
应该很简单的,现在很多程序都是模块化的,所以,有必要发一下~!
2009-5-3 15:42
0
雪    币: 183
活跃值: (203)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
其实还是不错的,加油~~
2009-5-7 09:28
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
9
如果有RTTI信息。类与类的关系还是好看。没有的话就比较麻烦了。要从构造函数分析类的关系。
2009-5-7 10:16
0
雪    币: 228
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
楼主列了两块反汇编,可要表达的意思很不明确,期待详细的说明。
也没涉及继承的内容,例子中的自动期变量也无法描述虚析构的表现。

c++的构造函数是静态编联,对*this处进行初始化。
而析构复杂一些,分两种,一种静态编联;
另一种为从*this的vptr找到vtbl中的虚析构函数,然后对*this做收尾工作。

rtti就是vtbl的识别,分析c++不同类之间的协作关系比较有价值。
2009-5-7 15:04
0
雪    币: 159
活跃值: (339)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
11
提一点个人的看法:
从逆向的角度看C++的目的是熟悉某种编译器对C++语法的解释。对碰到类似的编译器编译出来的CPP,能做到熟悉就OK了。完全没有必要以去理解C++的语法为目的去看汇编,毕竟每个编译器对C++的解释都是不一样的。

如果从熟悉编译器角度出发,lz的文章还是蛮有必要的。不过应该注明一下用的是VC6吧。
2009-5-8 01:09
0
雪    币: 211
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
C++逆向可是很有挑战的。
看来我是一人在奋斗。
兄弟姐妹们共勉!
2009-5-8 08:11
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
其实还是楼主那句话,各取所需,新手都要好好学习
2009-5-8 10:08
0
雪    币: 233
活跃值: (27)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
这种分析是不是应该跟平台和编译器的关系比较大呢?最好能够说明一下异同就更好了
2009-5-8 10:40
0
雪    币: 230
活跃值: (149)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
从汇编层面看C++,纯粹是自我折磨。

比如一个程序使用了多个C++的模式框架(工厂模式,代理模式之类的),你从汇编层面能看到什么?

高级语言的抽象逻辑,在汇编层面早就烟消云散了~~
2009-5-11 11:01
0
游客
登录 | 注册 方可回帖
返回
//