问题描述
我想根据文件对齐或节对齐正确扩展 PE 文件中的 .text 节。
详情:
让我们从头开始。 我有 .net v4.8 项目,其中有几个小类,如
public class A1
{
public int IntProperty {get;set;}
}
public class A2
{
public string StringProperty {get;set;}
}
这些类是什么并不重要。 使用 MSBuild v16 编译后,我有一个 PE 文件。 (exe 或 dll 也无关紧要)。 然后我用文件或节对齐扩展 .text 节(我都试过)。 因此,如果编译后的 PE 文件具有 512、1024 或 2048 对齐方式 - 效果很好。 但是当它有 4096 或 8192 字节时 - 它不起作用。 这是代码示例,我是怎么做的:
BYTE* dos_header_ptr = reinterpret_cast<BYTE*>(dosHeader2);
IMAGE_NT_HEADERS64* nt_header2 = reinterpret_cast<TNT_HEADERS*>(dos_header_ptr + dosHeader2->e_lfanew);
const IMAGE_FILE_HEADER* file_header = &nt_header2->FileHeader;
IMAGE_OPTIONAL_HEADER64* optional_headers2 = &nt_header2->OptionalHeader;
DWORD file_alignment = optional_headers2->FileAlignment;
file_alignment = optional_headers2->SectionAlignment;
std::vector<IMAGE_SECTION_HEADER*> sections = ExtractSections(nt_header2);
IMAGE_SECTION_HEADER* section_header_text2 = sections[0];
IMAGE_SECTION_HEADER* section_header_rsrc2 = sections[1];
file_info* old_file_info = file_info2;
file_info2 = RelocateBufferWithdisplacement(old_file_info,file_alignment,section_header_text2);
// Update pointers and VA
dosHeader2 = reinterpret_cast<IMAGE_DOS_HEADER*>(file_info2->buffer);
dos_header_ptr = reinterpret_cast<BYTE*>(dosHeader2);
nt_header2 = reinterpret_cast<IMAGE_NT_HEADERS64*>(dos_header_ptr + dosHeader2->e_lfanew);
file_header = &nt_header2->FileHeader;
sections.clear();
sections = ExtractSections<IMAGE_NT_HEADERS64>(nt_header2);
section_header_text2 = sections[0];
section_header_rsrc2 = sections[1];
section_header_text2->SizeOfRawData += file_alignment;
section_header_text2->Misc.VirtualSize = section_header_text2->SizeOfRawData;
for(int i=1; i<sections.size(); i++)
sections[i]->PointerToRawData += file_alignment;
optional_headers2 = &nt_header2->OptionalHeader;
optional_headers2->SizeOfCode += file_alignment;
delete old_file_info;
FlushToFile(input_params.file_name_output,file_info2);
RelocateBufferWithdisplacement 函数
file_info* RelocateBufferWithdisplacement(file_info* file_info2,DWORD file_alignment,IMAGE_SECTION_HEADER* text_section_header)
{
// copY BUFFERS
DWORD new_file_size = file_info2->file_size + file_alignment;
byte* new_buffer = new byte[new_file_size];
DWORD first_part_of_file_size = text_section_header->PointerToRawData + text_section_header->SizeOfRawData;
byte* end_first_part_old = file_info2->buffer + first_part_of_file_size;
byte* start_free_zone_of_file_ptr_new = new_buffer + first_part_of_file_size;
byte* second_part_of_file_ptr_new = start_free_zone_of_file_ptr_new + file_alignment;
std::copy(file_info2->buffer,end_first_part_old,new_buffer);
std::fill(start_free_zone_of_file_ptr_new,second_part_of_file_ptr_new,0);
std::copy(end_first_part_old,file_info2->buffer + file_info2->file_size,second_part_of_file_ptr_new);
return new file_info(new_file_size,new_buffer);
}
ExtractSections 方法
std::vector<IMAGE_SECTION_HEADER*>& ExtractSections(IMAGE_NT_HEADERS64* nt_headers)
{
std::vector<IMAGE_SECTION_HEADER*>* result = new std::vector<IMAGE_SECTION_HEADER*>();
for(int i=0; i < nt_headers->FileHeader.NumberOfSections; i++)
result->push_back(reinterpret_cast<IMAGE_SECTION_HEADER*>(reinterpret_cast<BYTE*>(nt_headers) + sizeof(TNT_HEADERS) + i * sizeof(IMAGE_SECTION_HEADER)));
return *result;
}
这对 x32/x64 文件的工作方式相同,但现在只考虑简化 x64 版本。 我还注意到: 如果我使用更大的项目(例如最多 30000 行代码),即使是 2048 文件对齐我也做不到。仅适用于 512 和 1024。但如果项目几乎明确 - 只有 8192 失败。 我希望也应该更新一些东西,但我不知道究竟是什么。
只是代码的高级愿景:
那么,我做错了什么?
谢谢。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)