PE操作—扩大节

------------恢复内容开始------------

1. 为什么只能扩大最后一个?

  节与节之间有相互依存的关系,a 节中的代码可能会使用 b 节、c 节的数据或者说 a 节中代码会跳转到 b 节、c 节。如果把其中某个节

 扩大了了,偏移就会改变。

  注解:详情参考 Intel 指令编码。

 

2. 扩大节方法

  1. 仿照 windows 加载器载入 PE 文件

    内存分配大小:SizeOfImage + 内存对齐(追加数据的字节数)

 

  2. 修改最后一个节的 Section Header

    修改 Section Header 的 Misc.VirtualSize 成员以及 SizeOfRawData 成员。

     

    Misc.VirtualSize 要分为两种情况考虑

      Misc.VirtualSize = 0 ;则不需要修改

      Misc.VirtualSize != 0 ;则 Misc.VirtualSize = 最后一个节的内存大小(对齐后)+ 追加数据的字节数

      注解:win10 pe 加载器会使用 Misc.VirtualSize (不为 0)

 

        SizeOfRawData = SizeOfRawData + 文件对齐(追加数据的字节数)

 

  3. 修改 Optional Header 的 SizeOfImage 成员

    SizeOfImage = SizeOfImage + 内存对齐(追加数据的字节数)

 

3. 伪代码

  

void* expand_section(const void* image, unsigned long expand_size)
{
    if (!is_pe_file(image))
        return nullptr;

    //----------------------------> 对齐
    auto expand_size_section_alignment = section_alignment(image, expand_size);

    //----------------------------> 拷贝原 pe 数据
    auto old_sizeof_image = get_sizeof_image(image);
    auto new_sizeof_image = old_sizeof_image + expand_size_section_alignment;
    std::unique_ptr<byte[]> new_image(CNew byte[new_sizeof_image]());
    if (!new_image) 
             return nullptr;
    memcpy_s(new_image.get(), new_sizeof_image, image, old_sizeof_image);

    //----------------------------> 修改 section header
    auto last_section = get_last_section(new_image.get());
    if (last_section->Misc.VirtualSize != 0)
    {
        last_section->Misc.VirtualSize = section_alignment(image, last_section->Misc.VirtualSize);
        last_section->Misc.VirtualSize += expand_size;
    }

    // 修改 SizeOfRawData
    last_section->SizeOfRawData += file_alignment(new_image.get(), expand_size);

    // 修改 SizeOfImage
    set_sizeof_image(new_image.get(), new_sizeof_image);

    //---------------------------->return std::move(new_image);
}        

 

 

 

 

 

 

 

 

 

------------恢复内容结束------------

上一篇:u-boot移植步骤


下一篇:busybox编译 fatal error: curses.h: 没有那个文件或目录