Hello people, well I want do a question about of why this happens.
I have this code of example:
.386
.model flat,stdcall
include kernel32.inc
includelib kernel32.lib
.data
.code
main proc
invoke Beep,100,100
mov edx,eax
main endp
end main
the disassembly:
00401001 > $ 6A 64 PUSH 64 ; /Duration = 100. ms
00401003 . 6A 64 PUSH 64 ; |Frequency = 64 (100.)
00401005 . E8 02000000 CALL <JMP.&kernel32.Beep> ; \Beep
0040100A . 8BD0 MOV EDX,EAX
0040100C $-FF25 00204000 JMP DWORD PTR DS:[<&kernel32.Beep>] ; kernel32.Beep
my question is why in the instruction:
00401005 . E8 02000000 CALL <JMP.&kernel32.Beep> ; \Beep
why jump to a address of the code? and not directly to the API. not understand
thanks :)
when the OS loads a PE EXE, it resolves all the API addresses
rather than vectoring each one, individually, it vectors each API used only once in the IAT...
http://www.masm32.com/board/index.php?topic=18420.msg155989#msg155989
thanks dedndave! then jump to the IAT?
if so it, why does not jump to the code of the IAT :S
well - when you call an API function, it executes a CALL to a JMP [address], which is the actual API code :P
let's say you use WriteFile in 30 places throughout your program
when the OS loads your EXE, it would have to find all those "relocatable" addresses and fill them in
instead, they use the IAT - they set one address in the IAT and all your calls are directed to that address
a while back, i wrote a routine that dereferences IAT branches...
DeRef.inc
;Dereference IAT Branches - include file
;DednDave - 7, 2011
;***********************************************************************************************
DeRef PROTO :DWORD,:DWORD,:DWORD
;***********************************************************************************************
.CODE
OPTION PROLOGUE:None
OPTION EPILOGUE:None
DeRef PROC lpStart:DWORD,lpStop:DWORD,lpExclusions:DWORD
;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
;***********************************************************************************************
;end of include file
wow thanks you very much dedndave dude :clap: