如何在Visual C ++中控制PE段顺序

时间:2012-10-04 09:05:32

标签: visual-c++ linker segment self-extracting packer

我正在尝试编写一个打包器/自解压exe类型的程序,但是我遇到了由Visual C ++的链接器创建的段顺序的问题。

基本上我有一个存根程序(加载器),它有一个像这样定义的特殊变量:

#pragma const_seg(".blah")
const char blah[1];
#pragma const_seg()

它与blah中的数据有关(例如解包数据)。

第二个程序(打包程序)然后使用加载程序作为模板,用blah创建包含一些数据的新程序。

基本上,打包程序会复制加载程序文件,然后使用一些新数据替换旧的.blah部分。执行新文件时,加载程序将对此新数据进行操作。

现在修改exe文件很棘手,所以为了简单起见,我希望.blah成为文件中的最后一段,以便我可以简单地将数据附加到加载器,然后修复几个大小的字段在PE标题中。

但是我无法弄清楚如何控制Visual C ++链接器中的段的顺序,以便在编译加载器时将.blah放在文件的末尾。

目前的部门顺序是:

.textbss
.text
.rdata
.data
.idata
.blah
.rsrc
.reloc

正如您所看到的.rsrc.reloc位置错误,我需要.blah之前。

如何更改此订单?

2 个答案:

答案 0 :(得分:2)

MSVC为细分提供的唯一控件是能够创建自定义的和merge现有的,以及每个细分control the access flags,除此之外的任何内容都变得毫无意义,因为没有设置规则排序,因此编译器可以自由选择最简单/最简单的选项。

对于你想要做的事情,而不是只是遍历PE中的段描述符,找到最大的基地址,并使用它加上段大小作为你的追加地址,它会更加可靠

答案 1 :(得分:0)

我最终解决这个问题的方法是在链接时不将.java部分添加到加载器。

而不是打包器在文件末尾创建一个新的.java部分。

当加载程序运行时,它获取它的基地址(来自GetModuleHandle)然后解析DOS,NT,最后解析部分标题以获取.java部分的相对虚拟地址。

值得注意的是,当Windows加载节标题时,它们会紧跟在可选标题中的数据目录之后,而不像磁盘那样偏移到文件对齐。

通过将基地址添加到相对地址来找到该部分的最终地址。