• Welcome to Valhalla Legends Archive.
 

Calling API from assembler?

Started by brew, October 02, 2007, 08:19 PM

Previous topic - Next topic

brew

So, I'm wondering. How do I call an API from the inline assembler? I've tried just about everything. This is what it's looking like so far:

inline void MsgBox(HWND hwnd, LPCTSTR text, LPCTSTR title, int otherstuff);
char asdfg[] = "hello";
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
__asm {
push MB_OK
push 0
push offset asdfg
push 0
call MsgBox
add esp, 16
}
return 0;
}

inline void MsgBox(HWND hwnd, LPCTSTR text, LPCTSTR title, int otherstuff) {
MessageBox(hwnd, text, title, otherstuff);
}


But I absolutely hate having to make a wrapper function for calling an API. What is the syntax for calling an API?
Like.... call dword ptr [apiname@ordinalname]? I've tried that, but it didn't work. MSDN has no documentation on this. I'm clueless.
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

Warrior

Perhaps there is a calling-convention confusion. Maybe using the naked keyword would help some.

/stabinthedark
Quote from: effect on March 09, 2006, 11:52 PM
Islam is a steaming pile of fucking dog shit. Everything about it is flawed, anybody who believes in it is a terrorist, if you disagree with me, then im sorry your wrong.

Quote from: Rule on May 07, 2006, 01:30 PM
Why don't you stop being American and start acting like a decent human?

warz

http://en.wikipedia.org/wiki/X86_calling_conventions

That explains everything. It's a useful link. I referenced it a lot back when I was dealing with game hacks.

brew

#3
Aha, i've got it! Thanks, guys! It's just call dword ptr [MessageBox].
It also pops my stack for me, I don't have to add 16 to esp manually. Say, msdn said that you're supposed to pop it to ebx 4 times, but is adding 16 to esp a good idea? (will it mess something up in the long run?) Doing that seems like i'm just making a workaround to stop the _chkesp error box and nothing more.
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

Camel

Quote from: brew on October 02, 2007, 09:11 PM
Aha, i've got it! Thanks, guys! It's just call dword ptr [MessageBox].
It also pops my stack for me, I don't have to add 16 to esp manually. Say, msdn said that it'd be a good idea to pop it to ebx 4 times, but is adding 16 to esp a good idea? (will it mess something up in the long run?)

The last time I looked at x86 asm, it added to esp after calls. Sometimes, the compiler will let esp float around to save instructions, which is pretty annoying.

warz

Look into different calling conventions. Some clean the stack for you, and some require the caller to clean the stack.

brew

About that link you posted, warz,
Quote
stdcall
The stdcall[1] calling convention is a variation on the pascal calling convention in which parameters are passed right-to-left. Registers EAX, ECX, and EDX are preserved for use within the function. Return values are stored in the EAX register.

Stdcall is the standard calling convention for the Microsoft WIN32 API.



push MB_OK
push 0
push offset hello
push 0
call dword ptr [MessageBox]


uh..
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

warz

I'm not sure what you're trying to point out.

brew

#8
I push the parameters in the reverse order. stdcall pushes them in order. That wiki article says that stdcall is the standard calling convention for win32 api. My code is working fine, though.
EDIT** Nevermind, i just failed to read it properly. It's identical to _cdecl. For some reason I always thought stdcall gets the parameters in order.

Also, I'm wondering how come i can't use ret in WinMain? and where is the previous execution address stored? (before the call, where the program returns to after ret)

EDIT**
why does the following code crash when it calls sprintf? :/

mov eax, 2
cmp eax, 1
jne overmsgbox

push 212121h
push 0
push ebx
mov ebx, esp
add ebx, 8
push ebx
push 0
call dword ptr [MessageBox]
add esp, 4
jmp done
overmsgbox:
push esp
push offset format
push asdf
call dword ptr [sprintf]
push 0
push 0
push asdf
push 0
call dword ptr [MessageBox]
done:
xor eax, eax

says it's an access violation.
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

devcode

Remove the "offset" from push offset format. Hi brew.

brew

Quote from: devcode on October 03, 2007, 09:05 PM
Remove the "offset" from push offset format. Hi brew.
Hi devcode. That doesn't work.
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

devcode

Quote from: brew on October 03, 2007, 09:47 PM
Quote from: devcode on October 03, 2007, 09:05 PM
Remove the "offset" from push offset format. Hi brew.
Hi devcode. That doesn't work.

Worked fine for me, but then again you didn't post your entire code, just a snippet of it.

Camel

Have you looked at the stack in a debugger? Does it match what you expect?

brew

<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

UserLoser

What is the point of doing this anyways?