【文章标题】:为程序添加启动消息框
【文章作者】: 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》