基于MinGW GCC为PE文件添加自定义段的技术求助
在TDM-GCC-64(Windows 10)中为PE文件添加自定义段及.idata相关源码说明
一、添加.inStore自定义段(.idata之后)
针对你之前尝试失败的问题,给出两种可行方案:
方案1:GCC属性+PE格式链接脚本
代码中定义自定义段数据
在C代码中用__attribute__指定段,并确保数据被引用(避免链接器优化丢弃):// 定义100字节的自定义段数据,aligned(4)符合PE段对齐要求 unsigned char inStore_data[100] __attribute__((section(".inStore"), aligned(4))) = {0}; // 强制引用,防止被优化 void keep_inStore() { (void)inStore_data; }编写PE链接脚本
PE链接器的脚本格式与ELF不同,需保证.idata段的原有结构完整,再追加.inStore段,示例custom.link:SECTIONS { // 保留.idata的原有段顺序,确保导入表正常工作 .idata BLOCK(4K) : { *(.idata$2) *(.idata$3) *(.idata$4) *(.idata$5) *(.idata$6) *(.idata$7) *(.idata$8) *(.idata$9) *(.idata$a) *(.idata$b) } // 在.idata之后添加.inStore段,对齐方式与PE一致 .inStore BLOCK(4K) : ALIGN(4) { *(.inStore) } }编译链接
指定链接脚本编译:gcc -o target.exe your_code.c -Wl,-T,custom.link
方案2:objcopy+强制保留段
编译目标文件
gcc -c your_code.c -o your_code.o用objcopy添加自定义段
准备一个100字节的二进制文件inStore.bin(可通过dd if=/dev/zero bs=1 count=100 of=inStore.bin生成),然后添加段:objcopy --add-section .inStore=inStore.bin your_code.o modified.o链接时强制保留段
通过--undefined参数让链接器认为段内符号被引用,避免丢弃:gcc -o target.exe modified.o -Wl,--undefined=_inStore_data
之前尝试失败的原因
- 尝试1:PE链接器默认会丢弃未被引用的段,需通过强制引用或链接脚本指定保留
- 尝试2:使用了ELF格式的链接脚本,PE链接器无法识别,必须用PE专属的脚本格式
二、.idata段生成源码及libstdc++-6.dll名称修改
.idata段的生成源码位置
.idata段由binutils的PE链接器和GCC的Windows平台配置共同生成:
- binutils部分:
binutils/ld/emultempl/pe.em,其中pe_create_import_sections函数负责创建.idata的各个子段,处理DLL导入的符号、名称及导入表结构。 - GCC部分:
gcc/config/i386/mingw32.h或gcc/config/i386/cygwin.h,通过LIBSTDCXX_DLL_NAME宏定义libstdc++-6.dll的名称,编译时该宏会被用来生成导入表中的DLL名称字符串。
修改DLL名称预留空间的步骤
修改GCC配置:找到上述头文件中的
LIBSTDCXX_DLL_NAME宏,修改为带预留空字节的名称,例如:#define LIBSTDCXX_DLL_NAME "libstdc++-6.dll\0\0\0\0"额外的空字节会在导入表中预留空间,避免后续修改名称时触发重定位。
修改binutils链接器逻辑:在
pe.em的导入表生成代码中,调整DLL名称的写入逻辑,确保预留足够的空间(比如固定字符串长度为32字节,不足部分用空字节填充)。重新编译GCC和binutils:基于修改后的源码重新编译TDM-GCC工具链,替换原有工具即可生效。
内容的提问来源于stack exchange,提问作者qknight
相关产品推荐
相关产品推荐

