背景

之前说过直接向类HelloWorld.exe的可执行文件添加一个MessageBox弹窗, 但有时候, 需要添加的内容太多了, 因为数据与代码一起插入, 以至于可执行文件本身没有足够的空闲空间存放这些内容时, 就需要添加一个Section.
 

确认节区头后面还有空间

用工具查看一下最后一个节区头后面是否还有多余的空间, 一般情况都会有的. 但若没有的话, 就要移动节区头后面的文件内容, 这个比较复杂, 在这里不说.
一般会结合PE View 和 WinHex 这两个工具, 如之前的HelloWorld.exe
先用PE View 查看最后一个节区头的起始地址: 00000218   可以推算出最后一个节区头的结束地址: 0000023F 
框选的部分就是最后一个节区头的内容
 
可以看到红框中的部分, 有足够的空间去添加一个节区头信息. 因为这个需要确保添加一个节区头后, 后面还有一个节区头的空间, 并且其值全为0
 

覆写一个节区头信息

接下来就是添加一个节区头信息, 我的做法是复制一下可执行文件原有的最后一个节区头的内容, 再覆写到其后面.  在WinHex中框选内容后, 右键 -> Edit 
Cope Block  -> Normally  ( 框选后直接Ctrl + C 也行 )
 
 
覆写操作: 点选要覆写的起始地址, 在这里是 00000240  一样先是 右键 -> Edit , 再就是 Clipboard Data Write ( 也可以直接ctrl + b )
 
但这里千万不要点了Paste (Ctrl + V ) , 因为那个是向文件里插入之前复制的内容, 这样的话, 后面的内容就会向后偏移了, 最后导致文件头信息中的文件偏移参数不对了.
 
 
到这里, 先保存一下!
 

修改Number Of Sections的值

完成上面的工作, 用PE View查看的时候, 还是不会看到新添的这个节区头的信息的.
所以需要去修改一下Number Of Sections 的值, 其实就是对其值加1
 
还是要用PE View查到Number Of Sections 的文件偏移 ( 000000D6 )
 
再用WinHex去到 000000D6 看一下(至于为什么不是 0003 而是0300的问题, 去看基础知道 )
 
把其中的3直接加1 改为4就好.  保存 
 
这个时候再用PE View查看, 就会发现多了一个节区头信息了
 
重复的.data节区头, 我习惯改一下新节区头的名称
这时, 会发现节区也多了一个, 但点开节区, 会发现, .dx节区和.data节区其实是同样的, 看文件偏移就知道
 
 
这个是因为.dx节区头的内容是从.data节区头复制过来的, 所以其中的文件偏移都是一样的. 这个后面再说
 

获取 File Alignment 和 Section Alignment的值

用PE View, 点开 PE可选头信息: 
 
 
 
Section Alignment 的值为    00001000

File Alignment 的值为    00001000

上面的值都是十六进制的, 先记下来, 后面会用到的
 

在文件中为.dx节区头添加节区

这个时候是需要用到File Alignment的值了, 因为节区在文件中的空间大小必须是FileAlignment的整数倍, 为了方便, 在这里就弄一个FileAlignment的文件空间. 
因为在用WinHex添加节区的时候, 是以整数个字节添加的, 换算一下: 00001000(十六进制)  =  4096(十进制)
具体操作是把WinHex拉到最低部, 在文件最后的一个字节上 右键 -> Edit -> Paste Zero Bytes 
 
按提示走, 会看到下面这样的输入框, 输入需要插入的字节数据量, 记得是十进制的, 
这里是一个FileAlignment的大小, 也就是4096. 点 ok .
 
蓝色的字就是新添加的, 因为还没保存, 所以WinHex标记为蓝色的, 要记下蓝色的开头地址,这里是  0000A000, 因为这个值就是新节区.dx的文件偏移, 下一步是需要设置到.dx节区头信息中Pointer to Raw Data上的.
 
记得保存.
 

设置新节区头的Size of Raw Data和Pointer to Raw Data

还是先用PE View看一下这两个属性的文件偏移量:
偏移量分别为:  00000250 和 00000254. 再用WinHex找到这两个地址:
 
把Size of Raw Data的值改为 00001000, 其实就是把其实的3改为1就可以了.
Pointer to Raw Data的值改为0000A000, 前面一步已经记下来的. 其实就是把7改为A
 
再保存. 并用PE View查看一下: 
这样就和前面看到的不一样了, 也证明修改成功了!
 

设置新节区的RVA

首先要查看两个参数, 分别是前一个节区头的 Virtual Size 和 RVA 的值:
Virtual Size : 00003E08
           RVA :  00007000
这两个值相加一下, 得 0000AE08  , 那么新节区的RVA都是需要大于这个值的, 为了方便操作, 一般都取整, 设置为:0000B000 
再查看一下新节区头的RVA在文件中的偏移量: 
找到文件中的0000024C, 修改上面的值为 0000B000, 再保存:
 

设置新节区的Virtual Size

Virtual Size 指定的是对应节区加载到内存后, 所占用的内存空间大小, 但它的值是Section Alignment的整数倍. 在这例程里, Section Alignment是00001000,  而且也应该不需要更多的内存空间了, 所以直接设置Virtaul Size为00001000就好:
先用PE View 找位置, 熟悉了后应该就不用了:
Virtual Size的文件偏移量是 00000248
 
找到并直接修改保存. 就好了!
 
 

修改Size of Image的值

这个参数是在IMAGE_OPTIONAL_HEADER中的, 它的作用是指定所有节区加载内存后, 一共需要多少内存空间大小. 修改起来问题不大, 就是找到指定的地址, 00000120
 
并在原有的值上加新节区头中的Virtual Size(00001000), 也就是把B改为C, 再保存
 
到这里, 把程序运行起来, 不报错, 基本上都证明是操作正确了!! 
 

修改新节区的属性(权限)

上面的操作是成功添加了一个节区, 还没上, 我们是需要向里面插入可执行代码和数据的. 但节区头信息里有一个参数会限定这个节区所能做的事, 下面看看这个参数: 
其中 IMAGE_SCN_CNT_INITIALIZED_DATA 说的是这个节区包含了初始化数据
剩下的 IMAGE_SCN_MEM_READ 和 IMAGE_SCN_MEM_WRITE 就是说程序可以对这个节区进行读与写操作.
但这样的话, 如果是插入了代码, 没有执行权限是不行的哦!
 
如果不知道怎么设置, 其实我们可以参考一下.text节区头中的 Characteristics :
 
  其实 IMAGE_SCN_CNT_CODE 说的是这个节区包含了可执行代码, 然后 IMAGE_SCN_MEM_EXECUTE 给了这个节区执行的权限. 
只要在新节区头中Characteristics 的值按位与运算就行了, (其实直接加20000020就行了, 但这个说法不够严谨)
 
新节区 Characteristics 的文件地址为 00000264 
再保存: 
 
 
具体怎么插入代码, 那是另外的工作, 在这里不说. 

http://www.cnblogs.com/dilex/p/5065007.html

向PE文件中添加一个Section的更多相关文章

  1. 对类HelloWorld程序中添加一个MessageBox弹窗

    对类HelloWorld程序中添加一个MessageBox弹窗 分析: 任一程序运行的时候都会加载kernel32.dll的,但MessageBoxA()这个API却是在user32.dll中的.所以 ...

  2. 008.Adding a model to an ASP.NET Core MVC app --【在 asp.net core mvc 中添加一个model (模型)】

    Adding a model to an ASP.NET Core MVC app在 asp.net core mvc 中添加一个model (模型)2017-3-30 8 分钟阅读时长 本文内容1. ...

  3. 如何在maven项目的pom.xml文件中添加jar包

    在使用maven进行项目开发时,我们需要在pom.xml文件中添加自己所需要的jar包.这就要求我们获取jar包的groupId和artifactId. 我们可以在一些maven仓库上搜索我们所需要的 ...

  4. 006.Adding a controller to a ASP.NET Core MVC app with Visual Studio -- 【在asp.net core mvc 中添加一个控制器】

    Adding a controller to a ASP.NET Core MVC app with Visual Studio 在asp.net core mvc 中添加一个控制器 2017-2-2 ...

  5. linux向文件中添加数据,数据被追加到了上一行的行尾

    当我们在windows上新建了文件,并且要上传到linux上时,一定要在文件后加上空格,否则就会出现标题上讲的,数据被追加到了上一行的行尾,而不是新起一行,但是如果是在linux上新建的文件,则没有这 ...

  6. PE文件中的输入表

    前言 PE文件中的输入表含有三个重要结构IID,IDT,IAT.PE文件为需要加载的DLL文件创建一个IID结构,一个DLL与一个IID对应.IDT是输入名称表,IAT输入地址表,在没有绑定输入的情况 ...

  7. [保姆级教程] 如何在 Linux Kernel (V5.17.7) 中添加一个系统调用(System call)

    最近在学习 <linux Kernel Development>,本书用的linux kernel 是v2.6 版本的.看完"系统调用"一节后,想尝试添加一个系统调用, ...

  8. Step by step 活动目录中添加一个子域

    原创地址:http://www.cnblogs.com/jfzhu/p/4006545.html 转载请注明出处 前面介绍过如何创建一个域,下面再介绍一下如何在该父域中添加一个子域. 活动目录中的森林 ...

  9. 如何在RCP程序中添加一个banner栏

    前言:这段时间还算比较空闲,我准备把过去做过的有些形形色色,甚至有些奇怪的研究总结一下,也许刚好有人用的着也不一定,不枉为之抓耳挠腮的时光和浪费的电力.以前有个客户提出要在RCP程序中添加一个bann ...

随机推荐

  1. Git Push 不用再次输入用户名和密码方法

    前言 在大家使用github的过程中,一定会碰到这样一种情况,就是每次要push 和pull时总是要输入github的账号和密码,这样不仅浪费了大量的时间且降低了工作效率.在此背景下,本文在网上找了两 ...

  2. windows 消息机制的学习

    概述 链接1:http://www.cppblog.com/suiaiguo/archive/2009/07/18/90412.html 链接2:http://www.cnblogs.com/find ...

  3. 搭建完整邮件系统(postfix+dovecot+clamAV+Spamassassin+amavisd-new)

    ============================ 相关软件: 1. 发送邮件 --- postfix 2. 身份认证 --- sasl2 3. 接收邮件 --- dovecot 4. 防病毒邮 ...

  4. ASP.NET MVC3调用分部视图-PartialView的几种方式(集)

    我们的网页通常会有好几个部分组成,一些公共的区域我们通常会做成PartialView(部分视图),但这些视图并不是完全固定的,所以还是需要 特定的Controller来控制.如果只是静态的html,虽 ...

  5. [Redux] Composition with Objects

    For example, current we have those todos: { todos: [ { completed: true, id: 0, text: "Learn Red ...

  6. NYOJ-745蚂蚁的难题(二)

    这道题和求字段和的要求就差一点,就是那个是一条链, 这个是个环,关于这么环,刚开始按照链那种方式推倒状态转移方程,但是没有写出来,后来看题解,才看到原来还是转化为普通的单链来做,好多题都是由不会的转化 ...

  7. #include<iostream.h>与#include<iostream> using namespace std的区别

    所谓namespace,是指标识符的各种可见范围.C++标准程序库中的所有标识符都被定义于一个名为std的namespace中.  一 :<iostream>和<iostream.h ...

  8. 在Blade中结合gperftools检查内存泄露

    Blade是我们开发的大规模C++项目构建工具. gperftools是google开发的性能工具,由高效内存分配器,CPU性能分析器,堆分析器,堆检查器等工具组成. 和其他构建工具不同,结合gtes ...

  9. hdu 2544

    #include <iostream> #include <cstdio> #define INF 9999999 //#define INF 0x3f3f3f3 using ...

  10. Linux命令行文本处理工具

    关键字搜索: grep  关键字  指定文件 -i   搜索时忽略大小写 -n  显示结果所在行 -v  显示不包含关键字的行 基于列的文本处理: cut -d: -f1 /etc/passwd -d ...