Hello, i'm new here and i'm currently trying to learn things from MASM32.
i need to ask something about the syntax.
so i'm importing function from an IAT:
example -> __exp db "ExitProcess", 00h,00h
and i would like to call that function in my code, so i've simply tried:
PUSH 0
CALL __exp or INVOKE __exp
with CALL i'm getting error A2024 ''invalid operand size for instruction''
and with INVOKE but i'm getting error A2026 ''undefined symbol : __exp"
so what's the correct syntax to call an imported function?
thanks in advance
I'm not sure what you mean by 'importing from IAT'
Perhaps you meant importing from an API??
but the correct syntax is either
push 0
call ExitProcess
---OR----
invoke ExitProcess, 0
There are a lot of examples in the 'examples' folder where you have masm32 installed
Oh by the way, welcome to the forum! :t
here is an example from \masm32\examples\exampl01\minimum
; #########################################################################
.386
.model flat, stdcall
option casemap :none ; case sensitive
; #########################################################################
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
; #########################################################################
.code
start:
jmp @F
szDlgTitle db "Minimum MASM",0
szMsg db " --- Assembler Pure and Simple --- ",0
@@:
push MB_OK
push offset szDlgTitle
push offset szMsg
push 0
call MessageBox
push 0
call ExitProcess
; --------------------------------------------------------
; The following are the same function calls using MASM
; "invoke" syntax. It is clearer code, it is type checked
; against a function prototype and it is less error prone.
; --------------------------------------------------------
; invoke MessageBox,0,ADDR szMsg,ADDR szDlgTitle,MB_OK
; invoke ExitProcess,0
end start
Thanks for your reply
I mean "importing" functions bcuz i'm making a dll with self mapping, so i need to use a custom import adress table where all my functions name stands.
I can't use CALL ExitProcess it would just error.
I still don't understand exactly what you are trying to do.
Can you post some of your code?
edit = typo
thanks for your reply
i.e
in the PE format you can use an import adress table aka iat
when you load the dll, it replace the adress in the iat.
So all the calls will directly point the iat, this make my program runs faster
bcuz even if there's many calls it's always the same entry in the iat
if i do not use an iat and just use basic CALL ExitProcess, it's going to be updated every times and runs slowly, but there i don't really care about the speed, it's just for learning purpose.
here's an example
IAT:
;Dll names
__dllk db "kernel32.dll",00h
__dllu db "user32.dll",00h
;var
__loadlibary dd ?
;imported function
__exp db "ExitProcess",00h,00h
;etc
but my goal is just to know the SYNTAX to call the exitprocess bcuz i can't do: CALL __exp it's throwin an error.
thanks again and sorry for my english which sucks lol!
So I think basically what you are trying to do is a 'direct call'?? - rather than calling the jump thunk table??
I have no idea how to do that.
well yes it's a direct call you're right, and my problem is the syntax
so since i can't do CALL __exp (error A2024) and (error A2026) with INVOKE __exp
miby i'm suposed to do PUSH DWORD PTR __exp
and then CALL EAX?
that's really a matter of syntax^^
but thanks anyway
Hello Ener,
IAT = Interrupt Address Table
If you're accessing conventional functions like ExitProcess and so forth you should just use the appropriate lib's and inc's found in the lib and include directories of the masm32 download package. There is very little advantage to "rolling your own" here; only worth it for special, advanced needs - if then.
If you really need to do it, it's not as simple as just putting the name in a data statement as you're attempting; you need the address in the IAT (it's not just about syntax). I recommend you get it working in the normal way, using the masm32rt.inc file specially designed for beginners. Then you'll understand the proper syntax etc.
However if you do have a special dll to deal with, not found there, tell us what it is and what functions you need, we can take it from there
Quote from: rrr314159 on September 21, 2015, 07:13:30 AM
IAT = Interrupt Address Table
IAT == IMPORT Address Table - lol
Possibly you could use LoadLibrary/GetProcAddress??
The the return value will then be the address of the imported function.
But I too, don't see why you can't just use 'call' or 'invoke' in the normal fashion. - Unless of course the dll is not in the
Windows API, but some other external dll.
In that case, if I didnt have the necessary .lib and .inc file, I would go with LoadLibrary/GetProcAddress.
But with that approach, you would have to be 100% sure how many arguments the function takes, AND their type.
in the IAT, the address of ExitProcess is updated when the system loads the EXE
there are different opcodes for CALL
inside a program, it will often be the near relative form - the operand is a signed offset from the next instruction
another form is a near indirect - which is what actually appears in "normal" code for IAT calls
the operand is an address of a pointer to the code
here's a routine i wrote few years ago
it dereferences IAT calls
the tricky part is to find the IAT :lol:
;*************************************************************************************************************
OPTION PROLOGUE:None
OPTION EPILOGUE:None
DeRef PROC lpStart:LPVOID,lpStop:LPVOID,lpExclusions:LPVOID
;Dereference IAT Branches
;DednDave - 7, 2011
;
; Dereferences all branches into the IAT, starting at lpStart, and ending at lpStop.
;If lpStop is NULL, the beginning of the IAT is used as the stop address.
;An exclusion list may be used to exclude specific addresses from conversion.
;Addresses in the list represent the address of the first instruction byte.
;If present, the list must be terminated with a NULL dword.
;No exclusion list is used if the lpExclusions parameter is NULL.
;
; This version allows for the conversion of JMP's, CALL's and conditional branches.
;It will convert declspec JMP's and CALL's, including those into the MSVCRT, etc.
;
; The converted instructions always result in a relative branch directly to the imported code.
;This will prevent hooking into the IAT, which may be overridden by hooking prior to DeRef
;execution or by use of the exclusion list.
;
;----------------------------------------------------
;
;[EBP+28] = lpExclusions
;[EBP+24] = lpStop
;[EBP+20] = lpStart
;[EBP-4] = address of IAT start
;[EBP-8] = address of IAT end
;[EBP-12] = adjusted lpStop (lpStop-4)
;[EBP-16] = original access protection value
;[EBP-20] = dereference count
;
;----------------------------------------------------
push ebx
push esi
push edi
push ebp
push 6
xor edx,edx
pop ebx
mov esi,VirtualProtect
mov ebp,esp
mov eax,25FFh
push esi
jmp short DeRef1
DeRef0: mov edx,esi
sub esi,ebx
DeRef1: cmp ax,[esi]
jz DeRef0
pop esi
or edx,edx
push edx ;[EBP-4] = address of IAT start
jz DeRefL
DeRef2: mov ecx,esi
add esi,ebx
cmp ax,[esi]
jz DeRef2
mov edi,[ebp+24] ;lpStop
add ecx,2
or edi,edi
push ecx ;[EBP-8] = address of IAT end
jnz DeRef3
mov edi,edx
DeRef3: mov edx,edi
mov esi,[ebp+20] ;lpStart
sub edx,4
sub edi,esi
push edx ;[EBP-12] = adjusted lpStop (lpStop-4)
mov [ebp+24],edi ;[EBP+24] is now code stream length
push eax ;[EBP-16] = previous access protection value
INVOKE VirtualProtect,esi,edi,PAGE_EXECUTE_READWRITE,esp
or eax,eax
push 0 ;[EBP-20] = dereference count
jnz DeRefH
jmp DeRefL
DeRef4: xor ecx,ecx
cmp al,0E8h ;CALL relative (to JMP indirect)
mov edx,ecx
jz DeRef5
cmp al,0E9h ;JMP relative (to JMP indirect)
jz DeRef6
inc ecx
cmp ax,15FFh ;CALL indirect (declspec)
mov edx,ecx
jz DeRef6
cmp ax,25FFh ;JMP indirect (declspec)
jz DeRef6
dec edx
cmp al,0Fh ;relative conditional branch candidate
jnz DeRefI
cmp ah,80h ;relative conditional branch candidate
jb DeRefI
cmp ah,8Fh ;relative conditional branch (to JMP indirect)
jbe DeRef6
jmp DeRefI
DeRef5: cmp esi,offset DeRefL-4
jz DeRefI
DeRef6: mov edi,esi
add edi,ecx
cmp edi,[ebp-12] ;adjusted lpStop (lpStop-4)
ja DeRefK
or edx,edx
mov ebx,[edi]
jz DeRef9
push esi
mov esi,[ebp-4] ;address of IAT start
add esi,2
DeRef7: cmp ebx,[esi]
jnz DeRef8
pop esi
jmp short DeRefA
DeRef8: add esi,6
cmp esi,[ebp-8] ;address of IAT end
jbe DeRef7
pop esi
jmp DeRefI
DeRef9: add ebx,edi
add ebx,4
cmp ebx,[ebp-4] ;address of IAT start
jb DeRefI
cmp ebx,[ebp-8] ;address of IAT end
ja DeRefI
push ebx
push eax
push edx
sub ebx,[ebp-4] ;address of IAT start
mov eax,0AAAAAAABh
push ebx
mul ebx
shr edx,2
mov eax,6
mul edx
pop ebx
cmp eax,ebx
pop edx
pop eax
pop ebx
jnz DeRefI
DeRefA: mov ecx,[ebp+28] ;lpExclusions
or ecx,ecx
jz DeRefD
push eax
dec esi
jmp short DeRefC
DeRefB: add ecx,4
cmp eax,esi
jnz DeRefC
inc esi
pop eax
jmp short DeRefI
DeRefC: mov eax,[ecx]
or eax,eax
jnz DeRefB
inc esi
pop eax
DeRefD: or edx,edx
jz DeRefF
cmp ah,15h
mov ebx,[ebx]
mov ax,0E890h
jz DeRefE
inc ah
DeRefE: mov [esi-1],ax
jmp short DeRefG
DeRefF: mov ecx,[ebx+2]
mov ebx,[ecx]
DeRefG: sub ebx,edi
sub ebx,4
mov [edi],ebx
inc dword ptr [ebp-20] ;dereference count
add edi,4
mov esi,edi
DeRefH: mov ax,[esi]
inc esi
jmp short DeRefJ
DeRefI: inc esi
mov al,ah
mov ah,[esi]
DeRefJ: cmp esi,[ebp-12] ;adjusted lpStop (lpStop-4)
jbe DeRef4
DeRefK: lea edx,[ebp-12]
INVOKE VirtualProtect,[ebp+20],[ebp+24],[ebp-16],edx
DeRefL: pop eax ;return dereference count
leave
pop edi
pop esi
pop ebx
ret 12
DeRef ENDP
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
;*************************************************************************************************************
Quote from: zedd151
Quote from: rrr314159IAT = Interrupt Address Table
IAT == IMPORT Address Table - lol
- I've gotten into the habit of always making some obvious, harmless error in my posts - it's the only way I can get a response.
Quote from: dedndave on September 21, 2015, 07:36:15 AM
in the IAT, the address of ExitProcess is updated when the system loads the EXE
there are different opcodes for CALL
inside a program, it will often be the near relative form - the operand is a signed offset from the next instruction
another form is a near indirect - which is what actually appears in "normal" code for IAT calls
the operand is an address of a pointer to the code
here's a routine i wrote few years ago
it dereferences IAT calls
the tricky part is to find the IAT :lol:
;*************************************************************************************************************
OPTION PROLOGUE:None
OPTION EPILOGUE:None
DeRef PROC lpStart:LPVOID,lpStop:LPVOID,lpExclusions:LPVOID
;Dereference IAT Branches
;DednDave - 7, 2011
;
; Dereferences all branches into the IAT, starting at lpStart, and ending at lpStop.
;If lpStop is NULL, the beginning of the IAT is used as the stop address.
;An exclusion list may be used to exclude specific addresses from conversion.
;Addresses in the list represent the address of the first instruction byte.
;If present, the list must be terminated with a NULL dword.
;No exclusion list is used if the lpExclusions parameter is NULL.
;
; This version allows for the conversion of JMP's, CALL's and conditional branches.
;It will convert declspec JMP's and CALL's, including those into the MSVCRT, etc.
;
; The converted instructions always result in a relative branch directly to the imported code.
;This will prevent hooking into the IAT, which may be overridden by hooking prior to DeRef
;execution or by use of the exclusion list.
;
;----------------------------------------------------
;
;[EBP+28] = lpExclusions
;[EBP+24] = lpStop
;[EBP+20] = lpStart
;[EBP-4] = address of IAT start
;[EBP-8] = address of IAT end
;[EBP-12] = adjusted lpStop (lpStop-4)
;[EBP-16] = original access protection value
;[EBP-20] = dereference count
;
;----------------------------------------------------
push ebx
push esi
push edi
push ebp
push 6
xor edx,edx
pop ebx
mov esi,VirtualProtect
mov ebp,esp
mov eax,25FFh
push esi
jmp short DeRef1
DeRef0: mov edx,esi
sub esi,ebx
DeRef1: cmp ax,[esi]
jz DeRef0
pop esi
or edx,edx
push edx ;[EBP-4] = address of IAT start
jz DeRefL
DeRef2: mov ecx,esi
add esi,ebx
cmp ax,[esi]
jz DeRef2
mov edi,[ebp+24] ;lpStop
add ecx,2
or edi,edi
push ecx ;[EBP-8] = address of IAT end
jnz DeRef3
mov edi,edx
DeRef3: mov edx,edi
mov esi,[ebp+20] ;lpStart
sub edx,4
sub edi,esi
push edx ;[EBP-12] = adjusted lpStop (lpStop-4)
mov [ebp+24],edi ;[EBP+24] is now code stream length
push eax ;[EBP-16] = previous access protection value
INVOKE VirtualProtect,esi,edi,PAGE_EXECUTE_READWRITE,esp
or eax,eax
push 0 ;[EBP-20] = dereference count
jnz DeRefH
jmp DeRefL
DeRef4: xor ecx,ecx
cmp al,0E8h ;CALL relative (to JMP indirect)
mov edx,ecx
jz DeRef5
cmp al,0E9h ;JMP relative (to JMP indirect)
jz DeRef6
inc ecx
cmp ax,15FFh ;CALL indirect (declspec)
mov edx,ecx
jz DeRef6
cmp ax,25FFh ;JMP indirect (declspec)
jz DeRef6
dec edx
cmp al,0Fh ;relative conditional branch candidate
jnz DeRefI
cmp ah,80h ;relative conditional branch candidate
jb DeRefI
cmp ah,8Fh ;relative conditional branch (to JMP indirect)
jbe DeRef6
jmp DeRefI
DeRef5: cmp esi,offset DeRefL-4
jz DeRefI
DeRef6: mov edi,esi
add edi,ecx
cmp edi,[ebp-12] ;adjusted lpStop (lpStop-4)
ja DeRefK
or edx,edx
mov ebx,[edi]
jz DeRef9
push esi
mov esi,[ebp-4] ;address of IAT start
add esi,2
DeRef7: cmp ebx,[esi]
jnz DeRef8
pop esi
jmp short DeRefA
DeRef8: add esi,6
cmp esi,[ebp-8] ;address of IAT end
jbe DeRef7
pop esi
jmp DeRefI
DeRef9: add ebx,edi
add ebx,4
cmp ebx,[ebp-4] ;address of IAT start
jb DeRefI
cmp ebx,[ebp-8] ;address of IAT end
ja DeRefI
push ebx
push eax
push edx
sub ebx,[ebp-4] ;address of IAT start
mov eax,0AAAAAAABh
push ebx
mul ebx
shr edx,2
mov eax,6
mul edx
pop ebx
cmp eax,ebx
pop edx
pop eax
pop ebx
jnz DeRefI
DeRefA: mov ecx,[ebp+28] ;lpExclusions
or ecx,ecx
jz DeRefD
push eax
dec esi
jmp short DeRefC
DeRefB: add ecx,4
cmp eax,esi
jnz DeRefC
inc esi
pop eax
jmp short DeRefI
DeRefC: mov eax,[ecx]
or eax,eax
jnz DeRefB
inc esi
pop eax
DeRefD: or edx,edx
jz DeRefF
cmp ah,15h
mov ebx,[ebx]
mov ax,0E890h
jz DeRefE
inc ah
DeRefE: mov [esi-1],ax
jmp short DeRefG
DeRefF: mov ecx,[ebx+2]
mov ebx,[ecx]
DeRefG: sub ebx,edi
sub ebx,4
mov [edi],ebx
inc dword ptr [ebp-20] ;dereference count
add edi,4
mov esi,edi
DeRefH: mov ax,[esi]
inc esi
jmp short DeRefJ
DeRefI: inc esi
mov al,ah
mov ah,[esi]
DeRefJ: cmp esi,[ebp-12] ;adjusted lpStop (lpStop-4)
jbe DeRef4
DeRefK: lea edx,[ebp-12]
INVOKE VirtualProtect,[ebp+20],[ebp+24],[ebp-16],edx
DeRefL: pop eax ;return dereference count
leave
pop edi
pop esi
pop ebx
ret 12
DeRef ENDP
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
;*************************************************************************************************************
I love you guy that's exactly what i needed to see.
thanks a lot.
here's a little test program
it demonstrates that dereferencing IAT calls can save a few clock cycles :biggrin:
Quote from: dedndave on September 21, 2015, 08:00:34 AM
here's a little test program
it demonstrates that dereferencing IAT calls can save a few clock cycles :biggrin:
thanks again thats nice for learning.
for the sake of completeness: You can also directly work with the pointer to import function, but this requires manual name mangling:
EXITPROCESS typedef proto dwExitCode:DWORD
EXTERNDEF _imp__ExitProcess@4: ptr EXITPROCESS ; is const pointer to ExitProcess (placed in the IAT as part of an JMP-opcode)
...
invoke _imp__ExitProcess@4,0
Quote from: qWord on September 21, 2015, 08:44:30 AM
for the sake of completeness: You can also directly work with the pointer to import function, but this requires manual name mangling:
EXITPROCESS typedef proto dwExitCode:DWORD
EXTERNDEF _imp__ExitProcess@4: ptr EXITPROCESS ; is const pointer to ExitProcess (placed in the IAT as part of an JMP-opcode)
...
invoke _imp__ExitProcess@4,0
thanks for your reply
I was not aware of this, so if it's a const pointer it doesn't need relocation, and would be easier but i don't understand how this could be placed in the IAT, sorry but what do you mean by "as part of an JMP-opcode"?