天象独行 发表于 2020-12-9 14:55:34

栈功能分析-局部变量传送

本帖最后由 天象独行 于 2020-12-9 15:12 编辑

栈功能分析-局部变量传送实验目的:逆向可执行文件,逐步分析局部变量如何通过栈进行传送。练习程序如附件测试代码如下图:   一;OD打开程序,定位到程序执行位置
       如下图:main()函数执行地址为0x401020。   二;int main()执行       在执行main()函数执行需要准备好栈环境。详细看如下代码:       首先,执行PUSH EBP 将寄存器EBP当中的值压入栈当中。如下图:       然后,执行MOV EBP,ESP。来初始化一个栈空间。详细如下图:总结1:       执行一个函数前,通常会准备一个栈空间。一般我们通过PUSH EBP;MOV EBP,ESP这两个指令来初始化一个栈帧。其中PUSH EBP 指令用来保存上一个栈的EBP值。MOV EBP,ESP指令来初始化一个栈帧。   三;“long a=1,b=2”
       执行局部变量a,b 赋值操作。该“long a=1,b=2”语句对应于汇编指令如下图:       首先,有“long”我们知道值是占用四个字节,那么两个变量,需要在栈中划分8个字节的空间。那么执行指令“SUB ESP,0X8”用来划分8个字节的空间。然后执行MOV指令。其中“和相当于变量a,b”栈内容如下:   四;调用子函数add()
       接下来,程序执行到如下图位置:       在执行add() 函数之前首先需要将函数需要的参数压入到栈,先将先前产生的局部变量通过EAX,ECX寄存器为中转站重新压入栈。详细如下图指令:       现在我们来观察一下,栈中的情况,我们发现栈中地址“0019FF18”和“0019FF1C”已经存放了局部变量a,b的值。       Add()函数已经存放入栈当中了,那么接下来需要调用add()函数。在汇编代码中,尝尝使用call 指令来调用。即如下代码:       执行Call指令,我们发现栈空间中将0040041压入栈空间。(该操作是为了add()函数执行完成之后跳回主程序运行位置)       继续查看,现在已经进入add()函数当中,第一步操作,初始化一个栈空间,详细入下图:       栈空间情况如下:总结2
       在高级语言当中的调用子程序,对应到汇编代码当中即执行了Call指令。如果该函数需要有参数,那么在调用Call指令之前,首先将需要用到的参数压入到栈当中。   五;“long x=a,y=b”
下面执行“long x=a,y=b”。该语句是将形参值放入局部变量x,y。那么我们查看对应的汇编代码:       从汇编代码中,我们知道一样通过sub指令来在add()函数的栈帧当中划分出一块8字节的空间,然后将之前压入栈中的a,b变量的数据通过寄存器为中转站放入到add()函数栈空间当中。EBP-8 等同于局部变量X, EBP-4 等同于局部变量Y。此时栈空间状态如下图:   六;”x+y”
       接下来执行如下图加法操作:       对应汇编代码如下:       将栈中的值放入寄存器中,使用add指令计算将结果保存在寄存器EAX当中。   七;返回主程序main()
       Return()语句,用来删除函数栈帧,且返回主程序。对应汇编代码如下:       汇编指令“MOV ESP,EBP”作用来删除ADD()栈。详细如下图:       汇编指令“POP EBP”作用恢复main()函数栈环境的值。“retn”作用返回主进程。即跳转到当初Call 指令压入栈地址的位置。栈空间状态如下:总结3   调用子程序首先将初始化一个属于自己的栈空间,然后将之前压入栈空间的形参通过寄存器为中转站来压入自己的栈空间当中。子程序运行结束之后,需要将子程序使用的栈空间清除。这样才不会影响主程序对栈空间的使用。且会恢复主程序当初的栈空间环境状态。



页: [1]
查看完整版本: 栈功能分析-局部变量传送