News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Understanding masm win32 api calls

Started by ketchup, May 24, 2008, 10:20:01 AM

Previous topic - Next topic

ketchup

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



BogdanOntanu

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.
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

Slugsnack

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:



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:



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



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:



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



The current virtual address of that function.  Hope this is what you were looking for.

BogdanOntanu

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.


Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

hutch--

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.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php