The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: ketchup on May 24, 2008, 10:20:01 AM

Title: Understanding masm win32 api calls
Post by: ketchup on May 24, 2008, 10:20:01 AM
My question about win32 api calls is:

For instance if you look at the following code snippets:

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib            ; calls to functions in user32.lib and kernel32.lib
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib


invoke GetModuleHandle, NULL            ; get the instance handle of our program. 

A procedure can be called by its name. How does this work, exactly?
The procedure 'GetModuleHandle' doesn't have a static location in memory, so how is 'GetModuleHandle' connected to a memory location?

Gr Eric


Title: Re: Understanding masm win32 api calls
Post by: BogdanOntanu on May 24, 2008, 12:09:27 PM
Quote from: ketchup on May 24, 2008, 10:20:01 AM
My question about win32 api calls is:

For instance if you look at the following code snippets:


.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib           
; calls to functions in user32.lib and kernel32.lib
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib

...

; get the instance handle of our program. 
invoke GetModuleHandle, NULL           


A procedure can be called by its name. How does this work, exactly?
The procedure 'GetModuleHandle' doesn't have a static location in memory, so how is 'GetModuleHandle' connected to a memory location?

Gr Eric


This is in no way specific to MASM32... it is more like a general question and I have moved it to the Campus.

It is the combined action of the compiler, linker and OS loader.

The compiler considers it as an external function, unknown at compile time and because of this it does generate a generic call to an unknown symbol.

The linker notices the unknown symbol and tries to resolve it. Because it does not find any references about it in a static library the linker will not add code for this function. However the linker does find a hint in a dynamic import library and because of this it will generate the required structures for dynamic linking.

The OS loader will notice the dynamic linking structures in the executable and will fix the unknown symbols with the correct runtime value. This last action is performed at run time just before starting the program.

This can be done because the  OS knows at this time where the API is located in the address space of the pre executing process and this solves the puzzle.

The OS loader will then start the execution of the program.
Title: Re: Understanding masm win32 api calls
Post by: Slugsnack on May 25, 2008, 09:48:05 PM
Well not sure if this is the info you are looking for but this is what I have found out by tracing code then finding what the name of each structure I come across is called.

First off, when you hit an API call, its address is dynamic so to determine the address of the function, the CALL is actually a call to an entry on the JMP thunk table.  All imports have an entry in the JMP thunk table.  This entry holds a pointer to the address of the entry for that function in the import address table.  And then the entry for that function in the import address holds the virtual address of the actual function.

So like with MessageBox, look:

(http://i121.photobucket.com/albums/o222/Slugsnack/1-49.png)

That is the disassembly of an app that just makes a call to MessageBox then ExitProcess.

If you look at the call instruction it is actually:

(http://i121.photobucket.com/albums/o222/Slugsnack/2-36.png)

A call to the entry in the JMP thunk table for that function.  Looking at the entry in the JMP thunk table:

(http://i121.photobucket.com/albums/o222/Slugsnack/3-29.png)

You can see it holds a pointer to something else, the entry for that function in the import address table.  Following that in the hex dump:

(http://i121.photobucket.com/albums/o222/Slugsnack/4-27.png)

Now bearing in mind the way the x86 uses little endians, you can follow the address to:

(http://i121.photobucket.com/albums/o222/Slugsnack/5-20.png)

The current virtual address of that function.  Hope this is what you were looking for.
Title: Re: Understanding masm win32 api calls
Post by: BogdanOntanu on May 25, 2008, 10:36:13 PM
Slugsnack,

1) At the moment of debugging in Olly the OS loader has already fixed the API address.
2) Not all executables have a "jump table".

For your info: FASM generated PE executables will directly call the API by doing a call [MessageBoxA] and will not have a jump table. Jump tables are usually generated by the linker and are not a requirement for the PE executable format.


Title: Re: Understanding masm win32 api calls
Post by: hutch-- on May 25, 2008, 11:10:03 PM
Interestingly enough MASM can do either call method, it depends on the prototypes used. The jump table is PE spec but the VC method is easy enough to do.