Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual Studio - Compiling 32-bit code inside 64-bit project

So straight to my question: how can I compile my ASM files with a 32-bit ASM compiler, include it in my 64-bit project and access the compiled code by using the ASM file's function names?

If it is a bit unclear, I can elaborate:

I'm converting a project of mine from 32-bit to 64-bit and I ran into a technical problem. My project compiles an ASM file and use the compiled binary as input for it's usage.

When my project was 32-bit, it was quite easy. I included the ASM files in the project and added a build rule to compile them with Microsoft Macro Assembler - then I could access the compiled code from my 32-bit project by exported each function I wanted to access from the ASM to a .h header file and access it using the function name (I was able to do so because it was compiled to obj and the linker knew the symbols because I exported the prototypes to a .h file).

Now, I need to convert this code to 64-bit, but I still need the ASM to be compiled as 32-bit code and still be able to do the same thing (accessing the compiled 32-bit code from my 64-bit program). However, when I try to compile it, it obviously doesn't recognize the instructions because now the whole project is being compiled as 64-bit code.

Thanks in advance.

like image 265
Aviv Avatar asked Mar 13 '17 11:03

Aviv


1 Answers

If I were trying to embed 32-bit code inside a 64-bit program (which is a dubious thing to do, but let's say for the sake of argument that you have a good reason and actually know what you're doing with the result) — I'd take the 32-bit code, whether written in C, assembly, or something else — and compile it as a separate project, producing a DLL as output. This involves no extra weirdness in the compile chain: It's just an ordinary 32-bit DLL.

That 32-bit DLL can then be embedded in your 64-bit application as a binary resource — just a blob of memory that you can load and access.

So then how can you actually do anything with the compiled code in that DLL? I'd use a somewhat-hacked version of Joachim Bauch's MemoryModule library to access it. MemoryModule is designed to load DLLs from a hunk of memory and provide access to their exports — it's just like the Windows API's LoadLibrary(), only from memory instead of from a file. It's designed to do it for the same bit size as the calling process, but with a bit of hackery, you could probably make it compile as a 64-bit library, but able to read a 32-bit library. The resulting usages would be pretty simple:

// 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");

That said, as I alluded to before (and others also alluded to), even if you can get pointers to the exports, you won't be able to invoke them, because the code's 32-bit and might not even be loaded at an address that exists below the 4GB mark. But if you really want to embed 32-bit code in a 64-bit application, that's how I'd go about it.

like image 64
Sean Werkema Avatar answered Oct 03 '22 02:10

Sean Werkema