《逆向工程核心原理》读书笔记——第6章 汇编编写的exe程序入口
Posted 大灬白
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《逆向工程核心原理》读书笔记——第6章 汇编编写的exe程序入口相关的知识,希望对你有一定的参考价值。
一级目录
6.1abex’ crackme #1
调试前先运行abex’crackme #1这个程序,大致了解一下它。
如图6-1所示,双击运行程序后弹出一个消息窗口,显示“Make me think your HD is a CD-Rom"消息。我刚开始并不理解这句英文。
消息的最后部分出现了“CD-Rom”这个词,我们只能根据它大致推测出前面的HD为HDD(Hard Disk Drive)的意思。由于没有更多选择,我们继续按消息窗口中的“确定”按钮。
如图6-2所示,程序弹出Error消息窗后就终止运行了。但是abex到底想要干什么(要怎样破解什么)仍然不得而知。下面直接调试分析它,把握这个小程序的意图。
6.1.1 开始调试
首先运行OllyDbg软件载入小程序,代码窗口中可以看到程序的汇编代码,如图6-3所示。
EP代码非常短,它与我们前面分析的HelloWorld.exe有非常大的不同。这是因为abex’crackme程序是使用汇编语言编写出来的可执行文件。
使用VC++、VC、Delphi等开发工具编写程序时,除了自己编写的代码外,还有一部分启动函数是由编译器添加的,经过反编译后,代码看上去就变得非常复杂。但是如果直接使用汇编语言编写程序,汇编代码会直接变为反汇编代码。观察图6-3中的代码可以看到,main()直接出现在EP中,简洁又直观,充分证明了这是一个直接用汇编语言编写的程序。
程序开始就是直接调用MessageBoxA函数,接下来就是一些跳转,破解就是修改跳转逻辑就可以了。
6.3 将参数压入栈
结束本章前,再向大家介绍一个代码逆向分析中比较重要的内容——函数调用时将函数参数压人栈的方法。
首先,请看地址00401000~0040100E之间的命令,可以发现调用MessageBoxA()函数之前使用了4个PUSH命令,把函数需要的参数逆序压入栈。
将上述汇编代码转换为C语言函数调用代码,如下所示。
MessageBox(NULL, "Make me think your HD is a CD-Rom.","abex'1stcrackme",MB_OKIMB_APPLMODAL);
比较C语言代码与汇编代码可以看到,函数调用时的参数顺序(正序)与参数入栈时的顺序(逆序)相反。那么参数入栈时,为什么要采用这种逆序的方式呢?要想理解这个问题,想想栈内存结构(FILO,First In Last Out或LIFO,Last In First Out)即可。
“栈的结构是FILO(先进后出),所以把参数压入栈时,只有按照逆序的方式压入,MessageBoxA()函数才能以正确的顺序接收到这些参数。”
利用调试器执行到EIP=0040100E地址处,观察右下角栈窗口,如图6-5所示。
x86环境下,栈向低地址延伸(即向栈压入数据时,EPS值减小,向低地址方向移动),观察图6-5中的栈窗口可以看到,MessageBoxA()函数的第一个参数在栈顶位置,最后一个参数(第四个参数)在其他参数下面,从PUSH命令执行的顺序可以很容易地理解这点。
00401000 >/$ 6A 00 push 0x0 ; /Style = MB_OK|MB_APPLMODAL
00401002 |. 68 00204000 push abexcm1-.00402000 ; |Title = "abex' 1st crackme"
00401007 |. 68 12204000 push abexcm1-.00402012 ; |Text = "Make me think your HD is a CD-Rom."
0040100C |. 6A 00 push 0x0 ; |hOwner = NULL
MessageBoxA()函数从栈中获取需要的参数时,存储在栈中的参数会按照FILO(先进后出)的规则依次弹出。从MessageBoxA()函数获取参数的角度来看,参数就像按照原来顺序被存入栈一样。
以上是关于《逆向工程核心原理》读书笔记——第6章 汇编编写的exe程序入口的主要内容,如果未能解决你的问题,请参考以下文章