?? lion-petut-c07.htm
字號:
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>
invoke
MessageBox, 0, addr FileMappingError, addr AppName,
MB_OK+MB_ICONERROR <br>
.endif <br>
invoke CloseHandle,hMapping <br>
.else <br>
invoke MessageBox, 0, addr
FileOpenMappingError, addr AppName, MB_OK+MB_ICONERROR <br>
.endif <br>
invoke CloseHandle, hFile <br>
.else <br>
invoke MessageBox, 0, addr
FileOpenError, addr AppName, MB_OK+MB_ICONERROR <br>
.endif <br>
.endif <br>
ret <br>
ShowExportFunctions endp <br>
<br>
AppendText proc hDlg:DWORD,pText:DWORD <br>
invoke SendDlgItemMessage,hDlg,IDC_EDIT,EM_REPLACESEL,0,pText <br>
invoke SendDlgItemMessage,hDlg,IDC_EDIT,EM_REPLACESEL,0,addr CRLF
<br>
invoke SendDlgItemMessage,hDlg,IDC_EDIT,EM_SETSEL,-1,0 <br>
ret <br>
AppendText endp <br>
<br>
RVAToFileMap PROC uses edi esi edx ecx pFileMap:DWORD,RVA:DWORD <br>
mov esi,pFileMap <br>
assume esi:ptr IMAGE_DOS_HEADER <br>
add esi,[esi].e_lfanew <br>
assume esi:ptr IMAGE_NT_HEADERS <br>
mov edi,RVA ; edi == RVA <br>
mov edx,esi <br>
add edx,sizeof IMAGE_NT_HEADERS <br>
mov cx,[esi].FileHeader.NumberOfSections <br>
movzx ecx,cx <br>
assume edx:ptr IMAGE_SECTION_HEADER <br>
.while ecx>0<br>
.if edi>=[edx].VirtualAddress <br>
mov eax,[edx].VirtualAddress <br>
add eax,[edx].SizeOfRawData <br>
.if edi<eax ; The address is in this section mov eax,[edx].VirtualAddress sub edi,eax edi="=" difference between specified RVA and's eax,[edx].PointerToRawData add eax,edi eax="=" file offset eax,pFileMap ret .endif edx,sizeof IMAGE_SECTION_HEADER dec ecx .endw assume edx:nothing esi:nothing RVAToFileMap endp ShowTheFunctions proc uses esi ebx hDlg:DWORD, pNTHdr:DWORD LOCAL temp[512]:BYTE NumberOfNames:DWORD Base:DWORD AddressOfFunctions:DWORD AddressOfNameOrdinals:DWORD edi,pNTHdr edi:ptr IMAGE_NT_HEADERS edi, [edi].OptionalHeader.DataDirectory.VirtualAddress .if invoke MessageBox,0, addr NoExportTable,addr AppName,MB_OK+MB_ICONERROR SetDlgItemText,hDlg,IDC_EDIT,0 AppendText,hDlg,addr buffer RVAToFileMap,pMapping,edi IMAGE_EXPORT_DIRECTORY eax,[edi].NumberOfFunctions RVAToFileMap, pMapping,[edi].nName wsprintf, temp,addr ExportTable,eax,[edi].nBase,[edi].NumberOfFunctions,[edi].NumberOfNames,[edi].AddressOfFunctions,[edi].AddressOfNames,[edi].AddressOfNameOrdinals temp push [edi].NumberOfNames pop NumberOfNames [edi].nBase Base [edi].AddressOfFunctions AddressOfFunctions RVAToFileMap,pMapping,AddressOfFunctions AddressOfFunctions,eax esi,[edi].AddressOfNames RVAToFileMap,pMapping,esi esi,eax ebx,[edi].AddressOfNameOrdinals RVAToFileMap,pMapping,ebx ebx,eax AddressOfNameOrdinals,ebx Header edi,AddressOfFunctions .while><eax<br>
mov eax,[edx].VirtualAddress
<br>
sub edi,eax<br>
mov
eax,[edx].PointerToRawData <br>
add eax,edi<br>
add eax,pFileMap <br>
ret <br>
.endif <br>
.endif <br>
add edx,sizeof IMAGE_SECTION_HEADER <br>
dec ecx <br>
.endw <br>
assume edx:nothing <br>
assume esi:nothing <br>
mov eax,edi <br>
ret <br>
RVAToFileMap endp <br>
<br>
ShowTheFunctions proc uses esi ecx ebx hDlg:DWORD, pNTHdr:DWORD <br>
LOCAL temp[512]:BYTE <br>
LOCAL NumberOfNames:DWORD <br>
LOCAL Base:DWORD <br>
<br>
mov edi,pNTHdr <br>
assume edi:ptr IMAGE_NT_HEADERS <br>
mov edi, [edi].OptionalHeader.DataDirectory.VirtualAddress <br>
.if edi==0 <br>
invoke MessageBox,0, addr NoExportTable,addr
AppName,MB_OK+MB_ICONERROR <br>
ret <br>
.endif <br>
invoke SetDlgItemText,hDlg,IDC_EDIT,0 <br>
invoke AppendText,hDlg,addr buffer <br>
invoke RVAToFileMap,pMapping,edi <br>
mov edi,eax <br>
assume edi:ptr IMAGE_EXPORT_DIRECTORY <br>
mov eax,[edi].NumberOfFunctions <br>
invoke RVAToFileMap, pMapping,[edi].nName <br>
invoke wsprintf, addr temp,addr ExportTable, eax, [edi].nBase,
[edi].NumberOfFunctions, [edi].NumberOfNames,
[edi].AddressOfFunctions, [edi].AddressOfNames,
[edi].AddressOfNameOrdinals <br>
invoke AppendText,hDlg,addr temp<br>
invoke AppendText,hDlg,addr Header <br>
push [edi].NumberOfNames<br>
pop NumberOfNames<br>
push [edi].nBase <br>
pop Base <br>
invoke RVAToFileMap,pMapping,[edi].AddressOfNames <br>
mov esi,eax <br>
invoke RVAToFileMap,pMapping,[edi].AddressOfNameOrdinals <br>
mov ebx,eax <br>
invoke RVAToFileMap,pMapping,[edi].AddressOfFunctions <br>
mov edi,eax<br>
.while NumberOfNames>0 <br>
invoke RVAToFileMap,pMapping,dword ptr [esi] <br>
mov dx,[ebx] <br>
movzx edx,dx <br>
mov ecx,edx <br>
shl edx,2 <br>
add edx,edi <br>
add ecx,Base <br>
invoke wsprintf, addr temp,addr template,dword ptr
[edx],ecx,eax <br>
invoke AppendText,hDlg,addr temp <br>
dec NumberOfNames <br>
add esi,4 <br>
add ebx,2 <br>
.endw <br>
ret <br>
ShowTheFunctions endp <br>
end start </font></p>
<h3>分析<font face="Arial, Helvetica, sans-serif">:</font></h3>
<p><font face="Fixedsys">mov edi,pNTHdr <br>
assume edi:ptr IMAGE_NT_HEADERS <br>
mov edi, [edi].OptionalHeader.DataDirectory.VirtualAddress <br>
.if edi==0 <br>
invoke MessageBox,0, addr NoExportTable,addr
AppName,MB_OK+MB_ICONERROR <br>
ret <br>
.endif </font></p>
<p><font size="2" face="MS Sans Serif">程序檢驗PE有效性后,定位到數據目錄獲取引出表的虛擬地址。若該虛擬地址為0,則文件不含引出符號。</font></p>
<p><font face="Fixedsys">mov eax,[edi].NumberOfFunctions <br>
invoke RVAToFileMap, pMapping,[edi].nName <br>
invoke wsprintf, addr temp,addr ExportTable, eax, [edi].nBase,
[edi].NumberOfFunctions, [edi].NumberOfNames,
[edi].AddressOfFunctions, [edi].AddressOfNames,
[edi].AddressOfNameOrdinals <br>
invoke AppendText,hDlg,addr temp </font></p>
<p><font size="2" face="MS Sans Serif">在編輯控件中顯示</font><font color="#CCFFCC" size="2"
face="MS Sans Serif"><b>IMAGE_EXPORT_DIRECTORY</b></font><font
size="2" face="MS Sans Serif"> 結構的一些重要信息。</font></p>
<p><font face="Fixedsys">push [edi].NumberOfNames <br>
pop NumberOfNames <br>
push [edi].nBase <br>
pop Base </font></p>
<p><font size="2" face="MS Sans Serif">由于我們要枚舉所有函數名,就要知道引出表里的名字數目。</font><font color="#FFFFCC" size="2"
face="MS Sans Serif"><b>nBase</b></font><font size="2"
face="MS Sans Serif"> 在將</font><font color="#FFFFCC" size="2"
face="MS Sans Serif"><b>AddressOfFunctions</b></font><font
size="2" face="MS Sans Serif"> 數組索引轉換成序數時派到用場。</font></p>
<p><font face="Fixedsys">invoke
RVAToFileMap,pMapping,[edi].AddressOfNames <br>
mov esi,eax <br>
invoke RVAToFileMap,pMapping,[edi].AddressOfNameOrdinals <br>
mov ebx,eax <br>
invoke RVAToFileMap,pMapping,[edi].AddressOfFunctions <br>
mov edi,eax</font></p>
<p><font size="2" face="MS Sans Serif">將三個數組的地址相應存放到esi,,ebx,edi中。準備開始訪問。</font></p>
<p><font face="Fixedsys">.while NumberOfNames>0 </font></p>
<p><font size="2" face="MS Sans Serif">直到所有名字都被處理完畢。</font></p>
<p><font face="Fixedsys"> invoke
RVAToFileMap,pMapping,dword ptr [esi] </font></p>
<p><font size="2" face="MS Sans Serif">由于esi指向包含名字字符串RVAs的數組,所以[esi]含有當前名字的RVA,需要將它轉換成虛擬地址,后面wsprintf要用的。</font></p>
<p><font face="Fixedsys"> mov dx,[ebx] <br>
movzx edx,dx <br>
mov ecx,edx<br>
add ecx,Base <br>
</font></p>
<p><font size="2" face="MS Sans Serif">ebx指向序數數組,值是字類型的。因此我們先要將其轉換成雙字,此時edx和ecx含有指向</font><font color="#FFFFCC" size="2"
face="MS Sans Serif"><b>AddressOfFunctions</b></font><font
size="2" face="MS Sans Serif"> 數組的索引。我們用edx作為索引值,而將ecx加上nBase得到函數的序數值。=</font><font
size="2" face="MS Sans Serif"></font></p>
<p><font face="Fixedsys"> shl edx,2 <br>
add edx,edi </font></p>
<p><font size="2" face="MS Sans Serif">索引乘以4 (</font><font color="#FFFFCC" size="2"
face="MS Sans Serif"><b>AddressOfFunctions</b></font><font
size="2" face="MS Sans Serif"> 數組中每個元素都是4字節大小) 然后加上數組首地址,這樣</font><font
size="2" face="MS Sans Serif">edx指向的就是所要函數的RVA了。</font></p>
<p><font face="Fixedsys"> invoke wsprintf, addr
temp,addr template,dword ptr [edx],ecx,eax <br>
invoke AppendText,hDlg,addr temp </font></p>
<p><font size="2" face="MS Sans Serif">在編輯控件中顯示函數的RVA, 序數, 和名字。</font></p>
<p><font face="Fixedsys"> dec NumberOfNames <br>
add esi,4 <br>
add ebx,2 <br>
.endw </font></p>
<p><font size="2" face="MS Sans Serif">修正計數器,</font><font color="#FFFFCC"
size="2" face="MS Sans Serif"><b>AddressOfNames</b></font><font
size="2" face="MS Sans Serif"> 和 </font><font color="#FFFFCC"
size="2" face="MS Sans Serif"><b>AddressOfNameOrdinals</b></font><font
size="2" face="MS Sans Serif"> 兩數組的當前指針,繼續遍歷直到所有名字全都處理完畢。</font></p>
<hr>
<p align="center"><font size="2"><b>翻譯:</b></font><font
size="2" face="MS Sans Serif"><b>iamgufeng [</b></font><a
href="http://win32asm.cjb.net/"><font size="2"
face="MS Sans Serif"><b>Iczelion's Win32 Assembly Homepage</b></font></a><font
size="2" face="MS Sans Serif"><b>]</b><strong>[</strong></font><a
href="http://asm.yeah.net"><font size="2" face="MS Sans Serif"><strong>LuoYunBin's
Win32 ASM Page</strong></font></a><font size="2"
face="MS Sans Serif"><strong>]</strong></font></p>
<p> </p>
</body>
</html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -