让我们先看看游戏规则:
defiler’s reversme no.1
The task of this little, lame reverseme is to add some code to it.
The code you have to add will be triggered by the ‘Exit’ menu and should
look like this:
A messagebox should appear asking the user “Do you fickbirne really want to quit?”.
Its buttons should be ‘Yes’ and ‘No’. If the user clicks ‘Yes’, simply exit the
program in a clean way, if the user clicks ‘No’ just do NOT exit the program
(it’s up to you what will happen when the user clicks ‘No’).
Valid solutions are solutions with a tutorial explaining what you did,
explaining the code you added and the modified binaries.
Mail your solution to defiler@immortaldescendants.org
Valid solutions will be published on http://immortaldescendants.org,
the first solution will be on http://defiler.cjb.net
thats it.. i hope i didn’t forget any more unimportant stuff ;)
best regards,
defiler
我们需要在没有源代码的情况下,给退出菜单增加一个对话框

打开这个程序,点击Exit没有任何反应,我们需要做的就是点击这个Exit后弹出一个确认退出的对话框,并处理对话框的是与否事件
这个程序是delphi语言写的,我们首先就是使用Dede查看一下一些信息
发现只有一个About的事件处理,我们记下地址,然后打开ollydbg,跳转到这个地址处
这里就是弹出关于对话框的代码了,我们可以模仿这个代码,写退出的对话框
现在的关键问题是,我们该在哪里添加代码?
经过浏览,我们发现程序结尾处(0x43E4BC,在文件中的偏移为0x3D8BC)有很大一片空间,我们或许可以把代码加到这里
好吧,就开干,先定义需要的字符串
字符串呢,最好内存对齐,因此,我们在字符串结尾有好几个0
然而,当我们把字符串每个字符的ascii码搞上去后,出现了上图所示的情况,ollydbg没有把它识别成字符串,当这不影响我们后续的操作。
上图,在0x43E4BC到0x43E4C3定义的是字符串”Exit”,待会会用作对话框的标题,
在0x43E4C4到0x43E4ED定义的是字符串” Do you fickbirne really want to quit?”,待会会用作对话框的提示内容
接下来,我们就模仿那个关于对话框(有人模仿我的脸还会模仿我的代码^_^),写了些代码。
来我们分析一下代码
首先我们push 0x24,而那个about是push 0x40,这个值代表了对话框样式,0x24的样式如下
!Title
XXXXXXXXXX
|Yes| |No|
这就是我们需要的样式
然后我们修改了一下两处地址,
mov ecx,0x43E4BC ;指向我们定义的标题”Exit”
mov edx,0x43E4C4 ;指向我们定义的提示内容”Do you fickbirne really want to quit?”
接下来三句照抄
mov eax,dword ptr ds:[0x43FBD0]
mov eax,dword ptr ds:[eax]
call 0043CC14 ;显示对话框
mov ebx,eax ;eax返回的按钮的点击情况,经过调试发现eax == 7时点击的是”No 否”按钮,eax == 6时点击的是”Yes是”按钮
cmp ebx,0x7
je 0x0043E512 ;如果点击的是否,我们跳到retn处,即函数执行结束
call 0040122C ;否则点击的是”是按钮”,我们调用这个ExitProcess()函数退出程序
retn
那么这个ExitProcess的地址是如何找到的呢????
首先,我们在ollydbg输入bpx ExitProcess命令
然后我们打开断点视图
我们发现,本程序其他地方正好有调用这个函数,那么我们自己点进去,复制汇编代码到我们自己需要的地方
Ojbk

接下来,我们需要做的是,在某个地方来调用我们的这段代码,即响应Exit菜单事件,为了找到事件处理的代码,我们先在About的事件响应处断点
然后运行程序,点About触发断点,然后我们单步执行,执行完retn后就会返回到调用者的地址处
继续单步,返回到更上一个的调用者处
到这里了,我们把两个call都断点,慢慢调试看看

重新运行,我们发现不管是点击About还是Exit,都可以触发这里的断点。
先分析第一个call函数,我们执行完这个call后,观察到edx的变化
当我们点击”About”菜单时,edx值变为2;当我们点击”Exit”菜单时,edx的值变为3。我们可以根据这个值来判断点击的是哪个按钮

接下来,我们分析第二个call,我们步入函数看看,我们单步执行,我们比对About和Exit的执行步骤,发现,0x42F41E处的执行不一样,我们点击Exit时会跳过最后的call dword ptr ds:[ebx+0x80],而我们点击About时,发现这个call跳到的就是About对话框处。由此,我们可以肯定,[ebx+0x80]处存储着需要执行的事件的地址。当我们点击Exit时,这个地址里面是空值,因此我们要做的就是在这个跳转之前,给[ebx+0x80]处赋上我们植入的代码段的地址
那么,我们再在程序末尾0x43E513添加一个函数来处理这件事情
我们把这里修改一下,来调用我们准备写的那个代理函数,修改0x430539处的汇编代码为
Call 0x43E513
然后这两条指令都被覆盖了,因此,我们需要在代理函数里把mov edx,dword ptr ds:[eax]重新添加上去
现在我们开始写0x43E513处的代理函数
cmp edx,0x3 ;判断是否是Exit按钮
mov edx,dword ptr ds:[eax] ;之前被覆盖掉的那条指令,我们重新添加上去
jnz 0x0043E524 ;如果不是Exit按钮,我们直接调用下面的call
mov dword ptr ds:[eax+0x80],0x43E4EE ;是Exit按钮,我们需要给[eax+0x80]存入我们的事件(退出对话框)的地址
call dword ptr ds:[edx+0x40]
retn
就这样,我们就完成了任务

现在,我们用c++写一个注册机
1 |
|