天天看點

函數位址動态加載api

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
           

繼續閱讀