NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: wyvern666 on January 29, 2012, 01:41:37 AM
-
Anybody knows how to import by ordinal with NASM and ALINK?. Currently the only way i can do it is writing the import section by hand, but that is a lot of ugly work.
Thanks.
-
I guess you are trying to do something like this.
MessageBox is called by ordinal in this example.
[Ordinal will change depending on the dll version. We might need to use tools like PE/DLL Viewer to get the correct one.]
;;Assemble with:
;;nasm -fobj HelloOrd.asm
;;Link with:
;;alink -c -oPE -subsys gui HelloOrd.obj
%include "win32n.inc"
extern GetProcAddress
import GetProcAddress kernel32.dll
extern LoadLibraryA
import LoadLibraryA kernel32.dll
global ..start
segment .data USE32
message db "Hello World!",0
msgtitle db "Hello",0
dllname1 db "user32.dll",0
apiname1 db "MessageBoxA",0
hMod dd 0
OrdinalMsgBox dd 0
segment .bss USE32
segment .code USE32 class=code
..start:
push dword dllname1
call [LoadLibraryA]
mov [hMod],eax ;; Save Module Handle for User32.dll
push dword 2039 ;; Alternatively use function name ;;; push dword apiname1
push dword [hMod]
call [GetProcAddress] ;; Get the Address of MessageBox api function.
mov [OrdinalMsgBox],eax
cmp eax,0
jz ExitOut ;; if zero then something is wrong
push dword MB_OK
push dword msgtitle
push dword message
push dword 0
call [OrdinalMsgBox] ;; call the function.
ExitOut:
ret
-
Hi Mathi, thank for your answer. I forgot to say i know i can use LoadLibrary and GetProcAddress, its a more dinamical way to do the job at runtime. But i was pretending something more "direct" and easy, for example en GOASM you just write CALL "[KERNEL32.DLL:248]" and there you go. Mmm maybe some macros can simplifiy this job. Anyway, by now, i will stick with LoadLibrary. :D
-
What little information I found suggests that Alink won't do this, but GoLink will... but you knew that!
I found a reference to a program that is supposed to do it after the fact:
http://www.masm32.com/board/index.php?topic=381.0
I wonder if that would help?
From what I found, it doesn't improve performance all that much anyway...
Best,
Frank
-
Yap, i see now that importing by ordinal require extra work in NASM, MASM and some others assemblers. By the way, and off-topic, i am curious about some little thing in Mathi's code ???:
extern GetProcAddress
import GetProcAddress kernel32.dll ; ???
I never used "IMPORT" in NASM... Usually i just use EXTERN and then i add neccesary .lib files in ALINK command line. But from what im trying right now with this code it seems like when you declare "EXTERN & IMPORT" you dont need to link with .lib files, so you just used "alink -c -oPE -subsys gui HelloOrd.obj" and thats all. Im wrong?.
-
when you declare "EXTERN & IMPORT" you dont need to link with .lib files, so you just used "alink -c -oPE -subsys gui HelloOrd.obj" and thats all. Im wrong?.
Thats correct.
We need to make sure that we give the correct Function Name and dll name.
Otherwise we will get runtime errors. (program won't start).
"The procedure entry point <apifunction> could not be located in the dynamic link library <dllname>. etc.
Regarding the call by Ordinal .
It can be simplified if you are using the nagoa+.inc include file with couple of macros.
;;Assemble with:
;;nasm -fobj HelloOrd1.asm
;;Link with:
;;alink -c -oPE -subsys gui HelloOrd1.obj
%include "nagoa+.inc"
%macro GETORDINAL 2
%ifndef GETORDINAL_IMPORT
extern GetProcAddress
import GetProcAddress kernel32.dll
extern LoadLibraryA
import LoadLibraryA kernel32.dll
%define GETORDINAL_IMPORT
%endif
call LoadLibraryA,%1
test eax,eax
jz %%ExitError
call GetProcAddress,eax,%2
%%ExitError:
%endmacro
%macro CALLORD 2-*
GETORDINAL %1,%2
test eax,eax
jz %%ExitError
%assign iparm %0
%if %0 > 1
%rep %0 - 2
%rotate -1
%assign iparm iparm-1
%rotate -1
%ifidni %1,"ADDR_"
%rotate 1
lea eax, [%1]
push eax
%rotate -1
%assign iparm iparm-1
%else
%rotate 1
STDPUSH {%1}
%endif
%if iparm <=1
%exitrep
%endif
%endrep
%rotate -1
%endif
CALL eax ;; Caps for actual CALL instruction
%%ExitError:
%endmacro
global ..start
segment .code USE32 class=code
..start:
CALLORD "user32.dll",2039,0,"HelloWorld!","Hello",MB_OK
ret
-
WOW, that is pretty cool. Thank you very much. And then i will try the IMPORT with COFF format too.
-
Well, sadly IMPORT only work with "obj" (OMF) format. Any knows why?
-
I don't know why, but you're correct - "import", as a Nasm keyword, is specific to "-f obj". Unless I'm mistaken, the NASMX package has "import" as a macro. I don't know if it does the same thing...
Best,
Frank
-
NASMX's import macro defines the appropriate external linkages to the shared libraries. For Windows we take advantage of the automatic resolving of the name table by GoLink which is also distributed with the package. It will not work with Alink without some effort. I'm not inclined to provide such effort for a tool such as Alink that's long considered dead.