【文章标题】:为程序添加启动消息框
【文章作者】: laomms
【软件名称】: Project1
【下载地址】: 看附件
【使用工具】: peditor、UltraEdit、ollydbg
【操作平台】: winxp sp2
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
类似的文章已经很多,跟以前有点区别的是没有为程序添加新的区段,而是利用区段间的空隙写入代码。对进一步了解PE结构有所帮助。
既然是为程序添加消息框,我们就得先了解消息函数MessageBox的各个参数。查一下WIN32API的帮助文件:
MessageBox(
HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType
);
第一个参数是对话框所有者的句柄,可以为NULL
第二个参数是要显示的字符串
第三个参数是对话框的标题
第四个参数是对话框的风格
我们随便找个带MessageBox函数 的PE文件,反汇编后找一下MessageBox,将会发现它的格式基本上是这样:
00404136 |. 6A 00 PUSH 0 ; /Style = 对话框的风格
00404138 |. 68 74704500 PUSH 00457074 ; |Title = 对话框的标题
0040413D |. 68 54704500 PUSH 00457054 ; |Text =对话框的内容
00404142 |. 6A 00 PUSH 0 ; |hOwner = 句柄
00404144 |. E8 4FD1FFFF CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA
这些就是我们要注入的内容。但是我们首要解决的问题是找放这些代码的空间。我们可以用LOADPE为程序增加一个新的区段,然后写入代码。这里介绍的方法是利用区段的空隙插入代码,你如果熟悉PE文件格式的话,应该知道一般代码都放在.TEXT段中,数据放在.DATA中。我们先用PEDITOR看看原程序的各区段分配情况:
节 虚拟大小 虚拟偏移 原始大小 原始偏移 特征值
.TEXT 00053818 00001000 00053A00 00000400 60000020
.DATA 00001AC4 00056000 00001C00 00054600 C0000040
可以看出,.TEXT区段起始地址是400,大小为53818,也就是说如果要写代码的话必须在400+53818= 53C18开始。再看看整个区段的大小为400+53A00=53E00。由此我们可以推算出.TEXT的可用空间为53A00-53818=1E8。
消息框的标题是文本数据,我们要放在.DATA段,也看一下该段的情况。代码开始地址:54600+1AC4=560C4,可用空间1C00-1AC4=13C。
空间都足够,也就是说也不必创建新的区段。
首先我们来添加MESSAGEBOX的标题内容。用UltraEdit打开Project1,找到000560C4
000560c0h: 9C 0C 41 00 B6 D4 BB B0 BF F2 00 D5 E2 CA C7 D7 ; ?A.对话框.这是?
000560d0h: A2 C8 EB B5 C4 C6 F4 B6 AF B6 D4 BB B0 BF F2 00 ; ⑷氲钠舳曰翱?
从下面的偏移位置提示信息中我们可以看出,对话框标题在偏移地址000560C4处,转为虚拟地址为00457AC4,对话框内容在偏移地址000560CB处,转为虚拟地址为00457ACB。
下面我们先看看原来程序调用MessageBoxA的地方,OD载入原程序,右击-搜索当前模块中名称,找到MessageBoxA函数,查找导入参考,双击:
00401234 - FF25 F4C64500 JMP DWORD PTR DS:[<&user32.MessageBoxA>] ; USER32.MessageBoxA
所以我们要呼叫MessageBoxA函数时,只要CALL 00401234即可。
下面我们开始添加代码。在这之前我们先看一下原程序的入口,用PEDITOR可以知道入口在004556D8。好,我们在CODE段的偏移地址00053C18处,即虚拟地址00454818处。OD载入已添加文本数据的程序,CTRL+G,输入00454818,修改代码:
00454818 6A 00 PUSH 0 //风格
0045481A 68 C47A4500 PUSH Project2.00457AC4 //消息框标题
0045481F 68 CB7A4500 PUSH Project2.00457ACB //消息框内容
00454824 6A 00 PUSH 0 //句柄
00454826 E8 09CAFAFF CALL <JMP.&user32.MessageBoxA> // CALL 00401234
0045482B - E9 A80E0000 JMP Project2.<ModuleEntryPoint> //跳回到原入口
修改后保存为新的可执行文件。这时,效果还没有出来,因为我们还得做最后一步,就是将新的可执行文件的入口改为调用MessageBoxA的地方,用PEDITOR载入新的可执行文件,将原来的入口点000556D8改为00054818,点“应用更改”保存。这时运行新的可执行文件,对话框出来了。
参考:
netsowell 《Hook And Inject 系列教程》
Sunshine 《Code Injection:Inserting a MessageBox》