如果您无法下载资料,请参考说明:
1、部分资料下载需要金币,请确保您的账户上有足够的金币
2、已购买过的文档,再次下载不重复扣费
3、资料包下载后请先用软件解压,在使用对应软件打开
第一课逆向分析基础知识1.1调用约定在分析汇编代码时总是要遇到无数的Call,对于这些Call,尽量要根据Call之前传递的参数和Call的返回值来判断Call的功能。传递参数的工作必须由函数调用者和函数本身来协调,计算机提供了一种被称为栈的数据结构来支持参数传递。当参数个数多于一个时,按照什么顺序把参数压入堆栈。函数调用后,由谁来把堆栈恢复。在高级语言中,通过函数调用约定来说明这两个问题。常见的调用约定有:【例】按__stdcall约定调用函数test2(Par1,Par2)pushpar2;参数2pushpar1;参数1calltest2;{pushebp;保护现场原先的EBP指针movebp,esp;设置新的EBP指针,指向栈顶moveax,[ebp+0C];调用参数2movebx,[ebp+08];调用参数1subesp,8;若函数要用局部变量,则要在堆栈中留出点空间…addesp,8;释放局部变量占用的堆栈popebp;恢复现场的ebp指针ret8;返回(相当于ret;addesp,8)}其堆栈调用示意图:资料HYPERLINK"http://bbs.pediy.com/showthread.php?t=38234"\t"_blank"函数调用堆栈变化分析1.2局部变量在子程序内部说明的变量称为局部变量,局部变量的作用域是其所在的子程序。从汇编角度来看,局部变量就是一个临时堆栈缓存,用完释放。例如这个实例:HYPERLINK"http://bbs.pediy.com/upload/bbs/faq/local.zip"\t"_blank"附件:local.zip其反汇编代码如下(红体字为局部变量):00401000>/$6A04push4;/Arg2=0000000400401002|.6A03push3;|Arg1=0000000300401004|.E816000000call0040101F;\Add.0040101F00401009|.8BD8movebx,eax0040100B|.6A00push0;/ExitCode=00040100D\.FF1500204000call[<&KERNEL32.ExitProcess>];\ExitProcess0040101F/$55pushebp;保护现场原先的EBP指针00401020|.8BECmovebp,esp;设置新的EBP指针,指向栈顶00401022|.83EC04subesp,4;分配局部变量所有空间00401025|.8B450Cmoveax,[ebp+C];调用参数200401028|.8B5D08movebx,[ebp+8];调用参数10040102B|.895DFCmov[ebp-4],ebx;参数1放局部变量里0040102E|.0345FCaddeax,[ebp-4];参数2与局部变量相加00401031|.83C404addesp,4;释放局部变量所有空间00401034|.5Dpopebp;恢复现场的ebp指针00401035\.C20800retn81.3返回值在调试程序时,不要见Call就跟进,在Call之前所做的所有PUSH动作以及对寄存器的操作都可能是在给函数传递参数,而函数的返回值一般都放在EAX里面,当然这个值可能是一个指针,指向一个数据结构。从汇编角度来看,主要有如下形式:1)通过寄存器返回函数值;2)通过参数按引用方式返回函数值;3)通过全局变量返回函数值;4)通过处理器标志返回函数值;一般情况下,由retrun操作符返回的值放在EAX寄存器之中,如果结果超过这个寄存器的位容量,那么该结果的高32位会加载到EDX寄存器中。如果返回一个含有几百个字节的结构或者一个近似大小的对象,编译器会在不告诉程序的情况下,给函数传递一个隐式参数,这个指针指向保存的返回结果。1.4启动函数在编写Win32应用程序时,都必须在源码里实现一个WinMain函数。但Windows程序执行并不是从WinMain函数开始的,首先被执行的是启动函数相关代码,这段代码是编译器生成的。启动代码完成初始化进程,再调用WinMain。标准编译器通常包含启动代码在内的库文件源码,例如VisualC++中,启动代码存放在CRT\SRC\crt0.c文件中。所有的C/C++运行时启动函数的作用基本都是相同的:检索指向新进程的命令行指针,检索指向新进程的环境变量指针,全局变量初始化,内存堆栈初始化等。当所有的初始化操作完毕后,启动函数就调用应用程序的进入点函数。调用WinMain如下所示:GetStartupInfo(&StartupInfo);IntnMainRetVal=WinMain(GetModuleHandle(NULL),NULL,pszC