第一步使用Restorarot打开程序
根据需要添加一个按钮,设置该按钮的消息ID,注意不要和其他控件的ID一样,添加完后保存。
此时这个程序上已经多出了一个按钮,点击它也会发送消息,但是程序不会对该消息做任何处理,因为我么还没有把对应的功能添加进去。
第二步制作一个可以实现功能的DLL。
我使用的是vs2019,编程语言为c语言。打开vs2019,创建新项目,选择桌面向导,点击创建,应用程序类型选择动态链接库,选择空项目,点击确定。
我们需要创建两个文件,一个.cpp文件,一个.h文件。.cpp文件里面就写你要实现功能的函数,就像平常写程序时写的函数一样,只是没有main()函数,但是注意要把.h文件包含进来。.h文件里面写的是函数的导出声明,书写方式如下图所示:
extern “C”是指以C语言的方式导出。后面的函数就是要导出的.cpp文件的里的函数,该函数如下图所示:
这里我把函数折叠起来了,.cpp文件里函数的书写方式和平常函数的书写方式没有任何区别。
两个文件都写好后直接点击运行,但是会出现报错提示:
不过并不用管,DLL文件已经生成了。找到项目的路径,在Debug文件夹里能看到DLL文件和LIB文件:
将DLL文件复制出来,放到和与要添加功能得程序同一个目录下。
现在DLL文件已经做好,第三步就是将DLL文件添加到程序中。用LordPE的PE编辑器打开程序,点击目录:
点击输入表那一行三个点的按钮:
在上面的框框右键,点击add import:
添加dll以及函数:
查看你添加进去的dll:
记住这个ThunkRVA的值,这个是新增的导入表的FirstThunk的偏移地址。
现在dll已经添加进去了,但是还没有调用的语句。这个时候要使用od来编辑程序。用od打开程序。我们要找到程序处理按钮消息的地方,所以下一个窗口消息断点。用OD打开程序后运行程序。
点击这个w。
如果没出现东西就右键刷新一下。
选择202 WM_LBUTTONUP,点击确定。
然后在程序上点击一下按钮,此时程序会中断在某个地方:
但是这个地方是系统函数,我们要让程序中断在程序自己处理消息的地方。键盘alt+ m,在代码段设置一个内存访问断点:
再点击运行程序,此时程序才真正中断在了处理消息的地方:
最后我们再添加调用代码。
首先要找到一个合适的地方,修改代码使得程序跳转到我们调用函数的地方,函数调用完后再跳回去,期间要注意维持堆栈平衡。
可以很容易辨认出消息判断的地方:
像这种一个比较然后接一个跳转就类似于c语言里的if else。我的方法是在这个地方进行修改,把那行进行比较的代码直接改成一个无条件跳转,跳转到我们要实现功能的地方,在那里进行消息的判断。
首先找到一块空闲的地方,然后修改指令:
在空闲地址处实现消息判断和函数调用:
因为修改指令那个地方的消息判断被我们直接改成跳转了,所以这里我们得自己进行消息判断,如果消息符合就跳回去执行原来的函数,不符合就继续判断是不是我们增加的那个按钮的消息,如果是就往下执行,不是就跳回原来那个模块,消息判断不符合之后要跳转的地方,之后用pushad保存寄存器环境,然后函数参数入栈,调用函数。函数地址就是之前ThunkRVA的值加上程序基址,要注意加上段寄存器。因为我这个函数没有自己维持堆栈平衡,所以调用完后我又出了一次栈,然后用popad恢复寄存器环境,最后跳回原来的地方。
修改完右键,复制到可执行文件就大功告成了。
运行程序,程序可以稳定运行,且点击按钮可以实现功能。