zoukankan      html  css  js  c++  java
  • PE知识复习之PE扩大节

     

                  PE知识复习之PE扩大节

    一丶为什么扩大节

      上面我们讲了,空白区添加我们的代码.但是有的时候.我们的空白区不够了怎么办.所以需要进行扩大节.

      扩大节其实很简单.修改节数据对齐后的大小即可. 并且在PE文件中添加0数据进行填充即可.

    首先看一下我们的节表

    typedef struct _IMAGE_SECTION_HEADER {
        BYTE    Name[IMAGE_SIZEOF_SHORT_NAME]; //8个字节名字.自己可以起.编译器也可以给定.不重要.
        union {
                DWORD   PhysicalAddress;       
                DWORD   VirtualSize;           //节数据没有对齐后的大小.也就是没有对齐.节数据有多大.
        } Misc;
        DWORD   VirtualAddress;          //加载到内存中的第一个字节的地址.也就是虚拟地址.节在内存中哪里开始.内存中的VA + ImageBase 才是真正的节开始位置
        DWORD   SizeOfRawData;           //修改这个属性的值,即可扩大节.并且在PE文件中添加相应的0数据进行填充.
        DWORD   PointerToRawData;          //在文件中的偏移.是文件对齐成员倍数.
        DWORD   PointerToRelocations;           //一下都是调试相关.
        DWORD   PointerToLinenumbers;           //
        WORD    NumberOfRelocations;
        WORD    NumberOfLinenumbers;
        DWORD   Characteristics;          //节的属性
    } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

    二丶扩大节实战以及注意问题

      PE扩大节的时候一般是最后一个节.原因是自己不用修正偏移等各项属性了.如果是最后一个节扩大就很简单了.

    我们节表要修改的属性就是将节对齐后的数据进行修改即可.

    公式: 设一块我们添加的控件为x的倍数

    设要修改后的值为M

    那么 M = (节.sizeofRawData 或者 节.VirtualSize 按照对齐后大小对齐) + X即可.

    看公式很复杂,其实就是节的对齐后的数据.按照内存对齐后修改.并且加上我们新空间的大小即可.

    例如原来大小:  0x600, 你要扩大0x100个字节. 那么 修改后的值就为 0x700. 0x700要按照内存对齐进行存放.

    还要修改扩展头中的 SizeofImage(内存PE镜像大小)

    三丶扩大节实战

      1.添加数据

      随便找一个PE文件.在最后文件偏移处添加数据. 比如我们要扩大0x1000.那么添加0x1000大小.

    开始位置89f0 添加0x1000大小. 那么结束位置是 0x99F0

    为了确认我们的节数据会映射到内存.我们0数据我们填充为FFFF

     2.修改节表属性

       因为我们添加了0x1000个字节大小.所以需要修改文件中节表的对齐后的大小. 也就是 节.sizeofRawToData

    此时我们没有修改之前.

    ,没有修改之前数据大小是0x0600.那么内存中节映射也不会有我们的FFFF数据. 观看内存节起始位置为0x01c000 那么我们去内存中

    节数据位置看看.是否有我们的FFF填充的数据

    并没有我们的FF数据. 我们修改文件节对齐数据为 0x1600.因为加了0x1000的数据.

    再次在内存中查看已经有我们映射的内存了. 第一个是F0结尾.下方是我们的数据.

    但是注意,修改之后并不能直接查看.因为PE没法运行.我们必须修改扩展头中的sizeofImage属性.这样我们的内存镜像大小才是真正的大小.

    我是修改过了.节才会映射到内存中.所以可以查看.

     3.修改SizeofImage属性

    我的SzieofImage属性.原值就是按照内存对齐进行存放的.也就是0x01D000. 所以当我增加0x1000个字节的数据.其实并没有超过SizeofImage的对其值.所以可以映射到内存那种.如果加了数据超过了SizeofImage

    那么我们就需要进行内存对齐了. 加上我们扩展后的数据.然后进行内存对齐.

    4.程序运行.

    程序可以正常运行.并且我们添加的数据也映射到内存中了.

  • 相关阅读:
    我的第一篇博客
    1.2 位于Shell脚本第一行的#!
    1.1 一个简单的脚本
    JDK与CGlib动态代理的实现
    解决Sublime Text3中文显示乱码问题
    多线程讲解
    (转)Spring中@Async用法总结
    (转)spring boot注解 --@EnableAsync 异步调用
    Spring Boot中的注解
    (转)如何用Maven创建web项目(具体步骤)
  • 原文地址:https://www.cnblogs.com/iBinary/p/9735276.html
Copyright © 2011-2022 走看看