2

我正在尝试编写一个打包器/自解压 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

我该怎么做才能更改此订单?

4

2 回答 2

2

MSVC 对段的唯一控制是创建自定义段和合并现有段的能力,以及控制每个段的访问标志,除此之外的任何事情都变得毫无意义,因为没有设置排序规则,因此编译器可以自由选择最简单/最简单的选项。

对于您想要做的事情,只需遍历PE中的段描述符,找到最大的基地址,然后使用它加上段大小作为附加地址,它会更加可靠。

于 2012-10-04T09:20:22.787 回答
0

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

相反,打包程序会在文件末尾创建一个新的 .java 部分。

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

值得注意的是,当 Windows 加载节标头时,它们会立即放置在可选标头中的数据目录之后,这与在磁盘上偏移到文件对齐方式不同。

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

于 2012-10-04T14:46:59.077 回答