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

📄 pe-tut2.html

📁 在DOS下编程因为实模式的限制
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<html>
<head>
<title>Iczelion's PE Tutorial 2: Detecting a Valid PE File</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>

<body bgcolor="#000066" text="#FFFFFF" link="#FFFFCC" vlink="#FFCCCC" alink="#CCFFCC">
<h1 align="center"><font face="Arial, Helvetica, sans-serif" color="#FFFFCC">Tutorial 
  2: Detecting a Valid PE File</font></h1>
<p><font face="MS Sans Serif" size="-1">In this tutorial, we will learn how to 
  check if a given file is a valid PE file.<br>
  Download <b><a href="files/PE-tut02.zip" style="text-decoration:none">the example</a></b>.</font></p>
<h3><font face="Arial, Helvetica, sans-serif">Theory:</font></h3>
<p><font face="MS Sans Serif" size="-1">How can you verify if a given file is 
  a PE file? That question is difficult to answer. That depends on the length 
  that you want to go to do that. You can verify every data structure defined 
  in the PE file format or you are satisfied with verifying only the crucial ones. 
  Most of the time, it's pretty pointless to verify every single structure in 
  the files. If the crucial structures are valid, we can assume that the file 
  is a valid PE. And we will use that assumption.</font></p>
<p><font face="MS Sans Serif" size="-1">The essential structure we will verify 
  is the PE header itself. So we need to know a little about it, programmatically. 
  The PE header is actually a structure called IMAGE_NT_HEADERS. It has the following 
  definition:</font></p>
<p><font face="MS Sans Serif" size="-1"><b>IMAGE_NT_HEADERS STRUCT <br>
  &nbsp;&nbsp;&nbsp;Signature dd ? <br>
  &nbsp;&nbsp;&nbsp;FileHeader IMAGE_FILE_HEADER <> <br>
  &nbsp;&nbsp;&nbsp;OptionalHeader IMAGE_OPTIONAL_HEADER32 <> <br>
  IMAGE_NT_HEADERS ENDS </b></font></p>
<p><font face="MS Sans Serif" size="-1"><b><font color="#FFFFCC">Signature</font></b> 
  is a dword that contains the value 50h, 45h, 00h, 00h. In more human term, it 
  contains the text &quot;PE&quot; followed by two terminating zeroes. This member 
  is the PE signature so we will use it in verifying if a given file is a valid 
  PE one.</font><br>
  <font face="MS Sans Serif" size="-1"><b><font color="#FFFFCC">FileHeader </font></b>is 
  a structure that contains information about the physical layout of the PE file 
  such as the number of sections, the machine the file is targeted and so on.<br>
  <font color="#FFFFCC"><b>OptionalHeader</b></font> is a structure that contains 
  information about the logical layout of the PE file. Despite the &quot;Optional&quot; 
  in its name, it's always present.</font></p>
<p><font face="MS Sans Serif" size="-1">Our goal is now clear. If value of the 
  signature member of the<font color="#CCFFCC"><b> IMAGE_NT_HEADERS</b></font> 
  is equal to &quot;PE&quot; followed by two zeroes, then the file is a valid 
  PE. In fact, for comparison purpose, Microsoft has defined a constant named 
  <font color="#CCFFCC"> <b>IMAGE_NT_SIGNATURE</b></font> which we can readily 
  use.</font></p>
<p><font face="MS Sans Serif" size="-1"><b><font color="#FFCCFF">IMAGE_DOS_SIGNATURE 
  equ 5A4Dh </font><br>
  IMAGE_OS2_SIGNATURE equ 454Eh <br>
  IMAGE_OS2_SIGNATURE_LE equ 454Ch <br>
  IMAGE_VXD_SIGNATURE equ 454Ch <br>
  <font color="#FFCCFF">IMAGE_NT_SIGNATURE equ 4550h </font></b></font></p>
<p><font face="MS Sans Serif" size="-1"> The next question: how can we know where 
  the PE header is? The answer is simple: the DOS MZ header contains the file 
  offset of the PE header. The DOS MZ header is defined as<font color="#CCFFCC"><b> 
  IMAGE_DOS_HEADER</b></font> structure. You can check it out in windows.inc. 
  The <font color="#CC9900"><b>e_lfanew</b></font> member of the <font color="#CCFFCC"><b>IMAGE_DOS_HEADER</b></font> 
  structure contains the file offset of the PE header. </font></p>
<p><font face="MS Sans Serif" size="-1">The steps are now as follows:</font></p>
<ol>
  <li><font face="MS Sans Serif" size="-1">Verify if the given file has a valid 
    DOS MZ header by comparing the first word of the file with the value <font color="#CCFFCC"><b>IMAGE_DOS_SIGNATURE</b></font>.</font></li>
  <li><font face="MS Sans Serif" size="-1">If the file has a valid DOS header, 
    use the value in e_lfanew member to find the PE header</font></li>
  <li><font face="MS Sans Serif" size="-1">Comparing the first word of the PE 
    header with the value<font color="#CCFFCC"><b> IMAGE_NT_HEADER</b></font>. 
    If both values match, then we can assume that the file is a valid PE.</font></li>
</ol>
<h3><font face="Arial, Helvetica, sans-serif">Example:</font></h3>
<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>
  SEH struct <br>
  PrevLink dd ? &nbsp;&nbsp;&nbsp;; the address of the previous seh structure 
  <br>
  CurrentHandler dd ?&nbsp;&nbsp;&nbsp; ; the address of the exception handler 
  <br>
  SafeOffset dd ? &nbsp;&nbsp;&nbsp;; The offset where it's safe to continue execution 
  <br>
  PrevEsp dd ? &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; the old value in esp <br>
  PrevEbp dd ? &nbsp;&nbsp;&nbsp;&nbsp;; The old value in ebp <br>
  SEH ends<br>
  <br>
  .data <br>
  AppName db "PE tutorial no.2",0 <br>
  ofn OPENFILENAME <> <br>
  FilterString db "Executable Files (*.exe, *.dll)",0,"*.exe;*.dll",0 <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  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>
  FileValidPE db "This file is a valid PE",0 <br>
  FileInValidPE db "This file is not a valid PE",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 proc <br>
  LOCAL seh:SEH <br>
  mov ofn.lStructSize,SIZEOF ofn <br>
  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>
  &nbsp;&nbsp;&nbsp; invoke CreateFile, addr buffer, GENERIC_READ, FILE_SHARE_READ, 
  NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL <br>
  &nbsp;&nbsp;&nbsp; .if eax!=INVALID_HANDLE_VALUE <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov hFile, eax <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke CreateFileMapping, hFile, NULL, 
  PAGE_READONLY,0,0,0 <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .if eax!=NULL <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov hMapping, eax <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke MapViewOfFile,hMapping,FILE_MAP_READ,0,0,0 
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .if eax!=NULL <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov 
  pMapping,eax <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assume 
  fs:nothing <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push 
  fs:[0] <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop 
  seh.PrevLink <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov 
  seh.CurrentHandler,offset SEHHandler <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov 
  seh.SafeOffset,offset FinalExit <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lea 
  eax,seh <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov 
  fs:[0], eax <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov 
  seh.PrevEsp,esp <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov 
  seh.PrevEbp,ebp <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov 
  edi, pMapping <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assume 
  edi:ptr IMAGE_DOS_HEADER <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .if 
  [edi].e_magic==IMAGE_DOS_SIGNATURE <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  add edi, [edi].e_lfanew <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 

⌨️ 快捷键说明

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