背景

之前说过直接向类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. [置顶] Firefox OS 学习——Gaia 编译分析

    Gaia作为用户的接口,也是用户可见部分,一些用户的应用也是安装在这一层,所以研究他是很有必要的,对于像我这样的初学者,最直接的学习方法就是通过修改代码,然后可以看到UI的变化,很直观的观察修改结果. ...

  2. ajax提交数据问题

    加入traditional:true属性 traditional 类型:Boolean 如果你想要用传统的方式来序列化数据,那么就设置为 true.请参考工具分类下面的 jQuery.param 方法 ...

  3. 提交表单时的等待(loading)效果

    $(document).ready(function () { $("body").prepend('<div id="overlay" class=&q ...

  4. [原创小知识] 如何优雅的判断 ie 版本

    之前一直不怎么做低版本ie的前端,毕竟ie的大半江山都被chrome 霸占,但大部分情况下,却还是要去兼容下那些老顽固.一切的原因,都是因为当年微软的年轻气盛,喜欢另起炉灶,真是很无语. 通常我们去h ...

  5. mongodb的write concern

    mongodb有一个write concern的设置,作用是保障write operation的可靠性.一般是在client driver里设置的,和db.getLastError()方法关系很大 一 ...

  6. session过期后自动跳转到登陆页

    项目需要做一个自动登出的功能,查询了网上的资料,一开始准备用session监听做,按照下面方式配置监听器 1.在项目的web.xml文件中添加如下代码: <!--添加Session监听器--&g ...

  7. 利用PCA来简化数据

    13.2.2 在NUmpy中实现PCA 将数据转换成前N个主成分的伪代码大致如下: 去除平均值 计算协方差矩阵 计算协方差矩阵的特征值和特征向量 将特征值从大到小排列 保留最上面的N个特征向量 将数据 ...

  8. nginx 2.基本配置

    死磕nginx 2.基本配置 鉴于深入浅出的原理,我们先从一个简单的配置了解nginx的配置 1.一个典型配置 nginx的配置文件默认在nginx安装目录的conf二级目录下面,主配置文件为 ngi ...

  9. Svg操作

    SVG文件的JavaScript操作 获取SVG DOM 如果使用img标签插入SVG文件,则无法获取SVG DOM.使用object.iframe.embed标签,可以获取SVG DOM. var ...

  10. yii2 添加模块过程

    本文以Yii2基本应用程序模板为例,介绍下向该框架下加入新模块的过程: 1. 新建模块相关目录与文件 step 1: 新建目录结构   首先在根目录下新建modules目录,然后在该目录下面添加模块目 ...