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

📄 pe-tut2.html

📁 在DOS下编程因为实模式的限制
💻 HTML
📖 第 1 页 / 共 2 页
字号:
  assume edi:ptr IMAGE_NT_HEADERS <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  .if [edi].Signature==IMAGE_NT_SIGNATURE <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  mov ValidPE, TRUE <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  .else <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  mov ValidPE, FALSE <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  .endif <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .else 
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  mov ValidPE,FALSE <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .endif 
  <br>
  FinalExit: <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .if 
  ValidPE==TRUE <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  invoke MessageBox, 0, addr FileValidPE, addr AppName, MB_OK+MB_ICONINFORMATION 
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .else 
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  invoke MessageBox, 0, addr FileInValidPE, addr AppName, MB_OK+MB_ICONINFORMATION 
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .endif 
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push 
  seh.PrevLink <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop 
  fs:[0] <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke 
  UnmapViewOfFile, pMapping <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .else <br>
  &nbsp;&nbsp;&nbsp;&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;&nbsp;&nbsp;&nbsp; .endif <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke CloseHandle,hMapping 
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .else <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke MessageBox, 0, 
  addr FileOpenMappingError, addr AppName, MB_OK+MB_ICONERROR <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .endif <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke CloseHandle, hFile <br>
  &nbsp;&nbsp;&nbsp; .else <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke MessageBox, 0, addr FileOpenError, 
  addr AppName, MB_OK+MB_ICONERROR <br>
  &nbsp;&nbsp;&nbsp; .endif <br>
  .endif <br>
  invoke ExitProcess, 0 <br>
  start endp <br>
  <br>
  SEHHandler proc uses edx pExcept:DWORD, pFrame:DWORD, pContext:DWORD, pDispatch:DWORD 
  <br>
  &nbsp;&nbsp;&nbsp; mov edx,pFrame <br>
  &nbsp;&nbsp;&nbsp; assume edx:ptr SEH <br>
  &nbsp;&nbsp;&nbsp; mov eax,pContext <br>
  &nbsp;&nbsp;&nbsp; assume eax:ptr CONTEXT <br>
  &nbsp;&nbsp;&nbsp; push [edx].SafeOffset <br>
  &nbsp;&nbsp;&nbsp; pop [eax].regEip <br>
  &nbsp;&nbsp;&nbsp; push [edx].PrevEsp <br>
  &nbsp;&nbsp;&nbsp; pop [eax].regEsp <br>
  &nbsp;&nbsp;&nbsp; push [edx].PrevEbp <br>
  &nbsp;&nbsp;&nbsp; pop [eax].regEbp <br>
  &nbsp;&nbsp;&nbsp; mov ValidPE, FALSE <br>
  &nbsp;&nbsp;&nbsp; mov eax,ExceptionContinueExecution <br>
  &nbsp;&nbsp;&nbsp; ret <br>
  SEHHandler endp <br>
  end start </font></p>
<h3><font face="Arial, Helvetica, sans-serif">Analysis:</font></h3>
<p><font face="MS Sans Serif" size="-1">The program opens a file and checks if 
  the DOS header is valid, if it is, it checks the PE header if it's valid. If 
  it is, then it assumes the file is a valid PE. In this example, I use structured 
  exception handling (SEH) so that we don't have to check for every possible error: 
  if a fault occurs, we assume that it's because the file is not a valid PE thus 
  giving our program wrong information. Windows itself uses SEH heavily in its 
  parameter validation routines. If you're interested in SEH, read <b><a href="Exceptionhandling.html" style="text-decoration:none">the 
  article</a></b> by Jeremy Gordon.</font></p>
<p><font face="MS Sans Serif" size="-1">The program displays an open file common 
  dialog to the user and when the user chooses an executable file, it opens the 
  file and maps it into memory. Before it goes on with the verification, it sets 
  up a SEH:</font></p>
<p><font face="Fixedsys">&nbsp;&nbsp; assume fs:nothing <br>
  &nbsp;&nbsp;&nbsp;push fs:[0] <br>
  &nbsp;&nbsp;&nbsp;pop seh.PrevLink <br>
  &nbsp;&nbsp;&nbsp;mov seh.CurrentHandler,offset SEHHandler <br>
  &nbsp;&nbsp;&nbsp;mov seh.SafeOffset,offset FinalExit <br>
  &nbsp;&nbsp;&nbsp;lea eax,seh <br>
  &nbsp;&nbsp;&nbsp;mov fs:[0], eax <br>
  &nbsp;&nbsp;&nbsp;mov seh.PrevEsp,esp <br>
  &nbsp;&nbsp;&nbsp;mov seh.PrevEbp,ebp </font></p>
<p><font face="MS Sans Serif" size="-1">We start by assuming the use of fs register 
  as nothing. This must be done because MASM assumes the use of fs register to 
  ERROR. Next we store the address of the previous SEH handler in our structure 
  for use by Windows. We store the address of our SEH handler, the address where 
  the execution can safely resume if a fault occurs, the current values of esp 
  and ebp so that our SEH handler can get the state of the stack back to normal 
  before it resumes the execution of our program.</font></p>
<p><font face="Fixedsys"> &nbsp;&nbsp;&nbsp;mov edi, pMapping <br>
  &nbsp;&nbsp;&nbsp;assume edi:ptr IMAGE_DOS_HEADER <br>
  &nbsp;&nbsp;&nbsp;.if [edi].e_magic==IMAGE_DOS_SIGNATURE </font></p>
<p><font face="MS Sans Serif" size="-1">After we are done with setting up SEH, 
  we continue with the verification. We put the address of the first byte of the 
  target file in edi, which is the first byte of the DOS header. For ease of comparison, 
  we tell the assembler that it can assume edi as pointing to the<font color="#CCFFCC"><b> 
  IMAGE_DOS_HEADER</b></font> structure (which is the truth). We then compare 
  the first word of the DOS header with the string &quot;MZ&quot; which is defined 
  as a constant in windows.inc named <font color="#CCFFCC"><b>IMAGE_DOS_SIGNATURE</b></font>. 
  If the comparison is ok, we continue to the PE header. If not, we set the value 
  in <font color="#FFFFCC"><b>ValidPE</b></font> to FALSE, meaning that the file 
  is not a valid PE.</font></p>
<p><font face="Fixedsys"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add edi, [edi].e_lfanew 
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assume edi:ptr IMAGE_NT_HEADERS <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.if [edi].Signature==IMAGE_NT_SIGNATURE 
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov ValidPE, TRUE <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.else <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov ValidPE, FALSE <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.endif </font></p>
<p><font face="MS Sans Serif" size="-1">To get to the PE header, we need the value 
  in <font color="#FFFFCC"><b>e_lfanew</b></font> of the DOS header. This field 
  contains the file offset of the PE header, relative to the file beginning. Thus 
  we add this value to edi and we get to the first byte of the PE header. It's 
  this place that a fault may occur. If the file is really not a PE file, the 
  value in e_lfanew will be incorrect and thus using it amounts to using a wild 
  pointer. If we don't use SEH, we must check the value of the <font color="#FFFFCC"><b>e_lfanew</b></font> 
  against the file size which is ugly. If all goes well, we compare the first 
  dword of the PE header with the string &quot;PE&quot;. Again there is a handy 
  constant named <font color="#CCFFCC"><b>IMAGE_NT_SIGNATURE</b></font> which 
  we can use. If the result of comparison is true, we assume the file is a valid 
  PE.<br>
  If the value in<font color="#FFFFCC"><b> e_lfanew</b></font> is incorrect, a 
  fault may occur and our SEH handler will get control. It simply restores the 
  stack pointer, bsae pointer and resumes the execution at the safe offset which 
  is at the FinalExit label.</font></p>
<p><font face="Fixedsys">FinalExit: <br>
  &nbsp;&nbsp;&nbsp;.if ValidPE==TRUE <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invoke MessageBox, 0, addr FileValidPE, 
  addr AppName, MB_OK+MB_ICONINFORMATION <br>
  &nbsp;&nbsp;&nbsp;.else <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invoke MessageBox, 0, addr FileInValidPE, 
  addr AppName, MB_OK+MB_ICONINFORMATION <br>
  &nbsp;&nbsp;&nbsp;.endif </font></p>
<p><font face="MS Sans Serif" size="-1">The above code is simplicity itself. It 
  checks the value in ValidPE and displays a message to the user accordingly.</font></p>
<p><font face="Fixedsys"> &nbsp;&nbsp;&nbsp;push seh.PrevLink <br>
  &nbsp;&nbsp;&nbsp;pop fs:[0] </font></p>
<p><font face="MS Sans Serif" size="-1">When the SEH is no longer used, we dissociate 
  it from the SEH chain.</font></p>
<hr>
<p align="center"><font face="MS Sans Serif" size="-1"><b>[<a href="http://win32asm.cjb.net">Iczelion's 
  Win32 Assembly Homepage</a>]</b></font></p>
<p>&nbsp;</p>
</body>
</html>

⌨️ 快捷键说明

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