News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

masm32 call to API

Started by malcode, February 11, 2013, 05:43:13 AM

Previous topic - Next topic

malcode

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

hutch--

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.

dedndave

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

Gunther

Hi malcode,

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

Gunther
You have to know the facts before you can distort them.

Vortex

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]

dedndave

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

Magnum

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.
Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

Vortex

Hi Magnum,

I was able to download Dave's attachment. The zip file is correct. Could please clear your browser cache and try again?

dedndave

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.....

Magnum

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

Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

dedndave

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

Vortex

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.

japheth

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

IMO this post deserves a few remarks

1. Wrong terminology:


  • there is no "absolute indirect addressing" - indirect addressing in intel terms means that a REGISTER is used at runtime to calculate the effective address. This is not the case here.
  • for calls/jmps there exist 2 variants of "direct addressing" in x86: with a) immediate operands ( that's what is called "direct" above ) or b) direct memory operands.

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.

dedndave

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

japheth

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 ).