`
cfree
  • 浏览: 18551 次
  • 性别: Icon_minigender_1
  • 来自: 成都
最近访客 更多访客>>
社区版块
存档分类
最新评论

压缩与脱壳-PE文件格式 二

阅读更多

检验PE文件的有效性

理论 :
   如何才能校验指定文件是否为一有效 PE 文件呢 ? 这个问题很难回答,完全取决于想要的精准程度。您可以检验 PE 文件格式里的各个数据结构,或者仅校验一些关键数据结构。大多数情况下,没有必要校验文件里的每一个数据结构,只要一些关键数据结构有效,我们就认为是有效的 PE 文件了。下面我们就来实现前面的假设。

  我们要验证的重要数据结构就是 PE header 。从编程角度看, PE header 实际就是一个 IMAGE_NT_HEADERS 结构。定义如下 :

Signature 一 dword 类型,值为 50h, 45h, 00h, 00h ( PE )。 本域为 PE 标记,我们可以此识别给定文件是否为有效 PE 文件。
  FileHeader 该结构域包含了关于 PE 文件物理分布的信息, 比如节数目、文件执行机器等。
  OptionalHeader 该结构域包含了关于 PE 文件逻辑分布的信息,虽然域名有 " 可选 " 字样,但实际上本结构总是存在的。
  我们目的很明确。如果 IMAGE_NT_HEADERS 的 signature 域值等于 "PE" ,那么就是有效的 PE 文件。实际上,为了比较方便, Microsoft 已定义了常量 IMAGE_NT_SIGNATURE 供我们使用。



 接下来的问题是 : 如何定位 PE header? 答案很简单 : DOS MZ header 已经包含了指向 PE header 的文件偏移量。 DOS MZ header 又定义成结构 IMAGE_DOS_HEADER 。查询 windows.inc ,我们知道 IMAGE_DOS_HEADER 结构的 e_lfanew 成员就是指向 PE header 的文件偏移量。

  现在将所有步骤总结如下 :

首先检验文件头部第一个字的值是否等于 IMAGE_DOS_SIGNATURE , 是则 DOS MZ header 有效。 一旦证明文件的 DOS header 有效后,就可用 e_lfanew 来定位 PE header 了。 比较 PE header 的第一个字的值是否等于 IMAGE_NT_HEADER 。如果前后两个值都匹配,那我们就认为该文件是一个有效的 PE 文件。 Example:

.386
.model flat,stdcall
option casemap:none
include masm32includewindows.inc
include masm32includekernel32.inc
include masm32includecomdlg32.inc
include masm32includeuser32.inc
includelib masm32libuser32.lib
includelib masm32libkernel32.lib
includelib masm32libcomdlg32.lib
SEH struct
PrevLink dd ? ; the address of the previous seh structure
CurrentHandler dd ? ; the address of the exception handler
SafeOffset dd ? ; The offset where it's safe to continue execution
PrevEsp dd ? ; the old value in esp
PrevEbp dd ? ; The old value in ebp
SEH ends
.data
AppName db "PE tutorial no.2",0
ofn OPENFILENAME <>
FilterString db "Executable Files (*.exe, *.dll)",0,"*.exe;*.dll",0
db "All Files",0,"*.*",0,0
FileOpenError db "Cannot open the file for reading",0
FileOpenMappingError db "Cannot open the file for memory mapping",0
FileMappingError db "Cannot map the file into memory",0
FileValidPE db "This file is a valid PE",0
FileInValidPE db "This file is not a valid PE",0
.data?
buffer db 512 dup(?)
hFile dd ?
hMapping dd ?
pMapping dd ?
ValidPE dd ?
.code
start proc
LOCAL seh:SEH
mov ofn.lStructSize,SIZEOF ofn
mov ofn.lpstrFilter, OFFSET FilterString
mov ofn.lpstrFile, OFFSET buffer
mov ofn.nMaxFile,512
mov ofn.Flags, OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_LONGNAMES or OFN_EXPLORER or OFN_HIDEREADONLY
invoke GetOpenFileName, ADDR ofn
.if eax==TRUE
invoke CreateFile, addr buffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
.if eax!=INVALID_HANDLE_VALUE
mov hFile, eax
invoke CreateFileMapping, hFile, NULL, PAGE_READONLY,0,0,0
.if eax!=NULL
mov hMapping, eax
invoke MapViewOfFile,hMapping,FILE_MAP_READ,0,0,0
.if eax!=NULL
mov pMapping,eax
assume fs:nothing
push fs:[0]
pop seh.PrevLink
mov seh.CurrentHandler,offset SEHHandler
mov seh.SafeOffset,offset FinalExit
lea eax,seh
mov fs:[0], eax
mov seh.PrevEsp,esp
mov seh.PrevEbp,ebp
mov edi, pMapping
assume edi:ptr IMAGE_DOS_HEADER
.if [edi].e_magic==IMAGE_DOS_SIGNATURE
add edi, [edi].e_lfanew
assume edi:ptr IMAGE_NT_HEADERS
.if [edi].Signature==IMAGE_NT_SIGNATURE
mov ValidPE, TRUE
.else
mov ValidPE, FALSE
.endif
.else
mov ValidPE,FALSE
.endif
FinalExit:
.if ValidPE==TRUE
invoke MessageBox, 0, addr FileValidPE, addr AppName, MB_OK+MB_ICONINFORMATION
.else
invoke MessageBox, 0, addr FileInValidPE, addr AppName, MB_OK+MB_ICONINFORMATION
.endif
push seh.PrevLink
pop fs:[0]
invoke UnmapViewOfFile, pMapping
.else
invoke MessageBox, 0, addr FileMappingError, addr AppName, MB_OK+MB_ICONERROR
.endif
invoke CloseHandle,hMapping
.else
invoke MessageBox, 0, addr FileOpenMappingError, addr AppName, MB_OK+MB_ICONERROR
.endif
invoke CloseHandle, hFile
.else
invoke MessageBox, 0, addr FileOpenError, addr AppName, MB_OK+MB_ICONERROR
.endif
.endif
invoke ExitProcess, 0
start endp
SEHHandler proc uses edx pExcept:DWORD, pFrame:DWORD, pContext:DWORD, pDispatch:DWORD
mov edx,pFrame
assume edx:ptr SEH
mov eax,pContext
assume eax:ptr CONTEXT
push [edx].SafeOffset
pop [eax].regEip
push [edx].PrevEsp
pop [eax].regEsp
push [edx].PrevEbp
pop [eax].regEbp
mov ValidPE, FALSE
mov eax,ExceptionContinueExecution
ret
SEHHandler endp
end start


分析 :
  本例程打开一文件,先检验 DOS header 是否有效,有效就接着检验 PE header 的有效性, ok 就认为是有效的 PE 文件了。这里,我们还运用了结构异常处理 (SEH) ,这样就不必检查每个可能的错误 : 如果有错误出现,就认为 PE 检测失效所致,于是给出我们的报错信息。其实 Windows 内部普遍使用 SEH 来检验参数传递的有效性。若对 SEH 感兴趣的话,可阅读 Jeremy Gordon 的 文章 。

  程序调用打开文件通用对话框,用户选定执行文件后,程序便打开文件并映射到内存。并在有效性检验前建立一 SEH:

assume fs:nothing
push fs:[0]
pop seh.PrevLink
mov seh.CurrentHandler,offset SEHHandler
mov seh.SafeOffset,offset FinalExit
lea eax,seh
mov fs:[0], eax
mov seh.PrevEsp,esp
mov seh.PrevEbp,ebp


一开始就假设寄存器 fs 为空( assume fs:nothing )。 记住这一步不能省却,因为 MASM 假设 fs 寄存器为 ERROR 。接下来保存 Windows 使用的旧 SEH 处理函数地址到我们自己定义的结构中,同时保存我们的 SEH 处理函数地址和异常处理时的执行恢复地址,这样一旦错误发生就能由异常处理函数安全地恢复执行了。同时还保存当前 esp 及 ebp 的值,以便我们的 SEH 处理函数将堆栈恢复到正常状态。

mov edi, pMapping
assume edi:ptr IMAGE_DOS_HEADER
.if [edi].e_magic==IMAGE_DOS_SIGNATURE

成功建立 SEH 后继续校验工作。置目标文件的首字节地址给 edi ,使其指向 DOS header 的首字节。为便于比较,我们告诉编译器可以假定 edi 正指向 IMAGE_DOS_HEADER 结构 ( 事实亦是如此 ) 。然后比较 DOS header 的首字是否等于字符串 "MZ" ,这里利用了 windows.inc 中定义的 IMAGE_DOS_SIGNATURE 常量。若比较成功,继续转到 PE header ,否则设 ValidPE 值为 FALSE ,意味着文件不是有效 PE 文件。
add edi, [edi].e_lfanew
assume edi:ptr IMAGE_NT_HEADERS
.if [edi].Signature==IMAGE_NT_SIGNATURE
mov ValidPE, TRUE
.else
mov ValidPE, FALSE
.endif

要定位到 PE header ,需要读取 DOS header 中的 e_lfanew 域值。该域含有 PE header 在文件中相对文件首部的偏移量。 edi 加上该值正好定位到 PE header 的首字节。这儿可能会出错,如果文件不是 PE 文件, e_lfanew 值就不正确,加上该值作为指针就可能导致异常。若不用 SEH ,我们必须校验 e_lfanew 值是否超出文件尺寸,这不是一个好办法。如果一切 OK ,我们就比较 PE header 的首字是否是字符串 "PE" 。这里在此用到了常量 IMAGE_NT_SIGNATURE ,相等则认为是有效的 PE 文件。

  如果 e_lfanew 的值不正确导致异常,我们的 SEH 处理函数就得到执行控制权,简单恢复堆栈指针和基栈指针后,就根据 safeoffset 的值恢复执行到 FinalExit 标签处。

FinalExit:
.if ValidPE==TRUE
invoke MessageBox, 0, addr FileValidPE, addr AppName, MB_OK+MB_ICONINFORMATION
.else
invoke MessageBox, 0, addr FileInValidPE, addr AppName, MB_OK+MB_ICONINFORMATION
.endif


上述代码简单明确,根据 ValidPE 的值显示相应信息。

push seh.PrevLink
pop fs:[0]
一旦 SEH 不再使用,必须从 SEH 链上断开。
  • 大小: 14.9 KB
  • 大小: 16.4 KB
分享到:
评论

相关推荐

    PE文件中脱壳技术的研究

    ### PE文件中脱壳技术的研究 #### 摘要与背景 随着信息技术的快速发展,软件保护成为了一个重要的议题。为了防止软件被非法复制或者逆向工程,开发人员常常采用一种称为“加壳”的技术来保护自己的软件产品。然而...

    PE文件的UPX脱壳算法的实现

    都会使计算机产生安全隐患或者使软件的核心技术被窃取,所以保护PE文件不被修改是一件很重要的工作,当前通常采用加壳的方法对PE文件进行保护,这其中UPX是具有代表性的压缩类外壳。 本文首先对PE文件格式进行了全面...

    脱壳工具UPX -EXE/Dll资源压缩工具-UPX-4.2.2

    UPX是一个着名的压缩壳,主要功能是压缩PE文件(比如exe,dll等文件),有时候也可能被病毒用于免杀。壳upx是一种保护程序。 ........................ UPX是大家熟悉的EXE/Dll资源压缩工具,也称作可执行文件压缩...

    PE万能脱壳工具想脱什么脱什么!!!

    PE文件格式是Windows操作系统中用于执行程序的标准格式,包括可执行文件(.exe)、动态链接库(.dll)等。PE脱壳工具能够识别并处理这些文件中的各种壳技术,例如UPX、ASPack、PECompact等。这些壳通常用于压缩程序...

    upx脱壳机--用于upx类脱壳

    UPX(UPX UnPacker eXtended)是一款广泛使用的可执行文件压缩工具,它能够将PE(Portable Executable,Windows平台上的可执行文件格式)文件进行压缩,从而减小程序的体积,提高分发效率。然而,这也为逆向工程和...

    PECompact脱壳工具

    在计算机安全领域,PECompact是一款知名的可执行文件打包和压缩工具,它能够将Windows下的PE(Portable Executable)格式文件进行压缩,从而减小文件体积,提高分发效率。然而,这样的压缩过程也使得一些恶意软件...

    Aspack stripper 自动脱壳 ASPack 2.12 - Alexey Solodovnikov.rar

    Aspack stripper就是这样的一个工具,它的主要功能是对使用ASPack 2.12版本压缩的可执行文件进行自动脱壳。这个工具的存在,使得安全分析人员能够揭示被压缩和混淆的原始代码,从而更好地理解软件的工作原理,检查...

    脱壳基础知识入门--强烈推荐

    总结以上内容,脱壳是逆向工程的重要组成部分,需要掌握PE文件格式、SEH机制、调试工具的使用,以及对各种加密算法和保护技术的理解。只有对这些基础知识和高级技术有了充分的认识,才能在软件安全和逆向工程的道路...

    解密之脱壳入门.pdf

    对于想要深入理解脱壳技术的学习者来说,熟悉PE文件格式至关重要。 **PE文件格式简介** - **定义**:PE格式由微软开发,用于定义Windows平台上可执行文件(如.EXE、.DLL等)的结构。 - **关键特性**:PE文件包含了...

    UPX加脱壳工具源码

    2. **脱壳机制**:脱壳工具的核心在于正确地解压UPX壳并恢复原始的未压缩PE文件。源码可能会包含解压算法,根据UPX的压缩格式进行还原。 3. **内存操作**:由于程序可能已经在内存中运行,脱壳工具可能需要在内存中...

    实现通用脱壳机

    - **静态与动态分析的兼容性**:构建一个可以在静态分析时重建有效PE文件,并在动态分析时执行的PE文件。 - **防止恶意软件检测**:确保脱壳过程不会被恶意软件检测到,避免分析过程中的干扰。 - **兼容性问题**:...

    Un-ASPACK2.1和2.2脱壳机 汉化版

    2. **代码压缩**:将原始代码进行压缩,以减少文件大小,同时增加解密和解压缩代码。 3. **反调试技术**:添加检测调试器的代码,一旦检测到调试器的存在,程序可能会立即终止运行。 4. **代码混淆**:通过修改指令...

    ASPack_2.12脱壳机

    这个过程涉及到对PE(Portable Executable)文件格式的理解,包括节区、导入表、导出表等关键结构。脱壳机通过识别和解析ASPack的特定标志和模式来实现这一目标。 在安全社区中,ASPack常被视为一种双刃剑。一方面...

    红黑全能自动脱壳机——全能脱壳机

    2.支持文件拖拽功能 3.脱未知壳时,如果IAT加密了,请选上解密加密IAT项,进行IAT还原 下面是它能脱的壳: upx 0.5x-3.00 aspack 1.x--2.x PEcompact 0.90--1.76 PEcompact 2.06--2.79 NsPack nPack FSG 1.0--...

    手动脱壳第二课 UPX 1.08.zip

    1. **分析PE文件结构**:首先要熟悉PE(Portable Executable)文件格式,这是Windows操作系统下的可执行文件格式。理解导入表、节区、重定位等概念是脱壳的基础。 2. **识别壳特征**:通过工具如PEview或OllyDbg,...

    free upx 脱壳工具

    你可以用它来压缩或解压缩PE(Windows)、ELF(Linux)或DOS格式的可执行文件。例如,将一个.exe文件压缩,可以使用以下命令: ``` upx -q your_program.exe ``` 如果想要脱壳,只需添加`-d`参数: ``` upx -qd your...

    .Net 脱壳 反混淆神器De4dot-3.1.41592最新版

    有些模糊处理一个Win32 PE等包装.NET程序集里面的.NET反编译器无法读取该文件。 移除大多数/所有的垃圾类添加混淆。 修复了一些的peverify错误。许多混淆器是马车和创建无法验证的代码错误。 还原类型的方法的参数和...

    UPX加壳、脱壳工具的UPX加壳、脱壳工具的

    但这需要深入理解PE文件格式和UPX壳的内部机制。 2. 自动脱壳工具:存在许多自动化工具如UPX-unpacker、PE-bear等,它们能识别并移除UPX壳,恢复原始可执行文件。例如,我们可以使用UPX-iT.EXE这个工具尝试对加壳...

Global site tag (gtag.js) - Google Analytics