使用汇编语言实现if else 循环函数调用的具体方法
<p style="text-align: left">需要使用汇编来演示如下代码 需要下载ollydbg汇编调试器 点击File-Open随意打开一个exe文件 我这里随便找到c:/windows/explorer.exe文件</p><p style="text-align: center"><img alt="" src="https://img.jbzj.com/file_images/article/202001/202001191421581.jpg" /><br />
</p>
<p>这里EIP的值表示下一次运行需要执行的代码位置</p>
<p style="text-align: center"><img alt="" src="https://img.jbzj.com/file_images/article/202001/202001191421582.jpg" /><br />
</p>
<p>双击 EIP红色地址 左边代码会自动跳转到对应的代码行 有了以下环节 接下来添加代码</p>
<p style="text-align: center"><img alt="" src="https://img.jbzj.com/file_images/article/202001/202001191421583.jpg" /><br />
</p>
<p>如果替换的代码 占用的字节数 小于原始的代码数 会自动补充 nop空指令</p>
<p><span style="color: #ff0000"><strong>一。实现 if else </strong></span></p>
<p>MOV EAX,1 表示将1立即数 设置给EAX寄存器</p>
<p>CMP EAX,1 比较EAX的值和1是否相等 Z标志位(如果减法运算 结果为0 该标志被置为1 不为0 标志位被置为0) 这里EAX=1 Z标志=1</p>
<p>JE 0101A572 表示有条件跳转 当Z标志=1(也就是EAX=1) 自动跳转到后面指定的0101A572 地址 就会执行 move EBX,1</p>
<p>JNE 0101A578 表示有条件跳转 当Z标志=0(也就是EAX!=1) 自动跳转到后面指定的0101A578 地址 就会执行 move ECX,1</p>
<p style="text-align: center"><img alt="" src="https://img.jbzj.com/file_images/article/202001/202001191421584.jpg" /><br />
</p>
<p>如果需要调试 参考如下图</p>
<p style="text-align: center"><img alt="" src="https://img.jbzj.com/file_images/article/202001/202001191421585.jpg" /><br />
</p>
<p><span style="color: #ff0000"><strong>二。实现 循环</strong></span></p>
<p>MOV ECX,4 表示将4立即数 设置给ECX寄存器</p>
<p>DEC ECX 将ECX的值 减去1</p>
<p>TEST ECX,ECX TEST指令是将ECX和ECX进去逻辑与 操作 1001&1001一定是自己1001 只有当ECX等于0时 0&0就是0 这个test指令 会修改Z标志</p>
<p>位 如果ECX等0 那么逻辑与 Z标志位就是1 ECX不等于0 Z标志位等于0 所以TEST ECX,ECX可以判断ECX是否为0</p>
<p>JNE 0101A564 表示有条件跳转 当ECX!=0时 z标志位=0 跳转到0101A564这个位置 继续递减 一直循环到 ECX=0时 此时z标志位=1</p>
<p>不执行跳转循环结束</p>
<p style="text-align: center"><img alt="" src="https://img.jbzj.com/file_images/article/202001/202001191421596.jpg" /><br />
</p>
<p>也可以使用 LOOP 跳转的位置来进行循环 该指令会自动将ECX的值 递减1 不需要单独控制ECX递减 当ECX递减到0时自动退出循环</p>
<p>loop</p>
<p style="text-align: center"><img alt="" src="https://img.jbzj.com/file_images/article/202001/202001191421597.jpg" /><br />
</p>
<p><span style="color: #ff0000"><strong>二。实现 函数调用</strong></span></p>
<p>这里需要明白一下函数调用的实际过程 是先将 参数压入栈中 在c语言中 stdcall 先压入函数右边的参数 这里假设有两个参数10和20</p>
<p>栈的原理是 先入后出 压入两个参数后 call指令会自动压入 函数调用完成后 下一个执行指令的位置</p>
<p>PUSH 10 压入第一个参数</p>
<p>PUSH 20 压入第二个参数</p>
<p>CALL 0101A56D 调用函数 函数的入口地址是0101A56D 可以查看如下图片中右下角堆栈的部分 分别压入了 10,20 以及call后面的一句代码的地址</p>
<p>0101A568 也就是call完成了执行0101A568 这里的代码</p>
<p>call 0101A56D 会自动跳转到0101A56D 代码的位置 这里取出栈中(ESP指向栈顶 栈顶是call完成后返回的地址) ESP栈顶+4(第二个参数) ESP栈顶+8(第一个参数)</p>
<p>retn 8 表示 函数返回 返回 就会自动跳转到栈顶指向的地址的代码位置0101A568 就会执行 (8这个数 表示自动将堆栈中两个参数的值出栈 抛弃)</p>
<p>jmp 0101A57A</p>
<p style="text-align: center"><img alt="" src="https://img.jbzj.com/file_images/article/202001/202001191421598.jpg" /><br />
</p>
<p style="text-align: left">以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持琼殿技术社区。</p>
<div class="art_xg">
<b>您可能感兴趣的文章:</b><ul><li>汇编分析 Golang 循环(推荐)</li><li>详解汇编语言RCL(带进位循环左移)和RCR(带进位循环右移)指令</li><li>从Go汇编角度解读for循环的问题</li></ul>
</div>
</div>
<!--endmain-->
頁:
[1]