1. 导入表

PE文件之导入表-LMLPHP

2. 显示导入表信息的例子

; 作用: 将RVA地址转成FOA即文件偏移
; 参数: _pFileHdr 	指向读到内存中文件的基址指针
;       _dwRVA 		目标RVA地址
; 返回: 目标RVA转成文件偏移的值
RVA2FOA PROC USES esi edi edx, _pFileHdr:PTR BYTE, _dwRVA:DWORD
	
	mov esi, _pFileHdr 
	assume esi:ptr IMAGE_DOS_HEADER
	; 获取PE头
	mov edi, [esi].e_lfanew
	assume esi:nothing
	add edi, esi 
	assume edi:ptr IMAGE_NT_HEADERS32
	; 获取节数
	movzx ecx, [edi].FileHeader.NumberOfSections
	assume edi:nothing
	; 获取节表地址
	add edi, SIZEOF IMAGE_NT_HEADERS32
	assume edi:ptr IMAGE_SECTION_HEADER
L0:
	mov edx, _dwRVA
	cmp edx, [edi].VirtualAddress
	jb @F

	mov eax, [edi].VirtualAddress
	add eax, [edi].SizeOfRawData
	cmp edx, eax
	jae @F

	sub edx, [edi].VirtualAddress
	add edx, [edi].PointerToRawData
	mov eax, edx
	jmp Ending
@@:
	add edi, SIZEOF IMAGE_SECTION_HEADER
	loop L0
	xor eax, eax
Ending:
	ret

RVA2FOA ENDP

.data 
Crlf 				BYTE 0dh, 0ah, 0
szDllName 			BYTE "导出表: %s", 0dh, 0ah, 0
szSep				BYTE "---------------------------", 0dh, 0ah, 0
szINTRVA			BYTE "OriginalFirstThunk: 0x%08X", 0dh, 0ah, 0
szTimeStmp  		BYTE "TimeDateStamp: 0x%08X", 0dh, 0ah, 0
szForwarderChain	BYTE "ForwarderChain: 0x%08X", 0dh, 0ah, 0
szNameRVA			BYTE "Name: 0x%08X", 0dh, 0ah, 0
szFirstThunk		BYTE "FirstThunk: 0x%08X", 0dh, 0ah, 0dh, 0ah, 0
szFnInfo			BYTE "%hd %s", 0dh, 0ah, 0

szBuf				BYTE 64 DUP(0)

.code 
; 作用: 打印输出导入表信息
; 参数: _pFileHdr 	指向读到内存中文件的基址指针
; 返回: 无
_getImportTblInfo PROC _pFileHdr:PTR BYTE
	pushad 
	mov esi, _pFileHdr
	assume esi:PTR IMAGE_DOS_HEADER
	add esi, [esi].e_lfanew 
	assume esi:PTR IMAGE_NT_HEADERS32 
	mov esi, [esi].OptionalHeader.DataDirectory[8].VirtualAddress
	push esi
	mov eax, _pFileHdr
	push eax 
	call RVA2FOA

	mov esi, eax 
	add esi, _pFileHdr 
	assume esi:PTR IMAGE_IMPORT_DESCRIPTOR 

L0:
	; 确定导入表是否结束
	mov edx, [esi].Name1
	test edx, edx 
	jnz @F 
	jmp Ending 
@@:
	mov edx, [esi].OriginalFirstThunk
	test edx, edx 
	jnz @F 
	jmp Ending 
@@:
	mov edx, [esi].TimeDateStamp
	test edx, edx 
	jnz @F 
	jmp Ending 
@@:
	mov edx, [esi].ForwarderChain
	test edx, edx 
	jnz @F 
	jmp Ending 
@@:
	mov edx, [esi].FirstThunk
	test edx, edx 
	jnz @F 
	jmp Ending 
@@:
	; 进行IAT显示
	mov edx, [esi].Name1 
	push edx 
	push _pFileHdr 
	call RVA2FOA 
	add eax, _pFileHdr
	; 显示dll名称
	invoke wsprintf, OFFSET szBuf, OFFSET szDllName, eax 
	invoke crt_printf, OFFSET szBuf 
	invoke crt_printf, OFFSET szSep
	; 显示OriginalFirstThunk的RVA地址
	invoke wsprintf, OFFSET szBuf, OFFSET szINTRVA, [esi].OriginalFirstThunk 
	invoke crt_printf, OFFSET szBuf
	; 显示时间戳
	invoke wsprintf, OFFSET szBuf, OFFSET szTimeStmp, [esi].TimeDateStamp 
	invoke crt_printf, OFFSET szBuf
	; 显示ForwarderChain
	invoke wsprintf, OFFSET szBuf, OFFSET szForwarderChain, [esi].ForwarderChain 
	invoke crt_printf, OFFSET szBuf
	; 显示Name的RVA地址
	invoke wsprintf, OFFSET szBuf, OFFSET szNameRVA, [esi].Name1 
	invoke crt_printf, OFFSET szBuf
	; 显示FirstThunk的RVA地址
	invoke wsprintf, OFFSET szBuf, OFFSET szFirstThunk, [esi].FirstThunk 
	invoke crt_printf, OFFSET szBuf
	; 打印具体函数信息
	; 获取INT的RVA地址, 把VA转成FOA
	push [esi].OriginalFirstThunk
	push _pFileHdr 
	call RVA2FOA
	add eax, _pFileHdr
L1:
	assume eax:PTR IMAGE_THUNK_DATA 
	mov ebx, [eax].u1.Function
	test ebx, ebx 
	jz NextDesc
	push eax 
	mov eax, [eax].u1.Function
	test eax, 80000000h
	jnz BySeq
	push eax 
	push _pFileHdr
	call RVA2FOA
	add eax, _pFileHdr
	assume eax:PTR IMAGE_IMPORT_BY_NAME 
	movzx edx, WORD PTR [eax].Hint
	lea ebx, [eax].Name1 
	invoke wsprintf, OFFSET szBuf, OFFSET szFnInfo, edx, ebx
	invoke crt_printf, OFFSET szBuf
	pop eax 
	add eax, SIZEOF IMAGE_THUNK_DATA
	jmp @F 
BySeq:
	
@@:
	jmp L1 
NextDesc:
	push OFFSET Crlf
	call crt_printf
	push OFFSET Crlf
	call crt_printf
	add esi, SIZEOF IMAGE_IMPORT_DESCRIPTOR
	jmp L0
Ending:
	popad 
	ret 

_getImportTblInfo ENDP 

运行的部分截图:
PE文件之导入表-LMLPHP

3. 导入表图

PE文件之导入表-LMLPHP
(完)

10-03 20:02