背景
之前说过直接向类HelloWorld.exe的可执行文件添加一个MessageBox弹窗, 但有时候, 需要添加的内容太多了, 因为数据与代码一起插入, 以至于可执行文件本身没有足够的空闲空间存放这些内容时, 就需要添加一个Section.
确认节区头后面还有空间
用工具查看一下最后一个节区头后面是否还有多余的空间, 一般情况都会有的. 但若没有的话, 就要移动节区头后面的文件内容, 这个比较复杂, 在这里不说.
一般会结合PE View 和 WinHex 这两个工具, 如之前的HelloWorld.exe
![](https://i-blog.csdnimg.cn/blog_migrate/c95ca8b85b5cba7af5fd701c9679b8d4.png)
先用PE View 查看最后一个节区头的起始地址: 00000218 可以推算出最后一个节区头的结束地址: 0000023F
![](https://i-blog.csdnimg.cn/blog_migrate/84725da40f5975ba147bd7321e29414f.png)
框选的部分就是最后一个节区头的内容
可以看到红框中的部分, 有足够的空间去添加一个节区头信息. 因为这个需要确保添加一个节区头后, 后面还有一个节区头的空间, 并且其值全为0
覆写一个节区头信息
接下来就是添加一个节区头信息, 我的做法是复制一下可执行文件原有的最后一个节区头的内容, 再覆写到其后面. 在WinHex中框选内容后, 右键 -> Edit
![](https://i-blog.csdnimg.cn/blog_migrate/b5e634dcbdffc852b5df12593b4002d1.png)
Cope Block -> Normally ( 框选后直接Ctrl + C 也行 )
![](https://i-blog.csdnimg.cn/blog_migrate/29762c02f5d78324247db34fcf950de3.png)
覆写操作: 点选要覆写的起始地址, 在这里是 00000240 一样先是 右键 -> Edit , 再就是 Clipboard Data Write ( 也可以直接ctrl + b )
![](https://i-blog.csdnimg.cn/blog_migrate/7d46754036b493649faecedb2149342c.png)
但这里千万不要点了Paste (Ctrl + V ) , 因为那个是向文件里插入之前复制的内容, 这样的话, 后面的内容就会向后偏移了, 最后导致文件头信息中的文件偏移参数不对了.
![](https://i-blog.csdnimg.cn/blog_migrate/d4e82c3cb0e5e60da9fa060b79a9b18a.png)
到这里, 先保存一下!
修改Number Of Sections的值
完成上面的工作, 用PE View查看的时候, 还是不会看到新添的这个节区头的信息的.
![](https://i-blog.csdnimg.cn/blog_migrate/dcccda8a453bc1cbc0e99e406dd0a67e.png)
所以需要去修改一下Number Of Sections 的值, 其实就是对其值加1
还是要用PE View查到Number Of Sections 的文件偏移 ( 000000D6 )
![](https://i-blog.csdnimg.cn/blog_migrate/1bf888ef71afa9d8a6f14be6caaab742.png)
再用WinHex去到 000000D6 看一下(至于为什么不是 0003 而是0300的问题, 去看基础知道 )
![](https://i-blog.csdnimg.cn/blog_migrate/9c64104e0010984ba3b512f2fcde5200.png)
把其中的3直接加1 改为4就好. 保存
![](https://i-blog.csdnimg.cn/blog_migrate/ae1593f2b4d7bc84ed94895d901af213.png)
这个时候再用PE View查看, 就会发现多了一个节区头信息了
![](https://i-blog.csdnimg.cn/blog_migrate/12bb189be2ba8cb45d1d7f097ffdb477.png)
重复的.data节区头, 我习惯改一下新节区头的名称
![](https://i-blog.csdnimg.cn/blog_migrate/c742a76c7165af18b25e9c1777b1203d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a0efffb80e4d1ca23aaa2d49f85bccdf.png)
这时, 会发现节区也多了一个, 但点开节区, 会发现, .dx节区和.data节区其实是同样的, 看文件偏移就知道
![](https://i-blog.csdnimg.cn/blog_migrate/e12825c6a744bba2c6732bb3919a7a36.png)
![](https://i-blog.csdnimg.cn/blog_migrate/71454031bae1d528a6d64709bfa748aa.png)
这个是因为.dx节区头的内容是从.data节区头复制过来的, 所以其中的文件偏移都是一样的. 这个后面再说
获取 File Alignment 和 Section Alignment的值
用PE View, 点开 PE可选头信息:
![](https://i-blog.csdnimg.cn/blog_migrate/3e7161b892e9944721b087ad052e3d9d.png)
Section Alignment 的值为 00001000
File Alignment 的值为 00001000
上面的值都是十六进制的, 先记下来, 后面会用到的
在文件中为.dx节区头添加节区
这个时候是需要用到File Alignment的值了, 因为节区在文件中的空间大小必须是FileAlignment的整数倍, 为了方便, 在这里就弄一个FileAlignment的文件空间.
因为在用WinHex添加节区的时候, 是以整数个字节添加的, 换算一下: 00001000(十六进制) = 4096(十进制)
具体操作是把WinHex拉到最低部, 在文件最后的一个字节上 右键 -> Edit -> Paste Zero Bytes
![](https://i-blog.csdnimg.cn/blog_migrate/b36eaf518250dcd45bf47563fe86d78d.png)
按提示走, 会看到下面这样的输入框, 输入需要插入的字节数据量, 记得是十进制的,
![](https://i-blog.csdnimg.cn/blog_migrate/220b59ef382befd2c3e56097acb50ebf.png)
这里是一个FileAlignment的大小, 也就是4096. 点 ok .
![](https://i-blog.csdnimg.cn/blog_migrate/1d4575f56d5b8d03d3a7f31adf510d70.png)
蓝色的字就是新添加的, 因为还没保存, 所以WinHex标记为蓝色的, 要记下蓝色的开头地址,这里是 0000A000, 因为这个值就是新节区.dx的文件偏移, 下一步是需要设置到.dx节区头信息中Pointer to Raw Data上的.
记得保存.
设置新节区头的Size of Raw Data和Pointer to Raw Data
还是先用PE View看一下这两个属性的文件偏移量:
![](https://i-blog.csdnimg.cn/blog_migrate/23e7fc4d5efe7752349b2f630a3673e2.png)
偏移量分别为: 00000250 和 00000254. 再用WinHex找到这两个地址:
![](https://i-blog.csdnimg.cn/blog_migrate/bea5e2c76989daabcc7a77be18ed4f19.png)
把Size of Raw Data的值改为 00001000, 其实就是把其实的3改为1就可以了.
Pointer to Raw Data的值改为0000A000, 前面一步已经记下来的. 其实就是把7改为A
![](https://i-blog.csdnimg.cn/blog_migrate/6a759a86dafbdaf53f251feb473059ee.png)
再保存. 并用PE View查看一下:
![](https://i-blog.csdnimg.cn/blog_migrate/0f8d49036f8083ede7eaa95bd6ce798f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1720a8d78e7b5ae19168d245cdc27197.png)
这样就和前面看到的不一样了, 也证明修改成功了!
设置新节区的RVA
首先要查看两个参数, 分别是前一个节区头的 Virtual Size 和 RVA 的值:
![](https://i-blog.csdnimg.cn/blog_migrate/9a774e4fdad10afba62e9737ec904dec.png)
Virtual Size : 00003E08
RVA : 00007000
这两个值相加一下, 得 0000AE08 , 那么新节区的RVA都是需要大于这个值的, 为了方便操作, 一般都取整, 设置为:0000B000
再查看一下新节区头的RVA在文件中的偏移量:
![](https://i-blog.csdnimg.cn/blog_migrate/34f653c8da3bc2427c59fc38b4005403.png)
找到文件中的0000024C, 修改上面的值为 0000B000, 再保存:
![](https://i-blog.csdnimg.cn/blog_migrate/43de3f18da46218ca8f39e9d78540b55.png)
![](https://i-blog.csdnimg.cn/blog_migrate/08ab1f92471607dce313985acbe71e0d.png)
设置新节区的Virtual Size
Virtual Size 指定的是对应节区加载到内存后, 所占用的内存空间大小, 但它的值是Section Alignment的整数倍. 在这例程里, Section Alignment是00001000, 而且也应该不需要更多的内存空间了, 所以直接设置Virtaul Size为00001000就好:
先用PE View 找位置, 熟悉了后应该就不用了:
![](https://i-blog.csdnimg.cn/blog_migrate/a3150b84bac38405036450477946349b.png)
Virtual Size的文件偏移量是 00000248
![](https://i-blog.csdnimg.cn/blog_migrate/ceb5430d0e918519d20ddc69b17b4845.png)
找到并直接修改保存. 就好了!
![](https://i-blog.csdnimg.cn/blog_migrate/8cb2fe142ddf3dfb9fbf516f70ca43f6.png)
修改Size of Image的值
这个参数是在IMAGE_OPTIONAL_HEADER中的, 它的作用是指定所有节区加载内存后, 一共需要多少内存空间大小. 修改起来问题不大, 就是找到指定的地址, 00000120
![](https://i-blog.csdnimg.cn/blog_migrate/0bd6718f9d17b3c8d5d4b857dacfde5f.png)
并在原有的值上加新节区头中的Virtual Size(00001000), 也就是把B改为C, 再保存
![](https://i-blog.csdnimg.cn/blog_migrate/dfd42a4e9ad4a8311952cafbc4fbf2cc.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f2fbbc859048931ba9159e5d483e759c.png)
到这里, 把程序运行起来, 不报错, 基本上都证明是操作正确了!!
修改新节区的属性(权限)
上面的操作是成功添加了一个节区, 还没上, 我们是需要向里面插入可执行代码和数据的. 但节区头信息里有一个参数会限定这个节区所能做的事, 下面看看这个参数:
![](https://i-blog.csdnimg.cn/blog_migrate/2af6cc0eb36a92631e69f16c2f706e86.png)
其中 IMAGE_SCN_CNT_INITIALIZED_DATA 说的是这个节区包含了初始化数据
剩下的
IMAGE_SCN_MEM_READ 和
IMAGE_SCN_MEM_WRITE 就是说程序可以对这个节区进行读与写操作.
但这样的话, 如果是插入了代码, 没有执行权限是不行的哦!
如果不知道怎么设置, 其实我们可以参考一下.text节区头中的
Characteristics :
![](https://i-blog.csdnimg.cn/blog_migrate/8bfa2b0669aa6a60057fca6672e9e578.png)
其实
IMAGE_SCN_CNT_CODE 说的是这个节区包含了可执行代码, 然后
IMAGE_SCN_MEM_EXECUTE 给了这个节区执行的权限.
只要在新节区头中
Characteristics 的值按位与运算就行了, (其实直接加20000020就行了, 但这个说法不够严谨)
新节区
Characteristics 的文件地址为 00000264
![](https://i-blog.csdnimg.cn/blog_migrate/3111e05a3d13e2247224c23371d43f64.png)
![](https://i-blog.csdnimg.cn/blog_migrate/eea8318c4210883f850aefe8752bf2b0.png)
再保存:
![](https://i-blog.csdnimg.cn/blog_migrate/96495c75ef9411129353e60dc4b2051e.png)
具体怎么插入代码, 那是另外的工作, 在这里不说.
复制来自http://www.cnblogs.com/findumars/p/5788894.html