前言
这篇文章也说画堆栈图,不过内容跟之前的差不多,如果已经理解前面画堆栈图的内容,这篇文章大可不看。这篇文章只能说是对前面的巩固吧。其实本id之所以写这篇文章,只是想写写JCC。
因为只是想写写JCC,所以画堆栈图部分写得可能会比较简陋。
说明:可执行exe和源码已经放网盘,地址在文末。
具体步骤
1、把下载的yiDaChengXuYuan_stack4.exe拖到OD中打开。按Ctrl+G,在弹出的对话框中输入“401098”,在定位到的行按F2设置断点,然后点击上方蓝色的小三角按钮,让程序运行到刚设置的断点处。
2、查看当前OD中的栈顶、栈底
根据OD中的内容,绘制当前的栈。(为节省空间,栈顶、底之间的空间就用一个格表示)。
3、下面的三条指令:PUSH 8,PUSH 4,PUSH 2,入栈。
按F8运行的结果。
4、下一条指令是call指令,执行这条指令会把call的下一条指令的地址压入栈中。
按F7运行。
5、下一条是JMP指令,没有改变栈,直接按F8运行就可以了。
6、下一条指令是:PUSH EBP,该指令把当前的栈底压入栈中。
按F8运行的结果如下
7、下一条指令是:MOV EBP,ESP,修改栈底。
按F8运行的结果。
8、下一条指令是:SUB ESP,40,提升栈顶,这里的40是十六进制的,因为画图时是4个地址为一个格,所以要画16个格。
按F8运行的结束。
9、下面三条指令:PUSH EBX,PUSH ESI,PUSH EDI,保存现场,把可能会修改的寄存器的值压入栈中。
按F8运行。
10、下面的指令:LEA EDI,DWORD PTR SS:[EBP-40],MOV ECX,10,MOV EAX,CCCCCCCC,REP STOS DWORD PTR ES:[EDI],这几条指令就是填充提升的栈空间。
按F8运行这几条指令。
11、下面是本节的重点了,JCC部分来了。在说JCC部分之前,先说明程序是如何获取外部传入的参数的。它可以通过栈顶(或者栈底)通过加偏移量来直接获取的。如下图:
MOV EAX,DWORD PTR SS:[EBP+8]:这条指令把参数2放到EAX中。
CMP EAX,DWORD PTR SS:[EBP+C]:这条CMP指令,比较参数2和参数4,只修改标志寄存器
JGE SHORT 00401052:这是一条JCC指令,意思是大于或等于时跳转到地址00401052。这条指令根据标志寄存器进行判断,因为O位和S位不相等,所以不跳转,继续指令下一条指令。
MOV ECX,DWORD PTR SS:[EBP+8]:这条指令把参数2放到ECX中,
CMP ECX,DWORD PTR SS:[EBP+10]:这条CMP指令,比较参数2和参数8,只修改标志寄存器。
JGE SHORT 0040104D:这是JGE指令,意思是大于或等于时跳转到地址0040104D。查看O位和S位,不同,所以是不跳转的,继续下一条指令。
MOV EAX,DWORD PTR SS:[EBP+8]:这条指令把参数2放到EAX中
JMP SHORT 00401062:直接跳转到地址:00401062
可以看到函数的功能已经完成的,其实这里的功能就是算出三个数中最小的那个数。等大家学了C语言,再来看看下面这张图吧。
12、下面三条指令:POP EDI,POP ESI,POP EBX,还原现场。
按F8运行。
13、下一条指令:MOV ESP,EBP,降低栈顶.
按F8运行。
14、下一条指令:POP EBP,还原原来的栈底.
按F8运行。
15、下一条指令:TETN,这条指令会把栈顶的内容弹出到EIP中,让程序返回到调用call的下一条指令处。
按F8运行。
16、下一条指令:ADD ESP,0C,只是为了调用前后栈结构相同,即栈平衡。
按F8运行。
完成。
就写这么多吧。
写于2020.7.7 23:19
资料网盘地址:
链接:https://pan.baidu.com/s/1se7M-WYI_PugY1BG-AlEww
提取码:vs7n
全图: