(内部文档)反汇编技术


反汇编技术反汇编技术 软件四部软件四部 Kenny.zhangKenny.zhang 20062006--0909--2525 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn 内容提要内容提要 §§ 反汇编简介反汇编简介 §§ 反汇编工具反汇编工具——IDA proIDA pro的简单使用的简单使用 §§ 高级语言高级语言(C++)(C++)特性的识别特性的识别 §§ 编译器优化编译器优化 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆反汇编简介反汇编简介 §§ 反向工程反向工程 反向工程就是把软件的机器代码退回到源代码;反向工程就是把软件的机器代码退回到源代码; §§ 反向编译反向编译 反编译包括了反汇编过程反编译包括了反汇编过程,,并将得到的汇编代码进并将得到的汇编代码进 行分析、进而反向编译成源代码;行分析、进而反向编译成源代码; §§ 反汇编反汇编 反汇编其实就是利用程序的机器代码与反汇编器反汇编其实就是利用程序的机器代码与反汇编器 反向解释出代码。反向解释出代码。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆反汇编简介反汇编简介 §§ 反汇编的用处:反汇编的用处: 11、更深层了解编译器特性、更深层了解编译器特性,,写出性能更高的程写出性能更高的程 序;序; 22、可以找到程序局部性能瓶颈;、可以找到程序局部性能瓶颈; 33、当调试程度时出现用户断点,可以帮助你查、当调试程度时出现用户断点,可以帮助你查 找找bug;bug; 44、不用说了吧、不用说了吧………….. 注:在很多软件的许可协议中可以看到这一条:注:在很多软件的许可协议中可以看到这一条: ““您不得对本您不得对本““软件产品软件产品””进行反向工程(进行反向工程(reverse reverse engineerengineer)、反向编译()、反向编译(decompiledecompile)或反汇编)或反汇编 ((disassembledisassemble))……”……” 关于这部分请参见:关于这部分请参见: \\\\bzlibzli\\studystudy\\软件保护中的反向工程软件保护中的反向工程--地位分析与制度比较地位分析与制度比较.pdf.pdf PDF 文件使用 "pdfFactory" 试用版本创建 呔z t 呔 z www.fineprint.com.cn ◆◆反汇编简介反汇编简介 §§ 说说软件破解说说软件破解 反汇编与软件破解的联系非常紧密。软反汇编与软件破解的联系非常紧密。软 件破解离不开反汇编,但是还包括其它相件破解离不开反汇编,但是还包括其它相 关技术:脱壳、解密技术等,所以反汇编关技术:脱壳、解密技术等,所以反汇编 只是这些技术的一个必要的基础。只是这些技术的一个必要的基础。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆反汇编工具反汇编工具 §§ 静态反汇编工具静态反汇编工具 对程序进行静态分析,把机器码转换成汇编的对程序进行静态分析,把机器码转换成汇编的 工具,常见有:工具,常见有:C32ASMC32ASM、、W32DasmW32Dasm、、IDA proIDA pro 等;等; §§ 调试工具调试工具 对可执行文件进行动态跟踪、调试,常见的对可执行文件进行动态跟踪、调试,常见的 有:有:SoftICESoftICE、、IDA proIDA pro等;等; §§ 十六进制编辑工具十六进制编辑工具 对二进制可执行文件进行修改操作,常见的有对二进制可执行文件进行修改操作,常见的有 WinHexWinHex、、HIEWHIEW等。等。 PDF 文件使用 "pdfFactory" 试用版本创建 ÿ ê ÿ www.fineprint.com.cn ◆◆反汇编工具反汇编工具 §§ IDA proIDA pro的特点的特点 11、反汇编、调试;、反汇编、调试; 22、支持众多处理器的文件格式、支持众多处理器的文件格式((近百种近百种));; 33、智能识别库函数和局部变量;、智能识别库函数和局部变量; 44、智能分析函数调用关系;、智能分析函数调用关系; 55、程序浏览智能感知;、程序浏览智能感知; ……………… 装上它吧装上它吧…….... PDF 文件使用 "pdfFactory" 试用版本创建 呔z t 呔 z www.fineprint.com.cn ◆◆反汇编工具反汇编工具 Windows版 PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆反汇编工具反汇编工具 Linux版 PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 主流主流C++C++编译器编译器 Intel C++ Intel C++ 、、 Visual C++ Visual C++ 、、GNU CC/++GNU CC/++、、 Borland C++Borland C++………… §§ C++C++各种特性各种特性 结构体、虚函数、继承关系、成员函数、结构体、虚函数、继承关系、成员函数、thisthis 指针、共用体(联合)指针、共用体(联合)…….. PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 堆栈堆栈 堆栈是一段数据结堆栈是一段数据结 构,提供先进后出的构,提供先进后出的 访问方式。主要用来访问方式。主要用来 传递函数参数、保存传递函数参数、保存 现场和保存局部变量现场和保存局部变量 等。等。 例:例: movmov eaxeax, [, [espesp –– 4]4] eaxeax的内容就是的内容就是5252 52 0 -4 -8 4 8 c 生长方向 PDF 文件使用 "pdfFactory" 试用版本创建 Ì ê ê ê www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 函数参数的传递函数参数的传递 函数的参数传递有堆栈方式、寄存器方函数的参数传递有堆栈方式、寄存器方 式和同时利用堆栈和寄存器。式和同时利用堆栈和寄存器。 §§ 参数的传递规范参数的传递规范 11、、____cdeclcdecl规范规范 按照参数的声明顺序从右往左向堆栈按照参数的声明顺序从右往左向堆栈 中压入堆栈。但清栈是由调用函数来完成中压入堆栈。但清栈是由调用函数来完成 的。编译器会函数名称前加一个的。编译器会函数名称前加一个““__””。。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 参数的传递规范参数的传递规范 如:如: intint ____cdeclcdecl swap(intswap(int a, a, intint b)b) 那么它是类似这样传递的:那么它是类似这样传递的: push bpush b push apush a call _swapcall _swap add add espesp, 8, 8 ;;清栈清栈 PDF 文件使用 "pdfFactory" 试用版本创建 呔z t 呔 z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 参数的传递规范参数的传递规范 22、、PascalPascal规范规范 函数参数由左往右压入堆栈,由被调用的函数负责清函数参数由左往右压入堆栈,由被调用的函数负责清 栈。如:栈。如: intint ____pascalpascal swap(intswap(int a, a, intint b);b); push apush a push bpush b call swapcall swap 在在swapswap内部:内部: 由由 retnretn 88 来清理堆栈。来清理堆栈。 注:在注:在VC++VC++中已不再支持,用相似的中已不再支持,用相似的WINAPIWINAPI来代替,也就来代替,也就 是说普通代码是不能编出是说普通代码是不能编出PascalPascal调用类型。调用类型。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z t 呔 z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 参数的传递规范参数的传递规范 33、标准规范、标准规范(__(__stdcallstdcall)) 是是____cdeclcdecl与与____pascalpascal的混和物。函数的混和物。函数 参数由右往左压入堆栈,而由被调函数负参数由右往左压入堆栈,而由被调函数负 责清栈。它在函数名前加责清栈。它在函数名前加““__””,以及加一个,以及加一个 后缀后缀““@@””,后面紧跟参数的字节数目。,后面紧跟参数的字节数目。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 参数的传递规范参数的传递规范 如:如: intint ____pascalpascal swap(intswap(int a, a, intint b);b); push bpush b push apush a call _swap@8call _swap@8 在在swapswap内部:内部: 由由 retnretn 88 来清理堆栈。来清理堆栈。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 参数的传递规范参数的传递规范 还有其它的一些规范:还有其它的一些规范:____fastcallfastcall、、 ____thiscallthiscall等。刚才所说的函数命只存在在等。刚才所说的函数命只存在在 OBJ(.oOBJ(.o))、、LIB(.aLIB(.a))和和DLL(.soDLL(.so))中,在最终可中,在最终可 执行文件中是不存在的执行文件中是不存在的 ((在在gccgcc中可以通过中可以通过 编译选项在最终二进制文件中保留符号编译选项在最终二进制文件中保留符号))。。 而且这个名字和编译器密切相关。而且这个名字和编译器密切相关。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 返回值返回值 对对Intel C++ Intel C++ 、、Visual C++Visual C++、、GCCGCC而言:而言: 11、如果是地址或整数就放在、如果是地址或整数就放在eaxeax中;中; 22、如果字节类型就放在、如果字节类型就放在alal中;中; 33、如果是浮点类型,放在浮点堆栈的、如果是浮点类型,放在浮点堆栈的 栈顶栈顶;; ………….. 一个简单的例子一个简单的例子 function.idbfunction.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 启动函数启动函数 在链接的时候,由你选择的应用程序类在链接的时候,由你选择的应用程序类 型与型与CRTCRT\\SRCSRC\\crtcrt***.c***.c文件进行链接,由它文件进行链接,由它 当中的代码来调用当中的代码来调用main main 或者或者WinMainWinMain函函 数。数。 静态链接:静态链接:crt0.ccrt0.c 动态链接:动态链接:crtexe.ccrtexe.c 控制台控制台 : : wincmdln.cwincmdln.c PDF 文件使用 "pdfFactory" 试用版本创建 呔z t 呔 z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 启动函数启动函数 一般一般WinMainWinMain的最后一个入栈的参数是的最后一个入栈的参数是 HINSTANCE HINSTANCE hInstancehInstance,,而这个实例句柄是由而这个实例句柄是由 GetModuleHandleGetModuleHandle取得的,所以,一般在取得的,所以,一般在 call call ediedi ; ; GetModuleHandleAGetModuleHandleA之后调用的就是之后调用的就是 WinMainWinMain。。 类似,控制台程序的类似,控制台程序的mainmain函数则是在函数则是在 call call dsds: : GetCommandLineAGetCommandLineA 后面不远处。后面不远处。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 局部变量局部变量 局部变量一般是放在堆栈中局部变量一般是放在堆栈中 的。例如:的。例如: intint swap(intswap(int a, a, intint b){b){ intint temp;temp; ……………….. }} 它当中的它当中的temptemp在编译后是在函数的开头:在编译后是在函数的开头: var_4 = var_4 = dworddword ptrptr --44 在用的时候:在用的时候: movmov [[espesp + var_4], 5555+ var_4], 5555 5555 0 -4 -8 4 8 c 生长方向 Var_4 PDF 文件使用 "pdfFactory" 试用版本创建 Ì ê ê ê www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 结构体结构体 如果定义一个局部变量的结构体实例:如果定义一个局部变量的结构体实例: structstruct person{person{ intint a;a; intint b;b; };}; Void Void test(voidtest(void){){ structstruct person r;person r; ………….... }} 在汇编中的函数开头:在汇编中的函数开头: varvar__8 = 8 = dworddword ptrptr --88 varvar__44 = = dworddword ptrptr --44 0 -4 -8 4 8 c 生长方向 Var_8 Var_4 PDF 文件使用 "pdfFactory" 试用版本创建 Ì ê ê ê www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 结构体结构体 当在函数参数传入的是一个结构体的自动变量当在函数参数传入的是一个结构体的自动变量 时时,,会把它的每一个成员单独传递:会把它的每一个成员单独传递: structstruct person r;person r; test(rtest(r);); 会用类似如下语句传递:会用类似如下语句传递: push push r.ar.a push push r.br.b call _testcall _test ………… 所以在确定函数参数个数的时候,不能仅凭所以在确定函数参数个数的时候,不能仅凭pushpush 的个数来确定,还要结合上下文。的个数来确定,还要结合上下文。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 结构体结构体 当函数参数是结构体指针的时候:当函数参数是结构体指针的时候: intint testp(structtestp(struct person *per){person *per){ return perreturn per-->a + per>a + per-->b;>b; }} 对它的成员的访问是:对它的成员的访问是:基地址基地址++偏移偏移的方式,的方式, movmov ecxecx, [, [espesp + arg_0]+ arg_0] movmov eaxeax, [, [ecxecx]] add add eaxeax, [, [ecxecx + 4]+ 4] retnretn 44 可以轻松的看出可以轻松的看出ecxecx 是一个结构体(或类)的指针,并是一个结构体(或类)的指针,并 访问了它的偏移为访问了它的偏移为00、、44的两个成员。的两个成员。 看一个例子:看一个例子: struct.idbstruct.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 (this(this指针指针)) 类的成员变量和结构类似,但是它在调类的成员变量和结构类似,但是它在调 用成员函数的时候会准备用成员函数的时候会准备thisthis指针的传递。指针的传递。 在在VC++VC++、、Intel C++Intel C++和一些我们还不知道和一些我们还不知道 的编译器中,的编译器中,thisthis指针是通过寄存器指针是通过寄存器ecxecx传传 递的。而在递的。而在gccgcc中中,,是通过堆栈传递的,最后是通过堆栈传递的,最后 一个被压入堆栈的一个被压入堆栈的,,在函数内部会表现为在函数内部会表现为 arg_0arg_0。。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 (this(this指针指针)) 11、、VC++VC++、、Intel C++Intel C++ lea lea ecxecx, [ebp+var_14], [ebp+var_14] call sub_4010B0call sub_4010B0 22、、GNU ccGNU cc push push dworddword ptrptr [esi+0BF4h][esi+0BF4h] call Mark__17ScriptObjectTablecall Mark__17ScriptObjectTable PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((成员函数成员函数)) 调用成员函数之前都会先准备调用成员函数之前都会先准备thisthis指针指针,, 一般可以通过这个识别出是否是一个类的一般可以通过这个识别出是否是一个类的 成员函数:成员函数: lea lea ecxecx, [ebp+var_14], [ebp+var_14] call sub_4010B0call sub_4010B0 可以得出可以得出var_14var_14是一个类对象,是一个类对象,sub_4010B0sub_4010B0是是 它的一个成员函数。它的一个成员函数。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((成员函数成员函数)) 众所周知,在成员函数内部访问成员变众所周知,在成员函数内部访问成员变 量,那在成员函数怎么访问的呢?当然是量,那在成员函数怎么访问的呢?当然是 通过通过thisthis指针,传递指针,传递thisthis指针的作用当然不指针的作用当然不 是为了访问成员函数,除了是为了访问成员函数,除了虚函数虚函数,所有,所有 的成员函数被编译之后都是全局函数。所的成员函数被编译之后都是全局函数。所 以传递以传递thisthis指针的作用就是为了访问成员变指针的作用就是为了访问成员变 量。量。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((成员函数成员函数)) 在成员函数内部:在成员函数内部: movmov eaxeax, [, [ecxecx] ] ;;将第一个成员赋给将第一个成员赋给eaxeax add add eaxeax, [ecx+4] , [ecx+4] ;;再用第一个成员的值加上再用第一个成员的值加上 ;;可能是第二个成员的值可能是第二个成员的值 看一个例子:看一个例子:class.idbclass.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 (new(new操作符操作符)) 编译器将编译器将newnew与与deletedelete转换成普通函转换成普通函 数。数。newnew有以下特点:有以下特点: 11、只有一个参数、只有一个参数((要分配的字节数要分配的字节数);); 22、返回值会赋给、返回值会赋给thisthis指针;指针; 33、会判断返回值是否为空;、会判断返回值是否为空; PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 (delete(delete操作符操作符)) deletedelete与大多函数差不多,所以识别要困与大多函数差不多,所以识别要困 难一点。但是它有一个显著特性:难一点。但是它有一个显著特性: 它最终会调用到它最终会调用到XXXFreeXXXFree一类的函数一类的函数;; 例:例:class2.idbclass2.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((构造函数构造函数)) 构造函数总是分配内存成功的情况下才会被调构造函数总是分配内存成功的情况下才会被调 用用,,一般紧跟在调用构造函数后是分配失败的跳转一般紧跟在调用构造函数后是分配失败的跳转 代码,将代码,将thisthis指针复指针复00。。 cmpcmp [ebp+var_1C], 0[ebp+var_1C], 0 jzjz short loc_401042short loc_401042 movmov ecxecx, [ebp+var_1C], [ebp+var_1C] call sub_4010A0 call sub_4010A0 ; ; 构造函数构造函数 movmov [ebp+var_28], [ebp+var_28], eaxeax jmpjmp short loc_401049short loc_401049 loc_401042:loc_401042: movmov [ebp+var_28], 0[ebp+var_28], 0 PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((析构函数析构函数)) 析构函数也总是在在内存分配成功的情析构函数也总是在在内存分配成功的情 况下才会被调用,而且析构函数与况下才会被调用,而且析构函数与deletedelete操操 作都被封装在一个作都被封装在一个““外壳外壳””中中.. 看一个例子看一个例子class2.idbclass2.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((构造函数与析构函数构造函数与析构函数)) 如果是处在堆栈中的自动变量的构造函如果是处在堆栈中的自动变量的构造函 数,那么就只能猜了数,那么就只能猜了~~~~~~ PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((虚函数虚函数)) 虚函数是虚函数是C++C++的重要特性。它根据你的的重要特性。它根据你的 具体对象的类型而去调用相应的函数。也具体对象的类型而去调用相应的函数。也 就是说这个函数必须和对象紧紧联系在一就是说这个函数必须和对象紧紧联系在一 起。在编译器上是用虚函数表来实现的。起。在编译器上是用虚函数表来实现的。 虚函数表是象一个数组一样,将每个虚虚函数表是象一个数组一样,将每个虚 函数的地址放在表中,而这个虚函数表的函数的地址放在表中,而这个虚函数表的 地址又被放置在对象的偏移为地址又被放置在对象的偏移为00的地方的地方((只针只针 对对VC++VC++、、Inter C++Inter C++;; GccGcc放置的位置不放置的位置不 定。定。)) PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((虚函数虚函数)) class parent {class parent { public:public: intint a;a; virtual void virtual void demo(voiddemo(void);); ………….. .. };}; aa vtalvtal 指向demo指向demo demovtal PDF 文件使用 "pdfFactory" 试用版本创建 ê ê ê ê www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((虚函数虚函数)) 在构造函数里面,会将虚函数表的地址在构造函数里面,会将虚函数表的地址 移入到对象实例的开头部分。移入到对象实例的开头部分。 movmov dworddword ptrptr [[eaxeax], offset off_40810C], offset off_40810C 调用:调用: call call dworddword ptrptr [[eaxeax]] 例子:例子:virtual.idbvirtual.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((纯虚函数纯虚函数)) 抽象类是不允许创建对象的,那它是怎抽象类是不允许创建对象的,那它是怎 么禁止的呢?么禁止的呢? 如果用抽象类实例化一个对象,那么这如果用抽象类实例化一个对象,那么这 个对象的虚函数表将是一个指向个对象的虚函数表将是一个指向____purecallpurecall 的指针,在程序执行时调用到它的话,由的指针,在程序执行时调用到它的话,由 它给用户警告。它给用户警告。 例:例:purecall.idbpurecall.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 浮点处理浮点处理 浮点数的处理与整数不一样,它是由浮点数的处理与整数不一样,它是由 FPUFPU完成的。完成的。floatfloat用用44个字节表示,个字节表示,doubledouble 则用则用88个。常用的浮点指令:个。常用的浮点指令: fldfld 压栈压栈 fstfst弹栈弹栈 fcomfcom 比较比较 faddfadd 加法加法 fdivfdiv除法除法 fmulfmul 乘法乘法 fsubfsub 减法减法 PDF 文件使用 "pdfFactory" 试用版本创建 呔z t 呔 z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 浮点处理浮点处理 浮点处理时,先把操作数压到浮点堆栈中浮点处理时,先把操作数压到浮点堆栈中,,比比 如:如: float a = 5.89 + 8.90;float a = 5.89 + 8.90; 在汇编中:在汇编中: fldfld 40BC7AE1h40BC7AE1h ; ; 压入压入5.895.89 faddfadd 410E6666h 410E6666h ; ; 加上加上8.908.90 fstpfstp [[espesp + var_4] + var_4] ; ; 将浮点堆栈顶部的值弹将浮点堆栈顶部的值弹 ; ; 到变量中到变量中 PDF 文件使用 "pdfFactory" 试用版本创建 呔z t 呔 z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 浮点处理浮点处理 浮点堆栈一共有八个单元,每个单元占浮点堆栈一共有八个单元,每个单元占 88个字节,栈顶为个字节,栈顶为st(0) st(0) 或称或称 stst, , 栈底为栈底为 st(7).st(7). st0 st1 st2 st3 ……. PDF 文件使用 "pdfFactory" 试用版本创建 ê f ê f www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 浮点处理浮点处理 如果函数的参数或返回值是浮点类型,如果函数的参数或返回值是浮点类型, 那么它们都是通过浮点堆栈传递的。那么它们都是通过浮点堆栈传递的。 例子:例子:float.idbfloat.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 浮点处理浮点处理 浮点有三种类型:浮点有三种类型:float float 、、double double 、、long long doubledouble。在处理这三种类型的数据的时。在处理这三种类型的数据的时 候,指令都是那几条,怎么样确定到底操候,指令都是那几条,怎么样确定到底操 作的类型是什么呢?作的类型是什么呢? 根据机器指令,比如根据机器指令,比如fldfld,对,对floatfloat的机器的机器 码是:码是:0xD9, 0xD9, 对对doubledouble是是0xDD, 0xDD, 对对long long double double 是是0xDB0xDB。。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 浮点数的比较浮点数的比较 浮点处理只有浮点处理只有fcomxfcomx指令,可没有用于指令,可没有用于 它的跳转指令,判断比较结果,必须将浮它的跳转指令,判断比较结果,必须将浮 点数的比较结果点数的比较结果((协处理器标志寄存器协处理器标志寄存器))送到送到 寄存器中,再与掩码进行判断。寄存器中,再与掩码进行判断。 14 13 10 9 815 busyzf pf cf ….. 进位奇偶零值 PDF 文件使用 "pdfFactory" 试用版本创建 ê f ê f www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 浮点数的比较浮点数的比较 用用fnstswfnstsw regreg 指令,可以将协处理器的指令,可以将协处理器的 标志寄存器的内容拷贝到指定的通用寄存标志寄存器的内容拷贝到指定的通用寄存 器中。类似这样:器中。类似这样: fldfld aa fcompfcomp bb fnstswfnstsw axax test ax (test ax (或或ah), ah), bit_maskbit_mask jxxxjxxx loc_xxxxxxloc_xxxxxx;; PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 浮点数的比较浮点数的比较 对于判断大小一类的,一般只用到标志的对于判断大小一类的,一般只用到标志的88、、 1414位,比如判断位,比如判断aa是否大于是否大于b:b: fldfld aa fcompfcomp bb fnstswfnstsw axax test test ahah, 41h , 41h jnzjnz loc_1234 loc_1234 ………… a > b a > b ; ; 既既CF = ZF = 0CF = ZF = 0 loc_1234:loc_1234: …….. a <= b .. a <= b 例:例:fcom.idbfcom.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆编译器优化编译器优化 编译器优化的程序取决于你的选项。一编译器优化的程序取决于你的选项。一 般而言,我们在用般而言,我们在用VC++VC++发布发布ReleaseRelease版的进版的进 候,默认优化级别是候,默认优化级别是O2O2。。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆编译器优化编译器优化 §§ 内联函数内联函数 并不是所有加了并不是所有加了inlineinline函数都会被展开,函数都会被展开, 也并不是没有也并不是没有inlineinline就不会被展开,这取决就不会被展开,这取决 于你的编译器。当一个函数很短小或是值于你的编译器。当一个函数很短小或是值 是固定的话,编译器会把它们展开或是直是固定的话,编译器会把它们展开或是直 接算出其值作为常数。接算出其值作为常数。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆编译器优化编译器优化 §§ 袪除无用函数袪除无用函数 如果一个函数没有被用到,编译器不会如果一个函数没有被用到,编译器不会 将它编译进目标代码。将它编译进目标代码。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆编译器优化编译器优化 §§ 代码合并代码合并 如果两个函数完成的功能完全一样,编如果两个函数完成的功能完全一样,编 译器会对它进行代码合并,即把两个函数译器会对它进行代码合并,即把两个函数 变成一个。变成一个。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆编译器优化编译器优化 §§ 数学运算数学运算 ((除法除法)) 除法在不做优化的情况会比乘法慢除法在不做优化的情况会比乘法慢1010倍左右。倍左右。 通常利用下面的公式来进行优化:通常利用下面的公式来进行优化: 公式公式: a/b = (2^n / b) * (a / 2^n): a/b = (2^n / b) * (a / 2^n) 一般看到如下代码,就是在做除法。一般看到如下代码,就是在做除法。 movmov eaxeax cdqcdq imulimul ecxecx sarsar edxedx, n, n movmov eaxeax, , edxedx sarsar eaxeax, m, m add add edxedx, , eaxeax PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ☺☺欢迎提问欢迎提问 ☺☺ 文中所提到的资料、工具与文中所提到的资料、工具与demodemo可以到:可以到: \\\\bzlibzli\\反汇编技术反汇编技术 中获取中获取 PDF 文件使用 "pdfFactory" 试用版本创建 ÿ ÿ ÿ www.fineprint.com.cn 谢谢大家!谢谢大家! PDF 文件使用 "pdfFactory" 试用版本创建 呔z ÿ呔z www.fineprint.com.cn 反汇编技术反汇编技术 软件四部软件四部 Kenny.zhangKenny.zhang 20062006--0909--2525 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn 内容提要内容提要 §§ 反汇编简介反汇编简介 §§ 反汇编工具反汇编工具——IDA proIDA pro的简单使用的简单使用 §§ 高级语言高级语言(C++)(C++)特性的识别特性的识别 §§ 编译器优化编译器优化 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆反汇编简介反汇编简介 §§ 反向工程反向工程 反向工程就是把软件的机器代码退回到源代码;反向工程就是把软件的机器代码退回到源代码; §§ 反向编译反向编译 反编译包括了反汇编过程反编译包括了反汇编过程,,并将得到的汇编代码进并将得到的汇编代码进 行分析、进而反向编译成源代码;行分析、进而反向编译成源代码; §§ 反汇编反汇编 反汇编其实就是利用程序的机器代码与反汇编器反汇编其实就是利用程序的机器代码与反汇编器 反向解释出代码。反向解释出代码。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆反汇编简介反汇编简介 §§ 反汇编的用处:反汇编的用处: 11、更深层了解编译器特性、更深层了解编译器特性,,写出性能更高的程写出性能更高的程 序;序; 22、可以找到程序局部性能瓶颈;、可以找到程序局部性能瓶颈; 33、当调试程度时出现用户断点,可以帮助你查、当调试程度时出现用户断点,可以帮助你查 找找bug;bug; 44、不用说了吧、不用说了吧………….. 注:在很多软件的许可协议中可以看到这一条:注:在很多软件的许可协议中可以看到这一条: ““您不得对本您不得对本““软件产品软件产品””进行反向工程(进行反向工程(reverse reverse engineerengineer)、反向编译()、反向编译(decompiledecompile)或反汇编)或反汇编 ((disassembledisassemble))……”……” 关于这部分请参见:关于这部分请参见: \\\\bzlibzli\\studystudy\\软件保护中的反向工程软件保护中的反向工程--地位分析与制度比较地位分析与制度比较.pdf.pdf PDF 文件使用 "pdfFactory" 试用版本创建 呔z t 呔 z www.fineprint.com.cn ◆◆反汇编简介反汇编简介 §§ 说说软件破解说说软件破解 反汇编与软件破解的联系非常紧密。软反汇编与软件破解的联系非常紧密。软 件破解离不开反汇编,但是还包括其它相件破解离不开反汇编,但是还包括其它相 关技术:脱壳、解密技术等,所以反汇编关技术:脱壳、解密技术等,所以反汇编 只是这些技术的一个必要的基础。只是这些技术的一个必要的基础。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆反汇编工具反汇编工具 §§ 静态反汇编工具静态反汇编工具 对程序进行静态分析,把机器码转换成汇编的对程序进行静态分析,把机器码转换成汇编的 工具,常见有:工具,常见有:C32ASMC32ASM、、W32DasmW32Dasm、、IDA proIDA pro 等;等; §§ 调试工具调试工具 对可执行文件进行动态跟踪、调试,常见的对可执行文件进行动态跟踪、调试,常见的 有:有:SoftICESoftICE、、IDA proIDA pro等;等; §§ 十六进制编辑工具十六进制编辑工具 对二进制可执行文件进行修改操作,常见的有对二进制可执行文件进行修改操作,常见的有 WinHexWinHex、、HIEWHIEW等。等。 PDF 文件使用 "pdfFactory" 试用版本创建 ÿ ê ÿ www.fineprint.com.cn ◆◆反汇编工具反汇编工具 §§ IDA proIDA pro的特点的特点 11、反汇编、调试;、反汇编、调试; 22、支持众多处理器的文件格式、支持众多处理器的文件格式((近百种近百种));; 33、智能识别库函数和局部变量;、智能识别库函数和局部变量; 44、智能分析函数调用关系;、智能分析函数调用关系; 55、程序浏览智能感知;、程序浏览智能感知; ……………… 装上它吧装上它吧…….... PDF 文件使用 "pdfFactory" 试用版本创建 呔z t 呔 z www.fineprint.com.cn ◆◆反汇编工具反汇编工具 Windows版 PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆反汇编工具反汇编工具 Linux版 PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 主流主流C++C++编译器编译器 Intel C++ Intel C++ 、、 Visual C++ Visual C++ 、、GNU CC/++GNU CC/++、、 Borland C++Borland C++………… §§ C++C++各种特性各种特性 结构体、虚函数、继承关系、成员函数、结构体、虚函数、继承关系、成员函数、thisthis 指针、共用体(联合)指针、共用体(联合)…….. PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 堆栈堆栈 堆栈是一段数据结堆栈是一段数据结 构,提供先进后出的构,提供先进后出的 访问方式。主要用来访问方式。主要用来 传递函数参数、保存传递函数参数、保存 现场和保存局部变量现场和保存局部变量 等。等。 例:例: movmov eaxeax, [, [espesp –– 4]4] eaxeax的内容就是的内容就是5252 52 0 -4 -8 4 8 c 生长方向 PDF 文件使用 "pdfFactory" 试用版本创建 Ì ê ê ê www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 函数参数的传递函数参数的传递 函数的参数传递有堆栈方式、寄存器方函数的参数传递有堆栈方式、寄存器方 式和同时利用堆栈和寄存器。式和同时利用堆栈和寄存器。 §§ 参数的传递规范参数的传递规范 11、、____cdeclcdecl规范规范 按照参数的声明顺序从右往左向堆栈按照参数的声明顺序从右往左向堆栈 中压入堆栈。但清栈是由调用函数来完成中压入堆栈。但清栈是由调用函数来完成 的。编译器会函数名称前加一个的。编译器会函数名称前加一个““__””。。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 参数的传递规范参数的传递规范 如:如: intint ____cdeclcdecl swap(intswap(int a, a, intint b)b) 那么它是类似这样传递的:那么它是类似这样传递的: push bpush b push apush a call _swapcall _swap add add espesp, 8, 8 ;;清栈清栈 PDF 文件使用 "pdfFactory" 试用版本创建 呔z t 呔 z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 参数的传递规范参数的传递规范 22、、PascalPascal规范规范 函数参数由左往右压入堆栈,由被调用的函数负责清函数参数由左往右压入堆栈,由被调用的函数负责清 栈。如:栈。如: intint ____pascalpascal swap(intswap(int a, a, intint b);b); push apush a push bpush b call swapcall swap 在在swapswap内部:内部: 由由 retnretn 88 来清理堆栈。来清理堆栈。 注:在注:在VC++VC++中已不再支持,用相似的中已不再支持,用相似的WINAPIWINAPI来代替,也就来代替,也就 是说普通代码是不能编出是说普通代码是不能编出PascalPascal调用类型。调用类型。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z t 呔 z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 参数的传递规范参数的传递规范 33、标准规范、标准规范(__(__stdcallstdcall)) 是是____cdeclcdecl与与____pascalpascal的混和物。函数的混和物。函数 参数由右往左压入堆栈,而由被调函数负参数由右往左压入堆栈,而由被调函数负 责清栈。它在函数名前加责清栈。它在函数名前加““__””,以及加一个,以及加一个 后缀后缀““@@””,后面紧跟参数的字节数目。,后面紧跟参数的字节数目。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 参数的传递规范参数的传递规范 如:如: intint ____pascalpascal swap(intswap(int a, a, intint b);b); push bpush b push apush a call _swap@8call _swap@8 在在swapswap内部:内部: 由由 retnretn 88 来清理堆栈。来清理堆栈。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 参数的传递规范参数的传递规范 还有其它的一些规范:还有其它的一些规范:____fastcallfastcall、、 ____thiscallthiscall等。刚才所说的函数命只存在在等。刚才所说的函数命只存在在 OBJ(.oOBJ(.o))、、LIB(.aLIB(.a))和和DLL(.soDLL(.so))中,在最终可中,在最终可 执行文件中是不存在的执行文件中是不存在的 ((在在gccgcc中可以通过中可以通过 编译选项在最终二进制文件中保留符号编译选项在最终二进制文件中保留符号))。。 而且这个名字和编译器密切相关。而且这个名字和编译器密切相关。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 返回值返回值 对对Intel C++ Intel C++ 、、Visual C++Visual C++、、GCCGCC而言:而言: 11、如果是地址或整数就放在、如果是地址或整数就放在eaxeax中;中; 22、如果字节类型就放在、如果字节类型就放在alal中;中; 33、如果是浮点类型,放在浮点堆栈的、如果是浮点类型,放在浮点堆栈的 栈顶栈顶;; ………….. 一个简单的例子一个简单的例子 function.idbfunction.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 启动函数启动函数 在链接的时候,由你选择的应用程序类在链接的时候,由你选择的应用程序类 型与型与CRTCRT\\SRCSRC\\crtcrt***.c***.c文件进行链接,由它文件进行链接,由它 当中的代码来调用当中的代码来调用main main 或者或者WinMainWinMain函函 数。数。 静态链接:静态链接:crt0.ccrt0.c 动态链接:动态链接:crtexe.ccrtexe.c 控制台控制台 : : wincmdln.cwincmdln.c PDF 文件使用 "pdfFactory" 试用版本创建 呔z t 呔 z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 启动函数启动函数 一般一般WinMainWinMain的最后一个入栈的参数是的最后一个入栈的参数是 HINSTANCE HINSTANCE hInstancehInstance,,而这个实例句柄是由而这个实例句柄是由 GetModuleHandleGetModuleHandle取得的,所以,一般在取得的,所以,一般在 call call ediedi ; ; GetModuleHandleAGetModuleHandleA之后调用的就是之后调用的就是 WinMainWinMain。。 类似,控制台程序的类似,控制台程序的mainmain函数则是在函数则是在 call call dsds: : GetCommandLineAGetCommandLineA 后面不远处。后面不远处。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 局部变量局部变量 局部变量一般是放在堆栈中局部变量一般是放在堆栈中 的。例如:的。例如: intint swap(intswap(int a, a, intint b){b){ intint temp;temp; ……………….. }} 它当中的它当中的temptemp在编译后是在函数的开头:在编译后是在函数的开头: var_4 = var_4 = dworddword ptrptr --44 在用的时候:在用的时候: movmov [[espesp + var_4], 5555+ var_4], 5555 5555 0 -4 -8 4 8 c 生长方向 Var_4 PDF 文件使用 "pdfFactory" 试用版本创建 Ì ê ê ê www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 结构体结构体 如果定义一个局部变量的结构体实例:如果定义一个局部变量的结构体实例: structstruct person{person{ intint a;a; intint b;b; };}; Void Void test(voidtest(void){){ structstruct person r;person r; ………….... }} 在汇编中的函数开头:在汇编中的函数开头: varvar__8 = 8 = dworddword ptrptr --88 varvar__44 = = dworddword ptrptr --44 0 -4 -8 4 8 c 生长方向 Var_8 Var_4 PDF 文件使用 "pdfFactory" 试用版本创建 Ì ê ê ê www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 结构体结构体 当在函数参数传入的是一个结构体的自动变量当在函数参数传入的是一个结构体的自动变量 时时,,会把它的每一个成员单独传递:会把它的每一个成员单独传递: structstruct person r;person r; test(rtest(r);); 会用类似如下语句传递:会用类似如下语句传递: push push r.ar.a push push r.br.b call _testcall _test ………… 所以在确定函数参数个数的时候,不能仅凭所以在确定函数参数个数的时候,不能仅凭pushpush 的个数来确定,还要结合上下文。的个数来确定,还要结合上下文。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 结构体结构体 当函数参数是结构体指针的时候:当函数参数是结构体指针的时候: intint testp(structtestp(struct person *per){person *per){ return perreturn per-->a + per>a + per-->b;>b; }} 对它的成员的访问是:对它的成员的访问是:基地址基地址++偏移偏移的方式,的方式, movmov ecxecx, [, [espesp + arg_0]+ arg_0] movmov eaxeax, [, [ecxecx]] add add eaxeax, [, [ecxecx + 4]+ 4] retnretn 44 可以轻松的看出可以轻松的看出ecxecx 是一个结构体(或类)的指针,并是一个结构体(或类)的指针,并 访问了它的偏移为访问了它的偏移为00、、44的两个成员。的两个成员。 看一个例子:看一个例子: struct.idbstruct.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 (this(this指针指针)) 类的成员变量和结构类似,但是它在调类的成员变量和结构类似,但是它在调 用成员函数的时候会准备用成员函数的时候会准备thisthis指针的传递。指针的传递。 在在VC++VC++、、Intel C++Intel C++和一些我们还不知道和一些我们还不知道 的编译器中,的编译器中,thisthis指针是通过寄存器指针是通过寄存器ecxecx传传 递的。而在递的。而在gccgcc中中,,是通过堆栈传递的,最后是通过堆栈传递的,最后 一个被压入堆栈的一个被压入堆栈的,,在函数内部会表现为在函数内部会表现为 arg_0arg_0。。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 (this(this指针指针)) 11、、VC++VC++、、Intel C++Intel C++ lea lea ecxecx, [ebp+var_14], [ebp+var_14] call sub_4010B0call sub_4010B0 22、、GNU ccGNU cc push push dworddword ptrptr [esi+0BF4h][esi+0BF4h] call Mark__17ScriptObjectTablecall Mark__17ScriptObjectTable PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((成员函数成员函数)) 调用成员函数之前都会先准备调用成员函数之前都会先准备thisthis指针指针,, 一般可以通过这个识别出是否是一个类的一般可以通过这个识别出是否是一个类的 成员函数:成员函数: lea lea ecxecx, [ebp+var_14], [ebp+var_14] call sub_4010B0call sub_4010B0 可以得出可以得出var_14var_14是一个类对象,是一个类对象,sub_4010B0sub_4010B0是是 它的一个成员函数。它的一个成员函数。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((成员函数成员函数)) 众所周知,在成员函数内部访问成员变众所周知,在成员函数内部访问成员变 量,那在成员函数怎么访问的呢?当然是量,那在成员函数怎么访问的呢?当然是 通过通过thisthis指针,传递指针,传递thisthis指针的作用当然不指针的作用当然不 是为了访问成员函数,除了是为了访问成员函数,除了虚函数虚函数,所有,所有 的成员函数被编译之后都是全局函数。所的成员函数被编译之后都是全局函数。所 以传递以传递thisthis指针的作用就是为了访问成员变指针的作用就是为了访问成员变 量。量。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((成员函数成员函数)) 在成员函数内部:在成员函数内部: movmov eaxeax, [, [ecxecx] ] ;;将第一个成员赋给将第一个成员赋给eaxeax add add eaxeax, [ecx+4] , [ecx+4] ;;再用第一个成员的值加上再用第一个成员的值加上 ;;可能是第二个成员的值可能是第二个成员的值 看一个例子:看一个例子:class.idbclass.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 (new(new操作符操作符)) 编译器将编译器将newnew与与deletedelete转换成普通函转换成普通函 数。数。newnew有以下特点:有以下特点: 11、只有一个参数、只有一个参数((要分配的字节数要分配的字节数);); 22、返回值会赋给、返回值会赋给thisthis指针;指针; 33、会判断返回值是否为空;、会判断返回值是否为空; PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 (delete(delete操作符操作符)) deletedelete与大多函数差不多,所以识别要困与大多函数差不多,所以识别要困 难一点。但是它有一个显著特性:难一点。但是它有一个显著特性: 它最终会调用到它最终会调用到XXXFreeXXXFree一类的函数一类的函数;; 例:例:class2.idbclass2.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((构造函数构造函数)) 构造函数总是分配内存成功的情况下才会被调构造函数总是分配内存成功的情况下才会被调 用用,,一般紧跟在调用构造函数后是分配失败的跳转一般紧跟在调用构造函数后是分配失败的跳转 代码,将代码,将thisthis指针复指针复00。。 cmpcmp [ebp+var_1C], 0[ebp+var_1C], 0 jzjz short loc_401042short loc_401042 movmov ecxecx, [ebp+var_1C], [ebp+var_1C] call sub_4010A0 call sub_4010A0 ; ; 构造函数构造函数 movmov [ebp+var_28], [ebp+var_28], eaxeax jmpjmp short loc_401049short loc_401049 loc_401042:loc_401042: movmov [ebp+var_28], 0[ebp+var_28], 0 PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((析构函数析构函数)) 析构函数也总是在在内存分配成功的情析构函数也总是在在内存分配成功的情 况下才会被调用,而且析构函数与况下才会被调用,而且析构函数与deletedelete操操 作都被封装在一个作都被封装在一个““外壳外壳””中中.. 看一个例子看一个例子class2.idbclass2.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((构造函数与析构函数构造函数与析构函数)) 如果是处在堆栈中的自动变量的构造函如果是处在堆栈中的自动变量的构造函 数,那么就只能猜了数,那么就只能猜了~~~~~~ PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((虚函数虚函数)) 虚函数是虚函数是C++C++的重要特性。它根据你的的重要特性。它根据你的 具体对象的类型而去调用相应的函数。也具体对象的类型而去调用相应的函数。也 就是说这个函数必须和对象紧紧联系在一就是说这个函数必须和对象紧紧联系在一 起。在编译器上是用虚函数表来实现的。起。在编译器上是用虚函数表来实现的。 虚函数表是象一个数组一样,将每个虚虚函数表是象一个数组一样,将每个虚 函数的地址放在表中,而这个虚函数表的函数的地址放在表中,而这个虚函数表的 地址又被放置在对象的偏移为地址又被放置在对象的偏移为00的地方的地方((只针只针 对对VC++VC++、、Inter C++Inter C++;; GccGcc放置的位置不放置的位置不 定。定。)) PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((虚函数虚函数)) class parent {class parent { public:public: intint a;a; virtual void virtual void demo(voiddemo(void);); ………….. .. };}; aa vtalvtal 指向demo指向demo demovtal PDF 文件使用 "pdfFactory" 试用版本创建 ê ê ê ê www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((虚函数虚函数)) 在构造函数里面,会将虚函数表的地址在构造函数里面,会将虚函数表的地址 移入到对象实例的开头部分。移入到对象实例的开头部分。 movmov dworddword ptrptr [[eaxeax], offset off_40810C], offset off_40810C 调用:调用: call call dworddword ptrptr [[eaxeax]] 例子:例子:virtual.idbvirtual.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 类类 ((纯虚函数纯虚函数)) 抽象类是不允许创建对象的,那它是怎抽象类是不允许创建对象的,那它是怎 么禁止的呢?么禁止的呢? 如果用抽象类实例化一个对象,那么这如果用抽象类实例化一个对象,那么这 个对象的虚函数表将是一个指向个对象的虚函数表将是一个指向____purecallpurecall 的指针,在程序执行时调用到它的话,由的指针,在程序执行时调用到它的话,由 它给用户警告。它给用户警告。 例:例:purecall.idbpurecall.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 浮点处理浮点处理 浮点数的处理与整数不一样,它是由浮点数的处理与整数不一样,它是由 FPUFPU完成的。完成的。floatfloat用用44个字节表示,个字节表示,doubledouble 则用则用88个。常用的浮点指令:个。常用的浮点指令: fldfld 压栈压栈 fstfst弹栈弹栈 fcomfcom 比较比较 faddfadd 加法加法 fdivfdiv除法除法 fmulfmul 乘法乘法 fsubfsub 减法减法 PDF 文件使用 "pdfFactory" 试用版本创建 呔z t 呔 z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 浮点处理浮点处理 浮点处理时,先把操作数压到浮点堆栈中浮点处理时,先把操作数压到浮点堆栈中,,比比 如:如: float a = 5.89 + 8.90;float a = 5.89 + 8.90; 在汇编中:在汇编中: fldfld 40BC7AE1h40BC7AE1h ; ; 压入压入5.895.89 faddfadd 410E6666h 410E6666h ; ; 加上加上8.908.90 fstpfstp [[espesp + var_4] + var_4] ; ; 将浮点堆栈顶部的值弹将浮点堆栈顶部的值弹 ; ; 到变量中到变量中 PDF 文件使用 "pdfFactory" 试用版本创建 呔z t 呔 z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 浮点处理浮点处理 浮点堆栈一共有八个单元,每个单元占浮点堆栈一共有八个单元,每个单元占 88个字节,栈顶为个字节,栈顶为st(0) st(0) 或称或称 stst, , 栈底为栈底为 st(7).st(7). st0 st1 st2 st3 ……. PDF 文件使用 "pdfFactory" 试用版本创建 ê f ê f www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 浮点处理浮点处理 如果函数的参数或返回值是浮点类型,如果函数的参数或返回值是浮点类型, 那么它们都是通过浮点堆栈传递的。那么它们都是通过浮点堆栈传递的。 例子:例子:float.idbfloat.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 浮点处理浮点处理 浮点有三种类型:浮点有三种类型:float float 、、double double 、、long long doubledouble。在处理这三种类型的数据的时。在处理这三种类型的数据的时 候,指令都是那几条,怎么样确定到底操候,指令都是那几条,怎么样确定到底操 作的类型是什么呢?作的类型是什么呢? 根据机器指令,比如根据机器指令,比如fldfld,对,对floatfloat的机器的机器 码是:码是:0xD9, 0xD9, 对对doubledouble是是0xDD, 0xDD, 对对long long double double 是是0xDB0xDB。。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 浮点数的比较浮点数的比较 浮点处理只有浮点处理只有fcomxfcomx指令,可没有用于指令,可没有用于 它的跳转指令,判断比较结果,必须将浮它的跳转指令,判断比较结果,必须将浮 点数的比较结果点数的比较结果((协处理器标志寄存器协处理器标志寄存器))送到送到 寄存器中,再与掩码进行判断。寄存器中,再与掩码进行判断。 14 13 10 9 815 busyzf pf cf ….. 进位奇偶零值 PDF 文件使用 "pdfFactory" 试用版本创建 ê f ê f www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 浮点数的比较浮点数的比较 用用fnstswfnstsw regreg 指令,可以将协处理器的指令,可以将协处理器的 标志寄存器的内容拷贝到指定的通用寄存标志寄存器的内容拷贝到指定的通用寄存 器中。类似这样:器中。类似这样: fldfld aa fcompfcomp bb fnstswfnstsw axax test ax (test ax (或或ah), ah), bit_maskbit_mask jxxxjxxx loc_xxxxxxloc_xxxxxx;; PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆高级语言特性的识别高级语言特性的识别 §§ 浮点数的比较浮点数的比较 对于判断大小一类的,一般只用到标志的对于判断大小一类的,一般只用到标志的88、、 1414位,比如判断位,比如判断aa是否大于是否大于b:b: fldfld aa fcompfcomp bb fnstswfnstsw axax test test ahah, 41h , 41h jnzjnz loc_1234 loc_1234 ………… a > b a > b ; ; 既既CF = ZF = 0CF = ZF = 0 loc_1234:loc_1234: …….. a <= b .. a <= b 例:例:fcom.idbfcom.idb PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ◆◆编译器优化编译器优化 编译器优化的程序取决于你的选项。一编译器优化的程序取决于你的选项。一 般而言,我们在用般而言,我们在用VC++VC++发布发布ReleaseRelease版的进版的进 候,默认优化级别是候,默认优化级别是O2O2。。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆编译器优化编译器优化 §§ 内联函数内联函数 并不是所有加了并不是所有加了inlineinline函数都会被展开,函数都会被展开, 也并不是没有也并不是没有inlineinline就不会被展开,这取决就不会被展开,这取决 于你的编译器。当一个函数很短小或是值于你的编译器。当一个函数很短小或是值 是固定的话,编译器会把它们展开或是直是固定的话,编译器会把它们展开或是直 接算出其值作为常数。接算出其值作为常数。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆编译器优化编译器优化 §§ 袪除无用函数袪除无用函数 如果一个函数没有被用到,编译器不会如果一个函数没有被用到,编译器不会 将它编译进目标代码。将它编译进目标代码。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆编译器优化编译器优化 §§ 代码合并代码合并 如果两个函数完成的功能完全一样,编如果两个函数完成的功能完全一样,编 译器会对它进行代码合并,即把两个函数译器会对它进行代码合并,即把两个函数 变成一个。变成一个。 PDF 文件使用 "pdfFactory" 试用版本创建 呔z ê呔z www.fineprint.com.cn ◆◆编译器优化编译器优化 §§ 数学运算数学运算 ((除法除法)) 除法在不做优化的情况会比乘法慢除法在不做优化的情况会比乘法慢1010倍左右。倍左右。 通常利用下面的公式来进行优化:通常利用下面的公式来进行优化: 公式公式: a/b = (2^n / b) * (a / 2^n): a/b = (2^n / b) * (a / 2^n) 一般看到如下代码,就是在做除法。一般看到如下代码,就是在做除法。 movmov eaxeax cdqcdq imulimul ecxecx sarsar edxedx, n, n movmov eaxeax, , edxedx sarsar eaxeax, m, m add add edxedx, , eaxeax PDF 文件使用 "pdfFactory" 试用版本创建 呔z胸l呔z www.fineprint.com.cn ☺☺欢迎提问欢迎提问 ☺☺ 文中所提到的资料、工具与文中所提到的资料、工具与demodemo可以到:可以到: \\\\bzlibzli\\反汇编技术反汇编技术 中获取中获取 PDF 文件使用 "pdfFactory" 试用版本创建 ÿ ÿ ÿ www.fineprint.com.cn 谢谢大家!谢谢大家! PDF 文件使用 "pdfFactory" 试用版本创建 呔z ÿ呔z www.fineprint.com.cn
还剩105页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

haiantj

贡献于2012-01-12

下载需要 10 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf