吾日三而省乎己!
级别: 论坛版主

UID: 1917
精华: 5
发帖: 2876
威望: 361 点
星星铁: 715 块
贡献值: 22 点
在线时间: 205(小时)
注册时间: 2006-04-28
最后登录: 2008-12-30
楼主  发表于: 2007-03-07 08:48

 【不断更新中】脱壳基础知识入门及FAQ(1--3课)

看雪论坛鼎力打造


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

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

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

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

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

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

Microsoft Visual C++提供的
WINNT.H里有PE数据结构的完整定义。
推荐文档:
  
ah007翻译的“PE文件格式”1.9版
  
qduwg翻译的PE文件格式   
  
Iczelion's 的PE文件格式
  PE结构各字段偏移参考
  
微软官方提供的PE文档(Revision 8.0 - May 16, 2006)


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


PE结构图:


第二课 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结构环境:

[pre]代码:
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;
[/pre]
第三课 认识壳


1. 什么是壳?

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

描述壳的示意图:



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)
    从这个时候起壳就把控制权交还给原程序了,一般的壳在这里会有明显的一个“分界线”。但现在的猛壳己没这界限了,壳里有肉,肉里有壳。



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 格式 的默认压缩算法,压缩率很高。转载原创帖请注明出自看雪论坛pediy.com,本贴地址请保留:http://bbs.pediy.com/showthread.php?s=&threadid=20366
2009今年过年不回家
吾日三而省乎己!
级别: 论坛版主

UID: 1917
精华: 5
发帖: 2876
威望: 361 点
星星铁: 715 块
贡献值: 22 点
在线时间: 205(小时)
注册时间: 2006-04-28
最后登录: 2008-12-30
1楼  发表于: 2007-03-07 08:49
自己沙发了!
[ 此贴被sunny在2007-03-07 08:55重新编辑 ]
2009今年过年不回家
★天使之翼★
级别: Windows 95

UID: 11839
精华: 1
发帖: 931
威望: 21 点
星星铁: 2 块
贡献值: 3 点
在线时间: 185(小时)
注册时间: 2006-09-21
最后登录: 2008-12-28
2楼  发表于: 2007-03-21 11:00
强烈支持了
有三种东西必须捍卫:祖国、荣誉和家庭
有三种东西必须控制:情绪、语言和行为
有三种行为必须摒弃:罪恶、无知和背叛
有三种做法必须避免:懒惰、野蛮和嘲讽
有三中品质必须尊敬:坚毅、自尊和仁慈
有三种习惯必须培养:理性、谦恭和好学

把梳子卖给和尚不算什么,把洗发水卖给和尚才算高
级别: AVF初窥者
UID: 11503
精华: 0
发帖: 5
威望: 11 点
星星铁: 255 块
贡献值: 0 点
在线时间: 0(小时)
注册时间: 2006-09-19
最后登录: 2007-03-06
3楼  发表于: 2007-05-19 22:43
谢谢楼主讲得这么好,看了给了我不少的启发
级别: AVF初窥者
UID: 66811
精华: 0
发帖: 5
威望: 10 点
星星铁: 4 块
贡献值: 0 点
在线时间: 1(小时)
注册时间: 2008-08-22
最后登录: 2008-10-09
4楼  发表于: 2008-09-08 16:23
引用
引用第3楼xzh119于2007-05-19 22:43发表的  :
谢谢楼主讲得这么好,看了给了我不少的启发


拜托,这是看雪的教程,楼主该说明下,不厚道