?? pe-tut6.html
字號:
<td nowrap> </td>
</tr>
<tr>
<td nowrap> </td>
</tr>
<tr>
<td nowrap> </td>
</tr>
<tr>
<td nowrap> </td>
</tr>
</table>
</td>
<td>
<table border="1" cellspacing="2" cellpadding="2" align="center">
<tr bgcolor="#666600">
<td>
<div align="center"><font face="MS Sans Serif" size="-1">Address of
Function 1</font></div>
</td>
</tr>
<tr bgcolor="#666600">
<td>
<div align="center"><font face="MS Sans Serif" size="-1">Address of
Function 2</font></div>
</td>
</tr>
<tr bgcolor="#666600">
<td>
<div align="center"><font face="MS Sans Serif" size="-1">Address of
Function 3</font></div>
</td>
</tr>
<tr bgcolor="#666600">
<td>
<div align="center"><font face="MS Sans Serif" size="-1">Address of
Function 4</font></div>
</td>
</tr>
<tr bgcolor="#666600">
<td>
<div align="center"><font face="MS Sans Serif" size="-1">...</font></div>
</td>
</tr>
<tr bgcolor="#666600">
<td>
<div align="center"><font face="MS Sans Serif" size="-1">Address of
Function n </font></div>
</td>
</tr>
</table>
</td>
</tr>
</table>
<p><font face="MS Sans Serif" size="-1">The array of RVAs pointed to by <font color="#FFFFCC"><b>OriginalFirstThunk</b></font>
remains unchanged so that if the need arises to find the names of import functions,
the PE loader can still find them.<br>
There is a little twist on this *straightforward* scheme. Some functions are
exported by ordinal only. It means you don't call the functions by their names:
you call them by their positions. In this case, there will be no <font color="#CCFFCC"><b>IMAGE_IMPORT_BY_NAME</b></font>
structure for that function in the caller's module. Instead, the <font color="#CCFFCC"><b>IMAGE_THUNK_DATA</b></font>
for that function will contain the ordinal of the function in the low word and
the most significant bit (MSB) of <font color="#CCFFCC"><b>IMAGE_THUNK_DATA</b></font>
set to 1. For example, if a function is exported by ordinal only and its ordinal
is 1234h, the <font color="#CCFFCC"><b>IMAGE_THUNK_DATA</b></font> for that
function will be 80001234h. Microsoft provides a handy constant for testing
the MSB of a dword, <font color="#CCFFCC"><b>IMAGE_ORDINAL_FLAG32</b></font>.
It has the value of 80000000h.<br>
Suppose that we want to list the names of ALL import functions of a PE file,
we need to follow the steps below:</font></p>
<ol>
<li><font face="MS Sans Serif" size="-1">Verify that the file is a valid PE</font></li>
<li><font face="MS Sans Serif" size="-1">From the DOS header, go to the PE header</font></li>
<li><font face="MS Sans Serif" size="-1">Obtain the address of the data directory
in <font color="#FFFFCC"><b>OptionalHeader</b></font></font></li>
<li><font face="MS Sans Serif" size="-1">Go to the 2nd member of the data directory.
Extract the value of <font color="#FFFFCC"><b>VirtualAddress</b></font></font></li>
<li><font face="MS Sans Serif" size="-1">Use that value to go to the first <font color="#FFFFCC"><b><font color="#CCFFCC">IMAGE_IMPORT_DESCRIPTOR</font></b></font>
structure</font></li>
<li><font face="MS Sans Serif" size="-1">Check the value of <font color="#FFFFCC"><b>OriginalFirstThunk</b></font>.
If it's not zero, follow the RVA in <font color="#FFFFCC"><b>OriginalFirstThunk</b></font>
to the RVA array. If <font color="#FFFFCC"><b>OriginalFirstThunk</b></font>
is zero, use the value in <font color="#FFFFCC"><b>FirstThunk</b></font> instead.
Some linkers generate PE files with 0 in <font color="#FFFFCC"><b>OriginalFirstThunk</b></font>.
This is considered a bug. Just to be on the safe side, we check the value
in <font color="#FFFFCC"><b>OriginalFirstThunk</b></font> first.</font></li>
<li><font face="MS Sans Serif" size="-1">For each member in the array, we check
the value of the member against <font color="#CCFFCC"><b>IMAGE_ORDINAL_FLAG32</b></font>.
If the most significant bit of the member is 1, then the function is exported
by ordinal and we can extract the ordinal number from the low word of the
member.</font></li>
<li><font face="MS Sans Serif" size="-1">If the most significant bit of the
member is 0, use the value in the member as the RVA into the <font color="#CCFFCC"><b>IMAGE_IMPORT_BY_NAME</b></font>,
skip <font color="#FFFFCC"> <b>Hint</b></font>, and you're at the name of
the function. </font></li>
<li><font face="MS Sans Serif" size="-1">Skip to the next array member, and
retrieve the names until the end of the array is reached (it's null -terminated).
Now we are done extracting the names of the functions imported from a DLL.
We go to the next DLL.</font></li>
<li><font face="MS Sans Serif" size="-1">Skip to the next <font color="#CCFFCC"><b>IMAGE_IMPORT_DESCRIPTOR</b></font>
and process it. Do that until the end of the array is reached (<font color="#CCFFCC"><b>IMAGE_IMPORT_DESCRIPTOR</b></font>
array is terminated by a member with all zeroes in its fields).</font></li>
</ol>
<h3><font face="Arial, Helvetica, sans-serif">Example:</font></h3>
<p><font face="MS Sans Serif" size="-1">This example opens a PE file and reads
the names of all import functions of that file into an edit control. It also
shows the values in the <font color="#CCFFCC"><b>IMAGE_IMPORT_DESCRIPTOR</b></font>
structures.</font></p>
<p><font face="Fixedsys">.386 <br>
.model flat,stdcall <br>
option casemap:none <br>
include \masm32\include\windows.inc <br>
include \masm32\include\kernel32.inc <br>
include \masm32\include\comdlg32.inc <br>
include \masm32\include\user32.inc <br>
includelib \masm32\lib\user32.lib <br>
includelib \masm32\lib\kernel32.lib <br>
includelib \masm32\lib\comdlg32.lib <br>
<br>
IDD_MAINDLG equ 101 <br>
IDC_EDIT equ 1000 <br>
IDM_OPEN equ 40001 <br>
IDM_EXIT equ 40003 <br>
<br>
DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD <br>
ShowImportFunctions proto :DWORD <br>
ShowTheFunctions proto :DWORD,:DWORD <br>
AppendText proto :DWORD,:DWORD <br>
<br>
SEH struct <br>
PrevLink dd ? ; the address of the previous seh structure <br>
CurrentHandler dd ? ; the address of the new exception handler <br>
SafeOffset dd ? ; The offset where it's safe to continue execution <br>
PrevEsp dd ? ; the old value in esp <br>
PrevEbp dd ? ; The old value in ebp <br>
SEH ends <br>
<br>
.data <br>
AppName db "PE tutorial no.6",0 <br>
ofn OPENFILENAME <> <br>
FilterString db "Executable Files (*.exe, *.dll)",0,"*.exe;*.dll",0 <br>
db
"All Files",0,"*.*",0,0 <br>
FileOpenError db "Cannot open the file for reading",0 <br>
FileOpenMappingError db "Cannot open the file for memory mapping",0 <br>
FileMappingError db "Cannot map the file into memory",0 <br>
NotValidPE db "This file is not a valid PE",0 <br>
CRLF db 0Dh,0Ah,0 <br>
ImportDescriptor db 0Dh,0Ah,"================[ IMAGE_IMPORT_DESCRIPTOR ]=============",0
<br>
IDTemplate db "OriginalFirstThunk = %lX",0Dh,0Ah <br>
db "TimeDateStamp
= %lX",0Dh,0Ah <br>
db "ForwarderChain
= %lX",0Dh,0Ah <br>
db "Name = %s",0Dh,0Ah
<br>
db "FirstThunk
= %lX",0 <br>
NameHeader db 0Dh,0Ah,"Hint Function",0Dh,0Ah <br>
db "-----------------------------------------",0
<br>
NameTemplate db "%u %s",0 <br>
OrdinalTemplate db "%u (ord.)",0 <br>
<br>
.data? <br>
buffer db 512 dup(?) <br>
hFile dd ? <br>
hMapping dd ? <br>
pMapping dd ? <br>
ValidPE dd ? <br>
<br>
.code <br>
start: <br>
invoke GetModuleHandle,NULL <br>
invoke DialogBoxParam, eax, IDD_MAINDLG,NULL,addr DlgProc, 0 <br>
invoke ExitProcess, 0 <br>
<br>
DlgProc proc hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD <br>
.if uMsg==WM_INITDIALOG <br>
invoke SendDlgItemMessage,hDlg,IDC_EDIT,EM_SETLIMITTEXT,0,0 <br>
.elseif uMsg==WM_CLOSE <br>
invoke EndDialog,hDlg,0 <br>
.elseif uMsg==WM_COMMAND <br>
.if lParam==0 <br>
mov eax,wParam <br>
.if ax==IDM_OPEN <br>
invoke ShowImportFunctions,hDlg <br>
.else ; IDM_EXIT <br>
invoke SendMessage,hDlg,WM_CLOSE,0,0 <br>
.endif <br>
.endif <br>
.else <br>
mov eax,FALSE <br>
ret <br>
.endif <br>
mov eax,TRUE <br>
ret <br>
DlgProc endp <br>
<br>
SEHHandler proc uses edx pExcept:DWORD, pFrame:DWORD, pContext:DWORD, pDispatch:DWORD
<br>
mov edx,pFrame <br>
assume edx:ptr SEH <br>
mov eax,pContext <br>
assume eax:ptr CONTEXT <br>
push [edx].SafeOffset <br>
pop [eax].regEip <br>
push [edx].PrevEsp <br>
pop [eax].regEsp <br>
push [edx].PrevEbp <br>
pop [eax].regEbp <br>
mov ValidPE, FALSE <br>
mov eax,ExceptionContinueExecution <br>
ret <br>
SEHHandler endp <br>
<br>
ShowImportFunctions proc uses edi hDlg:DWORD <br>
LOCAL seh:SEH <br>
mov ofn.lStructSize,SIZEOF <br>
ofn mov ofn.lpstrFilter, OFFSET FilterString <br>
mov ofn.lpstrFile, OFFSET buffer <br>
mov ofn.nMaxFile,512 <br>
mov ofn.Flags, OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_LONGNAMES
or OFN_EXPLORER or OFN_HIDEREADONLY <br>
invoke GetOpenFileName, ADDR ofn <br>
.if eax==TRUE <br>
invoke CreateFile, addr buffer, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL <br>
.if eax!=INVALID_HANDLE_VALUE <br>
mov hFile, eax <br>
invoke CreateFileMapping, hFile, NULL, PAGE_READONLY,0,0,0
<br>
.if eax!=NULL <br>
mov hMapping, eax <br>
invoke MapViewOfFile,hMapping,FILE_MAP_READ,0,0,0
<br>
.if eax!=NULL <br>
mov pMapping,eax <br>
assume fs:nothing <br>
push fs:[0] <br>
pop seh.PrevLink <br>
mov seh.CurrentHandler,offset
SEHHandler <br>
mov seh.SafeOffset,offset
FinalExit <br>
lea eax,seh <br>
mov fs:[0], eax <br>
mov seh.PrevEsp,esp <br>
mov seh.PrevEbp,ebp <br>
mov edi, pMapping <br>
assume edi:ptr IMAGE_DOS_HEADER
<br>
.if [edi].e_magic==IMAGE_DOS_SIGNATURE
<br>
add edi,
[edi].e_lfanew <br>
assume edi:ptr
IMAGE_NT_HEADERS <br>
.if [edi].Signature==IMAGE_NT_SIGNATURE
<br>
mov
ValidPE, TRUE <br>
.else
<br>
mov ValidPE, FALSE <br>
.endif <br>
.else <br>
mov ValidPE,FALSE
<br>
.endif <br>
FinalExit: <br>
push seh.PrevLink <br>
pop fs:[0] <br>
.if ValidPE==TRUE <br>
invoke ShowTheFunctions,
hDlg, edi <br>
.else <br>
invoke MessageBox,0,
addr NotValidPE, addr AppName, MB_OK+MB_ICONERROR <br>
.endif <br>
invoke UnmapViewOfFile,
pMapping <br>
.else <br>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -