flat assembler
Message board for the users of flat assembler.

Index > Windows > linkage problem

Author
Thread Post new topic Reply to topic
blackoil



Joined: 09 Feb 2009
Posts: 7
blackoil
I use fasmw16729 to assemble the source, but has runtime error.
then I use ollydbg to trace, the "call LoadIconA" has the wrong address.

Quote:
format PE
use32
entry WinMain
include 'include\win32a.inc'
section '.code' code readable executable


WinMain:
push ebp
push ebx
push esi
push edi
mov ebp, esp
sub esp, 0x00000048
mov [ ebp-0x00000048+0x00000000 ], dword 0x00000000
lea eax, [ WindowProc ]
mov [ ebp-0x00000048+0x00000004 ], dword eax
mov [ ebp-0x00000048+0x00000008 ], dword 0x00000000
mov [ ebp-0x00000048+0x0000000C ], dword 0x00000000
mov eax, [ ebp+0x00000014 ]
mov [ ebp-0x00000048+0x00000010 ], dword eax
push dword 0x00007F00
push dword 0x00000000
call LoadIconA
mov esi, eax
mov [ ebp-0x00000048+0x00000014 ], dword esi
push dword 0x00007F00
push dword 0x00000000
call LoadCursorA
mov esi, eax
mov [ ebp-0x00000048+0x00000018 ], dword esi
mov [ ebp-0x00000048+0x0000001C ], dword 0x0000000F
mov [ ebp-0x00000048+0x00000020 ], dword 0x00000000
mov [ ebp-0x00000048+0x00000024 ], dword c_c00000000
lea esi, [ ebp-0x00000048 ]
push dword esi
call RegisterClassA
mov esi, eax
push dword 0x00000000
push dword [ ebp+0x00000014 ]
push dword 0x00000000
push dword 0x00000000
push dword 0x000000FA
push dword 0x0000012C
push dword 0x00000064
push dword 0x00000064
push dword 0x10080000
push dword c_c00000001
push dword [ ebp-0x00000048+0x00000024 ]
push dword 0x00000000
call CreateWindowExA
mov esi, eax
.L00000001:
push dword 0x00000000
push dword 0x00000000
push dword 0x00000000
lea esi, [ ebp-0x00000020 ]
push dword esi
call GetMessageA
mov esi, eax
cmp esi, 0x00000001
jne .L00000002
lea esi, [ ebp-0x00000020 ]
push dword esi
call TranslateMessage
mov esi, eax
lea esi, [ ebp-0x00000020 ]
push dword esi
call DispatchMessageA
mov esi, eax
jmp .L00000001
.L00000002:
push dword 0x00000000
call ExitProcess
.L00000000:
mov esp, ebp
pop edi
pop esi
pop ebx
pop ebp
ret

WindowProc:
push ebp
push ebx
push esi
push edi
mov ebp, esp
cmp [ ebp+0x00000018 ], dword 0x00000002
je .L00000005
jmp .L00000006
.L00000005:
push dword 0x00000000
call PostQuitMessage
jmp .L00000004
.L00000006:
push dword [ ebp+0x00000020 ]
push dword [ ebp+0x0000001C ]
push dword [ ebp+0x00000018 ]
push dword [ ebp+0x00000014 ]
call DefWindowProcA
mov esi, eax
.L00000004:
.L00000003:
mov esp, ebp
pop edi
pop esi
pop ebx
pop ebp
ret

section '.data' data readable writeable
library kernel32,'KERNEL32.DLL',user32,'USER32.DLL'
include 'include\api\kernel32.inc'
include 'include\api\user32.inc'


c_c00000000: db "MYCLASS", 0x00000000
c_c00000001: db "TITLE", 0x00000000
[/quote]
Post 09 Feb 2009, 10:36
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7722
Location: Kraków, Poland
Tomasz Grysztar
The standard import macro create labels to the pointers, thus you need to call it this way:
Code:
call [LoadIconA]    
Post 09 Feb 2009, 11:01
View user's profile Send private message Visit poster's website Reply with quote
blackoil



Joined: 09 Feb 2009
Posts: 7
blackoil
ok thanks

If I want to use direct addressing "call LoadIconA", how to modify it?
Post 09 Feb 2009, 14:50
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17274
Location: In your JS exploiting you and your system
revolution
blackoil wrote:
If I want to use direct addressing "call LoadIconA", how to modify it?
Code:
invoke LoadIconA    
Post 09 Feb 2009, 14:58
View user's profile Send private message Visit poster's website Reply with quote
blackoil



Joined: 09 Feb 2009
Posts: 7
blackoil
the above code is compiler output, I need to use call instruction, what .inc file should I use for this?
Post 09 Feb 2009, 15:16
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
You program cannot call API directly, because it only has pointer to it in Import Table. You don't know address of function at compilation time.

Usual solution is to create "thunks" (or however it is called), something like:
Code:
ExitProcess: jmp [__imp__ExitProcess]
MessageBoxA: jmp [__imp__MessageBoxA]
    

where "__imp__ExitProcess" and "__imp__MessageBoxA" are pointers from the Import Table.

I don't think there is a FASM include file, which creates those "thunks" (or however that "" is called) for you.

What you can do:

1. Modify compiler if you can, to output "call [XY]" or "invoke XY" instead of "call XY"

2. Modify compiler to output code for OBJ file ("format MS COFF"), not directly to exe. In that case you can declare "extern XY", call it directly, and link with .LIB files that are part of every compiler kit. Those .LIB files contain that "ExitProcess: jmp [__imp__ExitProcess]" I mentioned.

3. Modify compiler to create those thunks for every imported function.
Post 09 Feb 2009, 15:52
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7722
Location: Kraków, Poland
Tomasz Grysztar
The other option is to use the import macros that would make those "jmp" functions for you. I already once posted such macros here, check out http://board.flatassembler.net/topic.php?p=40935#40935
Post 09 Feb 2009, 16:47
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
vid wrote:
I don't think there is a FASM include file, which creates those "thunks" (or however that "" is called) for you.


Tomasz Grysztar wrote:
The other option is to use the import macros that would make those "jmp" functions for you. I already once posted such macros here


So, I was wrong Smile
Post 10 Feb 2009, 00:26
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
blackoil



Joined: 09 Feb 2009
Posts: 7
blackoil
I tried to rename them to

call [LoadIconA]
invoke LoadIconA

Both don't work.

Addresses are still not correct.
Post 10 Feb 2009, 00:50
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17274
Location: In your JS exploiting you and your system
revolution
If you really need a direct call (what for?) then you need to make a runtime procedure to relink all the calls to OS APIs. You can't do it by just manipulating the imports section and thunks.
Post 10 Feb 2009, 02:24
View user's profile Send private message Visit poster's website Reply with quote
blackoil



Joined: 09 Feb 2009
Posts: 7
blackoil
making a runtime procedure is out of my action.
I tried NASM+ALINK with a WIN32.LIB ( 706,560 bytes ).
It works.
Post 10 Feb 2009, 05:11
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
Quote:
I tried to rename them to

call [LoadIconA]
invoke LoadIconA

Both don't work.


That's because you didn't flag import data as such. You must either put them into separate section flagged as "import", or into "data import" blocks. Just look at the existing. examples. (Import data in your example are three lines with "library" macro and two "include"s)
Post 10 Feb 2009, 12:09
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
blackoil



Joined: 09 Feb 2009
Posts: 7
blackoil
It works now.

Quote:

format PE
use32
entry WinMain
include 'include\win32a.inc'

section '.code' code readable executable

WinMain:
push ebp
push ebx
push esi
push edi
mov ebp, esp
sub esp, 0x00000048
mov [ ebp-0x00000048+0x00000000 ], dword 0x00000000
lea eax, [ WindowProc ]
mov [ ebp-0x00000048+0x00000004 ], dword eax
mov [ ebp-0x00000048+0x00000008 ], dword 0x00000000
mov [ ebp-0x00000048+0x0000000C ], dword 0x00000000
mov eax, [ ebp+0x00000014 ]
mov [ ebp-0x00000048+0x00000010 ], dword eax
push dword 0x00007F00
push dword 0x00000000
invoke LoadIconA
mov esi, eax
mov [ ebp-0x00000048+0x00000014 ], dword esi
push dword 0x00007F00
push dword 0x00000000
invoke LoadCursorA
mov esi, eax
mov [ ebp-0x00000048+0x00000018 ], dword esi
mov [ ebp-0x00000048+0x0000001C ], dword 0x0000000F
mov [ ebp-0x00000048+0x00000020 ], dword 0x00000000
mov [ ebp-0x00000048+0x00000024 ], dword c_c00000000
lea esi, [ ebp-0x00000048 ]
push dword esi
invoke RegisterClassA
mov esi, eax
push dword 0x00000000
push dword [ ebp+0x00000014 ]
push dword 0x00000000
push dword 0x00000000
push dword 0x000000FA
push dword 0x0000012C
push dword 0x00000064
push dword 0x00000064
push dword 0x10080000
push dword c_c00000001
push dword [ ebp-0x00000048+0x00000024 ]
push dword 0x00000000
invoke CreateWindowExA
mov esi, eax
.L00000001:
push dword 0x00000000
push dword 0x00000000
push dword 0x00000000
lea esi, [ ebp-0x00000020 ]
push dword esi
invoke GetMessageA
mov esi, eax
cmp esi, 0x00000001
jne .L00000002
lea esi, [ ebp-0x00000020 ]
push dword esi
invoke TranslateMessage
mov esi, eax
lea esi, [ ebp-0x00000020 ]
push dword esi
invoke DispatchMessageA
mov esi, eax
jmp .L00000001
.L00000002:
push dword 0x00000000
invoke ExitProcess
.L00000000:
mov esp, ebp
pop edi
pop esi
pop ebx
pop ebp
ret

WindowProc:
push ebp
push ebx
push esi
push edi
mov ebp, esp
cmp [ ebp+0x00000018 ], dword 0x00000002
je .L00000005
jmp .L00000006
.L00000005:
push dword 0x00000000
invoke PostQuitMessage
jmp .L00000004
.L00000006:
push dword [ ebp+0x00000020 ]
push dword [ ebp+0x0000001C ]
push dword [ ebp+0x00000018 ]
push dword [ ebp+0x00000014 ]
invoke DefWindowProcA
mov esi, eax
.L00000004:
.L00000003:
mov esp, ebp
pop edi
pop esi
pop ebx
pop ebp
ret

section '.idata' import data readable writeable
library kernel32,'KERNEL32.DLL',user32,'USER32.DLL'
include 'include\api\kernel32.inc'
include 'include\api\user32.inc'

section '.data' data readable writeable
c_c00000000: db "MYCLASS", 0x00000000
c_c00000001: db "TITLE", 0x00000000
Post 10 Feb 2009, 13:14
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17274
Location: In your JS exploiting you and your system
revolution
You have used invoke. So how about using it to make the code more human friendly Wink
Code:
invoke DefWindowProcA,[ebp+0x14],[ebp+0x18],[ebp+0x1C],[ebp+0x20]    
Then once you add symbolic names to things it can almost be readable.
Post 10 Feb 2009, 13:33
View user's profile Send private message Visit poster's website Reply with quote
blackoil



Joined: 09 Feb 2009
Posts: 7
blackoil
well, I want my compiler outputs assembly code in general syntax.
so I just add:

if ( calling_convention == stdcall ) emit_invoke();
else emit_call();

if ( calling_convention == stdcall ) do_nothing();
else clear_stack();
Post 10 Feb 2009, 13:52
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar.

Powered by rwasa.