⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lion-petut-c05.htm

📁 在DOS下编程因为实模式的限制
💻 HTM
📖 第 1 页 / 共 3 页
字号:
wsprintf,addr buffer,addr template,[esi].SizeOfRawData <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lea eax,buffer <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov
lvi.pszText,eax <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inc lvi.iSubItem
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke
SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_SETITEM,0,addr lvi <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke
wsprintf,addr buffer,addr template,[esi].PointerToRawData <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lea eax,buffer <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov
lvi.pszText,eax <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inc lvi.iSubItem
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke
SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_SETITEM,0,addr lvi <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke
wsprintf,addr buffer,addr template,[esi].Characteristics <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lea eax,buffer <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov
lvi.pszText,eax <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inc lvi.iSubItem
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke
SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_SETITEM,0,addr lvi <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inc lvi.iItem <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dec edi <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add esi, sizeof
IMAGE_SECTION_HEADER <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .endw <br>
&nbsp;&nbsp; .elseif <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uMsg==WM_CLOSE <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke
EndDialog,hDlg,NULL <br>
&nbsp;&nbsp; .else <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov eax,FALSE <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret <br>
&nbsp;&nbsp;&nbsp;.endif <br>
&nbsp;&nbsp; mov eax,TRUE <br>
&nbsp;&nbsp; ret <br>
DlgProc endp <br>
<br>
ShowSectionInfo proc uses edi <br>
&nbsp;&nbsp; mov edi, pMapping <br>
&nbsp;&nbsp; assume edi:ptr IMAGE_DOS_HEADER <br>
&nbsp;&nbsp; add edi, [edi].e_lfanew <br>
&nbsp;&nbsp; assume edi:ptr IMAGE_NT_HEADERS <br>
&nbsp;&nbsp; mov ax,[edi].FileHeader.NumberOfSections <br>
&nbsp;&nbsp; movzx eax,ax <br>
&nbsp;&nbsp; mov NumberOfSections,eax <br>
&nbsp;&nbsp; add edi,sizeof IMAGE_NT_HEADERS <br>
&nbsp;&nbsp; invoke DialogBoxParam, hInstance,
IDD_SECTIONTABLE,NULL, addr DlgProc, edi<br>
&nbsp;&nbsp; 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>
&nbsp;&nbsp; mov edi, pMapping <br>
&nbsp;&nbsp; assume edi:ptr IMAGE_DOS_HEADER <br>
&nbsp;&nbsp; add edi, [edi].e_lfanew<br>
&nbsp;&nbsp; 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">&nbsp;&nbsp; mov
ax,[edi].FileHeader.NumberOfSections<br>
&nbsp;&nbsp; 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">&nbsp;&nbsp; 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">&nbsp;&nbsp; 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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .while
edi&gt;0 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov
lvi.iSubItem,0 </font></p>

<p><font size="2">字符串置入第一列。</font></p>

<p><font face="Fixedsys">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke RtlZeroMemory,addr buffer,9 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invoke
lstrcpyn,addr buffer,addr [esi].Name1,8 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lea eax,buffer <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke
SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_INSERTITEM,0,addr lvi
</font></p>

<p><font size="2">然后显示第一列。<br>
继续我们伟大的工程,显示完本节中最后一个欲呈现的值后,立马下一个结构。</font></p>

<p><font face="Fixedsys">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
dec edi <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add esi, sizeof
IMAGE_SECTION_HEADER <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .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 + -