zoukankan      html  css  js  c++  java
  • 向PE文件中添加一个Section

    背景

    之前说过直接向类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 


    再保存: 



    具体怎么插入代码, 那是另外的工作, 在这里不说. 







  • 相关阅读:
    封装成帧、帧定界、帧同步、透明传输(字符计数法、字符串的首尾填充法、零比特填充的首尾标志法、违规编码法)
    计算机网络之数据链路层的基本概念和功能概述
    物理层设备(中继器、集线器)
    计算机网络之传输介质(双绞线、同轴电缆、光纤、无线电缆、微波、激光、红外线)
    计算机网络之编码与调制
    0953. Verifying an Alien Dictionary (E)
    1704. Determine if String Halves Are Alike (E)
    1551. Minimum Operations to Make Array Equal (M)
    0775. Global and Local Inversions (M)
    0622. Design Circular Queue (M)
  • 原文地址:https://www.cnblogs.com/dilex/p/5065007.html
Copyright © 2011-2022 走看看