News:

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

Main Menu

Little Question About Syntax

Started by Ener, September 21, 2015, 06:06:14 AM

Previous topic - Next topic

Ener

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

zedd151

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

zedd151

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


Ener

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.

zedd151

I still don't understand exactly what you are trying to do.
Can you post some of your code?


edit = typo

Ener

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!

zedd151

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.

Ener

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

rrr314159

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
I am NaN ;)

zedd151

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.

dedndave

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

;*************************************************************************************************************

rrr314159

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.
I am NaN ;)

Ener

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.

dedndave

here's a little test program
it demonstrates that dereferencing IAT calls can save a few clock cycles   :biggrin:

Ener

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.