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

📄 lion-petut-c06.htm

📁 在DOS下编程因为实模式的限制
💻 HTM
📖 第 1 页 / 共 5 页
字号:
MB_OK+MB_ICONERROR <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.endif
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke
UnmapViewOfFile, pMapping <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.else <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke
MessageBox, 0, addr FileMappingError, addr AppName,
MB_OK+MB_ICONERROR <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.endif <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invoke CloseHandle,hMapping <br>
&nbsp;&nbsp;&nbsp;&nbsp;.else <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke MessageBox, 0, addr
FileOpenMappingError, addr AppName, MB_OK+MB_ICONERROR <br>
&nbsp;&nbsp;&nbsp; .endif <br>
&nbsp;&nbsp;&nbsp; invoke CloseHandle, hFile <br>
&nbsp;&nbsp; .else <br>
&nbsp;&nbsp;&nbsp;invoke MessageBox, 0, addr FileOpenError, addr
AppName, MB_OK+MB_ICONERROR <br>
&nbsp;&nbsp; .endif <br>
&nbsp;.endif <br>
&nbsp;ret <br>
ShowImportFunctions endp <br>
<br>
AppendText proc hDlg:DWORD,pText:DWORD <br>
&nbsp;&nbsp; invoke
SendDlgItemMessage,hDlg,IDC_EDIT,EM_REPLACESEL,0,pText <br>
&nbsp;&nbsp; invoke
SendDlgItemMessage,hDlg,IDC_EDIT,EM_REPLACESEL,0,addr CRLF <br>
&nbsp;&nbsp; invoke
SendDlgItemMessage,hDlg,IDC_EDIT,EM_SETSEL,-1,0 <br>
&nbsp;&nbsp;&nbsp;ret <br>
AppendText endp <br>
<br>
RVAToOffset PROC uses edi esi edx ecx pFileMap:DWORD,RVA:DWORD <br>
&nbsp;&nbsp; mov esi,pFileMap <br>
&nbsp;&nbsp; assume esi:ptr IMAGE_DOS_HEADER <br>
&nbsp;&nbsp; add esi,[esi].e_lfanew <br>
&nbsp;&nbsp; assume esi:ptr IMAGE_NT_HEADERS <br>
&nbsp;&nbsp; mov edi,RVA ; edi == RVA <br>
&nbsp;&nbsp; mov edx,esi <br>
&nbsp;&nbsp; add edx,sizeof IMAGE_NT_HEADERS <br>
&nbsp;&nbsp; mov cx,[esi].FileHeader.NumberOfSections <br>
&nbsp;&nbsp; movzx ecx,cx <br>
&nbsp;&nbsp; assume edx:ptr IMAGE_SECTION_HEADER <br>
&nbsp;&nbsp; .while ecx&gt;0 ; check all sections <br>
&nbsp;&nbsp;&nbsp;&nbsp; .if edi&gt;=[edx].VirtualAddress <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov eax,[edx].VirtualAddress
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add eax,[edx].SizeOfRawData <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .if edi&lt;eax ; The address
is in this section <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov
eax,[edx].VirtualAddress <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sub edi,eax<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov
eax,[edx].PointerToRawData <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add eax,edi ;
eax == file offset <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .endif <br>
&nbsp;&nbsp;&nbsp;&nbsp; .endif <br>
&nbsp;&nbsp;&nbsp;&nbsp; add edx,sizeof IMAGE_SECTION_HEADER <br>
&nbsp;&nbsp;&nbsp;&nbsp; dec ecx <br>
&nbsp;&nbsp; .endw <br>
&nbsp;&nbsp; assume edx:nothing <br>
&nbsp;&nbsp; assume esi:nothing <br>
&nbsp;&nbsp; mov eax,edi <br>
&nbsp;&nbsp; ret <br>
RVAToOffset endp <br>
<br>
ShowTheFunctions proc uses esi ecx ebx hDlg:DWORD, pNTHdr:DWORD <br>
&nbsp;&nbsp; LOCAL temp[512]:BYTE <br>
&nbsp;&nbsp; invoke SetDlgItemText,hDlg,IDC_EDIT,0 <br>
&nbsp;&nbsp; invoke AppendText,hDlg,addr buffer <br>
&nbsp;&nbsp; mov edi,pNTHdr <br>
&nbsp;&nbsp; assume edi:ptr IMAGE_NT_HEADERS <br>
&nbsp;&nbsp; mov edi, [edi].OptionalHeader.DataDirectory[sizeof
IMAGE_DATA_DIRECTORY].VirtualAddress <br>
&nbsp;&nbsp; invoke RVAToOffset,pMapping,edi <br>
&nbsp;&nbsp; mov edi,eax <br>
&nbsp;&nbsp; add edi,pMapping <br>
&nbsp;&nbsp; assume edi:ptr IMAGE_IMPORT_DESCRIPTOR <br>
&nbsp;&nbsp; .while !([edi].OriginalFirstThunk==0 &amp;&amp;
[edi].TimeDateStamp==0 &amp;&amp; [edi].ForwarderChain==0
&amp;&amp; [edi].Name1==0 &amp;&amp; [edi].FirstThunk==0) <br>
&nbsp;&nbsp;&nbsp;&nbsp; invoke AppendText,hDlg,addr
ImportDescriptor <br>
&nbsp;&nbsp;&nbsp;&nbsp; invoke RVAToOffset,pMapping, [edi].Name1
<br>
&nbsp;&nbsp;&nbsp;&nbsp; mov edx,eax <br>
&nbsp;&nbsp;&nbsp;&nbsp; add edx,pMapping <br>
&nbsp;&nbsp;&nbsp;&nbsp; invoke wsprintf, addr temp, addr
IDTemplate, [edi].OriginalFirstThunk,[edi].TimeDateStamp,[edi].ForwarderChain,edx,[edi].FirstThunk
&nbsp;&nbsp;&nbsp;&nbsp; invoke AppendText,hDlg,addr temp <br>
&nbsp;&nbsp;&nbsp;&nbsp; .if [edi].OriginalFirstThunk==0 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov
esi,[edi].FirstThunk <br>
&nbsp;&nbsp;&nbsp;&nbsp; .else <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov
esi,[edi].OriginalFirstThunk <br>
&nbsp;&nbsp;&nbsp;&nbsp; .endif <br>
&nbsp;&nbsp;&nbsp;&nbsp; invoke RVAToOffset,pMapping,esi <br>
&nbsp;&nbsp;&nbsp;&nbsp; add eax,pMapping <br>
&nbsp;&nbsp;&nbsp;&nbsp; mov esi,eax <br>
&nbsp;&nbsp;&nbsp;&nbsp; invoke AppendText,hDlg,addr NameHeader <br>
&nbsp;&nbsp;&nbsp;&nbsp; .while dword ptr [esi]!=0 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; test dword ptr
[esi],IMAGE_ORDINAL_FLAG32 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jnz ImportByOrdinal <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke
RVAToOffset,pMapping,dword ptr [esi] <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov edx,eax <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add edx,pMapping <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assume edx:ptr
IMAGE_IMPORT_BY_NAME <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov cx, [edx].Hint <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movzx ecx,cx <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke wsprintf,addr
temp,addr NameTemplate,ecx,addr [edx].Name1 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jmp ShowTheText <br>
ImportByOrdinal: <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov edx,dword ptr [esi] <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and edx,0FFFFh <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke wsprintf,addr
temp,addr OrdinalTemplate,edx <br>
ShowTheText: <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke AppendText,hDlg,addr
temp <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add esi,4 <br>
&nbsp;&nbsp;&nbsp; .endw <br>
&nbsp;&nbsp;&nbsp; add edi,sizeof IMAGE_IMPORT_DESCRIPTOR <br>
&nbsp; .endw <br>
&nbsp;&nbsp;ret <br>
ShowTheFunctions 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 color="#CC9900" size="2" face="MS Sans Serif"><b>ShowTheFunctions</b></font><font
size="2">。</font></p>

<p><font face="Fixedsys">ShowTheFunctions proc uses esi ecx ebx
hDlg:DWORD, pNTHdr:DWORD <br>
&nbsp;&nbsp; LOCAL temp[512]:BYTE </font></p>

<p><font size="2">保留</font><font size="2"
face="MS Sans Serif">512</font><font size="2">字节堆栈空间用于字符串操作。</font></p>

<p><font face="Fixedsys">&nbsp;&nbsp; invoke
SetDlgItemText,hDlg,IDC_EDIT,0 </font></p>

<p><font size="2">清除编辑控件内容。</font></p>

<p><font face="Fixedsys">&nbsp;&nbsp; invoke AppendText,hDlg,addr
buffer </font></p>

<p><font size="2">将</font><font size="2" face="MS Sans Serif">PE</font><font
size="2">文件名插入编辑控件。 </font><font
color="#CC9900" size="2" face="MS Sans Serif"><b>AppendText </b></font><font
size="2">通过传递一个 </font><font color="#CCFFCC" size="2"
face="MS Sans Serif"><b>EM_REPLACESEL </b></font><font size="2">消息以通知向编辑控件添加文本。然后它又向编辑控件发送一个设置了
</font><font size="2" face="MS Sans Serif">wParam=-1</font><font
size="2">和</font><font size="2" face="MS Sans Serif">lParam=0</font><font
size="2">的</font><font color="#CCFFCC" size="2"
face="MS Sans Serif"><b>EM_SETSEL</b></font><font size="2"
face="MS Sans Serif"> </font><font size="2">消息,使光标定位到文本末。</font></p>

<p><font face="Fixedsys">&nbsp;&nbsp; mov edi,pNTHdr <br>
&nbsp;&nbsp; assume edi:ptr IMAGE_NT_HEADERS <br>
&nbsp;&nbsp; mov edi, [edi].OptionalHeader.DataDirectory[sizeof
IMAGE_DATA_DIRECTORY].VirtualAddress </font></p>

<p><font size="2">获取</font><font size="2"
face="MS Sans Serif">import symbols</font><font size="2">的</font><font
size="2" face="MS Sans Serif">RVA</font><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></p>

<p><font face="Fixedsys">&nbsp;&nbsp; invoke
RVAToOffset,pMapping,edi <br>
&nbsp;&nbsp; mov edi,eax <br>
&nbsp;&nbsp; add edi,pMapping </font></p>

<p><font size="2" face="MS Sans Serif">这儿对PE编程初学者来说可能有点困难。在PE文件中大多数地址多是RVAs 而 
  </font><font color="#FF6666" size="2"
face="MS Sans Serif"><b>RVAs</b></font><font color="#FF6666"
size="2"><b>只有当</b></font><font color="#FF6666" size="2"
face="MS Sans Serif"><b>PE</b></font><font color="#FF6666"
size="2"><b>文件被</b></font><font color="#FF6666" size="2"
face="MS Sans Serif"><b>PE</b></font><font color="#FF6666"
size="2"><b>装载器装入内存后才有意义。</b></font><font
size="2" face="MS Sans Serif"> 本例中,我们直接将文件映射到内存而不是通过PE装载器载入,因此我们不能直接使用那些RVAs。必须先将那些RVAs转换成文件偏移量,RVAToOffset函数就起到这个作用。 
  这里不准备详细分析。指出的是,它还将给定的RVA和PE文件所有节的始末RVA作比较(检验RVA的有效性),然后通过</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
color="#FFFFCC" size="2" face="MS Sans Serif"><b>PointerToRawData</b></font><font
size="2" face="MS Sans Serif">域(当然是所在节的那个</font><font
color="#FFFFCC" size="2" face="MS Sans Serif"><b>PointerToRawData</b></font><font
size="2" face="MS Sans Serif">域啦</font><font
size="2" face="MS Sans Serif">)将RVA转换成文件偏移量。<br>
  函数使用需要传递两个参数: 内存映射文件指针和所要转换的RVA。eax里返回文件偏移量。上面代码中,我们必须将文件偏移量加上内存映射文件指针以转换成虚拟地址。是不是有点复杂? 
  :)</font></p>

<p><font face="Fixedsys">&nbsp;&nbsp; assume edi:ptr
IMAGE_IMPORT_DESCRIPTOR <br>
&nbsp;&nbsp; .while !([edi].OriginalFirstThunk==0 &amp;&amp;
[edi].TimeDateStamp==0 &amp;&amp; [edi].ForwarderChain==0
&amp;&amp; [edi].Name1==0 &amp;&amp; [edi].FirstThunk==0) </font></p>

<p><font size="2" face="MS Sans Serif">edi</font><font size="2">现在指向第一个
</font><font color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_IMPORT_DESCRIPTOR</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">结构。接下来我们遍历整个结构数组直到遇上一个全</font><font
size="2" face="MS Sans Serif">0</font><font size="2">结构,这就是数组末尾了。</font></p>

<p><font face="Fixedsys">&nbsp;&nbsp;&nbsp;&nbsp; invoke
AppendText,hDlg,addr ImportDescriptor<br>
&nbsp;&nbsp;&nbsp;&nbsp; invoke RVAToOffset,pMapping, [edi].Name1
<br>
&nbsp;&nbsp;&nbsp;&nbsp; mov edx,eax <br>
&nbsp;&nbsp;&nbsp;&nbsp; add edx,pMapping </font></p>

<p><font size="2">我们要显示当前 </font><font
color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_IMPORT_DESCRIPTOR</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">结构的值。</font><font
size="2" face="MS Sans Serif">Name1 </font><font size="2">不同于其他结构成员,它含有指向相关</font><font
size="2" face="MS Sans Serif">dll</font><font size="2">名的</font><font
size="2" face="MS Sans Serif">RVA</font><font size="2">。因此必须先将其转换成虚拟地址。</font></p>

<p><font face="Fixedsys">&nbsp;&nbsp;&nbsp;&nbsp; invoke
wsprintf, addr temp, addr IDTemplate, [edi].OriginalFirstThunk,[edi].TimeDateStamp,[edi].ForwarderChain,edx,[edi].FirstThunk
&nbsp;&nbsp;&nbsp;&nbsp; invoke AppendText,hDlg,addr temp </font></p>

<p><font size="2">显示当前 </font><font color="#CCFFCC"
size="2" face="MS Sans Serif"><b>IMAGE_IMPORT_DESCRIPTOR</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">结构的值。</font></p>

<p><font face="Fixedsys">&nbsp;&nbsp;&nbsp;&nbsp; .if
[edi].OriginalFirstThunk==0 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov
esi,[edi].FirstThunk <br>
&nbsp;&nbsp;&nbsp;&nbsp; .else <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov
esi,[edi].OriginalFirstThunk <br>
&nbsp;&nbsp;&nbsp;&nbsp; .endif </font></p>

<p><font size="2">接下来准备遍历 </font><font
color="#CCFFCC" size="2" face="MS Sans Serif"><b>IMAGE_THUNK_DATA</b></font><font
size="2" face="MS Sans Serif"> </font><font size="2">数组。通常我们会选择</font><font
color="#FFFFCC" size="2" face="MS Sans Serif"><b>OriginalFirstThunk</b></font><font
size="2">指向的那个数组,不过,如果某些连接器错误地将</font><font
co

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -