Visual Studio - 在64位项目

时间:2017-03-13 11:09:12

标签: c windows visual-studio assembly x86

直截了当地问我:如何使用32位ASM编译器编译ASM文件,将其包含在我的64位项目中并使用ASM文件的函数名访问编译后的代码?

如果有点不清楚,我可以详细说明:

我正在将我的一个项目从32位转换为64位,我遇到了技术问题。我的项目编译一个ASM文件,并使用编译后的二进制文件作为其用法的输入。

当我的项目是32位时,它很容易。我在项目中包含了ASM文件并添加了一个构建规则以使用Microsoft Macro Assembler编译它们 - 然后我可以通过将我想要从ASM访问的每个函数导出到{{}}来访问我的32位项目中的编译代码{1}}头文件并使用函数名访问它(我能够这样做,因为它被编译为obj并且链接器知道符号,因为我将原型导出到.h文件)。

现在,我需要将此代码转换为64位,但我仍然需要将ASM编译为32位代码,并且仍然能够执行相同的操作(从我的64位访问已编译的32位代码)比特计划)。 但是,当我尝试编译它时,它显然无法识别指令,因为现在整个项目被编译为64位代码。

提前致谢。

1 个答案:

答案 0 :(得分:2)

如果我试图在64位程序中嵌入32位代码(这是一个可疑的事情,但让我们说为了论证你有充分的理由并且实际上知道你在做什么结果) - 我将采用32位代码,无论是用C语言编写,汇编还是其他东西 - 并将其编译为单独的项目,生成DLL作为输出。这在编译链中没有任何额外的怪异:它只是一个普通的32位DLL。

然后可以将32位DLL作为二进制资源嵌入到64位应用程序中 - 只需要一个可以加载和访问的内存块。

那么你怎么能对该DLL中的编译代码做任何事情呢?我会使用一个有点被黑客攻击的Joachim Bauch的MemoryModule库来访问它。 MemoryModule旨在从大量内存中加载DLL并提供对其导出的访问 - 它就像Windows API的LoadLibrary()一样,仅来自内存而不是文件。它被设计为与调用进程相同的位大小,但有一点hackery,你可以使它编译为64位库,但能够读取32位库。由此产生的用法非常简单:

// Load the embedded DLL first from the current module.
hresource = FindResource(hmodule, "MyLibrary.DLL", "binary");
hglobal = LoadResource(hmodule, hresource);
data = LockResource(hglobal);
size = SizeofResource(hmodule, hresource);

// Turn the raw buffer into a "library".
libraryHandle = MemoryLoadLibrary(data, size);

// Get a pointer to some export within it.
myFunction = MemoryGetProcAddress(libraryHandle, "myFunction");

也就是说,正如我之前提到的(以及其他人也提到过),即使你可以获得指向导出的指针,你也无法调用它们,因为代码是32位甚至可能不是加载在4GB标记以下的地址。但是如果你真的想在64位应用程序中嵌入32位代码,我就是这样做的。