Is there any documentation about External "C" calling conventions in GoASM.
I am playing with the following C code which I am trying to translate to use with GoASM:
// #1: XWSAStartup
extern "C" int __stdcall XWSAStartup (WORD wVersionRequested, LPWSADATA lpWsaData) {
lpWsaData->wVersion = 2;
return 0;
}
I've tried using:
_XWSAStartup@8 frame wVersionRequested, lpWsaData
mov eax, [lpWsaData]
mov w[eax+WSADATA.wVersion]
xor eax, eax
ret
endf
But somehow this is not working at all. I found out about using the _xxxx@8 from a post made by Jeremy. But comparing the compiled c file with the goasm compiled in IDA they are not looking the same in anyway.
.text:10001070 ; __stdcall XWSAStartup(x, x)
.text:10001070 public _XWSAStartup@8
.text:10001070 _XWSAStartup@8 proc near
From the compiled C file it perfectly created the external C label. But in Goasm it simply doesn't look like that in anyway.
Hi FlySky,
Could you try this GoAsm switch?
/ms=decorate for ms linker
Also, modify _XWSAStartup@8 to XWSAStartup
Here is an example for you :
MsgBox.asm :
.data
title db 'Demo',0
.code
MsgBox FRAME message
invoke MessageBoxA,0,[message],ADDR title,0
ret
MsgBox ENDF
Demo.cpp :
extern "C" int __stdcall MsgBox(char *message);
extern "C" int __stdcall ExitProcess(unsigned int uExitCode);
void WinMain()
{
char *msg="GoAsm demo";
MsgBox(msg);
ExitProcess(0);
}
Building the project wit VC++ :
\goasm\goasm /ms MsgBox.asm
cl /Zl /c /Ogtyb2 /Gs /G6 /Gz /FoDemo.OBJ Demo.cpp
\masm32\bin\polink /SUBSYSTEM:WINDOWS /LIBPATH:\masm32\lib /entry:WinMain@0 Demo.obj MsgBox.obj kernel32.lib user32.lib
Vortex thanks for your posts and information.
Maybe I am misunderstanding the concept of External functions.
I am playing with windows network API's atm on a small tool I made.
Basicly what I am working on is creating a wrapper dll.
The dll is created and placed in the same dir as the tool is executing from. Now it does not load the system Winsock.dll
but my wrapper dll, and that's where I am trying to use the XWSAStartup function from.
Using the C created file calling the function goes fine.
Doing it with an GoASM dll it's not working. So I assumed it had to do with the external calling.
Comparing both compiled functions:
From C
.text:10001070 ; __stdcall XWSAStartup(x, x)
.text:10001070 public _XWSAStartup@8
.text:10001070 _XWSAStartup@8 proc near ; DATA XREF: .rdata:off_1000C858o
.text:10001070
.text:10001070 arg_4 = dword ptr 0Ch
.text:10001070
.text:10001070 push ebp
.text:10001071 mov ebp, esp
.text:10001073 mov eax, 2
.text:10001078 mov ecx, [ebp+arg_4]
.text:1000107B mov [ecx], ax
.text:1000107E push offset aXwsastartup ; "XWSAStartup \n"
.text:10001083 call trace
.text:10001088 add esp, 4
.text:1000108B xor eax, eax
.text:1000108D pop ebp
.text:1000108E retn 8
.text:1000108E _XWSAStartup@8 endp
GoASM:
code:10001013
code:10001016 ; ---------------------------------------------------------------------------
code:10001016 push ebp
code:10001017 mov ebp, esp
code:10001019 mov eax, [ebp+0Ch]
code:1000101C mov word ptr [eax], 2
code:10001021 xor eax, eax
code:10001023 pop ebp
code:10001024 retn 8
Maybe it's the calling convention that I need to change
From what I see, extern "C" simply undecorates the exported names.
For example, without extern "C" the exported name is "int __cdecl TestFunc(int,int)".
With extern "C" it's just "TestFunc".
Quote from: Yuri on August 29, 2011, 03:56:38 AM
From what I see, extern "C" simply undecorates the exported names.
For example, without extern "C" the exported name is "int __cdecl TestFunc(int,int)".
With extern "C" it's just "TestFunc".
Hi Yuri,
I am afraid that is not true. Disassembling Demo.obj :
.386
option dotname
.model flat
public _WinMain@0
extern _MsgBox@4: near
extern _ExitProcess@4: near
@comp.id equ 000B224FH
_data SEGMENT DWORD PUBLIC 'DATA'
$SG272 label byte
db 47H, 6FH, 41H, 73H, 6DH, 20H, 64H, 65H ; 0000 _ GoAsm de
db 6DH, 6FH, 00H ; 0008 _ mo.
_data ENDS
_text SEGMENT PARA PUBLIC 'CODE'
_WinMain@0 PROC NEAR
push offset $SG272
call _MsgBox@4
push 0
call _ExitProcess@4
ret
_WinMain@0 ENDP
As you can see, all the functions are decorated.
If you remove the "C" statements, the result will be like the following :
extern int __stdcall MsgBox(char *message);
extern int __stdcall ExitProcess(unsigned int uExitCode);
.386
option dotname
.model flat
public _WinMain@0
extern ?MsgBox@@YGHPAD@Z: near
extern ?ExitProcess@@YGHI@Z: near
This decoration type is specific to MS VC++ Other C++ compiler can have different decoration conventions.
Hmm... Actually I was talking about DLLs. When I build one (in VS2008 Express) with the exported function marked as extern "C" and then look into the DLL via Dll Export Viewer, I see that the exported name is exactly the name of my function in the source code, e.g. TestFunc. If I don't use extern "C", the exported name looks like "int __cdecl TestFunc(int,int)".
Maybe I used the term "decorated" wrongly. Sorry if so.
Honestly I am not quite sure what problem FlySky is struggling with. But he said he was trying to build a wrapper DLL. So I assumed it was some issue with the names of the functions exported by that DLL.
Yuri and Vortex thanks for the replies so far.
I've included the GoASM source and the C-compiled DLL.
The thing is the following, using the C-compiled DLL the program is able to communicate properly with it.
Using the GoASM project it can't communicate properly with it.
Since the C-compiled dll (test1 function) is using the EXTERN "C" decoration I was assuming that was the problem.
As when comparing both DLL's in IDA, the C-compiled DLL is nicely generating an export while GoASM doesn't.
So the question was how would I be able to do the same in GoAsm what the C-compiled version looks like.
Hi Flysky,
I haven't had much time to look at your problem but I have also had fits when using C libraries. I've had some success with the /mix switch for GoLink.
Quote from: FlySky on August 29, 2011, 05:52:14 PM
Since the C-compiled dll (test1 function) is using the EXTERN "C" decoration I was assuming that was the problem.
Hi FlySky,
EXTERN "C" is a bit confusing here as your source code is C and not C++ The EXTERN "C" statement is specific to C++ if I am not wrong.
Remove the space and use "EXPORT:5332" as well as omitting the ":NONAME" part, since that will not include the function for export by name in the DLL (only by ordinal). How about this...
EXPORT:5332
XWSAStartup FRAME wVersionRequested, lpWsaData
;
;
ENDF
You can decorate the name manually in GoAsm source:
export _test_1@8 FRAME param1, param2
mov eax,1
ret
ENDF
But the problem may be the wrong calling convention, since the FRAME directive is intended for Windows callback functions, which use stdcall, while your C DLL probably uses cdecl. To do this in GoAsm, you have to write your functions without FRAMEs.
Quote from: VortexThe EXTERN "C" statement is specific to C++ if I am not wrong.
Vortex is correct. You don't need extern "C" with C. It is used with
C++ to undecorate mangled names.
Quote from: wjr on August 29, 2011, 07:46:52 PM
Remove the space and use "EXPORT:5332" as well as omitting the ":NONAME" part, since that will not include the function for export by name in the DLL (only by ordinal). How about this...
EXPORT:5332
XWSAStartup FRAME wVersionRequested, lpWsaData
;
;
ENDF
Sorry for the later reply. The issues is perfectly fixed using what WJR suggested. I didn't find this in GoASM documentation though. Exporting by ordinals fixed the problems. Thanks for all suggestion guys.