首页
论坛
课程
招聘
脱壳入门初级教学
2006-1-14 17:20 765287

脱壳入门初级教学

2006-1-14 17:20
765287
标 题: 脱壳基础知识入门及FAQ
作 者: kanxue
时 间: 2006-01-14 17:20
链 接: http://bbs.pediy.com/showthread.php?t=20366

声明:本篇文章个人用户可以免费的收藏、参考,但是谢绝任何商业网站及传统媒体(如出版物)摘编转载!

    现在加解密发展己形成2个分支了,一个就是传统的算法,另一个就是加密壳。越来越多的软件采用了密码学相关算法,现在要做出一个软件注册机己不象前几年那么容易,这就要求解密者必须要有一定的数学功底和密码学知识,而这些在短时间内是不容易掌握的。除了密码学的应用,越来越多的软件加壳了,因此要求解密者必须掌握一些脱壳技术,这就使得壳成了解密必须迈过的一个门槛。壳发展到今天,强度越来越高了,将许多人挡在门外,使得大家望壳兴叹。另外,论坛现在两极分化比较严重,高手讨论的脱壳技术新手看不懂,很多人想学脱壳,但看到壳这么难,只好放弃了,造成新手与高手间一个断档,为了鼓励更多新人加入脱壳的行列,很有必要将壳有关知识总结一下。www.pediy.com主页提供的教学确实有点过时了,己到非更新不可了。为此,整理这篇脱壳入门指导的文章,方便脱壳新手们学习。相对于密码学算法,脱壳并不难,只要肯花时间,短期内还是比较容易取得成绩的。
   但是,不建议那些加解密刚入门,调试一个普通软件都费劲的朋友来脱壳。至少要等你有一定的调试技能再来学脱壳。也就是说必须掌握这篇文章所讲的东西:新手入门必读(FAQ)

     在本篇文章没完成前,不欢迎转载!我会利用业余时间不断更新中,为保持文章连续性,因此锁帖,如学习过程中有问题请开新帖大家一起交流。这篇入门教学将长期置顶,以代替原来脱壳版块的FAQ,收集一些常见的脱壳问题。希望更多的朋友一起参与进来,如果想参与进来请告诉我撰写的主题,我会开通你跟此帖的权限。

注:本人水平有限,因此这篇文章只是负责将新手领进门,更深入技术的请参考论坛中的精华文章。


第一课 PE格式.................2楼 
第二课 SEH技术................3楼 
第三课 认识壳.................4楼 
第四课 常见压缩壳与加密壳......5楼 
第五课 文件类型分析............6楼
第六课 寻找OEP................7楼
第七课 Dump内存映像............9楼
第八课 重建输入表.............10楼
第九课 手动确定IAT的地址与大小.11楼
第十课 DLL文件脱壳 ........12楼
第十一课 优化与自校验去除........12楼

[公告] 2021 KCTF 春季赛 防守方征题火热进行中!

收藏
点赞34
打赏
分享
打赏 + 7.00
打赏次数 2 金额 + 7.00
 
赞赏  spider佳   +5.00 2020/07/17 感谢分享~
赞赏  wolovbm   +2.00 2018/06/28
最新回复 (83)
雪    币: 1850
活跃值: 活跃值 (4719)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 活跃值 8 2006-1-14 17:22
2
0

   第一课 PE格式

   要想学脱壳,第一步就得掌握PE格式,PE是Portable Executable File Format(可移植的执行体)简写,它是目前Windows平台上的主流可执行文件格式。

Microsoft Visual C++提供的WINNT.H里有PE数据结构的完整定义。
推荐文档:
  ah007翻译的“PE文件格式”1.9版
  qduwg翻译的PE文件格式   
  Iczelion's 的PE文件格式
  微软官方提供的PE文档(英文)(Revision 8.1- March 27, 2008)
  微软官方提供的PE文档(Revision 8.1)(zhzhtst翻译成中文)
  探索PE文件内幕—— Win32可移植可执行文件格式之旅(zhzhtst翻译)
  深入剖析Win32可移植可执行文件格式(zhzhtst翻译)   
  PE结构各字段偏移参考

   学习PE格式的方法是自己先准备一个十六进制工具,如HexWorkshopWinHex,用这些工具打开一个EXE文件对照着学。强烈推荐你用
Stud_PE v.2.6.1.0
这款工具辅助学习PE格式。PE格式学习的重点是在输入表(Import Table)这块。
Stud_PE工具界面:

https://bbs.pediy.com/upload/bbs/unpackfaq/Stud_PE.gif

PE结构图:
https://bbs.pediy.com/upload/bbs/unpackfaq/pe.gif

最后于 2020-7-4 22:08 被kanxue编辑 ,原因:
雪    币: 1850
活跃值: 活跃值 (4719)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 活跃值 8 2006-1-14 17:26
3
0

第二课 SEH技术

   结构化异常处理(Structured Exception Handling,SEH)是Windows操作系统处理程序错误或异常的技术。SEH是Windows操作系统的一种系统机制,与特定的程序设计语言无关。
   外壳程序里大量地使用了SEH,如果不了解SEH,将会使你跟踪十分困难。

SEH in ASM 研究(一)by hume
SEH in ASM 研究(二)by hume
Structured Exception Handling
加密与解密二版菜鸟学习笔记(2) - SEH 结构化异常处理 by ytcswb

由于 Ollydbg 对SEH处理异常灵活,因此脱壳用Ollydbg会大大提高效率。

附CONTEXT结构环境:

typedef struct _CONTEXT {

/*000*/ DWORD       ContextFlags;

/*004*/ DWORD       Dr0;
/*008*/ DWORD       Dr1;
/*00C*/ DWORD       Dr2;
/*010*/ DWORD       Dr3;
/*014*/ DWORD       Dr6;
/*018*/ DWORD       Dr7;

/*01C*/ FLOATING_SAVE_AREA FloatSave;

/*08C*/ DWORD       SegGs;
/*090*/ DWORD       SegFs;
/*094*/ DWORD       SegEs;
/*098*/ DWORD       SegDs;

/*09C*/ DWORD       Edi;
/*0A0*/ DWORD       Esi;
/*0A4*/ DWORD       Ebx;
/*0A8*/ DWORD       Edx;
/*0AC*/ DWORD       Ecx;
/*0B0*/ DWORD       Eax;

/*0B4*/ DWORD       Ebp;
/*0B8*/ DWORD       Eip;
/*0BC*/ DWORD       SegCs;
/*0C0*/ DWORD       EFlags;
/*0C4*/ DWORD       Esp;
/*0C8*/ DWORD       SegSs;

/*0CC*/     BYTE    ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];

/*2CC*/ } CONTEXT;
最后于 2020-7-4 22:10 被kanxue编辑 ,原因:
雪    币: 1850
活跃值: 活跃值 (4719)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 活跃值 8 2006-1-14 17:27
4
0

    第三课 认识壳

1. 什么是壳?

   在一些计算机软件里也有一段专门负责保护软件不被非法修改或反编译的程序。它们一般都是先于程序运行,拿到控制权,然后完成它们保护软件的任务。由于这段程序和自然界的壳在功能上有很多相同的地方,基于命名的规则,就把这样的程序称为“壳”了。
   
推荐文档:
一切从“壳”开始

描述壳的示意图:
https://bbs.pediy.com/upload/bbs/unpackfaq/intrpack.gif 

2. 壳的加载过程

    这里谈的加壳工具不是WinZIP、WinRAR等数据压缩工具,而是谈压缩可执行文件EXE或DLL的工具。加壳过的EXE文件是可执行文件,它可以同正常的EXE文件一样执行。用户执行的实际上是外壳程序,这个外壳程序负责把用户原来的程序在内存中解压缩,并把控制权交还给解开后的真正程序,这一切工作都是在内存中运行的,整个过程对用户是透明的。
   壳和病毒在某些方面比较类似,都需要比原程序代码更早的获得控制权。壳修改了原程序的执行文件的组织结构,从而能够比原程序的代码提前获得控制权,并且不会影响原程序的正常运行。
   这里简单说说一般壳的装载过程。(参考了Ljtt以前写过的一篇文章)
   1)获取壳自己所需要使用的API地址
   如果用PE编辑工具查看加壳后的文件,会发现未加壳的文件和加壳后的文件的输入表不一样,加壳后的输入表一般所引入的DLL和API函数很少,甚至只有Kernel32.dll以及GetProcAddress这个API函数。
   壳实际上还需要其他的API函数来完成它的工作,为了隐藏这些API,它一般只在壳的代码中用显式链接方式动态加载这些API函数:3个脱壳相关的重要函数介绍
   2)解密原程序的各个区块(Section)的数据
   壳出于保护原程序代码和数据的目的,一般都会加密原程序文件的各个区块。在程序执行时外壳将会对这些区块数据解密,以让程序能正常运行。 壳一般按区块加密的,那么在解密时也按区块解密,并且把解密的区块数据按照区块的定义放在合适的内存位置。
   如果加壳时用到了压缩技术,那么在解密之前还有一道工序,当然是解压缩。这也是一些壳的特色之一,比如说原来的程序文件未加壳时1~2M大小,加壳后反而只有几百K。
   3)重定位
   文件执行时将被映像到指定内存地址中,这个初始内存地址称为基地址(ImageBase)。当然这只是程序文件中声明的,程序运行时能够保证系统一定满足其要求吗?
   对于EXE的程序文件来说,Windows系统会尽量满足。例如某EXE文件的基地址为0x400000,而运行时Windows系统提供给程序的基地址也同样是0x400000。在这种情况下就不需要进行地址“重定位”了。由于不需要对EXE文件进行“重定位”,所以加壳软件把原程序文件中用于保存重定位信息的区块干脆也删除了,这样使得加壳后的文件更加小巧。有些工具提供“Wipe Reloc”的功能,其实就是这个作用。
   不过对于DLL的动态链接库文件来说,Windows系统没有办法保证每一次DLL运行时提供相同的基地址。这样“重定位”就很重要了,此时壳中也需要提供进行“重定位”的代码,否则原程序中的代码是无法正常运行起来的。从这点来说,加壳的DLL比加壳的EXE更难修正。
   4)HOOK-API
   程序文件中的输入表的作用是让Windows系统在程序运行时提供API的实际地址给程序使用。在程序的第一行代码执行之前,Windows系统就完成了这个工作。
   壳一般都修改了原程序文件的输入表,然后自己模仿Windows系统的工作来填充输入表中相关的数据。在填充过程中,外壳就可填充HOOK-API的代码的地址,这样就可间接地获得程序的控制权。
   5)跳转到程序原入口点(OEP)
    从这个时候起壳就把控制权交还给原程序了,一般的壳在这里会有明显的一个“分界线”。但现在的猛壳己没这界限了,壳里有肉,肉里有壳。

https://bbs.pediy.com/upload/bbs/unpackfaq/loadpack.gif 

3. 压缩引擎   
   
    各类加壳软件,其压缩算法一般不是自己实现的,大多是调用其他的压缩引擎。目前压缩引擎种类比较多,不同的压缩引擎有不同特点,如一些对图像压缩效果好,一些对数据压缩效果好。而加壳软件选择压缩引擎有一个特点,在保证压缩比的条件下,压缩速度慢些关系不是太大,但解压速度一定要快,这样加了壳的EXE文件运行起来速度才不会受太大的影响。例如下面几个压缩引擎就能满足这要求:

1. aPLib压缩引擎 http://www.ibsensoftware.com/,这个库对于低于64K的文件压缩效果较好,速度较快。
2. JCALG1压缩引擎,相对于aPlib,JCALG1对于大文件效果好些。
3. LZMA压缩引擎 http://www.7-zip.org/zh-cn/sdk.html,LZMA 是 7-Zip 程序中 7z 格式 的默认压缩算法,压缩率很高。

最后于 2020-7-4 21:55 被kanxue编辑 ,原因:
雪    币: 1850
活跃值: 活跃值 (4719)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 活跃值 8 2006-1-14 17:30
5
0

    第四课 常见压缩壳与加密壳

    加壳软件按照其加壳目的和作用,可分为两类:一是压缩(Packers),二是保护(Protectors)。压缩这类壳主要目的是减小程序体积,如ASPacK、UPX和PECompact等。另一类是保护程序,用上了各种反跟踪技术保护程序不被调试、脱壳等,其加壳后的体积大小不是其考虑的主要因素,如ASProtect、Armadillo、EXECryptor等。随着加壳技术的发展,这两类软件之间的界线越来越模糊,很多加壳软件除具有较强的压缩性能,同时也有了较强的保护性能。

    目前流行的一些壳可以参考这里:https://tool.pediy.com/   windows/加密工具


1.常用压缩壳介绍   

1). ASPacK   
主页:http://www.aspack.com/
   ASPack是款Win32可执行文件压缩软件,可压缩Windows 32位可执行文件(.exe)以及库文件(.dll、.ocx),文件压缩比率高达40%~70%。

https://bbs.pediy.com/upload/bbs/unpackfaq/aspack.gif 

2). UPX
主页:http://upx.sourceforge.net/
   UPX是一个以命令行方式操作的可执行文件经典免费压缩程序,压缩算法自己实现,速度极快。(开源)

3). PECompact
主页:http://www.bitsum.com/
   PECompact同样也是一款能压缩可执行文件的工具(支持EXE、DLL、SCR、OCX等文件)。相比同类软件,PECompact提供了多种压缩项目的选择,用户可以根据需要确定哪些内部资源需要压缩处理。同时,该软件还提供了加解密的插件接口功能。

https://bbs.pediy.com/upload/bbs/unpackfaq/PECompact.gif 

2.加密保护壳介绍   

  为了保护自己的软件不轻易被他人“借鉴”,有必要对软件进行一些加密保护,而这方面目前己有成熟的专业加密软件可选择。但不要太依赖壳的保护,大多数壳是可以被攻破的,还是在自身保护上下些功夫。加密软件比较多,但在强度与兼容性上做的好的并不多,这里向大家介绍几款常见的。

 现在壳的发展一个趋势就是虚拟机保护,利用虚拟机保护后,能大大提高强度,因此建议尽可能使用此类技术保护软件。如Themida ,WinLicense,EXECryptor等壳带有虚拟机保护功能,因此得用好其SDK。

1). ASProtect
主页:http://www.aspack.com/
   ASProtect是一款非常强大的Windows 32位保护工具,这4、5年来,其一直在更新进步。其开发者是俄国人Alexey Solodovnikov。它拥有压缩、加密、反跟踪代码、反-反汇编代码、CRC校验和花指令等保护措施。它使用Blowfish、Twofish、TEA等强劲的加密算法,还用RSA1024作为注册密钥生成器。它还通过API钩子(API hooks,包括Import hooks(GPA hook)和Export hooks)与加壳的程序进行通信。甚至用到了多态变形引擎(Polymorphic Engine)。反Apihook代码(Anti-Apihook Code)和BPE32的多态变形引擎(BPE32的Polymorphic Engine)。并且ASProtect为软件开发人员提供SDK,实现加密程序内外结合。

https://bbs.pediy.com/upload/bbs/unpackfaq/ASProtect.gif 

   ASProtect SKE系列己采用了部分虚拟机技术,主要是在Protect Original EntryPoint与SDK上。保护过程中建议大量里使用SDK, SDK使用请参考其帮助文档,在使用时注意SDK不要嵌套,并且同一组标签用在同一个子程序段里。ASProtect使用相当的简单,打开被保护的EXE/DLL文件后,选上保护的选项。再单击菜单Modes,单击Add Mode按钮,将Is this Mode Avtive选上,最后,单击Protection标签,对软件进行保护即可。ASProtect加壳过程中也可外挂用户自己写的DLL文件,方法是在上图中的External Options选项加上目标DLL即可。这样,用户可以在DLL加入自己的反跟踪代码,以提高软件的反跟踪能力。

强度评介:由于ASProtect名气太大,研究它的人很多,因此很容易被脱壳,不推荐使用。

2). Armadillo加密壳

   Armadillo也称穿山甲,是一款应用面较广的壳。可以运用各种手段来保护你的软件,同时也可以为软件加上种种限制,包括时间、次数,启动画面等等!很多商用软件采用其加壳。Armadillo对外发行时有Public,Custom两个版本。Public是公开演示的版本,Custom是注册用户拿到的版本。只有Custom才有完整的功能,Public版有功能限制,没什么强度,不建议采用。

https://bbs.pediy.com/upload/bbs/unpackfaq/image003.gif 

强度评介:Armadillo中比较强大的保护选项是Nanomites保护(即CC保护),用的好能提高强度,其他选项没什么强度。

3). EXECryptor加密壳

    EXECryptor也是一款猛壳,可能由于兼容性等原因,采用其保护的商业软件不是太多。这款壳的特点是Anti-Debug做的比较隐蔽,另外就是采用了虚拟机保护一些关键代码。

https://bbs.pediy.com/upload/bbs/unpackfaq/image005.gif 

强度评介:用好EXECryptor 虚拟机保护功能,将关键敏感代码用虚拟机保护起来,能提高强度。EXECryptor 壳能脱的人很多,但对付其虚拟机代码的人不多。

4). Themida加密壳

    Themida是Oreans的一款商业壳,官方链接:www.oreans.com。Themida 1.1以前版本带驱动,稳定性有些影响。Themida最大特点就是其虚拟机保护技术,因此在程序中擅用SDK,将关键的代码让Themida用虚拟机保护起来。Themida最大的缺点就是生成的软件有些大。WinLicense这款壳和Themida是同一公司的一个系列产品,WinLicense主要多了一个协议,可以设定使用时间,运行次数等功能,两者核心保护是一样的。

https://bbs.pediy.com/upload/bbs/unpackfaq/image007.gif 

强度评介:用好其虚拟机保护功能,将关键敏感代码用虚拟机保护起来,能提高强度。

5). VMProtect

  VMProtect是一款纯虚拟机保护软件,官方链接:www.VMProtect.ru。它是当前最强的虚拟机保护软件,经VMProtect处理过的代码,至今还没有人公开宣称能还原。

  但也有缺点,就是会影响程序速度,因此在一些对速度要求很高的场合就不适合用了。VMProtect 1.22.3之前是免费版,可以支持EXE,DLL等文件。更高版本需要购买,其支持驱动的保护。现在流行的做法,先用VMProtect将你的核心代码处理一下,再选用一款兼容性好的壳保护。

(1).关键代码自己定位
 VMProtect并没有提供使用说明,必须告诉VMProtect你要加密的代码具体地址,这对使用者有一定的要求,至少要懂一些跟踪技术,可以用调试器,如OllyDbg跟踪到程序需要保护的地址,然后添加地址到VMProtect。
在这以一个记事本程序为例来演示一下使用方法。

 运行VMProtect后,打开NOTEPAD.EXE文件。单击Dump标签,输入要加密的起始地址,光标来到要加密代码起始地址后,点击菜单“project/new procedure”,会出现一个新的项目,如下图。

https://bbs.pediy.com/upload/bbs/unpackfaq/vm.gif 

需要处理其他地址时,请依次操作。

注意事项:
1.用VMProtect处理,请多测试,如果不稳定,请调整被保护代码的范围。
2.VMProtect对双线程支持不是太好,请同一次仅处理一个线程内的代码。


(2).用SDK标记代码

 VMProtect v1.2以上支持SDK了,可以编程时插入一个标记,然后在加密时,VMProtect会认出这些标记,并在有标记的地方进行保护。在程序源码中,用这对标签将一些核心代码包含,编译成EXE文件。然后用VMProtect打开EXE,单击“Project”菜单下的“New procedure”或者单击工具栏中的“New procedure”按钮,在弹出的添加地址窗口中会自动将SDK定义代码的地址填上。然后在VMProtect的“Options”窗口中设置相应的选项,最后单击工具栏中的“Compilation (F9)”按钮,便可对目标软件进行保护。经VMProtect处理过的软件,可以继续用Asprotect, Themida等加壳软件进一步保护。

 VMProtect是当前最强的虚拟机保护软件,经过VMProtect处理的软件基本是没法分析原程序思路的,关键是用好,一定要将程序关键代码进行处理。另外,经虚拟机处理代码效率会降低,因此一些对效率要求比较高的代码就不要用VMProtect进行处理。

Delphi 中的标记模式

asm                             
  db $EB,$10,'VMProtect begin',0       //标记开始处.
end;
//想保护的程序代码
asm
  db $EB,$0E,'VMProtect end',0         //标记结束处.
end;



VC的VMProtect的宏 :

#define  VMBEGIN 
 __asm    //标记开始处.
    {  
      _emit 0xEB
      _emit 0x10  
      _emit 0x56  
      _emit 0x4D  
      _emit 0x50 
      _emit 0x72 
      _emit 0x6F 
      _emit 0x74 
      _emit 0x65 
      _emit 0x63 
      _emit 0x74 
      _emit 0x20 
      _emit 0x62 
      _emit 0x65 
      _emit 0x67 
      _emit 0x69 
      _emit 0x6E 
      _emit 0x00
    }
    //想保护的程序代码

 #define  VMEND
    __asm  //标记结束处.
    {  
      _emit 0xEB
      _emit 0x0E  
      _emit 0x56   
      _emit 0x4D   
      _emit 0x50 
      _emit 0x72 
      _emit 0x6F 
      _emit 0x74 
      _emit 0x65 
      _emit 0x63 
      _emit 0x74 
      _emit 0x20 
      _emit 0x65 
      _emit 0x6E 
      _emit 0x64 
      _emit 0x00
    }



VMProtect使用相关文档:
VMProtect配合PESpin的SDK加密的另一方法   作者:acafeel
VMProtect SDK+ASProtect SDK混合编程[代码演示] 作者:Anskya
VMProtect 与 ASProtect 在VC中的SDK编程 作者:glucose

3.小结   

更多与壳有关的描述参考:
   纵横间谁能相抗―论壳与加壳技术  作者:forgot

常见加密壳官方站点

ASProtect           http://www.aspack.com/
ACProtect           http://www.ultraprotect.com/
Armadillo           http://www.siliconrealms.com
EXECryptor          http://www.strongbit.com/
Obsidium            http://www.obsidium.de/
PESpin              http://pespin.w.interia.pl/
VMProtect           http://www.polytech.ural.ru/
Xtreme-Protector    http://www.oreans.com/xprotector/
Themida/WinLicense  http://www.oreans.com

本站的工具栏目:    http://www.pediy.com/tools/packers.htm

最后于 2020-7-4 22:13 被kanxue编辑 ,原因:
雪    币: 1850
活跃值: 活跃值 (4719)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 活跃值 8 2006-1-15 11:13
6
0

    第五课 文件类型分析

   拿到一个壳,第一步就是用相关工具分析一下是什么壳,然后就可心中有数地跟踪分析。文件分析工具有PEIDFileInfo等。

1.PEiD

   PEiD的GUI界面操作非常方便直观。它的原理是利用查特征串搜索来完成识别工作的。各种开发语言都有固定的启动代码部分,利用这点就可识别出是何种语言编编译的。同样,不同的壳也有其特征码,利用这点就可识别是被何种壳所加密。PEiD提供了一个扩展接口文件userdb.txt ,用户可以自定义一些特征码,这样就可识别出新的文件类型。
   有些外壳程序为了欺骗PEiD等文件识别软件,会伪造启动代码部分,例如将入口代码改成与Visual C++ 6.0所编程程序入口处类似代码,即可达到欺骗目的。所以,文件识别工具所给出的结果只是个参考,文件是否被加壳处理过,还得跟踪分析程序代码才可得知。 可参考这个文档了解如何伪装:让侦测工具把壳识别为VC++7.0的源代码 。目前Hying的壳PE-Armor伪装能力是最强的:

https://bbs.pediy.com/upload/bbs/unpackfaq/hying.gif 

   PEiD分析不出类型的文件就报告是“Nothing found *”,如出现这情况一般都是未知壳或新版的壳。

下面PEiD识别出这个软件是用Asprotect 1.2x加的壳。


https://bbs.pediy.com/upload/bbs/unpackfaq/peid.gif 

2.FileInfo

   FileInfo(简称Fi)另一款不错的文件检测工具。Fi运行时是DOS界面,在DOS窗口中运行程序相当不便,建议采用下面的技巧:
1.用鼠标将文件拖到Fi主文件上。
2.将Fi快捷方放进Windows的SendTo文件夹里.以后要分析某文件,只需右击“发送到”功能就可打开Fi。   
   FileInfo升级慢,其识别库不能自定义。而PEiD升级比较频繁,用户也可自定义特征码,因此PEiD用的比较普遍。

   有时,FileInfo和PEID会报“PE Win GUI”,Win GUI就是Windows图形用户界面程序统称,表明程序可能没加壳。但不排除也有加壳的可能性,下图是一个ExeCryptor 2.2x的壳,FileInfo报“*PE Win GUI *section* ??”,其不能识别出来。识别信息中带了个问号,表明FI对给出的结果不是太肯定。

https://bbs.pediy.com/upload/bbs/unpackfaq/FileInfo.gif

最后于 2020-7-4 21:58 被kanxue编辑 ,原因:
雪    币: 1850
活跃值: 活跃值 (4719)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 活跃值 8 2006-1-15 16:22
7
0

第六课 寻找OEP

一般的压缩壳,如Aspack等都有专用的脱壳机 。而加密壳(如ASProtect,Armadillo) 一般很少有脱壳机,必须手工脱壳。手工脱壳一般情况是分三步:一是查找程序的真正入口点(OEP);二是抓取内存映像文件;三是输入表重建。(当然现在的加密壳复杂些,要考虑更多的东西)
OEP是Original Entry Point缩写,即程序加壳前的真正的入口点。
外壳初始化的现场环境(各寄存器值)与原程序的现场环境是相同的。加壳程序初始化时保存各寄存器的值,外壳执行完毕,会恢复各寄存器内容。其代码形式一般如下:

PUSHFD ; 将标志寄存器入栈保存
PUSHAD ; push eax, ecx, edx, ebx, esp, ebp, esi, edi
…… ; 外壳代码部分
POPAD ; pop edi, esi, ebp, esp, ebx, edx, ecx, eax
POPFD ; 恢复标志寄存器
JMP OEP ;
OEP: …… ; 解压后的程序原代码

为了讲述方便,本节用UPX加壳的Win98记事本来演示。首先用PEid查看加壳前的记事本:

 

PEid显示Notepad.exe程序是用Microsoft Visual C++ 6.0编译的,接下来用UPX来加壳,方法是开个DOS窗口,用命令upx notepad.exe。如下图所示:



这时再用PEid查看加壳的文件,PEid会给出如下信息:UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo


UPX的壳可以用UPX.exe自身来脱,命令是:upx -d 文件名 。一些变种的UPX壳用UPX.EXE自身脱不了,这时可以试试UPX ShellEx 这款工具。

本节实例下载:notepad.upx.rar

脱壳前建议用PE工具LordPE打开目标文件查看一下区块,以尽可能地多了解一些信息,对脱壳有帮助,如下图:

 

1.根据跨段指令寻找OEP

推荐用Ollydbg来调试脱壳,比SoftICE和TRW2000方便多了。运行Ollydbg,点击菜单“选项/调试设置”,将第一次暂停设在WinMain函数上。再用Ollydbg打开实例notepad.upx.exe就可中断在外壳的入口点处了:

 

上图相关代码如下:
0040E8C0 > 60 pushad //一开始Ollydbg就会中断这行,这个就是外壳的入口点,注意这个pushad指令

绝大多数加壳程序在被加密的程序中加上一个或多个段,所以依据跨段的转移指令(JMP)就可找到真正的入口点,此时就会有POPAD/POPFD指令出现。UPX 用了一次跨段的转移指令(JMP),在跳到OEP处会看到虚拟地址的值有一个突变,此时就能确定OEP了。
UPX壳比较简单,大家不必要跟踪去找这个跨段的转移指令,中断WinMain后,只需要在Ollydbg里往下翻屏,就会发现这个跨段转移指令:

 

上图相关代码如下:
0040EA0E 61 popad //注意这里的popad指令,和开始的pushad对应
0040EA0F - E9 B826FFFF jmp 004010CC //这里跳到OEP,将光标移到这,按F4执行到这行

这一句0040EA0F jmp 004010CC 就是跳到OEP的指令,执行到这,UPX外壳己将程序解压完毕,并模拟Windows加载器的将原始程序加载到内存,004010CC 就是映射到内存目标程序的入口点,此时就可抓取内存映像文件了。

2.根据堆栈平衡原理找OEP

这个堆栈平衡原理其找OEP原理这篇文档描述的比较详细:寻找真正的入口(OEP)--广义ESP定律 作者:Lenus
操作方法:多数壳在运行到OEP的时候ESP=0012FFC4,这就是说程序的第一句是对0012FFC0进行写入操作,只要在0012FFC0下硬件写入断点(命令行里键入HW 12FFC0),我们就能停在OEP的第二句处。
注意:并不是所有程序加载时,ESP的值是0012FFC4,这个值是什么由操作系统决定,将SizeOfStackCOmmit改大ESP就会变,这是因为操作系统从这个页向上找一个足够大地方当作stack了(感谢forgot解释)。你只要记住你系统加载时的ESP值,对其设断即可。

用OllyDBG重新加载实例程序notepad.upx.exe,在命令行下硬件写断点:

 

按F9执行程序,就会中断在OEP第二行:

 

此时如果将光标向上移,会发现第一句代码变乱了:
004010C7 000D 0A000055 add [5500000A], cl
004010CD 8BEC mov ebp, esp

这是因为Ollydbg将数据当汇编代码来分析了,你可以按 Ctrl+ALT+向上光标键 将当前显示的代码向上滚动一个字节就可看到正确的汇编代码了:

004010CC 55 push ebp
004010CD 8BEC mov ebp, esp //中断在这行
004010CF 83EC 44 sub esp, 44
004010D2 56 push esi
004010D3 FF15 E4634000 call [4063E4] ; kernel32.GetCommandLineA

中断后,别忘点击菜单“调试/硬件断点/”打开硬件断点面板,将刚才的硬件断点删除。


 

小知识: 硬件断点的原理 作者:Lenus

3.根据编译语言特点找OEP

各类语言编译的文件入口点都有一些规律,可以这利用这点来寻找入口点。
1)Delphi程序
执行程序,用LordPE(或Prodump)选dump(full)脱壳,存为dump.exe。接着用Hex Workshop打开dump.exe,搜索文本“runtime”,搜到后,向前查找离“runtime”最近的十六进制数字“55 8B EC”,数字所在的地址就是程序的OEP。
2)Visual C程序
可以利用Visual C启动部分的几个函数GetCommandLineA(W)、GetVersion、GetModuleHandleA(W)、GetStartupInfoA(W) 等来定位程序的OEP。

常见的各类编译语言的入口汇编代码都要熟悉,因为一些加密强壳会偷OEP处的代码到壳里,一般情况各编译语言入口代码都相同,到时只需要直接引用相关程序的入口代码,这给我们恢复代码带来方便。

雪    币: 197
活跃值: 活跃值 (76)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝