Here is an example demonstarting direct function calls avoid jump tables. ArgCount and prX macros coded by Hutch.
.386
.model flat,stdcall
option casemap:none
ArgCount MACRO number
LOCAL txt
txt equ <typedef PROTO :DWORD>
REPEAT number - 1
txt CATSTR txt,<,:DWORD>
ENDM
EXITM <txt>
ENDM
pr0 typedef PROTO
pr1 ArgCount(1)
pr2 ArgCount(2)
pr3 ArgCount(3)
pr4 ArgCount(4)
MB_OK equ 0
EXTERNDEF _imp__MessageBoxA:pr4
EXTERNDEF _imp__ExitProcess:pr1
MessageBox TEXTEQU <_imp__MessageBoxA>
ExitProcess TEXTEQU <_imp__ExitProcess>
.data
capt db 'Hello',0
msg db 'Direct function call demo',0
.code
start:
push MB_OK
push OFFSET capt
push OFFSET msg
push 0
call MessageBox
push 0
call ExitProcess
END start
Yes that because you added the "__imp"
In a normal use I have:
nop
jmp qword ptr [00000001400045B8]
jmp qword ptr [00000001400045C0]
jmp qword ptr [00000001400045C8]
jmp qword ptr [00000001400045D0]
What is the best having obj files or dll.lib files to bypass the stub?
Hi Vortex. I was intrigued by this program. I adapted it (slightly) to work with ml & link. It works, no jump table. :tongue:
.386
.model flat,stdcall
option casemap:none
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
ArgCount MACRO number
LOCAL txt
txt equ <typedef PROTO :DWORD>
REPEAT number - 1
txt CATSTR txt,<,:DWORD>
ENDM
EXITM <txt>
ENDM
pr0 typedef PROTO
pr1 ArgCount(1)
pr2 ArgCount(2)
pr3 ArgCount(3)
pr4 ArgCount(4)
MB_OK equ 0
EXTERNDEF _imp__MessageBoxA:pr4
EXTERNDEF _imp__ExitProcess:pr1
MessageBox TEXTEQU <_imp__MessageBoxA>
ExitProcess TEXTEQU <_imp__ExitProcess>
.data
capt db 'Hello',0
msg db 'Direct function call demo',0
.code
start:
push MB_OK
push OFFSET capt
push OFFSET msg
push 0
call dword ptr [MessageBox]
push 0
call dword ptr [ExitProcess]
END start
Cannot be assembled and linked with qeditors "Assemble & Link" menu item, since hutch uses "/OPT:NOREF" for linking there, batch file must be used.
batch file to assemble and link:
SET asm="DirectCall"
\masm32\bin\ml /c /coff /nologo %asm%.asm
\masm32\bin\Link /SUBSYSTEM:WINDOWS /nologo %asm%.obj
pause
Of course to eek out some more bytes, merging the sections ain't a bad idea if that is the object here. :smiley:
Hi Philippe,
The method based on specifying leading __imp_ tag is also adopted by Pelles C.
Example :
#include <stdio.h>
#include <windows.h>
int main(void)
{
printf("Hello world");
MessageBox(0,"Test","Hello",MB_OK);
return 0;
}
Disassembling the object module :
_text SEGMENT PARA PUBLIC 'CODE'
_main PROC NEAR
push offset @1023
call _printf
pop ecx
push 0
push offset @1026
push offset @1025
push 0
call dword ptr [__imp__MessageBoxA@16]
xor eax, eax
ret
_main ENDP
_text ENDS
Interesting ?
The case of a curious __imp_. (https://dennisbabkin.com/blog/?i=AAA10500)
#pragma comment(lib, "msvcrt.lib")
int __declspec(dllimport) __cdecl printf(char* fmt, ...);
int main(void)
{
printf("Hello world");
return 0;
}
_main:
[00000000] 6800000000 push @9
[00000005] FF1500000000 call dword ptr [__imp__printf]
[0000000B] 59 pop ecx
[0000000C] 31C0 xor eax,eax
[0000000E] C3 ret
Hi Zedd,
Thanks for your Masm version.
Hi Timo,
Thanks for the info.
Quote from: Vortex on January 09, 2025, 06:59:39 AMHi Zedd,
Thanks for your Masm version.
I was curious if it would work in masm. It took some trial and error, with a couple of different methods that worked. What I had posted was the simplest approach. It was either that, or specifying the libs on the link.exe command line, which also worked.