The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: Ehtyar on October 19, 2006, 11:06:16 PM

Title: Linking C With ASM
Post by: Ehtyar on October 19, 2006, 11:06:16 PM
Hi all.
I recently came across an excellent piece of code here (http://www.joachim-bauch.de/tutorials/load_dll_memory.html/en) that allows you to load a dll from resources, and uses custom functions to emulate LoadLibrary, GetProcAddress, and FreeLibrary using a memory pointer instead of a zero-terminated string. Unfortunately, as many of us are probably aware, a lot of good code is in C :(
I spent the majority of yesterday afternoon attempting to link the object file i compiled in MinGW with the object file from MASM using mslink, polink and the linker that comes with MinGW. Unfortunately, Polink took issue with my declaration of STDCALL functions in the C object file, and the MinGW linker took issue with the MASM object file's lib inclusions. I came closest to accomplishing the link using mslink, but it seems that in order for MinGW to compile on multiple platforms, it injects custom startup code from one of it's librarys into the object file. The library file from MinGW which exports the custom functions is not compatible with mslink.
My question is whether or not anyone can give me any ideas on how best to link the c object file to the MASM one using a free C compiler and a linker of some kind. The ONLY problem i'm having is this injected code from MinGW, so if anyone has a solution to that problem, it would aos be greatly appreciated.

Thanks, Ehtyar.

P.S. Please forgive any mistakes, was in kind of a hurry :(
Title: Re: Linking C With ASM
Post by: hutch-- on October 19, 2006, 11:15:19 PM
The object module compatibility is the main factor, if the mingw object format does not work with MASM's COFF format, perhaps you could use the source in a Microsoft C compiler building COFF output and that will link fine. As usual you will have to write a MASM prototype for the C module making sure you get the calling convention correct but it should be simple enough to do.
Title: Re: Linking C With ASM
Post by: Ehtyar on October 20, 2006, 04:54:52 AM
I have completed he prototypes, only needed three functions, but it's the compiler i wonder about. Do you have any suggestions on which microsoft compiler? I *CAN* use visual studio if i have absolutely no other choice, but any other solution would be greatly appreciated.
I did check the file created by masm and by MinGW, and the first few bytes were a match, and i noticed a similar structure when looking at a hex dump....so i just assumed they were both coff. My bad i guess.

Thanks, Ehtyar
Title: Re: Linking C With ASM
Post by: Vortex on October 20, 2006, 05:32:24 AM
Ehtyar,

Have a look at this thread :

Loading and running EXEs and DLLs from memory

http://www.masm32.com/board/index.php?topic=3150.0
Title: Re: Linking C With ASM
Post by: Ehtyar on October 20, 2006, 08:48:33 AM
My god microsoft sure know how to turn compiling an object file into a fiasco..i know why i use MinGW. Anyway, thank you for that link Vortex, i'm rather annoyed with myself for not having found that link earlier. I will give it a go and report back, maybe with a demo of what i'm making ;)
Title: Re: Linking C With ASM
Post by: Vortex on October 20, 2006, 09:28:28 AM
Ehtyar,

Please feel free to post here all your questions regarding linking C with asm. Paul and me , we created a set of examples of mixed C & asm, have a look at the GeneSys project. Would you like that I send here a new example of C&asm?
Title: Re: Linking C With ASM
Post by: Ehtyar on October 20, 2006, 12:54:44 PM
Well i'll try to cut a long story short.
I tried your library Vortex, but couldnt get it to not crash when i tried to load the dll from a pointer returned by LockResource. So, i had a look at GeneSys like you suggested, and noticed you had used PellesC, so i gave it a shot myself.
It compiled the MemoryModule code perfectly (i had to substitute stricmp with lstrcmpi, but what ya gonna do). I have compiled it into a static library, and included it in my test project. Unfortunately, despite almost 4 hours now of working on it, i cannot get it to not-crash when loading the dll.
In the attachment, i have included the library (MemoryModule.lib) with its PellesC project files (in MemoryModule dir), an asm test project (the one that isnt working) (MemoryModuleTest.asm), and a C test (MemoryModule\MemoryModuleTest.c) that does exactly the same thing as the asm version, but it works. If anyone can provide any insight into this problem, i'd be very appreciative.

Thanks, Ehtyar.

P.S. Thanks for the help so far guys, think i'd have lost my mind by now otherwise :U

[attachment deleted by admin]
Title: Re: Linking C With ASM
Post by: Vortex on October 20, 2006, 01:22:40 PM
Quotebut couldnt get it to not crash when i tried to load the dll from a pointer returned by LockResource.

Ehtyar,

My library doesn't accept normal resources, it cannot handle them:

http://www.masm32.com/board/index.php?topic=3150.msg24252#msg24252

The solution is to use binary resource template for dialog boxes etc. To embed a DLL in your executable, you need to convert it to an object file with Hutch's file data assembler fda.exe My example project explains how to do this. Back home, I will check your attachment.

Title: Re: Linking C With ASM
Post by: Ehtyar on October 20, 2006, 08:38:21 PM
Oh i'm sorry Vortex, i thought it meant you couldnt load resources from the loaded DLL. Right now though, i really want to know why the c version isnt working, so i;m looking foreward to your feedback, but ill try using your method again the right way in the meantime :)
Title: Re: Linking C With ASM
Post by: Ehtyar on October 21, 2006, 03:02:28 AM
It seems PellesC is missing a protoype for the return value used for the MemoryGetProcAddress function: FARPROC (line 40 in MemoryModule.h). I searched a little for it, but i am in a rush to get to work, but if anyone has any quick solutions, i'd appreciate it :)

Thanks, Ehtyar.
Title: Re: Linking C With ASM
Post by: Ehtyar on October 21, 2006, 12:43:17 PM
OK, apparently this is not the case either. If i typedef FARPROC above the prototypes, i get a redinfintion error..So that leaves me officially without any more ideas...
Any help would be really appreciated guys.

Thanks, Ehtyar.
Title: Re: Linking C With ASM
Post by: drizz on October 21, 2006, 02:28:26 PM
Hello Ehtyar,

I'm sorry i didnt have time sooner to reply, i'd save you some time....

basically everything is fine but your asm code.

When statically linkiing C library you MUST NOT override its startup code
by placing entrypoint directly (label "code:" in your case, "END code")
you MUST write either "main proc c argc,argv"  procedure  for console
or "WinMain proc stdcall hInst,hInstPrev,szCmdLine,iCmdShow" for GUI.

from your MemoryModuleTest.zip file, replace MemoryModuleTest.asm
with my modifications:
.386
.MODEL FLAT,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
includelib MemoryModule.lib
include \masm32\macros\macros.asm
MemoryFreeLibrary PROTO :DWORD
MemoryGetProcAddress PROTO :DWORD, :DWORD
MemoryLoadLibrary PROTO :DWORD
.data?
hInstance dd ?
.code
WinMain proc stdcall hInst,hInstPrev,szCmdLine,iCmdShow
local hLib
push hInst
pop hInstance
invoke FindResource, NULL, 1000, chr$("RT_RCDATA", 0)
cmp eax, 0
je damn
invoke LoadResource, NULL, eax
cmp eax, 0
je damn
invoke LockResource, eax
cmp eax, 0
je damn
push eax
invoke MemoryLoadLibrary, eax
mov hLib,eax
cmp eax, 0
je damn
invoke MemoryGetProcAddress, eax, chr$("TestPublic", 0)
cmp eax, 0
jz damn
call eax
invoke MemoryFreeLibrary, hLib
jmp get_out
damn:
invoke MessageBox, NULL, chr$("damn", 0), NULL, MB_OK
get_out:
ret
WinMain endp

END
Title: Re: Linking C With ASM
Post by: Ehtyar on October 21, 2006, 11:42:05 PM
Thank you for the help drizz, and it probably works perfectly, if not for this s**t.
crt.lib(_setenvp.obj) : error LNK2001: unresolved external symbol __imp__GetEnvironmentStrings@0
To explain this line, crt.lib is the PellesC static lib for linking to the crt. It is placed inside the working dir for the test app so that mslink can find it when MemoryModule.lib wants it. Basically, this is the error i get when i try to assemble your code drizz. It never popped up earlier, but what i really can't understand is how that is the only api it is missing when the test app is linked to kernel32 anyway.....
Please someone tell me this is not normal, because i'm really starting to build up a major aversion to hlls at the moment....

Once again, any help is much appreciated, Ehtyar.

[edit]
Playing with the settings in PellesC, and adding a pragma or two has taken me to now having _WinMainCRTStartup unresolved...guess that's not much of an advancement.
[/edit]
Title: Re: Linking C With ASM
Post by: drizz on October 22, 2006, 02:15:24 AM
i dont know what  is wrong, it compiles perfectly here...

Microsoft (R) Windows (R) Resource Compiler Version 5.2.3668.0
Copyright (C) Microsoft Corporation.  All rights reserved.
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000.  All rights reserved.
Microsoft (R) Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation.  All rights reserved.


DLL_PROCESS_ATTACH
Called exported function TestPublic.
DLL_PROCESS_DETACH


i dont use MASM32 includes... i've looked at them and i see that GetEnvironmentStrings is defined as
GetEnvironmentStrings equ <GetEnvironmentStringsA>

but kernel32 exports 3 functions:
GetEnvironmentStrings
GetEnvironmentStringsA
GetEnvironmentStringsW

so i assume that that is the cause of error

try this:
comment this line in your kernel32.inc
;GetEnvironmentStrings equ <GetEnvironmentStringsA>
and write this:
GetEnvironmentStrings PROTO


hope that does it...
Title: Re: Linking C With ASM
Post by: Ehtyar on October 22, 2006, 02:38:57 AM
You won't believe this. All i had to do was specify WinMain as the entry point...and lookie lookie, i get 3 pretty little messageboxes saying "DLL_PROCESS_ATTACH", "Called exported function TestPublic." and "DLL_PROCESS_DETACH". I'm going to leave my comments at that, in case my language gets too colorful, lol, having spent 3 days working on something that took about 10 characters of typing to fix.

Thank you very much for your help gentlemen, i will post my working copy in probably about an hour or so, after i've cleaned up this mess i've made here, and incorporate this code into my existing project.

Thanks again guys, Ehtyar.
Title: Re: Linking C With ASM
Post by: Relvinian on October 22, 2006, 08:26:31 AM
Here is part of the description from a Platform SDK help on GetEnvironmentStrings:


prototype:  LPVOID GetEnvironmentStrings(void);

Remarks
The GetEnvironmentStrings function returns a pointer to a block of memory
that contains the environment variables of the calling process. Treat this memory
as read-only; do not modify it directly.


This shouldn't have any 'A' or 'W' for ANSI or UNICODE. So if the MASM32 Kernel32.lib has A or W defined, then it is indeed incorrect and needs to be fixed.

Relvinian
Title: Re: Linking C With ASM
Post by: drizz on October 22, 2006, 10:10:54 AM
Quote from: Ehtyar on October 22, 2006, 02:38:57 AMYou won't believe this. All i had to do was specify WinMain as the entry point...and lookie lookie
you shouldn't do that, try doing what i wrote in my previous post.
Title: Re: Linking C With ASM
Post by: Ehtyar on October 23, 2006, 12:13:13 AM
As i said drizz, yours crashed, until i put /ENTRY:WinMain in the linker command line.
Unfortunately, the dll i was going to use in this project is packed with petite, and the author refuses to give me an unpacked copy, despite the fact that it is freeware (i won't make further comment on this topic as i'm afraid streams of profanity may find their way into my post) thus i cannot use it as a memory module, thus i cannot create the project i was hoping to. Therefore, i will not be posting the project i was hoping to create, sorry guys, and thanks again for the help.

Regards, Ehtyar.