The MASM Forum

General => The Campus => Topic started by: malcode on February 11, 2013, 05:43:13 AM

Title: masm32 call to API
Post by: malcode on February 11, 2013, 05:43:13 AM
Hello all,


I write code below:


.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

.data
szMsg db "HELLO WORD",0
.code
start:
invoke MessageBoxA, NULL, addr szMsg, addr szMsg, MB_OK 
invoke ExitProcess, 0
end start


when i compile generate follow code:


00401000 >/$ 6A 00          PUSH 0                                   ; /Style = MB_OK|MB_APPLMODAL
00401002  |. 68 00304000    PUSH hellowor.00403000                   ; |Title = "HELLO WORD"
00401007  |. 68 00304000    PUSH hellowor.00403000                   ; |Text = "HELLO WORD"
0040100C  |. 6A 00          PUSH 0                                   ; |hOwner = NULL
0040100E  |. E8 0D000000    CALL  00401020
00401013  |. 6A 00          PUSH 0                                   ; /ExitCode = 0
00401015  \. E8 00000000    CALL 0040101A
0040101A   .-FF25 00204000  JMP DWORD PTR DS:[<&kernel32.ExitProcess>;  kernel32.ExitProcess
00401020   $-FF25 08204000  JMP DWORD PTR DS:[<&user32.MessageBoxA>] ;  user32.MessageBoxA


Because compiler make the call to the address "0040101A" then jump for api address JMP DWORD PTR DS:[<&user32.MessageBoxA>?

Compiler could make direct call for user32.MessageBoxA (call user32.MessageBoxA)?

thanks
Title: Re: masm32 call to API
Post by: hutch-- on February 11, 2013, 09:11:38 AM
The method you have shown is the standard 32 bit PE function call form but in MASM you can change that to a direct call by changing the API prototype.
Title: Re: masm32 call to API
Post by: dedndave on February 11, 2013, 09:27:10 AM
the pe exe can use an Import Address Table (IAT)
it speeds up loading the executable

let's say you had a program that used MessageBox in 25 places
when the os loads the exe, it replaces the address in the IAT (one time)
your 25 calls all point to the same entry in the IAT
otherwise, the os would have to update the call address in 25 places
Title: Re: masm32 call to API
Post by: Gunther on February 11, 2013, 10:10:33 AM
Hi malcode,

welcome to the forum. I think your question is answered. Have fun. :t

Gunther
Title: Re: masm32 call to API
Post by: Vortex on February 12, 2013, 06:23:15 AM
Hi malcode,

Welcome to the forum.

Here is a quick example :

.386
.model flat,stdcall
option casemap:none

include     \masm32\include\windows.inc

includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\user32.lib

EXTERNDEF   _imp__ExitProcess@4:PTR pr1
ExitProcess EQU <_imp__ExitProcess@4>

EXTERNDEF   _imp__MessageBoxA@16:PTR pr4
MessageBox  EQU <_imp__MessageBoxA@16>

.data

capt        db 'Hello',0
msg         db 'Direct call test',0

.code

start:

    invoke  MessageBox,0,ADDR msg,ADDR capt,MB_OK

    invoke  ExitProcess,0

END start


\masm32\bin\dumppe.exe -disasm DirectAPIcall.exe
.
.
.
Disassembly

00401000                    start:
00401000 6A00                   push    0
00401002 6800204000             push    offset off_00402000 ; 'Hello',000h
00401007 6806204000             push    offset off_00402006 ; 'Direct call test',000h
0040100C 6A00                   push    0
0040100E FF156C204000           call    dword ptr [MessageBoxA]
00401014 6A00                   push    0
00401016 FF1564204000           call    dword ptr [ExitProcess]
Title: Re: masm32 call to API
Post by: dedndave on February 12, 2013, 06:33:51 AM
well - those calls actually use absolute indirect addressing
they can still be dereferenced once more

if you want "direct" calls using near relative addressing....

http://www.masmforum.com/board/index.php?topic=17073.msg142389#msg142389 (http://www.masmforum.com/board/index.php?topic=17073.msg142389#msg142389)
Title: Re: masm32 call to API
Post by: Magnum on February 12, 2013, 07:00:33 AM
Got a bad zip file by 7zip and winzip.

http://www.masmforum.com/board/index.php?topic=17073.msg142389#msg142389

Andy

Lt Hedgecock: What kind of car, Miller?

Miller: Something with reclining leather seats, that goes really fast, and gets really crappy gas mileage! Alright.
Title: Re: masm32 call to API
Post by: Vortex on February 12, 2013, 07:05:50 AM
Hi Magnum,

I was able to download Dave's attachment. The zip file is correct. Could please clear your browser cache and try again?
Title: Re: masm32 call to API
Post by: dedndave on February 12, 2013, 07:15:50 AM
yes - i downloaded and unzipped it with no trouble using windows xp unzipper

looking at the code, i see some improvements i could make   :P
when i have some time.....
Title: Re: masm32 call to API
Post by: Magnum on February 12, 2013, 07:23:43 AM
Cleared the cache in FF, but no luck. Will have to investigate.

Chrome dled it o.k.

I understand the import address table and it's use.

Thought it was interesting that some packers destroy that table and take it on themselves to figure out which dlls to load.

I don't understand what deref is doing and what "being more robust" means in the context of the program.

Andy

Title: Re: masm32 call to API
Post by: dedndave on February 12, 2013, 07:49:57 AM
hiya Andy,

what i meant by more robust was the Deref function, itself
previously, i had some code that did it, piece-meal, you might say

but, i wanted a function that....
located the IAT
allowed start/stop addresses
allowed an exclusion list

the function finds API calls in a section of code (defined by start/stop)
and derferences them into near relative calls

for example, you might have a call in your code...
    INVOKE  GetCurrentProcess

that generates code something like this
    call    [IATaddressOfGetCurrentProcess]

in the IAT....
    jmp dword ptr [AddressOfActualCode]

the function finds the address of the actual code and replaces the original call with a near relative call
Title: Re: masm32 call to API
Post by: Vortex on February 16, 2013, 09:11:23 PM
The l2extia tool :

\masm32\tools\l2extia

QuoteL2EXTIA.EXE

This is an alternative method of creating include files that can be used
with MASM32. It produces include files in the EXTERNDEF format for system
DLL imports. This method allows direct calls to imported functions rather
that the lookup table that is the native format for MASM 32 bit EXE files.
Title: Re: masm32 call to API
Post by: japheth on February 16, 2013, 10:19:28 PM
Quote from: dedndave on February 12, 2013, 06:33:51 AM
well - those calls actually use absolute indirect addressing
they can still be dereferenced once more

if you want "direct" calls using near relative addressing....

http://www.masmforum.com/board/index.php?topic=17073.msg142389#msg142389 (http://www.masmforum.com/board/index.php?topic=17073.msg142389#msg142389)

IMO this post deserves a few remarks

1. Wrong terminology:


2. The DeRef tool is interesting, but AFAICS it's not at all proved that it reaches its goal - which probably is to increase speed. And, after a brief look into this "not-so-easy" to read code I'd say that the approach how the "dereferencing" is done isn't fool-proved; at least you must know exactly what you're doing - probably something that you cannot assume in the Campus.
Title: Re: masm32 call to API
Post by: dedndave on February 16, 2013, 11:00:39 PM
call it what you like (pun)
but, it is not the same as a near relative call

i know how much you like to poop on my pile - lol
QuoteThe DeRef tool is interesting
thank you - the nicest thing you ever said, not just to me, but to anyone   :biggrin:

while the tool isn't "fool-proof", i have yet to find a case where it made an improper conversion
i am sure you can invent one if you go out of your way
all you have to do is point it at the beginning of the code section (you can use NULL for the other parms)

as for speed, it does help in some cases
certain types of WM_PAINT code is an example
other cases vary, but include things that are repeated, where the call overhead is large compared to the code

as for the "easy to read" part - that's ok
i already mentioned that i saw room for improvement in the code
Title: Re: masm32 call to API
Post by: japheth on February 17, 2013, 05:25:04 AM
Quote from: dedndave on February 16, 2013, 11:00:39 PM
call it what you like (pun)
but, it is not the same as a near relative call

i know how much you like to poop on my pile - lol

still so sensitive to criticism, Dave? Good ... that ensures a lasting effect.

Quote
thank you - the nicest thing you ever said, not just to me, but to anyone   :biggrin:

Pretty close, yes. However, those 5 words did cost an significant amount of effort - I'll have to stay in recovery-mode for the next couple of months.

Quote
while the tool isn't "fool-proof", i have yet to find a case where it made an improper conversion
i am sure you can invent one if you go out of your way
all you have to do is point it at the beginning of the code section (you can use NULL for the other parms)

The question is: would you dare to use the deref proc on a real-life application - when you don't know every byte? As for me: probably not.

Quote
as for speed, it does help in some cases
certain types of WM_PAINT code is an example

WM_PAINT?  :shock: Are you serious? I'm not a member the "cycle-counting"-brigade. In fact, I have mostly abandoned low-level optimization at all ( due to my experience with HDPMI, a tool that I wrote 20 years ago and which is now fast, but virtually unmaintainable ).

Title: Re: masm32 call to API
Post by: dedndave on February 17, 2013, 06:47:42 AM
i have used it on several apps with no problems
if you don't like the tool, don't use it

this is the campus, so i'll respect the op
Title: Re: masm32 call to API
Post by: malcode on February 19, 2013, 02:13:37 AM
Thanks everybody for welcome.

This thread very useful for me, but still little doubt.

Masm32 by default use jump table to call winapi.

Advantage of this approach and that Linker can generate PE file more faster than use direct call (call iat_address), becouse have less place for replace by address IAT.

Disadvantage of this approach is more inefficient in run time than direct call, because all call to winapi need two instruction: call and jmp.

My doubt is this affirmation about is correct.

this my reference: http://msdn.microsoft.com/en-us/magazine/cc301805.aspx
Title: Re: masm32 call to API
Post by: qWord on February 19, 2013, 02:35:50 AM
Quote from: malcode on February 19, 2013, 02:13:37 AMDisadvantage of this approach is more inefficient in run time than
that is a question of the proportionality: how much does the additional jump cost in compare to the API itself? I would say that only a very small minority of APIs calls would benefit from a "direct" call.
Title: Re: masm32 call to API
Post by: dedndave on February 19, 2013, 02:36:20 AM
it is less efficient
however, in most cases, the time required to execute the jump is reasonably small,
compared to the time required to execute the code of the function

for functions like BitBlt, the code takes much longer than the call
but, for functions like CreateDIBSection, the code is fast, so dereferencing can help a little
in a paint operation, you might use both of these functions together
so, the call overhead is small

you have to weigh the time of the call against the time of the function
and - it is much more meaningful if you execute the code in a loop
if you call an API function 100,000 times, the overhead may be substantial