05月17, 2007

通过汇编代码研究C++

首先树立以下几个概念:

  • 编译器 compiler
  • 链接器 linker
  • 编译时期 compile time
  • 运行时期 runtime
  • 数据段 data segment/ds
  • 代码段 code segment/cs
  • 语法 syntax
  • 语义 semantics
  • 栈 stack
  • 堆 heap

全局变量

int global_var = 5;

int
main(int argc,char** argv)
{
static int i=3;
i=7;
return 0;
}
PUBLIC          ; global_var
_DATA SEGMENT

;静态变量和全局变量在数据段分配
DD 05H          ; global_var
DD 03H
_DATA ENDS
PUBLIC _main
_TEXT SEGMENT
_main PROC NEAR
push ebp
mov ebp, esp

; 直接对数据段内存赋值
mov DWORD PTR , 7 
xor eax, eax
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END

类的静态成员变量

class MyClass
{
public:
       int static       STATIC_VAR;
};

int MyClass::STATIC_VAR = 7;

int
main(int argc,char** argv)
{
MyClass::STATIC_VAR = 6;
return 0;
}
PUBLIC         ; MyClass::STATIC_VAR
_DATA SEGMENT

;类的静态成员同样在数据段分配分配内存
DD 07H         ; MyClass::STATIC_VAR
_DATA ENDS


PUBLIC _main
_TEXT SEGMENT
_main PROC NEAR
push ebp
mov ebp, esp

;直接对数据段内存赋值
mov DWORD PTR , 6 ; MyClass::STATIC_VAR
xor eax, eax
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END

枚举

enum COLOR{
cl0,cl1,cl2,cl3,cl4,cl5,cl6,cl7,cl8,cl9,cl10,cl11,cl12,cl13,cl14,cl15,
cl16,cl17,cl18,cl19,cl20,cl21,cl22,cl23,cl24,cl25,cl26,cl27,cl28,cl29,cl30,
cl31,cl32,cl33,cl34,cl35,cl36,cl37,cl38,cl39,cl40,cl41,cl42,cl43,cl44,cl45,
cl46,cl47,cl48,cl49,cl50,cl51,cl52,cl53,cl54,cl55,cl56,cl57,cl58,cl59,cl60,
cl61,cl62,cl63,cl64,cl65,cl66,cl67,cl68,cl69,cl70,cl71,cl72,cl73,cl74,cl75,
cl76,cl77,cl78,cl79,cl80,cl81,cl82,cl83,cl84,cl85,cl86,cl87,cl88,cl89,cl90,
cl91,cl92,cl93,cl94,cl95,cl96,cl97,cl98,cl99,cl100,cl101,cl102,cl103,cl104,
cl105,cl106,cl107,cl108,cl109,cl110,cl111,cl112,cl113,cl114,cl115,cl116,
cl117,cl118,cl119,cl120,cl121,cl122,cl123,cl124,cl125,cl126,cl127,cl128,
cl129,cl130,cl131,cl132,cl133,cl134,cl135,cl136,cl137,cl138,cl139,cl140,
cl141,cl142,cl143,cl144,cl145,cl146,cl147,cl148,cl149,cl150,cl151,cl152,
cl153,cl154,cl155,cl156,cl157,cl158,cl159,cl160,cl161,cl162,cl163,cl164,
cl165,cl166,cl167,cl168,cl169,cl170,cl171,cl172,cl173,cl174,cl175,cl176,
cl177,cl178,cl179,cl180,cl181,cl182,cl183,cl184,cl185,cl186,cl187,cl188,
cl189,cl190,cl191,cl192,cl193,cl194,cl195,cl196,cl197,cl198,cl199,cl200,
cl201,cl202,cl203,cl204,cl205,cl206,cl207,cl208,cl209,cl210,cl211,cl212,
cl213,cl214,cl215,cl216,cl217,cl218,cl219,cl220,cl221,cl222,cl223,cl224,
cl225,cl226,cl227,cl228,cl229,cl230,cl231,cl232,cl233,cl234,cl235,cl236,
cl237,cl238,cl239,cl240,cl241,cl242,cl243,cl244,cl245,cl246,cl247,cl248,
cl249,cl250,cl251,cl252,cl253,cl254,cl255,cl256,cl257,cl258};

int
main(int argc,char** argv)
{
COLOR color = cl258;
color = cl2;
return 0;
}
PUBLIC _main
_TEXT SEGMENT
_color$ = -4
_main PROC NEAR
push ebp
mov ebp, esp
push ecx

; 枚举类型最终是以无符号整数实现的
; COLOR color = cl258;
mov DWORD PTR _color$[ebp], 258

; color = cl2;
mov DWORD PTR _color$[ebp], 2

xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END

类的构造函数

class MyClass
{
public:
     int i;
     int j;
     int k;
     MyClass();
     ~MyClass();
     void f(int i);
};
MyClass::MyClass(){
this->i=7;
this->j=9;
this->k=11;
}
MyClass::~MyClass(){}
void MyClass::f(int j)
{
this->j = j;
__asm{
     mov this,5
}
}

int
main(int argc,char** argv)
{
MyClass *my = new MyClass();
my->f(3);
return 0;
}
;-----------------------------------------------
; MyClass::MyClass
;-----------------------------------------------
PUBLIC        ; MyClass::MyClass
_TEXT SEGMENT
_this$ = -4
PROC NEAR       ; MyClass::MyClass

push ebp
mov ebp, esp
push ecx
mov DWORD PTR _this$[ebp], ecx
mov eax, DWORD PTR _this$[ebp]
mov DWORD PTR [eax], 7
mov ecx, DWORD PTR _this$[ebp]
mov DWORD PTR [ecx+4], 9
mov edx, DWORD PTR _this$[ebp]
mov DWORD PTR [edx+8], 11      ; 0000000bH
mov eax, DWORD PTR _this$[ebp]
mov esp, ebp
pop ebp
ret 0
ENDP        ; MyClass::MyClass
_TEXT ENDS


;-----------------------------------------------
; MyClass::~MyClass
;-----------------------------------------------
PUBLIC        ; MyClass::~MyClass
_TEXT SEGMENT
_this$ = -4
PROC NEAR       ; MyClass::~MyClass
push ebp
mov ebp, esp
push ecx
mov DWORD PTR _this$[ebp], ecx
mov esp, ebp
pop ebp
ret 0
ENDP        ; MyClass::~MyClass
_TEXT ENDS


;-----------------------------------------------
; MyClass::f()
;-----------------------------------------------
PUBLIC        ; MyClass::f
_TEXT SEGMENT
_j$ = 8
_this$ = -4
PROC NEAR       ; MyClass::f
push ebp
mov ebp, esp
push ecx
push ebx
push esi
push edi
mov DWORD PTR _this$[ebp], ecx
mov eax, DWORD PTR _this$[ebp]
mov ecx, DWORD PTR _j$[ebp]
mov DWORD PTR [eax+4], ecx
mov DWORD PTR _this$[ebp], 5
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret 4
ENDP       ; MyClass::f
_TEXT ENDS


;-----------------------------------------------
; 主函数
;-----------------------------------------------
PUBLIC _main

;new操作符号就是一个函数
EXTRN        ; operator new
_TEXT SEGMENT
_my$ = -4
$T254 = -8
_main PROC NEAR
; Line 27
push ebp
mov ebp, esp
sub esp, 12
; MyClass *my = new MyClass();

; 调用new()在堆中分配一块内存,大小为MyClass左右成员变量大小之和,this指针在计算之内
; 12入栈,12是new的参数,由于编译时期MyClass已知,所以掉用new的时候不用给出参数,由编译器自己计算
push 12
call        ; operator new
add esp, 4

; new()将在堆中分配的内存块的首地址放在EAX,然后将EAX中的内容(首地址)放入变量my中
mov DWORD PTR $T254[ebp], eax

; 检查new()是否分配失败,如果失败则跳转到$L255
cmp DWORD PTR $T254[ebp], 0
je SHORT $L255

; 如果分配成功,以new()返回的首地址为参数调用MyClass的构造函数
mov ecx, DWORD PTR $T254[ebp]
call       ; MyClass::MyClass
mov DWORD PTR -12+[ebp], eax
jmp SHORT $L256
mov DWORD PTR -12+[ebp], 0
mov eax, DWORD PTR -12+[ebp]
mov DWORD PTR _my$[ebp], eax
; my->f(3);
push 3
mov ecx, DWORD PTR _my$[ebp]
call       ; MyClass::f


xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP

指针和地址

int main(int argc, char *argv[])
{
int i=7;
char c = 'c';
int *pi=&i; 
char *pc=&c;
pi = (int*)pc;

return 0;
}
PUBLIC _main
_TEXT SEGMENT
_i$ = -12
_c$ = -8
_pi$ = -4
_pc$ = -16
_main PROC NEAR

push ebp
mov ebp, esp
sub esp, 16

; int i = 7;
mov DWORD PTR _i$[ebp], 7

; char c = "c";
mov BYTE PTR _c$[ebp], 99

; int *pi = &i;
lea eax, DWORD PTR _i$[ebp]
mov DWORD PTR _pi$[ebp], eax

; char *pc = &c;
lea ecx, DWORD PTR _c$[ebp]
mov DWORD PTR _pc$[ebp], ecx

; pi = (int*)pc; 
mov edx, DWORD PTR _pc$[ebp]
mov DWORD PTR _pi$[ebp], edx

xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END

更新: 推荐下面这本书,对理解c++如何实现各种语言特性很有帮助

[C++反汇编与逆向分析技术揭秘](https://book.douban.com/subject/6849800/)

本文链接:http://aztack.wang/post/learn-cpp-with-asm.html

-- EOF--

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。