声明:本人分享的一些视频教程、脚本、工具之类的仅供于学习交,也让自己在分享的过程中学习进步。教程所涉及的一些app并非针对其厂家,只是让大家学习了解一些逆向知识。都只用于学习交流安全技术,请不要用于任何非法用途, 否则后果自付
工具:
- OD(吾爱破解版)
- geek
开始时注意,由于geek是需要管理员模式才能打开的,所以这里我们要用管理员模式打开OD进行修改
加载过后,我们成功打开geek,OD默认跳转到程序的入口点(程序开始的地方,一般c++/c的入口点是main()、WinMain()、以及DLLMain)并记录一下 00599F84 OD会标记入口点
地址
数据
汇编代码
00599F84 geek.<ModuleEntryPoint>
$E8 F4110000
call geek.0059B17D
00599F89 .
^ E9 7AFEFFFF
jmp geek.00599E08
我们要加入我们的代码,如果直接写在这在这里显然是不可能的,所以我们需要一个新的空间来储存它。
那么,要怎么加呢?我们可以联想一下我们做笔记没有空间了,我们会有两种方法,一种是在哪里贴一张新纸来添加空间,另一种则是在上面做好标记,让他指向一个空白的地方,到时候到那里去查就好。当然第一种方法的实现貌似有些麻烦,但是,第二种方法则是非常容易的,我们只需要在程序的入口处写上 jmp 跳转到一个空的地址,在空地址上进行执行,最后再次使用jmp返回程序本该运行的位置即可。
那么我们直接用end跳转到程序底部,然后找到程序的最后的一行,我找到的地址为 005E9330
可以看到,这个地址后的内存地址都是没有任何指令的,这时如果我们要在其后面运行我们的代码,就需要先把这些地址处理一下,右键 - Binary(二进制)- Fill with “00s” 将其填充上“0”
填充完是这样的,一般情况下我们可以多填充一些,以免再之后操作中出现地址不够用再次去填充的问题,再一个重要点就是新的开辟的位置最好从最后的指令后开始填充。
既然我们已经找到我们要写代码的空间了,之后我们需要把他们链接一下,让代码的逻辑改为先运行我们的程序再正常执行,所以我们要在入口点先做点手脚
程序入口点是这样的
我们看到其中一个是call 一个为jmp命令,这就非常好了,因为它入口点后的第二个命令就是跳转,可以让我们减少写跳转的次数,同时让我们能更清晰的理解程序的运行方式。
我们选中这两个命令,然后用nop填充,填充完是这样的
我们把地址栏向右拖开,可以看见,虽然我们替换了那两个指令,但是入口点是依然不变的。
那么我们就要进行我们的操作了,我们在它的入口点先写上一个跳转,让他跳转到我们开辟的新内存空间上去,直接选中双击或者打空格,并输入jmp 005e9335(这个地址就是你的代码的第一段,不必和我的完全相同)
那之后,我们把还是nop的代码填充为“00”,填充完毕后是这个样子
那这段代码的意思就是(程序开始的时候)跳转到栈005E9335处,将执行那里的命令。
好了,现在程序已经跳转过来了,接下来就是执行我们的代码了,在这里我将写一个简单的弹窗代码,因为geek使用了windows api中的弹窗窗口的句柄(Messagebox),所以我们可以直接使用他的。
我们先找到Messagebox的地址
右键-search for-name in all modules,它会新建一个All Name窗口
我们从中找到User32.MessageBox,这里我找到了一个MessageBoxA和一个MessageBoxW
这里我解释一下两者的区别
MessageBoxA 指的是多字节字符集环境下所使用的函数 MessageBoxW 指的是Unicode字符集(宽字符)环境下所使用的函数
这里两个的区别就是编码是否定长了,这个先不细讲,我会在以后专门写一篇和编码相关的文章,在那里将会讲到两者的区别,咱们这用USER32.MessageBoxW就好,注意一定要选前面写着 geek 的 rdata 段的。(至于为什么我再挖个坑,以后讲)
右键-copy-address得到地址:005EA7A4 geek
我们回到写自己程序的地方,在之前你跳转到的位置(我是005e9335)在那里进行编辑写入一下内容
push 0
push 114514(这个数只是先随便一写,在这占的位之后要替换)
push 114514(同上)
push 0
写完后是这样的:
接下来就是调用window api
在最后的push 0后面写上这一句CALL DWORD PTR DS:[005EA7A4]其中中括号中的就是你刚刚找到的地址
ok,写完这步,我现在可以告诉你这些代码的作用了,首先是两个push ,在api中,常常会出现push 0传参操作,其实就是一个在传参数的过程
然后call就是调用我们的窗口函数
而中间两个占位就是将我们之后内容的地址转递给这个函数,紧接着,我们把内容加入代码段中,这个代码段可以不与你之前的代码放在一起,可以放在后面,这里我将放在内存地址005E9365的地方上
在你要输入文本的地方 右键-二进制-编辑
注意这里的编辑内容多少是由你选中内存地址数量决定的这里我将写入 Infernoid 和 Make the Infernoid great again,所以我对应一个字母一2地址,来储存文字
之后把我们的两个push输出值改成这两个地址
第一个的位置我写在005E935B 第二个位置在005E9376上,写完后这样
我们的程序已经写完了,现在该让程序回到正轨上了,那我们在我们写的函数后加上原先我们删除的部分,如果原先没有跳转,我们可以自己写跳转到程序的下一个执行的点。(注:汇编这里无需在地址前写 geek. 了这个geek是一个程序的label)
完成这些,我们就完成了?
一斤鸭梨!
我们还需要把写好的程序保存一下,右键-copy to executable-all
然后我们选copy all
出现这样一个(基佬紫)窗口
右键-save file即可
如果对自己的操作无信心,也可以从入口点进行点f8一步步调试
保存后打开,可以看到没有先打开geek,而是先打开了我们的程序
关闭后才打开geek,并且不影响geek的正常使用
ok所有的内容就这么多,自己尝试一下吧