C版本:GetProcAddress 實作
asm:
.386
.model flat, stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include msvcrt.inc
includelib msvcrt.lib
.code
seh_handler proc C pExceptionRecord, pSehStack, pContext, DispatcherContext
pushad
assume esi:ptr CONTEXT
mov esi,pContext
mov edx,pSehStack
push [edx+8]
pop [esi].regEip
push [edx+0ch]
pop [esi].regEbp
push edx
pop [esi].regEsp
assume esi:nothing
popad
mov eax,ExceptionContinueExecution
ret
seh_handler endp
isPe proc mem:dword
local ok:dword
pushad
mov ok,0
mov esi,mem
.if esi == 0
jmp done
.endif
assume esi:ptr IMAGE_DOS_HEADER
.if [esi].e_magic != IMAGE_DOS_SIGNATURE
jmp done
.endif
add esi,[esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS
.if [esi].Signature != IMAGE_NT_SIGNATURE
jmp done
.endif
mov ok,1
done:
popad
mov eax,ok
ret
isPe endp
search_api proc module_addr:dword , api_name_addr:dword
local api_addr:dword
local str_len:dword
local export_dir_addr : dword
local loop_times:dword
pushad
mov api_addr ,0
; 重定位
call @F
@@:
pop ebx
sub ebx,offset @B
; 建構異常
assume fs:nothing
push ebp
lea eax,[ebx + offset done]
push eax
lea eax,[ebx + offset seh_handler]
push eax
push fs:[0]
mov fs:[0],esp
;檢查合法pe
invoke isPe,module_addr
.if eax == 0
jmp done
.endif
;計算字元串長度
mov ecx,-1
mov edi,api_name_addr
xor al,al
cld
repne scasb
mov ecx,edi
sub ecx,api_name_addr
mov str_len,ecx
;讀取導出表
assume esi:ptr IMAGE_DOS_HEADER
mov esi, module_addr
add esi,[esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS
mov esi,[esi].OptionalHeader.DataDirectory[0].VirtualAddress
add esi,module_addr
mov export_dir_addr,esi
assume esi : ptr IMAGE_EXPORT_DIRECTORY
mov edx,[esi].AddressOfNames
add edx,module_addr
mov ebx,[esi].NumberOfNames
mov loop_times,ebx
xor ebx,ebx
assume esi:nothing
;根據名字搜尋比對
.while ebx < loop_times
mov ecx,str_len
mov edi,[edx]
add edi,module_addr
mov esi,api_name_addr
cld
repe cmpsb
je found
add edx,4
inc ebx
.endw
jmp done
;找到了, AddressOfNameOrdinals 是一個word類型的位址
found:
assume esi:ptr IMAGE_EXPORT_DIRECTORY
mov esi,export_dir_addr
mov edi , [esi].AddressOfNameOrdinals
add edi,module_addr
xor edx,edx
mov dx,[edi+ 2 * ebx]
mov edi,[esi].AddressOfFunctions
add edi,module_addr
mov eax,[edi+4*edx]
add eax,module_addr
mov api_addr,eax
done:
assume esi:nothing
pop fs:[0]
add esp,0ch
popad
mov eax,api_addr
ret
search_api endp