1. 导入表
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
运行的部分截图:
3. 导入表图
(完)