手动修改PE文件:添加自定义代码

来源:互联网 发布:淘宝补差价怎么弄 编辑:程序博客网 时间:2024/05/22 08:28

在PE文件里有很多位置可以添加自己的代码(其实就是感染PE),凡是用不到的地方都能加。想到的位置有(在文件中不是在内存中):Dos头和Nt头之间、每个节末尾的Padding(间隙)、新增节分配在文件末尾的空间;其它覆盖数据的方法不安全容易引起错误还是算了。添加后还要在程序中设置跳转以执行自己的代码,有用跳转和改入口点的方法。总之方法很多,下面举个例子:


1. 准备


在这里我要加的代码功能为:弹出一个对话框,关掉对话框后就运行一个计算器。这个需要涉及到的问题是,弹出对话框和运行程序的函数未导入,对话框显示的字符串和运行计算器的路径放的位置。对于不设置导入表和不设置数据段的方法,看了一下我测试用的程序,PE头是够写这些的。不过现在要说到写Shellcode就有点跑题了,以后再说,在这里先记一下,虽然在这里用那个会比较简单(前面的内容都可以跳过了),不过相对简单的东西另有自己的一个复杂度,还是换一篇来说比较好。现在用的是设置导入表并把数据放到数据段的方法,这个方法需要设置重定位,有可能需要新建重定位表。那么现在先开始写代码。
测试程序的情况是这样:




2. 设置导入表和数据


编之前需要确定要调用的函数在哪和要使用的字符串在哪,不然没办法编。所以先添加函数导入。导入表是一个IMAGE_IMPORT_DESCRIPTOR数组,数组包括两个Thunk数组的rva,数组后直接跟了会用到的一些字符串,所以想在导入表中添加一项新的导入,只能在相应的数组后添加,但是这个结构存储的十分紧凑,所以需要重建。
重建导入表有三种思路:在原先位置重建、在新节重建、在空的位置重建。在原先位置重建难度很大,不过可以让程序显得好像没有被改过一样;在新节重建就比较简单,不过多了一个节,文档大小也可能会增加(如果找程序中空的位置重建的话就不会增加,不过就相当于第三种方法了);在空的位置重建就是找节后的Padding,在那里添加就行了,这样就不会出现新的节。
后两种方法都会修改到数据目录的导入表RVA,改动的东西比较明显;第一种方法不用改RVA,但是如果添加了过多导入函数的话,原先的节可能放不下,第二种就可以随便放。折衷来看在现在的情况下还是第三种比较方便一些(= =其实直接用Shellcode的方法哪有那么麻烦,如果已经准备好了代码就直接跳到后面就行了,我前面说的是不用那种的方法)。
新建节的话需要确定节有可写属性,载入的时候Thunk会被修改。新建节主要就是重建IMAGE_IMPORT_DESCRIPTOR数组就行了,复制原先的数组然后在末尾加上自己的导入IMAGE_IMPORT_DESCRIPTOR结构,两个Thunk和名字什么的在自己的节中找个位置再设置好Rva就行。
需要导入的两个函数为User32.MessageBoxA、Kernel32.WinExec,所以我这样设置:

这是修改后载入看到的样子:

然后修改导入表rva为新的位置就行了。
需要记住两个地址,0x00006c8 - MessageBoxA、0x000006e8 - WinExec。
建立数据:

记下地址0x00000800 - 0x00000820
载入OD可以看到已经修改成功(程序的代码也截进来了):



3. 写代码


为了避免重复写内容,直接写在PE头里吧。写的代码需要保存原先的现场,不然影响了其它东西程序会出错。另外PE头会比其它地方多出一个限制,就是我们从0x02开始写,所以0x3A要跳过。代码需要放在一个可运行的节,一般方法是直接放代码段或者找空隙设置属性或者新建节。我新建个节吧。

然后我偷懒用OD来写一下代码吧,注意跳过0x3A就行。里面的地址后面要转一下。

代码比较短,没过3A,白操心。如果是动态取函数的地址的可能会超过。可以看到里面的重定位位置错了,我之前写完了一次,发现参数忘记压了一个,后面改的,所以重定位还是原来的位置,根据这个原来的位置有人可以看出我原先少压了哪个参数吗?= =
需要记下地址0x00405002、0x00405006、0x0040500B、0x00405013、0x0040501A、0x00405020。把二进制复制出来,修改相应地址的值,我这里基址没有被重定位,所以里面的地址就不用改了,如果被重定位了就改成程序基址对应的值。改完写回程序,我不用OD写回,直接改二进制文件:



4. 重建/添加重定位表


需要重定位5个地址,因为是在新节,直接加重定位表就行了,如果在旧节,就要重建,因为数组加元素后面的要往后移。5个地址因为对齐关系新加的重定位结构要占20字节,所以这样:

改一下重定位表大小:

在CFF看到的样子:



5. 修改跳转


要么改入口点,要么在程序中跳转。在程序中转我觉得会跟后面说的东西重复,直接改入口点好了。

改完载入OD看看:

可以看到重定位位置正确,其它也正确,没什么可说的了。放到其它任何一个节里都是可以的,设置好属性就行了。
运行,关掉那个弹出框就运行计算器,不多截图了:

0 0
原创粉丝点击