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

📄 chap8-1-2.htm.primary

📁 加密与解密,软件加密保护技术与解决方案,看雪文档!
💻 PRIMARY
📖 第 1 页 / 共 2 页
字号:
               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; 
  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 color="#000000">分析<font face="Arial, Helvetica, sans-serif">:</font></font></h3>
<p><font size="2" color="#000000">本例程打开一文件,先检验</font><font face="MS Sans Serif" size="2" color="#000000">DOS 
  header</font><font size="2" color="#000000">是否有效,有效就接着检验</font><font face="MS Sans Serif" size="2" color="#000000">PE 
  header</font><font size="2" color="#000000">的有效性,</font><font face="MS Sans Serif" size="2" color="#000000">ok</font><font size="2" color="#000000">就认为是有效的</font><font face="MS Sans Serif" size="2" color="#000000">PE</font><font size="2" color="#000000">文件了。这里,我们还运用了结构异常处理</font><font face="MS Sans Serif" size="2" color="#000000">(SEH)</font><font size="2" color="#000000">,这样就不必检查每个可能的错误</font><font face="MS Sans Serif" size="2" color="#000000">: 
  </font><font size="2" color="#000000">如果有错误出现,就认为</font><font face="MS Sans Serif" size="2" color="#000000">PE</font><font size="2" color="#000000">检测失效所致,于是给出我们的报错信息。其实</font><font face="MS Sans Serif" size="2" color="#000000">Windows</font><font size="2" color="#000000">内部普遍使用</font><font face="MS Sans Serif" size="2" color="#000000">SEH</font><font size="2" color="#000000">来检验参数传递的有效性。若对</font><font face="MS Sans Serif" size="2" color="#000000">SEH</font><font size="2" color="#000000">感兴趣的话,可阅读</font><font face="MS Sans Serif" size="2" color="#000000">Jeremy 
  Gordon</font><font size="2" color="#000000">的</font><font face="MS Sans Serif" size="2" color="#000000"> 
  </font><font color="#000000"><a 
href="http://bigluo.tz163.net/program/iczelion/Exceptionhandling.html"><font 
size=2>文章</font></a><font size=2>。</font></font></p>
<p><font size="2" color="#000000">程序调用打开文件通用对话框,用户选定执行文件后,程序便打开文件并映射到内存。并在有效性检验前建立一</font><font face="MS Sans Serif" size="2" color="#000000"> 
  SEH:</font></p>
<p><font face="Fixedsys" color="#000000">&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 size="2" color="#000000">一开始就假设寄存器</font><font face="MS Sans Serif" size="2" color="#000000"> 
  fs</font><font size="2" color="#000000">为空(</font><font face="MS Sans Serif" size="2" color="#000000">assume 
  fs:nothing</font><font size="2" color="#000000">)。</font><font face="MS Sans Serif" size="2" color="#000000"> 
  </font><font size="2" color="#000000">记住这一步不能省却,因为</font><font face="MS Sans Serif" size="2" color="#000000">MASM</font><font size="2" color="#000000">假设</font><font face="MS Sans Serif" size="2" color="#000000">fs</font><font size="2" color="#000000">寄存器为</font><font face="MS Sans Serif" size="2" color="#000000">ERROR</font><font size="2" color="#000000">。接下来保存</font><font face="MS Sans Serif" size="2" color="#000000"> 
  Windows</font><font size="2" color="#000000">使用的旧</font><font face="MS Sans Serif" size="2" color="#000000">SEH</font><font size="2" color="#000000">处理函数地址到我们自己定义的结构中,同时保存我们的</font><font face="MS Sans Serif" size="2" color="#000000">SEH</font><font size="2" color="#000000">处理函数地址和异常处理时的执行恢复地址,这样一旦错误发生就能由异常处理函数安全地恢复执行了。同时还保存当前</font><font face="MS Sans Serif" size="2" color="#000000">esp</font><font size="2" color="#000000">及</font><font face="MS Sans Serif" size="2" color="#000000">ebp</font><font size="2" color="#000000">的值,以便我们的</font><font face="MS Sans Serif" size="2" color="#000000">SEH</font><font size="2" color="#000000">处理函数将堆栈恢复到正常状态。</font></p>
<p><font face="Fixedsys" color="#000000">&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 size="2" color="#000000">成功建立</font><font face="MS Sans Serif" size="2" color="#000000">SEH</font><font size="2" color="#000000">后继续校验工作。置目标文件的首字节地址给</font><font face="MS Sans Serif" size="2" color="#000000">edi</font><font size="2" color="#000000">,使其指向</font><font face="MS Sans Serif" size="2" color="#000000">DOS 
  header</font><font size="2" color="#000000">的首字节。为便于比较,我们告诉编译器可以假定</font><font face="MS Sans Serif" size="2" color="#000000">edi</font><font size="2" color="#000000">正指向</font><font color="#000000" face="MS Sans Serif" size="2"><b>IMAGE_DOS_HEADER</b></font><font size="2" color="#000000">结构</font><font face="MS Sans Serif" size="2" color="#000000">(</font><font size="2" color="#000000">事实亦是如此</font><font face="MS Sans Serif" size="2" color="#000000">)</font><font size="2" color="#000000">。然后比较</font><font face="MS Sans Serif" size="2" color="#000000">DOS 
  header</font><font size="2" color="#000000">的首字是否等于字符串</font><font face="MS Sans Serif" size="2" color="#000000">"MZ"</font><font size="2" color="#000000">,这里利用了</font><font face="MS Sans Serif" size="2" color="#000000">windows.inc</font><font size="2" color="#000000">中定义的</font><font color="#000000" face="MS Sans Serif" size="2"><b>IMAGE_DOS_SIGNATURE</b></font><font size="2" color="#000000">常量。若比较成功,继续转到</font><font face="MS Sans Serif" size="2" color="#000000">PE 
  header</font><font size="2" color="#000000">,否则设</font><font color="#000000" face="MS Sans Serif" size="2"><b>ValidPE</b> 
  </font><font size="2" color="#000000">值为</font><font face="MS Sans Serif" size="2" color="#000000">FALSE</font><font size="2" color="#000000">,意味着文件不是有效</font><font face="MS Sans Serif" size="2" color="#000000">PE</font><font size="2" color="#000000">文件。</font></p>
<p><font face="Fixedsys" color="#000000">&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 size="2" color="#000000">要定位到</font><font face="MS Sans Serif" size="2" color="#000000">PE 
  header</font><font size="2" color="#000000">,需要读取</font><font face="MS Sans Serif" size="2" color="#000000">DOS 
  header</font><font size="2" color="#000000">中的</font><font color="#000000" face="MS Sans Serif" size="2"><b>e_lfanew</b></font><font size="2" color="#000000">域值。该域含有</font><font face="MS Sans Serif" size="2" color="#000000">PE 
  header</font><font size="2" color="#000000">在文件中相对文件首部的偏移量。</font><font face="MS Sans Serif" size="2" color="#000000">edi</font><font size="2" color="#000000">加上该值正好定位到</font><font face="MS Sans Serif" size="2" color="#000000">PE 
  header</font><font size="2" color="#000000">的首字节。这儿可能会出错,如果文件不是</font><font face="MS Sans Serif" size="2" color="#000000">PE</font><font size="2" color="#000000">文件,</font><font face="MS Sans Serif" size="2" color="#000000">e_lfanew</font><font size="2" color="#000000">值就不正确,加上该值作为指针就可能导致异常。若不用</font><font face="MS Sans Serif" size="2" color="#000000">SEH</font><font size="2" color="#000000">,我们必须校验</font><font color="#000000" face="MS Sans Serif" size="2"><b>e_lfanew</b></font><font size="2" color="#000000">值是否超出文件尺寸,这不是一个好办法。如果一切</font><font face="MS Sans Serif" size="2" color="#000000">OK</font><font size="2" color="#000000">,我们就比较</font><font face="MS Sans Serif" size="2" color="#000000">PE 
  header</font><font size="2" color="#000000">的首字是否是字符串</font><font face="MS Sans Serif" size="2" color="#000000">"PE"</font><font size="2" color="#000000">。这里在此用到了常量</font><font color="#000000" face="MS Sans Serif" size="2"><b>IMAGE_NT_SIGNATURE</b></font><font size="2" color="#000000">,相等则认为是有效的</font><font face="MS Sans Serif" size="2" color="#000000">PE</font><font size="2" color="#000000">文件。</font><font face="MS Sans Serif" size="2" color="#000000"><br>
  </font><font size="2" color="#000000">如果</font><font color="#000000" face="MS Sans Serif" size="2"><b>e_lfanew</b></font><font size="2" color="#000000">的值不正确导致异常,我们的</font><font face="MS Sans Serif" size="2" color="#000000">SEH</font><font size="2" color="#000000">处理函数就得到执行控制权,简单恢复堆栈指针和基栈指针后,就根据</font><font face="MS Sans Serif" size="2" color="#000000">safeoffset</font><font size="2" color="#000000">的值恢复执行到</font><font face="MS Sans Serif" size="2" color="#000000">FinalExit</font><font size="2" color="#000000">标签处。</font></p>
<p><font face="Fixedsys" color="#000000">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 size="2" color="#000000">上述代码简单明确,根据</font><font face="MS Sans Serif" size="2" color="#000000">ValidPE</font><font size="2" color="#000000">的值显示相应信息。</font></p>
<p><font face="Fixedsys" color="#000000">&nbsp;&nbsp;&nbsp;push seh.PrevLink <br>
  &nbsp;&nbsp;&nbsp;pop fs:[0] </font></p>
<p><font size="2" color="#000000">一旦</font><font face="MS Sans Serif" size="2" color="#000000">SEH</font><font size="2" color="#000000">不再使用,必须从</font><font face="MS Sans Serif" size="2" color="#000000">SEH</font><font size="2" color="#000000">链上断开。</font></p>
<p align=center><font size=2><b>翻译:</b></font><font face="MS Sans Serif" 
size=2><b>iamgufeng [</b></font><a href="http://win32asm.cjb.net/" target="_blank"><font 
face="MS Sans Serif" size=2><b>Iczelion's Win32 Assembly Homepage</b></font></a><font face="MS Sans Serif" 
size=2><b>]</b><strong>[</strong></font><a href="http://asm.yeah.net/" target="_blank"><font 
face="MS Sans Serif" size=2><strong>LuoYunBin's Win32 ASM Page</strong></font></a><font face="MS Sans Serif" 
size=2><strong>]</strong></font></p>
<p align="center"><a href="../Catalog.htm"><img src="../image/navtoc.gif" width="84" height="23" border="0"></a><a href="Chap8-1-1.htm"><img src="../image/Navprev.gif" width="80" height="23" border="0"></a><a href="Chap8-1-3.htm"><img src="../image/navnext.gif" width="83" height="23" border="0"></a></p>
<hr width=735>
<div align="center"><span class="p9"><font size="2"><span class="p9"><font size="2"><span class="p9">Copyright 
  &copy; 2000-2001 <a href="http://www.pediy.com/">KanXue Studio</a> All Rights 
  Reserved.</span></font></span></font></span></div>
</body>
</html>

⌨️ 快捷键说明

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