📄 chap8-1-2.htm.primary
字号:
<html>
<head>
<title>Crack Tutorial</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<link rel="stylesheet" href="style/css.css" type="text/css">
<link rel="stylesheet" href="../STYLE/Css.css" type="text/css">
</head>
<body bgcolor="white" text="#000000" link="#004080" vlink="#004080" background="../image/Back.gif">
<p><a href="../catalog.htm">目录</a>>>第8章</p>
<p align="center" class="shadow1Copy"><b class="p3">第8章 压缩与脱壳</b></p>
<table width="80%" border="0" cellspacing="0" cellpadding="3" align="center" bgcolor="#bcbcbc" bordercolor="#111111" class="shadow1">
<tr>
<td class="shadow1" width="20%">
<div align="center"><a href="Chap8-1.htm"><font color="#FFFFFF">第一节 PE文件格式</font></a></div>
</td>
<td class="shadow1" width="20%">
<div align="center"><a href="Chap8-2.htm"><font color="#FFFFFF">第二节 认识脱壳</font></a></div>
</td>
<td class="shadow1" width="20%">
<div align="center"><a href="Chap8-3-1.htm"><font color="#FFFFFF">第三节 自动脱壳</font></a></div>
</td>
<td class="shadow1" width="20%">
<div align="center"><a href="Chap8-4.htm"><font color="#FFFFFF">第四节 手动脱壳</font></a></div>
</td>
<td class="shadow1" width="20%">
<div align="center"><a href="Chap8-5.htm"><font color="#FFFFFF">第五节 脱壳高级篇</font></a></div>
</td>
</tr>
</table>
<p align="center"><span class="p9"><b>第一节 PE文件格式</b></span></p>
<table width="80%" border="1" align="center" bgcolor="#efefef" cellpadding="5" cellspacing="0" bordercolor="#111111">
<tr>
<td>1、<a href="Chap8-1-1.htm">PE文件格式一览 </a></td>
<td>2、<a href="Chap8-1-2.htm">检验PE文件的有效性 </a> </td>
<td><span class="p9"><span class="p9">3、<span class="p9"><a href="Chap8-1-3.htm">File
Header(文件头)</a></span></span></span></td>
<td>4、<a href="Chap8-1-4.htm">Optional Header</a></td>
</tr>
<tr>
<td>5、<a href="Chap8-1-5.htm">Section Table</a></td>
<td>6、<a href="Chap8-1-6.htm">Import Table</a></td>
<td>7、<a href="Chap8-1-7.htm">Export Table</a></td>
<td> </td>
</tr>
</table>
<h1 align=center><font color="#000000">PE教程2: 检验PE文件的有效性</font></h1>
<p><font size="2" color="#000000">本教程中我们将学习如何检测给定文件是一有效</font><font face="MS Sans Serif" size="2" color="#000000">PE</font><font size="2" color="#000000">文件。<br>
下载 </font><font color="#000000"><a
href="technology/PE-tut02.zip"><font
size=2>范例</font></a></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">PE</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">PE</font><font size="2" color="#000000">文件了。下面我们就来实现前面的假设。</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">PE
header </font><font size="2" color="#000000">实际就是一个 </font><font face="MS Sans Serif" size="2" color="#000000">IMAGE_NT_HEADERS
</font><font size="2" color="#000000">结构。定义如下</font><font face="MS Sans Serif" size="2" color="#000000">:</font></p>
<p><font face="MS Sans Serif" size="2" color="#000000"><b>IMAGE_NT_HEADERS STRUCT
<br>
Signature dd ? <br>
FileHeader IMAGE_FILE_HEADER <> <br>
OptionalHeader IMAGE_OPTIONAL_HEADER32 <> <br>
IMAGE_NT_HEADERS ENDS </b></font></p>
<p><font color="#000000" face="MS Sans Serif" size="2"><b>Signature</b> </font><font size="2" color="#000000">一</font><font face="MS Sans Serif" size="2" color="#000000">dword</font><font size="2" color="#000000">类型,值为</font><font face="MS Sans Serif" size="2" color="#000000">50h,
45h, 00h, 00h</font><font size="2" color="#000000">(</font><font face="MS Sans Serif" size="2" color="#000000">PE\0\0</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">PE</font><font size="2" color="#000000">文件。</font><font color="#000000"><br>
<font
face="MS Sans Serif" size=2><b>FileHeader </b></font></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">
</font><font size="2" color="#000000">比如节数目、文件执行机器等。</font><font face="MS Sans Serif" size="2" color="#000000"><br>
<b>OptionalHeader</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">"</font><font size="2" color="#000000">可选</font><font face="MS Sans Serif" size="2" color="#000000">"</font><font size="2" color="#000000">字样,但实际上本结构总是存在的。</font></p>
<p><font size="2" color="#000000">我们目的很明确。如果</font><font color="#000000" face="MS Sans Serif" size="2"><b>IMAGE_NT_HEADERS</b></font><font size="2" color="#000000">的</font><font face="MS Sans Serif" size="2" color="#000000">signature</font><font size="2" color="#000000">域值等于</font><font face="MS Sans Serif" size="2" color="#000000">"PE\0\0"</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">Microsoft</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></p>
<p><font color="#000000" face="MS Sans Serif" size="2"><b>IMAGE_DOS_SIGNATURE
equ 5A4Dh <br>
IMAGE_OS2_SIGNATURE equ 454Eh <br>
IMAGE_OS2_SIGNATURE_LE equ 454Ch <br>
IMAGE_VXD_SIGNATURE equ 454Ch <br>
IMAGE_NT_SIGNATURE equ 4550h </b></font></p>
<p><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
header? </font><font size="2" color="#000000">答案很简单</font><font face="MS Sans Serif" size="2" color="#000000">:
DOS MZ 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">DOS
MZ header </font><font size="2" color="#000000">又定义成结构<b> </b></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">windows.inc</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 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></p>
<p><font size="2" color="#000000">现在将所有步骤总结如下</font><font face="MS Sans Serif" size="2" color="#000000">:</font></p>
<ol>
<li><font size="2" color="#000000">首先检验文件头部第一个字的值是否等于 </font><font color="#000000" face="MS Sans Serif" size="2"><b>IMAGE_DOS_SIGNATURE</b></font><font color="#000000" size="2"><b>,</b>是则
</font><font face="MS Sans Serif" size="2" color="#000000">DOS MZ header </font><font size="2" color="#000000">有效。</font>
<li><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">e_lfanew</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>
<li><font size="2" color="#000000">比较 </font><font face="MS Sans Serif" size="2" color="#000000">PE
header </font><font size="2" color="#000000">的第一个字的值是否等于<b> </b></font><font color="#000000" face="MS Sans Serif" size="2"><b>IMAGE_NT_HEADER</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>
</li>
</ol>
<h3><font face="Arial, Helvetica, sans-serif" color="#000000">Example:</font></h3>
<p><font face="Fixedsys" color="#000000">.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 ? ; the address of the previous seh structure
<br>
CurrentHandler dd ? ; the address of the exception handler
<br>
SafeOffset dd ? ; The offset where it's safe to continue execution
<br>
PrevEsp dd ? ; the old value in esp <br>
PrevEbp dd ? ; 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>
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>
invoke CreateFile, addr buffer, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL <br>
.if eax!=INVALID_HANDLE_VALUE <br>
mov hFile, eax <br>
invoke CreateFileMapping, hFile, NULL,
PAGE_READONLY,0,0,0 <br>
.if eax!=NULL <br>
mov hMapping, eax <br>
invoke MapViewOfFile,hMapping,FILE_MAP_READ,0,0,0
<br>
.if eax!=NULL <br>
mov
pMapping,eax <br>
assume
fs:nothing <br>
push
fs:[0] <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -