ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Re(3)

2022-01-23 17:59:57  阅读:154  来源: 互联网

标签:ESP EDI 栈顶 Re 指令 EBP 跳转


CMP指令
指令是比较两个操作数,实际上,相当于SUB指令,但是相间的结构并不保存到第一个操作数中,知识根据相减的结果来改变标志位的,当两个操作数相等的时候,零标志位置1
TEST指令:
在一定程度上和CMP指令类似,两个数值进行与操作,结果不保存,但是会改变相应标志位。
(观察Z位)
JE,JZ 结果为零则跳转 ZF=1
JNE,JNZ 结果不为零则跳转 ZF=0
JS 结果为负则跳转 SF=1
JNS 结果为非负则跳转 SF=0
JP,JPE 结果中1的个数为偶则跳转 PF=1
JNP,JPO 结果中1的个数为偶数则跳转 PF=0
JO 结果溢出则跳转 OF=1
JNO 结果没有溢出则跳转 OF=0
JB,JNAE 大于则跳转(无符号数) CF=1
JNB,JAE 大于等于则跳转(无符号数) CF=0
JBE,JNA 小于等于则跳转(无符号数) CF=1 or ZF=1
JNBE,JA 大于则跳转(无符号数) CF=0 or ZF=0
JL,JNGE 小于则跳转(有符号数) SF≠OF
JNL,JGE 大于等于则跳转(有符号数) SF=OF
JLE,JNG 小于等于则跳转(有符号数) ZF=1 or SF≠OF
JNLE,JG 大于则跳转(有符号数) ZF=0 and SF=OF
画堆栈图

在定位到的行设置断点 
设置好断点后,按下图中蓝色这个按钮,让程序运行到刚设置的断点处停下来。
程序运行到“0x401068”时,当前OD中的显示。
栈是一个连续的内存块。根据当前ESP,EBP寄存器中的值,可以画出当前的栈顶、栈底。
下一条指令是,PUSH 2,这是一条入栈的指令,指令2会被压入栈顶,ESP的值也会减那么
按F8,执行PUSH 2指令。OD上的显示跟预想的结果一样。
然后用的指令是PUSH 1,跟上一条指令一样,1被压入栈顶,DSP的值减4.
然后使用指令是:CALL 00401005,之前说过,call指令会把Call的下一条指令的地址压入栈顶,当前call的地址是0x40106C,因为第二列中有5个字节,我们可以算出call指令的下一行地址是0x401071,所以指令该条指令后,0x401071会被压入栈顶,EIP寄存器中的值被改为0x401005。
然后用JMP指令,只是跳转,不会修改栈中的内容,直接按F8运行,或者按回车键。
用指令PUSH EBP,入栈操作,EBP寄存器中的值被压入栈顶,ESP减4:
然后用的是MOV EBP,ESP,该指令只是修改栈底EBP的值。
下一条指令是SUB ESP,40,这是一个减法指令,修改的是ESP,也就是栈顶,栈顶被提升了。注意这里的40是十六进制的,也就是十进制的64,因为地址是4个字节的,所以64除以4,得到16,也就是向上画16个格。
然后用的是PUSH EBX,把寄存器EBX中的值压入栈顶,ESP减4.
下一条指令是PUSH ESI,把ESI中的值压入栈,ESP再减4.
然后用的是PUSH EDI,把EDI中的值压入栈顶,ESP减4
下一条指令LEA EDI,DWORD PTR SS:[EBP-40],这是一条取地址的指令,取EBP减0x40所把的内存地址,保存到EDI中
可以看到只修改了EDI中的值。栈并没有发生改变。
然后用的是MOV ECX,10,只是修改ECX中的值,栈没有发生改变。
然后用的是MOV EAX,CCCCCCCC,只是把EAX中的值修改为CCCCCCCC,栈没有发生改变。
然后用的是REP STOS DWORD PTR ES:[EDI],这里有两个指令:STOS指令是把EAX中的值写入到EDI所指的内存中,然后EDI中值根据标志寄存器DF位进行加或者减一个数,因为这里的DF是0,所以STOS执行一次,EDI中的值就加4。REP是重复指令指令,重复执行的次数是EAX中保存的值。执行这条指令后,前面步骤10提升的栈的16个内存都被填入CCCCCCCC。
这一步是填的是INT3,是为了防止访问越界了。
然后用的是MOV EAX,DWORD PTR SS:[EBP+8],是把EBP+8所指的内存中的值(即步骤6压入栈的1)保存到EAX中。没有改变栈中的内容。
下一条指令:ADD EAX,DWORD PTR SS:[EBP+C],加法指令,把EBP所指内存的值(即步骤5压入栈的2)与EAX中的值相加,保存到EAX中
然后用的是POP EDI,出栈,栈顶的值复制到EDI中,栈顶加4.
下一条指令:POP ESI,出栈,栈顶的值复制到ESI中,栈顶加4.
然后用的是POP EBX,出栈,栈顶的值复制到EBX中,栈顶加4
下一条指令:MOV ESP,EBP,把EBP中的值复制到ESP中,即修改栈顶到现在的栈底。
可以看到ESP、EBP中的值相等。
然后用的是POP EBP,出栈,把现在栈顶的值复制到EBP中,结合步骤8,可以知道栈底的返回到调用前的状态。
下一条指令:RETN,RETN指令会把栈顶的值弹出到EIP中,即程序运行到调用Call指令(步骤7)的下一条指令。栈顶被修改
最后ADD ESP,8,是加法指令,ESP的值加了8,这是为了平衡堆栈,即调用函数前后,堆栈的结构要一样。像这种在调用函数外面平衡堆栈的叫外平栈,如果在调用函数里面平衡堆栈的叫内平栈。

标签:ESP,EDI,栈顶,Re,指令,EBP,跳转
来源: https://blog.csdn.net/qq_63267612/article/details/122654408

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有