PE文件格式应用实例__为PE文件添加启动时对话框

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/WUDAIJUN/article/details/8684822
      本实例通过为修改目标PE文件内容来实现在该PE文件启动时,弹出一个对话框。对话框内容和标题由用户指定。
     
     点击生成,在QQ.exe目录下有QQ_Box.exe。双击运行,弹出消息框:
     
     点击确定,即开始运行QQ。

     主要涉及到文件映射,虚拟地址空间,PE文件格式等知识;
     
     为了让PE文件实现这一功能,我们在PE文件入口代码之前插入一块用于弹出消息框的代码,在弹出消息框后,再跳转至原入口代码。并将插入代码与其需要的数据(消息框标题和内容,MessageBox的IDD等)放入一个新的区块中。因此总的来说流程如下:

     用户点击OK-->验证用户输入-->加载并映射目标PE文件-->生成新区块数据-->生成新区块头部-->创建一个新的文件映像-->拷贝原PE映像中的全部内容-->在新的文件映像中添加新区块首部和数据-->修改必要字段(目录表地址,代码入口,区块数目,映像大小)


一。生成新区块数据:
     由于我们要添加一个输入表(USER32.dll,用于使用MessageBox),因此我们将原IDD和新IDD(USER32.dll)放在了新区块中,这样在添加数据时不会发生覆写。新区块主要包含:
     IDD,DllName,FunName,BoxTitle, BoxContent,NewEntryCode这六个部分
     IDD为原IDD后添加一个新的USER32.dll组成的新输入表
     DllName为 "USER32.dll"
     FunName为"MessageBoxA"
     BoxTitle和BoxContent由用户自定义
     NewEntryCode为插入的新入口代码,代码以jmp OldAddressOfEntry 结束
     

二。新增数据的存放:
     目标PE文件主要增设了三个数据:新区块首部,新区块原始数据,为使用MessageBox而准备的IDD
     前面已经说了,将IDD放在新区块原始数据中,而新区块头直接放在原区块表之后(区块表之后的区块原始数据的起始地址需要对齐的缘故,一般对齐单位为一个扇区512字节,具体由OptionalHeader的FileAlignment指出。这样在之后放40个字节的新区块首部是不易冲突的),新区块原始数据放在PE文件最后(原始数据的虚拟地址可由SizeOfImage指定,文件偏移可以通过计算得到文件大小来指定)。
  
三。地址空间的转换:
     这里涉及到了三个地址空间:磁盘文件,目标PE文件地址空间,当前进程地址空间。需要比较小心的进行数据读取和写入,很容易出现内存非法读写。通过将磁盘文件映射到本进程进行修改,此时磁盘上的PE文件和映射到进程的PE文件是一样的,只是多了一个映射基址。在通过文件偏移地址修改PE文件数据时,可通过映射基址+PointerToRawData(文件偏移)来实现修改。在通过虚拟地址修改PE文件数据时,可通过ImageRvaToVa来实现将PE文件地址空间中的地址转换为本进程地址空间中的对应地址。ImageRvaToVa是微软提供的,它通过PE文件偏移为中转来实现转换,也可自己实现,对地址空间会有更深理解。


     之后就是实现了,由本人参照《Windows编程循序渐进》中的实例代码:为PE文件基本数据和操作建一个类CPEInfo,实现简单封装,并可以将新区块头直接交予它维护。CPEInfo主要实现文件映射,维护区块首部,保存PE文件基本数据的功能
     在主对话框类中,通过GenSecData来生成新区块数据,通过一个CPEInfo成员来获取PE文件基本信息,按照前面所述的流程进行修改即可。

代码 下载地址:http://download.csdn.net/detail/wudaijun/5151933
          

猜你喜欢

转载自blog.csdn.net/WUDAIJUN/article/details/8684822