逆向分析技术学习小结

来源:互联网 发布:淘宝网址怎么做 编辑:程序博客网 时间:2024/06/06 05:08

1、所有C/C++运行时的启动函数作用基本相同:检索指向新进程的命令行指针、检索指向新进程的环境变量指针、全局变量初始化、内存堆栈初始化等。当所有的初始化操作完成后,启动函数就调用应用程序的入口点函数。

拿VC编译的程序来讲,有GetVersion(确定Windows系统版本)、GetCommondLineA(指向进程的完整命令行的指针)、GetStratupInfoA(获取进程的启动信息)、GetMoudleHandleA(返回进程地址空间执行文件基地址),然后调用入口点函数。当然,不同版本编译信息不同。

当入口点返回时,启动函数便调用C运行库的exit函数,将返回值(nMainRetVal)传递给它,进行一些必要的处理,最后调用系统函数ExitProcess退出。


2、函数的部分:返回值、函数名、参数、功能。

返回值:return一般放在EAX寄存器,如果超出大小,则放在EDX:EAX中。当然,也有通过引用传递和全局变量来返回值的。

名称修饰约定



参数传递:通过寄存器、全局变量、堆栈。其中传递参数需要遵循一定的调用约定,既是定义说明应该按照什么顺序把参数压入堆栈,函数结束后该由谁平衡堆栈。

调用约定约定类型参数传递顺序平衡堆栈者允许使用不确定参数__cdecl(C规范)从右到左调用者允许Pascal从左到右子程序否stdcall从右到左子程序允许Fastcall使用寄存器和堆栈子程序 

(其中__cdecl是C和C++程序的默认规范,stdcall调用约定是Win32API函数采用的,有部分也是用C规范的。Fastcall特点是快,左边一些参数用寄存器传递)子程序大概流程如下:

push ebp;保护现场原先的EBP指针mov ebp, esp;设置新的EBP指针,指向栈顶mov eax, dword ptr [ebp+0c];调用参数2mov ebx, dword ptr [ebp+08];调用参数1sub esp, 8;局部变量空间```add esp, 8;释放局部变量占用空间pop ebp;恢复现场的EBP指针ret 8;返回,ret后面的值是参数的个数乘以4h

关于enter和leave指令,可以用来帮助维护堆栈的。enter 8, 0(0表示是空间是用来放局部变量的)可以替代push ebp和mov ebp,esp和sub esp,8这三条指令,同时leave恢复现场,相当于add esp,8和pop ebp两条指令。

3、局部变量的生成。

1、堆栈

a、sub esp, n …… add esp,n
b、add esp, -n …… sub esp,-n
c、push reg …… pop reg
一般引用局部变量方法为【ebp-xxxx】,而引用参数则是【ebp+xxxx】。但是编译器在优化模式下则是通过【esp+xxxx】来统一调用。关于局部变量的初始化,可以直接push 常数,或者再mov。
2、寄存器
局部变量的生存周期短,要注意确定寄存器所代表的变量。


4、虚函数是要通过虚函数表来调用的,每个保护虚函数的对象中都有虚函数表指针。


5、关于转移指令,三大类吧,短转移、长转移、子程序调用。


6、几种字符串编码形式

a、C字符串,以‘\0’结束;

b、DOS字符串,以'$'结束;

c、Pascal字符串,头部有一个字节用来说明字符串长度,所以字符串最长为255个字符。

d、Delphi字符串,有双字节和四字节,与Pascal相似。


7、计算字符串长度的strlen优化,其优化模式下的汇编代码如下:

mov ecx, FFFFFFFF;不解释sub eax, eax;eax清零repnz;重复串操作ecx次scasb;将AL内容与EDI指定的附加段中的数据逐个比较not ecx;ecx为字符串的长度dec ecx;ecs为字符串的实际长度je xxxxxx;如果ecx为0,既是字符串长度为0,则跳转


8、很多之类针对eax寄存器有优化,比如说xchg eax,ecs只需要一个字节,换做其它寄存器则要两个字节

原创粉丝点击