PE文件格式--------------导出表
一、導出表位置
在數據目錄的的第0項,即IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]項
二、導出表結構
IMAGE_EXPORT_DESCRIPTRO struc
+00h? Characteristics????????? dd
+04h? TimeDateStamp????????dd
+08h? MajorVersion??????????? dw
+0ah? MinorVersion???????????? dw?
+0ch? nName????????????????????? dd????????????????????? ;RVA指向編譯時的模塊名
+10h? nBase?????????????????????? dd????????????????????? ;起始序號
+14h? NumberOfFunctions??? dd????????????????????? ;導出函數總數
+18h? NumberOfNames????????dd????????????????????? ;已名字導出的函數數量
+1ch? AddressOfFunctions??? dd????????????????????? ;RVA指向導出函數地址列表
+20h? AddressOfNames????????dd????????????????????? ;RVA指向函數名稱地址列表,注意該列表項是指向函數名稱的RVA
+24h? AddressOfNameOrdinal? dd??????????????????? ;RVA指向序號列表,列表項為word型,是聯系函數名稱與函數地址的橋梁
IMAGE_EXPORT_DESCRIPTOR ends
三、加載器加載過程
?1、根據名稱查找函數地址
(1)定位導出模塊的IMAGE_EXPORT_DESCRIPTOR
(2)以NumberOfNames為循環次數,循環比較AddressOfNames指向的地址項所對應的函數名字符串,如果沒找到匹配的名稱字符串,則找不到所對應的函數。
(3)如果找到匹配的函數名字符串,則以此為索引號,取出AddressOfNameOrdinal所指向的序號。
(4)取出的序號-nBase=函數地址索引號
(5)以此為索引號,取出AddressOfFunctions指向的函數地址。
2、根據序號查找函數地址
(1)定位導出模塊的IMAGE_EXPORT_DESCRIPTOR
(2)序號-nBase=函數地址索引號
(3)以此為索引號,取出AddressOfFunctions指向的函數地址。
四、示例
?processpefile_export.asm
;======================
;pe文件導出表
;by 紫陌
;======================
;======================
;數據段
;======================
.const
szExportTable????db '導出表IMAGE_EXPORT_DIRECTORY(%08X)', 0dh, 0ah
????????db 'nName????????????????? (%08X):%s', 0dh, 0ah
????????db 'nBase????????????????? (%08X):%08X', 0dh, 0ah
????????db 'NumberOfFunctions????? (%08X):%08X', 0dh, 0ah
????????db 'NumberOfNames????????? (%08X):%08X', 0dh, 0ah
????????db 'AddressOfFunction????? (%08X):%08X', 0dh, 0ah
????????db 'AddressOfNames???????? (%08X):%08X', 0dh, 0ah
????????db 'AddressOfNameOrdinal?? (%08X):%08X', 0dh, 0ah, 0
szTitleAddressOfFunctions??db '=========AddressOfFunctions=========', 0dh, 0ah, 0
szAddressOfFunctions????db '(索引號%04X)(%08X):%08X', 0dh, 0ah, 0
szTitleAddressOfNames???db '=========AddressOfNames=========', 0dh, 0ah, 0
szAddressOfNames?????db '(索引號%04X)(%08X):%08X->%s', 0dh, 0ah, 0
szTitleAddressOfNameOrdinal?db '=========AddressOfNameOrdinal=========', 0dh, 0ah, 0
szAddressOfNameOrdinal???db '(索引號%04X)(%08X):%04X', 0dh, 0ah, 0
;======================
;代碼段
;======================
.code
_ProcessPeFile_Export proc _lpImageBase
?local @szBuf[400h]:BYTE
?local @nName
?local @NumberOfFunctions
?local @NumberOfNames
?local @nIndex
?local @nIndexOfAddress
?
?pushad
?
?mov edi, _lpImageBase
?assume edi:ptr IMAGE_DOS_HEADER
?add edi, [edi].e_lfanew
?assume edi:ptr IMAGE_NT_HEADERS
?mov eax, [edi].OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT * sizeof IMAGE_DATA_DIRECTORY].VirtualAddress
?.if !eax
??jmp _overpos
?.endif
?invoke _RvaToOffset, _lpImageBase, eax
?mov edi, eax
?add edi, _lpImageBase
?assume edi:ptr IMAGE_EXPORT_DIRECTORY
?;************************
?;導出表IMAGE_EXPORT_DIRECTORY
?;************************
?invoke _RvaToOffset, _lpImageBase, [edi].nName
?add eax, _lpImageBase
?mov @nName, eax
?invoke wsprintf, addr @szBuf, addr szExportTable, \
??edi, \
??addr [edi].nName, @nName, \
??addr [edi].nBase, [edi].nBase, \
??addr [edi].NumberOfFunctions, [edi].NumberOfFunctions, \
??addr [edi].NumberOfNames, [edi].NumberOfNames, \
??addr [edi].AddressOfFunctions, [edi].AddressOfFunctions, \
??addr [edi].AddressOfNames, [edi].AddressOfNames, \
??addr [edi].AddressOfNameOrdinals, [edi].AddressOfNameOrdinals
?invoke lstrcpy, addr szShowMsg, addr @szBuf
?invoke SetWindowText, hRichEdit, addr szShowMsg
?;***********************
?;導出函數地址表
?;***********************
?invoke lstrcat, addr szShowMsg, addr szTitleAddressOfFunctions
?mov ecx, [edi].AddressOfFunctions
?invoke _RvaToOffset, _lpImageBase, ecx
?add eax, _lpImageBase
?mov esi, eax
?mov ecx, [edi].NumberOfFunctions
?mov @NumberOfFunctions, ecx
?xor eax, eax
?mov @nIndex, eax
?.while ecx
??mov @NumberOfFunctions, ecx
??invoke wsprintf, addr @szBuf, addr szAddressOfFunctions, \
???@nIndex, \
???esi, \
???DWORD ptr [esi]
??invoke lstrcat, addr szShowMsg, addr @szBuf
??mov ecx, @nIndex
??inc ecx
??mov @nIndex, ecx
??mov ecx, @NumberOfFunctions
??dec ecx
??add esi, 4
?.endw
?invoke SetWindowText, hRichEdit, addr szShowMsg
?;**************************
?;導出函數名稱
?;**************************
?invoke lstrcat, addr szShowMsg, addr szTitleAddressOfNames
?mov ecx, [edi].AddressOfNames
?invoke _RvaToOffset, _lpImageBase, ecx
?add eax, _lpImageBase
?mov esi, eax
?mov ecx, [edi].NumberOfNames
?mov @NumberOfNames, ecx
?xor eax, eax
?mov @nIndex, eax
?.while ecx
??mov @NumberOfNames, ecx
??mov ecx, [esi]
??invoke _RvaToOffset, _lpImageBase, ecx
??add eax, _lpImageBase
??invoke wsprintf, addr @szBuf, addr szAddressOfNames, \
???@nIndex, \
???esi, \
???DWORD ptr [esi], \
???eax
??invoke lstrcat, addr szShowMsg, addr @szBuf
??mov ecx, @nIndex
??inc ecx
??mov @nIndex, ecx
??mov ecx, @NumberOfNames
??dec ecx
??add esi, 4
?.endw
?invoke SetWindowText, hRichEdit, addr szShowMsg
?;**************************
?;導出函數名稱地址索引表
?;**************************
?invoke lstrcat, addr szShowMsg, addr szTitleAddressOfNameOrdinal
?mov ecx, [edi].AddressOfNameOrdinals
?invoke _RvaToOffset, _lpImageBase, ecx
?add eax, _lpImageBase
?mov esi, eax
?mov ecx, [edi].NumberOfNames
?mov @NumberOfNames, ecx
?xor eax, eax
?mov @nIndex, eax
?.while ecx
??mov @NumberOfNames, ecx
??movzx ecx, WORD ptr [esi]
??mov @nIndexOfAddress, ecx
??invoke wsprintf, addr @szBuf, addr szAddressOfNameOrdinal, \
???@nIndex, \
???esi, \
???@nIndexOfAddress
??invoke lstrcat, addr szShowMsg, addr @szBuf
??mov ecx, @nIndex
??inc ecx
??mov @nIndex, ecx
??mov ecx, @NumberOfNames
??dec ecx
??add esi, 4
?.endw
?invoke SetWindowText, hRichEdit, addr szShowMsg
_overpos:?
?assume edi:nothing
?popad
?ret
_ProcessPeFile_Export endp
?
轉載于:https://www.cnblogs.com/guanlaiy/archive/2012/05/03/2479985.html
總結
以上是生活随笔為你收集整理的PE文件格式--------------导出表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 广宁省安兴社豆河工业区晶科工程邮政编码是
- 下一篇: css样式命名规则(仅供参考)