📄 lion-petut-c05.htm
字号:
wsprintf,addr buffer,addr template,[esi].SizeOfRawData <br>
lea eax,buffer <br>
mov
lvi.pszText,eax <br>
inc lvi.iSubItem
<br>
invoke
SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_SETITEM,0,addr lvi <br>
invoke
wsprintf,addr buffer,addr template,[esi].PointerToRawData <br>
lea eax,buffer <br>
mov
lvi.pszText,eax <br>
inc lvi.iSubItem
<br>
invoke
SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_SETITEM,0,addr lvi <br>
invoke
wsprintf,addr buffer,addr template,[esi].Characteristics <br>
lea eax,buffer <br>
mov
lvi.pszText,eax <br>
inc lvi.iSubItem
<br>
invoke
SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_SETITEM,0,addr lvi <br>
inc lvi.iItem <br>
dec edi <br>
add esi, sizeof
IMAGE_SECTION_HEADER <br>
.endw <br>
.elseif <br>
uMsg==WM_CLOSE <br>
invoke
EndDialog,hDlg,NULL <br>
.else <br>
mov eax,FALSE <br>
ret <br>
.endif <br>
mov eax,TRUE <br>
ret <br>
DlgProc endp <br>
<br>
ShowSectionInfo proc uses edi <br>
mov edi, pMapping <br>
assume edi:ptr IMAGE_DOS_HEADER <br>
add edi, [edi].e_lfanew <br>
assume edi:ptr IMAGE_NT_HEADERS <br>
mov ax,[edi].FileHeader.NumberOfSections <br>
movzx eax,ax <br>
mov NumberOfSections,eax <br>
add edi,sizeof IMAGE_NT_HEADERS <br>
invoke DialogBoxParam, hInstance,
IDD_SECTIONTABLE,NULL, addr DlgProc, edi<br>
ret <br>
ShowSectionInfo endp <br>
end start </font></p>
<h3>分析<font face="Arial, Helvetica, sans-serif">:</font></h3>
<p><font size="2">本例重用了</font><font size="2"
face="MS Sans Serif">PE</font><font size="2">教程</font><font
size="2" face="MS Sans Serif">2</font><font size="2">的代码,校验</font><font
size="2" face="MS Sans Serif">PE</font><font size="2">文件的有效性后,继续调用函数</font><font
size="2" face="MS Sans Serif">ShowSectionInfo</font><font
size="2">显示各节信息。</font></p>
<p><font face="Fixedsys">ShowSectionInfo proc uses edi <br>
mov edi, pMapping <br>
assume edi:ptr IMAGE_DOS_HEADER <br>
add edi, [edi].e_lfanew<br>
assume edi:ptr IMAGE_NT_HEADERS</font></p>
<p><font size="2">我们将</font><font size="2"
face="MS Sans Serif">edi</font><font size="2">用作指向</font><font
size="2" face="MS Sans Serif">PE</font><font size="2">文件数据的指针。首先,将指向</font><font
size="2" face="MS Sans Serif">DOS header</font><font size="2">地址的</font><font
size="2" face="MS Sans Serif">pMapping</font><font size="2">赋给</font><font
size="2" face="MS Sans Serif">edi</font><font size="2">,再加上</font><font
color="#FFFFCC" size="2" face="MS Sans Serif"><b>e_lfanew</b></font><font
size="2">域值等于</font><font size="2" face="MS Sans Serif">PE
header</font><font size="2">的地址。</font></p>
<p><font face="Fixedsys"> mov
ax,[edi].FileHeader.NumberOfSections<br>
mov NumberOfSections,ax </font></p>
<p><font size="2">因为我们要遍历节表,所以必须先获取文件的节数目。这就得靠</font><font
size="2" face="MS Sans Serif">file header</font><font size="2">里的</font><font
size="2" face="MS Sans Serif">NumberOfSections</font><font
size="2">域了,切记这是个</font><font size="2"
face="MS Sans Serif">word</font><font size="2">域。</font></p>
<p><font face="Fixedsys"> add edi,sizeof
IMAGE_NT_HEADERS </font></p>
<p><font size="2">现在</font><font size="2"
face="MS Sans Serif">edi</font><font size="2">正指向</font><font
size="2" face="MS Sans Serif">PE header</font><font size="2">的起始地址,加上</font><font
size="2" face="MS Sans Serif">PE header</font><font size="2">结构大小后恰好指向节表了。</font></p>
<p><font face="Fixedsys"> invoke DialogBoxParam,
hInstance, IDD_SECTIONTABLE,NULL, addr DlgProc, edi</font></p>
<p><font size="2">调用 </font><font color="#FFFFCC" size="2"
face="MS Sans Serif"><b>DialogBoxParam</b></font><font size="2"
face="MS Sans Serif"> </font><font size="2">显示列表对话框,注意我们已将节表地址作为最后一个参数传递过去了,该值可从</font><font
color="#CCFFCC" size="2" face="MS Sans Serif"><b>WM_INITDIALOG</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">消息的</font><font
size="2" face="MS Sans Serif">lParam</font><font size="2">参数中提取。</font></p>
<p><font size="2">在对话框过程里我们响应</font><font
size="2" face="MS Sans Serif">WM_INITDIALOG</font><font size="2">消息,将</font><font
size="2" face="MS Sans Serif">lParam</font><font size="2">值 </font><font
size="2" face="MS Sans Serif">(</font><font size="2">节表地址</font><font
size="2" face="MS Sans Serif">)</font><font size="2">存入</font><font
size="2" face="MS Sans Serif">esi</font><font size="2">,节数目赋给</font><font
size="2" face="MS Sans Serif">edi</font><font size="2">并设置列表控件。万事俱备后,进入循环将各节信息插入到列表控件中,这部分相当简单。</font></p>
<p><font face="Fixedsys"> .while
edi>0 <br>
mov
lvi.iSubItem,0 </font></p>
<p><font size="2">字符串置入第一列。</font></p>
<p><font face="Fixedsys">
invoke RtlZeroMemory,addr buffer,9 <br>
invoke
lstrcpyn,addr buffer,addr [esi].Name1,8 <br>
lea eax,buffer <br>
mov
lvi.pszText,eax </font></p>
<p><font size="2">要显示节名,当然要将其转换为</font><font
size="2" face="MS Sans Serif">ASCIIZ</font><font size="2">字符串先。</font></p>
<p><font face="Fixedsys">
invoke
SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_INSERTITEM,0,addr lvi
</font></p>
<p><font size="2">然后显示第一列。<br>
继续我们伟大的工程,显示完本节中最后一个欲呈现的值后,立马下一个结构。</font></p>
<p><font face="Fixedsys">
dec edi <br>
add esi, sizeof
IMAGE_SECTION_HEADER <br>
.endw </font></p>
<p><font size="2">每处理完一节就递减</font><font
size="2" face="MS Sans Serif">edi</font><font size="2">,然后将</font><font
size="2" face="MS Sans Serif">esi</font><font size="2">加上</font><font
color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_SECTION_HEADER</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">结构大小,使其指向下一个</font><font
color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_SECTION_HEADER</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">结构。</font></p>
<p><font size="2">遍历节表的步骤</font><font size="2"
face="MS Sans Serif">:</font></p>
<ol>
<li><font size="2" face="MS Sans Serif">PE</font><font
size="2">文件有效性校验。</font></li>
<li><font size="2">定位到 </font><font size="2"
face="MS Sans Serif">PE header </font><font size="2">的起始地址。</font></li>
<li><font size="2">从 </font><font size="2"
face="MS Sans Serif">file header </font><font size="2">的</font><font
color="#FFFFCC" size="2"><b> </b></font><font
color="#FFFFCC" size="2" face="MS Sans Serif"><b>NumberOfSections</b></font><font
size="2">域获取节数。</font></li>
<li><font size="2">通过两种方法定位节表</font><font
size="2" face="MS Sans Serif">: </font><font
color="#FFFFCC" size="2" face="MS Sans Serif"><b>ImageBase</b></font><font
size="2" face="MS Sans Serif">+</font><font
color="#FFFFCC" size="2" face="MS Sans Serif"><b>SizeOfHeaders</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">或者
</font><font size="2" face="MS Sans Serif">PE header</font><font
size="2">的起始地址</font><font size="2"
face="MS Sans Serif">+ PE header</font><font size="2">结构大小。
</font><font size="2" face="MS Sans Serif">(</font><font
size="2">节表紧随 </font><font size="2"
face="MS Sans Serif">PE header)</font><font size="2">。如果不是使用文件映射的方法,可以用</font><font
color="#FFFFCC" size="2" face="MS Sans Serif"><b>SetFilePointer</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">直接将文件指针定位到节表。节表的文件偏移量存放在
</font><font color="#FFFFCC" size="2"
face="MS Sans Serif"><b>SizeOfHeaders</b></font><font
size="2">域里。</font><font size="2"
face="MS Sans Serif">(</font><font color="#FFFFCC"
size="2" face="MS Sans Serif"><b>SizeOfHeaders</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">是 </font><font
color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_OPTIONAL_HEADER
</b></font><font size="2">的结构成员</font><font
size="2" face="MS Sans Serif">)</font></li>
<li><font size="2">处理每个 </font><font color="#CCFFCC"
size="2" face="MS Sans Serif"><b>IMAGE_SECTION_HEADER</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">结构。</font></li>
</ol>
<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 + -