首页
社区
课程
招聘
[破解资料大全]:来至网上,不断更新
发表于: 2004-8-3 15:37 81237

[破解资料大全]:来至网上,不断更新

2004-8-3 15:37
81237
收藏
免费 1
支持
分享
最新回复 (117)
雪    币: 106728
活跃值: (202444)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
76
日期:2003年6月16日  出处:嬴政天下整理收藏  作者:PererS  人气:
2、ProcDump应用文章一

注:本文作者PererS是台湾的,因此要注意在一些名词上称呼与我们不同。
由于此文写作时间较早,在此推荐两个新版工具:
侦测工具:推荐FileInfo。
脱壳工具:ProcDump32 v1.6.2 FINAL终结版本 。(作者不升级了,对目前新版压缩工具的壳无效,为了你对 Procdump有个认识,在此提供一较老版本ASPack压缩的记事本程序供练习:下载)

标题:软体名称 中文哇!档案阅览器  2000 (Version 4.1)
保护方法 壳
需要工具 TYP( 侦测工具 ) & ProcDump 1.50( 剥壳机 )
文章作者 Peter S. (彼得的家)

侦测与剥  CWView 2000 (Version 4.1) 的壳

一、前言

     何谓壳 ? 相信这是很多人的疑问。

  其实壳,顾名思义,就像鸡蛋的壳一样,主要是保护鸡的「卵」。从外观上看来,鸡蛋是白色的,但是把壳剥掉以后呢 ? 是黄色的卵 + 透明的蛋白 ( 未熟蛋 ) 。这应用到我们的破解与保护上呢,也是同样的意思,假若我今天要修改一个执行档 ( 就像我要把黄色的卵,涂成绿色 ) ,但是因为有壳,所以根本找不到你要修改的地方 ( 就像光从鸡蛋的外观上看来,根本找不到有黄色的地方一样 ) ,一定要把壳「剥掉」,才能达成你的目的。我这样说,应该比较容易了解什么是壳了吧 ?  

当然,正确的说,「壳」与「加密」是一体的,这类似你有一个纯文字档,如果你用 zip 压缩它以后,能够再更改它吗 ? 不可能,因为资料已经被重新排列、且压缩运算过,成为一堆乱码,所以根本不能直接改。

这个教学文件所需要的软体如下 :

1. TYP   这是一个能侦测你的软体是被哪一种「壳」给加密了

   ( 就好像侦测你的文件档是被 zip 、 rar 、 arj 哪一个给压缩了一样,如果连被哪种软体加了壳都不晓得,那要剥壳就难很多 ) 。

2. Procdump 1.5  这是剥壳机器,可剥许多已知壳、未知的 for win32 的壳。

二 . 用 TYP 测试 CWView2000 是被哪种壳给加密了 :

     废话不多说,直接来 :

1. 首先,你要把你下载来的 TYP 先解压缩到某个目录 ( 我假设 c:\try)

2. 再来,把 CWView2000 的主程式 cwview32.exe ,由 c:\cwv2000 下拷贝到上面讲的目录 (c:\try) ,接下来,从 win95 开一个 dos 视窗,并且切换到 c:\try 目录下,然后键入 typ3 cwview32.exe

3. 过几秒以后,直接跳到最后一行,有没有看到 ASPACK / Solodovnikov Alexy [1.07b] 这行 ?

     哦 ~~~ 原来 CWView2000 是用 ASPACK 1.07b  来加密的啊。那要脱壳不就简单了,去找一个专门脱 ASPACK 1.07 的软体不就得了 ??

     没错,不过我在来要教的,是使用目前全世界最强的拨壳机 Procdump 来剥壳。

三 . 用 Procdump 1.50  来剥 ASPACK 1.07b 的壳 :

1. 首先,当然也是把 Procdump 解压缩到刚刚的目录 (C:\TRY)

2. 执行 Procdump ,你会看到如下的视窗 :

3. 因为我们要剥壳,所以按下 Unpack( 其他的按钮是干什么的,我也不清楚,大概是跟 WIN 的 PE 执行档有关的吧 ):

4. 由刚刚 TYP 侦测得知, CWView2000 是用 Aspack 1.07b 加的壳,所以理所当然的我们要选择  [Aspack<108] ,选好后,按下 OK( 要选对喔,选错会剥不出来 ):

5. 此时, ProcDump 会要求你开启你要剥壳的执行档,当然,我们要把路径指到 c:\try\cwview32.exe

6. 紧接著马上会出现如下的视窗,此时,千万不要按下 [ 确定 ] 。稍微等一下,有耐心一点,你马   上就会看到 CWView2000 被呼叫执行了,此时,将视窗切换至 CWView ,随便使用一二个   功能,然后在不要关掉 CWView2000 之下,按下 [ 确定 ] 钮。 ( 这个按钮是当程式 [ 完全 ] 被载入以后,才要按的 )

上面这个步骤很重要,如果心急乱按或乱关,你就得重来了。

7. 按下 [ 确定 ] 后没多久,会出现下面的视窗,并且此时 cwview 会自动被关掉,然后开始剥壳   运算,当出现 Step by step analyzis activated ... 时,过不久, Prucdump 就会要求你键入要输出的   档名 ( 也就壳剥掉以后,原始的卵要存成什么档名 ) ,我这里举例成 unshell.exe ,此时,也代表剥壳成功 !!:

剥壳还蛮简单的嘛,对不对 ?

三 . 试试看剥壳了以后的 CWView32.exe 可不可用 :

     你可以自己执行看看,应该可以用吧 ? 或许你也可以比较一下剥壳与未剥之间的差别,   你将惊觉 : 没有剥壳的 CWView32 只有 602kb ,但是剥壳后,竟然高达 1634kb 。很惊人的压缩率吧 !( 所以加密或加壳的确有存在的必要,就好像压缩一样,可以帮助人们节省很多硬碟空间 )

四 . 试试看剥壳了以后的 CWView32.exe 可不可以修改成注册版 ?:

       你可以用 16 位元编辑器,打开刚刚剥壳后的档案 (unshell.exe) ,然后

寻找  C60520864F0001

改成  ------------00

嘿嘿,找的到对不对 ? 也可以改了吧 ... 这样就不用使用外挂的「动态破解」软体 PPATCHER 了 !

五 . 我知道你在想什么 ...

     你是不是在想,可不可以把刚刚修改完成的 unshell.exe 再把它加壳,让它变的小一点啊 ?

当然可以,只要你有加壳软体 ... 还等什么,赶快去做啊 !

从这次的破解教学我们学到 :

1.  如何使用 TYP 来侦测壳,与如何使用史上最强的 procdump 来剥壳。

2.  要剥壳,其实并不难,只要 TYP 侦测得出来、 procdump 有列表的,都很简单。

要注意的是 :

1. 当你发现 TYP 的回报是 Unknow 时候,别慌, procdump 也可以针对未知的壳作剥壳的运算,只要选择  **unknow**  就可以啦,不过成功率当然降低许多。

2. 为什么要介绍 procdump? 因为它可以外挂 script.ini 来增加剥壳的能力。也就是你可以自己用 sice 追某个被不知名加密软体给加壳的软体,然后纪录起相关的资料,再交由 Procdump 来把记忆体的内容「 dump 」 ( 存 ) 起来,只是这篇教学没有教 ( 我也不太会啦 ...) 。   

3.TYP 是目前世界上侦测壳、压缩资料,能力最强的软体,要善用,你可以在下面的网站抓到 :

阿伦的家 (GB 码 ): 077K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3y4J5j5h3y4C8k6i4u0K6i4K6u0W2x3e0j5K6i4K6u0W2L8X3g2@1i4K6u0r3
作者网页 : 2ffK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6s2g2K6k6i4u0Q4x3X3g2f1g2g2)9J5k6p5y4G2N6s2c8T1N6i4y4Q4x3X3g2p5c8g2)9J5c8W2)9%4c8h3E0S2L8X3&6W2k6%4j5`.

注意 : 要抓 dos32 的版本,才能在 windows 下正常使用

4.Procdump 是目前世界上最强的拨壳软体,除可以剥已知道的壳外,还可以剥许多未知的壳。更可以以手动的方法,增强其剥壳能力 ( 可惜的是,它只支援 win32 的软体, win16 与 dos 的他都不支援 ) 。,你可以在下面的网站抓到 :

阿伦的家 (GB 码 ): 1deK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3y4J5j5h3y4C8k6i4u0K6i4K6u0W2x3e0j5K6i4K6u0W2L8X3g2@1i4K6u0r3
吴朝相的家 (GB 码 ):2cbK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3#2W2L8h3u0W2M7W2)9J5k6h3&6W2N6r3g2S2M7$3g2Q4x3X3g2U0L8$3#2Q4x3V1k6Q4y4@1g2@1L8%4m8S2k6$3f1`.
2004-8-4 11:27
0
雪    币: 106728
活跃值: (202444)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
77
日期:2003年6月16日  出处:嬴政天下整理收藏  作者:Ru Feng  人气:1624
ProcDump应用文章二

 今天,在吴朝相的网页上看到一篇由台湾的 Peter's 写的关于脱壳的文章,里面提及到的了 Procdump1.50 的使用,但由于所写的内容比较地肤浅,并没有交待到 Procdump1.50 的强大之处,同时由于最近在网上的软件,加壳之风日盛,如果作为一个 Cracker ,不跟着时代走,可 能在不久的将来,你就没有什么软件可以修改了,所以一定要在加脱方法下点苦功才行,为此, 小弟想把一月来学习到的脱壳技术 Post 出来,让大家了解一下在 Windows 上是如何进行软件脱 壳的,同时也想向大家介绍强大的 Procdump1.50 是如何使用的,如何用它来进行手动脱壳的, 如何扩展自已的 Procdump1.50 的脱壳种类。但由于小弟在脱壳方面还是新手,如果文章中有错误之处,请来信指教。

读者要求:

你可以阅读和传播本文章,但不能对文章的内容作任何的修改,请尊重作者的劳动。

首先我们要先准备我们的工具:

1.Procdump1.50

2.Ultraedit6.10 (这个你也可以用别的编辑器)

3.Winsoftice4.0

4.Trw0.75

5.MakePE1.27

6.Wdasm8.93

好了!工具都准备齐全了,我们就去下载一个实验品吧!今次我们选的是UPX ,在 Procdump1.50 的脱壳文件列表中,你可以清楚地看到有 UPX 的选项,所以我们今次就选它了,目前它的最新版本是 0.82 ,好了下载完毕了,我们先用它来为软件加一个脱吧!
操作:

1. 在 windows 上打开一个 Dos 窗口 , 进入 UPX0.82 所在的目录;

2. 输入 upx  [ 要加壳的文件路径和文件名 ]

3.OK! 加壳成功了!

好了!现在可以试一试脱壳了!

操作:

1. 运行 Procdump1.50 ;

2. 按 Unpack 按钮,这时就出现了 Choose Unpacker 窗口;

3. 在窗口中选择 UPX ,这时就会跳出一个选择你要脱壳文件的选择窗口;

4. 按下打开,哦天啊!好痛苦啊!程序没有脱壳竟然运行了, Procdump1.50 提示一个错

误发生在 script 的第一行。

以上的所有操作,是对自动脱壳来说的,基本上的自动脱壳的操作都是这样的。好了,难道就这样没有戏唱了吗?作者写文章那会就写这几十行废话呢?请接着看下面的吧! 好了,看一看它没有没防住 winsoftice 呢?重新启动机器,换一个有安装 winsoftice 的 windows 平台 吧!再次运行被加脱了的程序,还好!没有当掉 winsoftice ,这样心中暗喜,你有难了啊!看来外 国人写的东西还是比较有善,不象 Ding Boy 的幻影系列,比小燕子还凶( ^o^ ,又说 Ding Boy 的坏 话了,其实有时我觉得他比较象 Crack 界的小燕子,令人又爱又恨)。好了关闭程序,用 winsoftice 载入去,唉刚刚还说好呢!原来它还是对 winsoftice 作了一点小动作, winsoftice 不能中断于程序的入口的第一句处。没有关系,现在有三种方法,第一种方法是通过对程序的 exe 文件作一点修改, 使其符合标准的 PE 文件格式,因为 winsoftice 毕竟不是专为 Crack 设计的,所以它的中断程序入口 是针对标准的 PE 文件格式来写的,对于那些不符合的,它就没有能力了,具体的 PE 文件格式,大 家可以看一看 VC 中的 MSDN 中的帮助和 WINNT.H 中的解释;第二种方法就是不用 winsoftice ,而用 TRW ,因为刘涛涛先生的 TRW 是专为 Crack 设计的,所以几乎所有可以在 Windows 上运行的程序,它 都可以中断得了;第三种方法,就是在原 exe 文件中加插 int 3 语句,令 winsoftice 强行中断。   好了,方法说了一大罗,我们就用最简单的方法吧!没人会有简单的不用,去用最繁的,如果有吧!大家就。。。。。。。。

运行 TRW0.75 ,选择菜单中的 TRNEWTCB 命令,然后运行加脱的程序,程序马上中断于第一句了。

具体如下:

0137:0043D100  PUSHAD                  程序会中断于这里

0137:0043D101  MOV       ESI,0042B0D9

0137:0043D106  LEA       EDI,[ESI+FFFD5F27]

0137:0043D10C  PUSH      EDI

0137:0043D10D  OR        EBP,-01

0137:0043D110  JMP       0043D122           跳到解压程序

0137:0043D112  NOP

0137:0043D113  NOP

解压程序的入口:

0137:0043D122  8B1E                MOV       EBX,[ESI]

0137:0043D124  83EEFC            SUB        ESI,-04

0137:0043D127  11DB                ADC        EBX,EBX

0137:0043D129  72ED                JB           0043D118

0137:0043D12B  B801000000      MOV       EAX,00000001

0137:0043D130  01DB                ADD        EBX,EBX

0137:0043D132  7507                 JNZ         0043D13B

0137:0043D134  8B1E                MOV       EBX,[ESI]

好了在解压程序里面,程序会做无数次的循环,我没有必要了解它是如何进行加压的,所以就把光标一直向下走,一直走到这里:

0137:0043D250  EBD6                JMP       0043D228

0137:0043D252  61                    POPAD

0137:0043D253  C3                     RET

0137:0043D254  61                     POPAD

0137:0043D255  E9D6A1FDFF    JMP       00417430         这就是程序的真正入口了

0137:0043D25A  0000                 ADD       [EAX],AL

0137:0043D25C  0000                 ADD       [EAX],AL

0137:0043D25E  0000                 ADD       [EAX],AL

好开心啊!终于找到了入口地址,如果你只是针对某一个特定的程序而脱壳的,那么现在就可以 用 TRW 的 pedump 命令直接脱壳了,但这不是我们所要的,我们现在是要研究 UPX0.82 的壳,要写一个通用的脱壳 ini 加入到 Procdump1.50 里面,那么,这样你以后就可以很方便脱掉 UPX0.82 所 的脱了,同时也很方便网上传播了,让别人也能分享你的成果,这才是真正的 Cracker 精神。

操作:

1. 用 Ultraedit6.10 打开 Procdump1.50 目录下的 Script.ini 文件;

它的格式如下:

[INDEX]

P1=Hasiuk/NeoLite

P2=PESHiELD

P3=Standard

P4=Shrinker 3.3

P5=Wwpack32 I

P6=Manolo

P7=Petite<1.3

P8=Wwpack32 II

P9=Vbox Dialog

PA=Vbox Std

PB=Petite 1.x

PC=Shrinker 3.2

PD=PEPack

PE=UPX                          修改为 PE=UPX<0.7X

PF=Aspack<108

P10=SoftSentry

P11=CodeSafe 3.X

P12=Aspack108

P13=Neolite2

P14=Aspack108.2

P15=Petite 2.0

P16=Sentinel

P17=PKLiTE

P18=Petite 2.1

P19=PCShrink

P1A=PCGUARD v2.10

P1B=Aspack108.3

P1C=Shrinker 3.4

P1D=UPX0.7X-0.8X      加入这句

然后找到:

[UPX]                        修改为 [UPX<0.7X]

然后在文件最下面加入:

[UPX0.7X-0.8X]

好了,准备功夫我们都做好了,现在可以写 UPX0.82 的脱壳扩展了,首先我们可以见到程序有两个跳动的地方,第一个是:
0137:0043D110  JMP       0043D122           跳到解压程序

所以我们马上把机器代码抄下来:

EB,10

第二个是:

0137:0043D255  E9D6A1FDFF    JMP       00417430         这就是程序的真正入口了

机器代码就是:

E9,D6,A1,FD,FF

好了,所有的要找到东西我们都已经找到了,我们就开始编写 UPX0.82 的脱壳扩展了。

我编写的具体如下:

[UPX0.7X-0.8X]

L1=OBJR                                    ; 在扫描开始处设置初始的内存地址

L2=LOOK EB,10            ; 查找第一个 EB,10 程序代码

L3=BP                                        ; 在当前内存位置设置断点

L4=WALK                                    ; 交还控制权到 Procdump 并且执行下一个指令

L5=OBJR                                    ; 在扫描开始处设置初始的内存地址

L6=LOOK 61,E9                       ; 查找第一个 EB,10 程序代码

L7=BP                                        ; 在当前内存位置设置断点

L8=STEP                                    ; 一步一步地跟踪分析程式

好了,以上的解释都很清楚了,没有什么不明白了,我们把文件保存后,再次运行 Procdump1.50 , 在 Choose Unpacker 中可以见到多了一个 UPX0.7X-0.8X 项了,选择它,进行脱我们加了脱的程序, 哈哈,叫我们保存了,你可以不要高兴得太早了,你试一试运行 dump 程序,哦不能运行,非法操作。 不要心急,我们好象还有点东西要加上呢!那就是 dump 的可选参数了, Procdump1.50 一共给我们 提供了五组可选参数,如果你没有特别指出,就用默认值。好我们加上去试一试吧!

OPTL1=00000000

OPTL2=01010001

OPTL3=01010001

OPTL4=00030000

OPTL5=00000000

  以上这五参数是最常用的,你加参数时可要先试试,或者加了之后就可以用了,好我们加上,试一试。
以下文章所述,可能在有的机器上有不同的结果,请自行修正:

作者的机器是:

赛扬 300A (超 450 )

PC100-64M 内存

当我再次运行 Procdump1.50 来脱壳程序时,竟然程序一下子就运行了,根本不象上次那样提示要我保存 脱壳后的文件,所以我想,可能这些参数有些不合适我的机器,于是我认真分析了每一个参数的真正含义之后,就把参数作了如下的修改:

OPTL1=00000001         这是延迟时间,我设为 1ms  

OPTL2=01010101         采用了快速 dump 的工作方式

OPTL3=01010001

OPTL4=00030000

OPTL5=00000000

今次再运行 Procdump1.50 进行脱壳,哈哈!!!可以脱了,然后再双击脱壳后的文件,咦,可以执行了, 再用 Wdasm8.93 反汇编分析一下文件,发现基本和原文件相同,只是文件大小有点不同,大了一点,再用了一下软件的各种功能,一切正常,所以应该说脱壳是成功的,到此,文章也该在此结束了,不过好象还漏了点事,就是用 MakePe1.27 帮助脱壳后的文件作进一步的优化,这就不一一描述了 ,自己看帮助进 行吧! 好了,最后总结一下吧!
完整地加入:

[UPX0.7X-0.8X]

L1=OBJR

L2=LOOK EB,10

L3=BP

L4=WALK

L5=OBJR

L6=LOOK 61,E9

L7=BP

L8=STEP

OPTL1=00000001

OPTL2=01010101

OPTL3=01010001

OPTL4=00030000

OPTL5=00000000

By The Way !

我发现对于使用 UPX0.7x 到 UPX0.8x 加壳的软件,用我的方法都可以成功脱壳。
2004-8-4 11:30
0
雪    币: 106728
活跃值: (202444)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
78
日期:2003年6月20日  出处:嬴政天下整理收藏  作者:嬴政天下整理收藏  人气:947
1、基本知识

  手动脱壳就是不借助自动脱壳工具,而是用动态调试工具SOFTICE或TRW2000来脱壳。这课谈谈一些入门方面的知识,如要了解更深的脱壳知识,请参考《脱壳高级篇》这课。

工具

*调试器:SoftICE 、TRW2000
*内存抓取工具:Procdump等;
*十六进制工具:Hiew、UltraEdit、Hex Workshop等;
*PE编辑工具: Procdump、PEditor等;

名词概念

★PE文件:Microsoft设计了一种新的文件格式Portable Executable File Format(即PE格式),该格式应用于所有基于Win32的系统:Windows NT、Windows 2000、Win32s及Windows 95/98。

★基址(ImageBase ):是指装入到内存中的EXE或DLL程序的开始地址,它是Win32中的一个重要概念。 在Windows NT中,缺省的值是10000h;对于DLLs,缺省值为400000h。在Windows 95中,10000h不能用来装入32位的执行文件,因为该地址处于所有进程共享的线性地址区域,因此Microsoft将Win32可执行文件的缺省基地址改变为400000h。

★RVA:相对虚拟地址(Relative Virual Address),是某个项相对于文件映象地址的偏移。例如:装载程序将一个PE文件装入到虚拟地址空间中,从10000h开始的内存中,如果PE中某个表在映像中的起始地址是10464h,那么该表的RVA就是464h。虚拟地址(RVA)=偏移地址+基址(ImageBase )

★Entry Point:入口点,就是程序在完成了对原程序的还原后,开始跳转到刚还原的程序执行,此时的地址就是入口点的值。

步骤

★确定壳的种类

一般拿到软件后,可用工具FileInfo、gtw、TYP32等侦测文件类型的工具来看看是何种壳,然后再采取措施。

★入口点(Entry Point)确定

对初学者来说定位程序解壳后的入口点确定较难,但熟练后,入口点查找是很方便的。 决大多数 PE 加壳程序在被加密的程序中加上一个或多个段。 所以看到一个跨段的 JMP 就有可能是了。如:UPX 用了一次跨段的 JMP , ASPACK 用了两次跨段的 JMP 。 这种判断一般是跟踪分析程序而找到入口点,如是用TRW2000也可试试命令:PNEWSEC,它可让TRW2000中断到入口点上。
PNEWSEC:运行直到进入一个 PE 程序内存的新的 section时产生断点。(如不懂,以后到脱壳高级篇自会明白)

另外也可用D.boy的冲击波2000,它能轻易的找到任何加密壳的入口点,

★dump取内存己还原文件

找到入口点后,在此处可以用 Procdump的FULL DUMP功能来抓取内存中整个文件,
如是用TRW2000也可用命令:

makepe命令含义:从内存中整理出一个指令名称的PE格式的exe文件, 当前的 EIP 将成为新的程序入口,生成文件的 Import table 已经重新生成过了。生成的PE文件可运行任何平台和微机上。

pedump命令含义:将PE文件的内存映像直接映像到指定的文件里。生成的文件只能在本机运行,不能在其它系统平台或微机运行。

★修正刚dump取的文件

如是用 Procdump的FULL DUMP功能脱壳的文件,要用 Procdump或PEditor等PE编辑工具修正入口点(Entry Point)。
2004-8-4 11:34
0
雪    币: 106728
活跃值: (202444)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
79
日期:2003年6月20日  出处:嬴政天下整理收藏  作者:嬴政天下整理收藏  人气:1450
2、UPX V1.01的壳

目标程序: 用 UPX V1.01压缩过的Notepad.exe

方法一、使用TRW2000来脱壳

★使用工具

TRW2000
FileInfo

★确定壳的种类

拿到这软件后,可用工具FileInfo、gtw、TYP32等侦测文件类型的工具来看看是何种软件压缩的,在这我们以FileInfo 为例,把目标文件复制到FileInfo目录下,在资源管理器下双击FileInfo,再按回车,你将看到报告出来:告诉你这是UPX1.01压缩的软件。

★入口点(Entry Point)确定

◇利用跟踪分析来确定入口点

决大多数 PE 加壳程序在被加密的程序中加上一个或多个段。 所以看到一个跨段的 JMP 就有可能是了。 UPX 用了一次跨段的 JMP 。 就是你一步步跟踪时会看到代码有一突跃,一般再跟据领空文件名的变化,就能确定入口点了。运行TRW2000并装载目标程序,然后LOAD,你将中断在主程序入口处:此时合理按F10、F7及F12一直向前走,注意此时领空会是:NOTUPX!UPX1+2xxx.

在你跟踪过程中会出现如下代码:

该程序的具体情况如下:

XXX:XXXXXXXX 60 PUSHAD ;所有的寄存器进栈
XXX:XXXXXXXX BE2EFD4200 MOV ESI, XXXXXXXX ;将下一条指令送入进行解压
XXX:XXXXXXXX 8DBED21FFDFF LEA EDI, [ESI+XXXXXXXX]

.......
....... <---- 按F10跟踪 ;-P
XXX:XXXXXXXX FF96A8C90400 CALL [ESI+XXXXXXXX]
XXX:XXXXXXXX 61 POPAD ;所有寄存器出栈
XXX:XXXXXXXX E9A44AFBFF JMP 00401000 ;跳到程序真正入口点(OEP),文件完全解压。

0137:40ddbe popa
0137:40ddf jmp 00401000 <-此行己完全解压结束,将要跳到记事本程序入口点执行程序(注意此处的一个大的突跃)。
........................
0137:401000 push ebp <-完全解压后的记事本程序第一行

因此入口点(Entry Point)找到为:401000

◇利用TRW2000特有命令PNEWSEC

TRW2000也是一款优秀的脱壳工具,有许多特有的命令对脱壳很有帮助,在此时用PNEWSEC命令也可方便找到入口点。
运行TRW2000并装载目标程序,然后LOAD,你将中断在主程序入口处,下令:PNEWSEC
等上一段时间,程序将中断在入口点处。

◇用冲击波2000

冲击波2000是D.boy开发的一个专门查找加壳软件入口点的工具,先运行冲击波2000,点击Track按钮:开始进行跟踪,然后运行要跟踪的程序, 找到入口点后,会在Enter point 显示。可是用这个记事本程序却无效。

★dump取内存中己脱壳的文件

不管你用何种方法找到入口点,首先要来到入口点一行:

0137:401000 push ebp

执行命令makepe 路径/文件名或pedump 路径/文件名

就这样脱壳成功。

注:TRW2000的makepe重建的PE文件可跨平台运行,pedump抓取的文件却不可。

方法二、用SOFTICE来脱壳

★使用工具

TRW2000
FileInfo
ProcDump

★入口点(Entry Point)确定

◇利用跟踪分析来确定入口点

方法同TRW2000。

★dump取内存中己脱壳的文件

0137:40ddf jmp 00401000
现在这一行,键入以下命令:
a eip (然后按回车)
jmp eip (然后按回车)
按下F5

这样将改变0137:40ddf行的代码. 你会注意到在键入"jmp eip"并按下回车后,40ddf的指令现在是一个jmp.这将有效地使程序"暂停"(有点类似TRW2000的suspend命令). 按下F5使你回到window。

运行ProcDump,在Task的列表中的第一个list上点击鼠标右键,然后选择"Refresh list". 在Task列表中找到notepad.exe,在它的上面点击鼠标右键. 然后,选中"Dump (Full)",给脱壳的程序起名存盘. 再在notepad.exe上点击鼠标右键,然后选中"Kill Task".

注:用此方法抓取的文件不可跨平台运行。

★修正刚dump取的文件的入口点

脱壳的notepad.exe程序入口是00401000.
再次使用ProcDump的PE Editor功能, 打开已脱壳的notepad.exe.

在"Header Infos"一项, 你会看见程序Entry Point(入口值)是0000DC70,这当然是错误的. 如果你试着不改动这个入口值而运行脱壳后的notepad.exe,程序将无法运行.

在 Procdump可看到ImageBase =00400000,我们上面跟踪找到的入口值的RVA是00401000,因为:虚拟地址(RVA)=偏移地址+基址(ImageBase ),因此

Entry Poin=00401000-00400000=1000,改变入口值为1000,点击"OK".

现在, 运行脱壳后的notepad.exe吧,它应该正常运行了。
2004-8-4 11:36
0
雪    币: 106728
活跃值: (202444)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
80
日期:2003年6月20日  出处:嬴政天下整理收藏  作者:Etenal Bliss 冰毒  人气:921
3、Shrinker v3.4 的壳

英文原作: Etenal Bliss
电子邮件: [email]Eternal_Bliss@hotmail.com[/email]
作者网址: 479K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3y4J5j5h3y4C8L8h3g2K6i4K6u0W2j5$3A6T1i4K6u0W2L8X3g2@1
          ad6K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4y4#2M7X3k6Q4x3X3g2@1L8#2)9J5c8X3y4J5j5h3y4C8L8h3g2K6
写作日期: 2000年2月25日
中文翻译: 冰毒
翻译日期: 2000年3月14日

目标程序: 用Shrinker v3.4压缩过的Notepad.exe

******************************************************************
冰毒注:
1. Notepad.exe就是Windows自带的写字板程序,相信大家的机器中都会有.
2. Shrinker v3.4可以在1fcK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4M7K6i4K6u0W2N6r3!0Q4x3V1k6H3M7X3!0@1L8$3!0D9M7#2!0q4y4q4!0n7z5q4)9^5b7W2!0q4z5q4!0n7c8q4!0n7c8q4)9J5b7#2!0q4z5q4!0n7c8W2)9&6z5g2!0q4z5g2)9^5y4#2)9^5b7#2!0q4y4q4!0n7c8q4!0m8x3q4!0q4y4g2)9^5c8W2!0m8c8W2!0q4y4q4!0n7b7W2!0m8y4g2!0q4y4W2)9^5z5g2!0n7c8g2!0q4y4g2)9^5z5q4!0n7x3q4!0q4y4q4!0n7c8q4!0m8x3l9`.`.
想要的几乎所有的工具.
******************************************************************

使用工具:
ProcDump
Softice
Symbol Loader (冰毒注:这个是Softice自带的,用过Softice的应该知道)

破解方法:
手动脱壳

教学目的:
教你手动脱壳的基本技术
__________________________________________________________________________

                        关于这个教程

这是我打算写的*简单*的脱壳系列教程的第一篇. 目标程序是notepad.exe,在大多数
的电脑中都有它. 因为我还不能很好地解释脱壳中的一些问题,我只能尽我所能向你们
展示简单的方法. 至于高级的方法,你们必须去读别的教程.
_________________________________________________________________________

        使Softice中断于程序入口处

用Symbol Loader打开已压缩的notepad.exe.

点击Symbol loader任务条上的第二个图标,当你把鼠标移到图标上时,在Symbol Loader
窗口底部提示行你会见到"Load the currently open module"的字样

你将得到一条出错信息并问你是否尽管出错还是要装入这个exe文件. 点击"Yes".

假如Softice已经运行的话, 它应该在程序的入口处中断.可是它并没有中断,压缩过的
notepad.exe直接就运行了.

该到改变characteristics of the sections的时间了...
通过改变characteristics, 你可以使Softice中断于程序入口.

用ProcDump装入压缩过的notepad.exe (使用PE Editor)
你会看到这个以"PE Structure Editor"作为标题的窗口.
点击称作"Sections"的按钮.

你将得到另一个以"Sections Editor"做标题的窗口.
你会见到压缩过的notepad.exe的不同sections.

第一个是 .shrink0 它的characteristics是C0000082.
改变characteristics: 鼠标左键点击.shrink0再点击右键并选择edit section.

你将得到另一个窗口,它用'Modify section value" 作标题.
把Section Characteristics由C0000082改为E0000020.
一路按OK直到你回到ProcDump的主窗口.
你现在可以把ProcDump放在一边了.

**我愿意多作解释为什么必须这样做,但我没这个能力. 8P
  你也许要读些PE结构的资料来找到原因.
  别人教我说, E0000020将使section成为可执行的,因此Softice将会中断于入口处

找到程序真正入口并进行脱壳

现在, 希望你没有关闭symbol loader. 假如你关掉的话,重新运行它,打开并装入已
压缩的notepad.exe

当你这次点击"Yes"时, 你会发现你已在进入Softice中了...
我把下面的代码贴出来并加上注解.

************************* 你在SICE中所见到的 *************************

**Softice中断时,你会在这儿. 一直按F10走过这部分代码

0041454F  FFFF                INVALID
00414556  55                  PUSH      EBP
00414557  8BEC                MOV      EBP,ESP
00414559  56                  PUSH      ESI
0041455A  57                  PUSH      EDI
0041455B  756B                JNZ      004145C8                (NO JUMP)
0041455D  6800010000          PUSH      00000100
00414562  E8D60B0000          CALL      0041513D
00414567  83C404              ADD      ESP,04
0041456A  8B7508              MOV      ESI,[EBP+08]
0041456D  A3B4F14000          MOV      [0040F1B4],EAX
00414572  85F6                TEST      ESI,ESI
00414574  7423                JZ        00414599                (JUMP)
00414599  33FF                XOR      EDI,EDI
0041459B  57                  PUSH      EDI
0041459C  893D8C184100        MOV      [0041188C],EDI
004145A2  FF1510224100        CALL      [KERNEL32!GetModuleHandleA]
004145A8  8BF0                MOV      ESI,EAX
004145AA  68FF000000          PUSH      000000FF
004145AF  A1B4F14000          MOV      EAX,[0040F1B4]
004145B4  897D10              MOV      [EBP+10],EDI
004145B7  C7450C01000000      MOV      DWORD PTR [EBP+0C],00000001
004145BE  50                  PUSH      EAX
004145BF  56                  PUSH      ESI
004145C0  FF15F4214100        CALL      [KERNEL32!GetModuleFileNameA]
004145C6  EB03                JMP      004145CB                (JUMP)
004145CB  E830EAFFFF          CALL      00413000
004145D0  FF7510              PUSH      DWORD PTR [EBP+10]
004145D3  FF750C              PUSH      DWORD PTR [EBP+0C]
004145D6  56                  PUSH      ESI
004145D7  E806000000          CALL      004145E2

**当你走过这个位于004145D7的CALL, 压缩过的notepad.exe就自由运行了. 再次用
  symbol loader装入. 再次来到这个CALL时, 按F8追进去. 你将看到以下代码. 不
  过记着先BPX 004145D7.

004145E2  64A100000000        MOV      EAX,FS:[00000000]
004145E8  55                  PUSH      EBP
004145E9  8BEC                MOV      EBP,ESP
004145EB  6AFF                PUSH      FF
004145ED  6810E04000          PUSH      0040E010
004145F2  68EC5D4100          PUSH      00415DEC
004145F7  50                  PUSH      EAX
004145F8  64892500000000      MOV      FS:[00000000],ESP
004145FF  83EC14              SUB      ESP,14
00414602  C745E401000000      MOV      DWORD PTR [EBP-1C],00000001
00414609  53                  PUSH      EBX
0041460A  56                  PUSH      ESI
0041460B  57                  PUSH      EDI
0041460C  8965E8              MOV      [EBP-18],ESP
0041460F  C745FC00000000      MOV      DWORD PTR [EBP-04],00000000
00414616  8B450C              MOV      EAX,[EBP+0C]
00414619  83F801              CMP      EAX,01
0041461C  7510                JNZ      0041462E                (NO JUMP)
0041461E  E886030000          CALL      004149A9
00414623  FF05C0F14000        INC      DWORD PTR [0040F1C0]
00414629  E882F6FFFF          CALL      00413CB0
0041462E  8B35C0F14000        MOV      ESI,[0040F1C0]
00414634  85F6                TEST      ESI,ESI
00414636  0F848D000000        JZ        004146C9                (NO JUMP)
0041463C  833DC4F1400000      CMP      DWORD PTR [0040F1C4],00
00414643  7526                JNZ      0041466B                (NO JUMP)
00414645  833D6417410000      CMP      DWORD PTR [00411764],00
0041464C  741D                JZ        0041466B                (NO JUMP)
0041464E  A164174100          MOV      EAX,[00411764]

**EAX现在的值是000010CC

00414653  030588184100        ADD      EAX,[00411888]

**EAX现在的值是004010CC

00414659  8945DC              MOV      [EBP-24],EAX

**[EBP-24]现在含的是004010CC

0041465C  FF7510              PUSH      DWORD PTR [EBP+10]
0041465F  FF750C              PUSH      DWORD PTR [EBP+0C]
00414662  FF7508              PUSH      DWORD PTR [EBP+08]
00414665  FF55DC              CALL      [EBP-24]

**假如你追过最后这个CALL,notepad.exe将再次自由运行.
  由上得知, 既然[EBP-24] = 004010CC, 最后这句代码就意味着压缩过的程序在
  CALL 004010CC. 如果你追进这个CALL, 你会发现notepad.exe很快就会运行了.
  
假如你曾经追过更多shrinker v3.4压缩的程序, 你总会见到这个"CALL [EBP-24]".
所以, 程序实际上正在进入已脱壳的程序的真正入口.

再次装入压缩过的notepad.exe,中断之后,按F5,你将中断于004145D7行(这里你原来
设过断点). 追进去直到你到达00414665行,这里程序正要进入已脱壳程序的真正入口.

现在,键入以下命令:
a eip (然后按回车)
jmp eip (然后按回车)
按下F5

这样将改变00414665行的代码. 你会注意到在键入"jmp eip"并按下回车后,00414665的
指令现在是一个jmp.这将有效地使程序"暂停". 按下F5使你回到window,你就可以dump
已经脱壳的程序到你的硬盘了.

现在又要用ProcDump了,在Task的列表中的第一个list上点击鼠标右键,然后选择"Refresh
list". 在Task列表中找到notepad.exe,在它的上面点击鼠标右键.
然后,选中"Dump (Full)",给脱壳的程序起名存盘.
再在notepad.exe上点击鼠标右键,然后选中"Kill Task".

_________________________________________________________________________

            改动程序入口值

如果你记得的话, 脱壳的notepad.exe程序入口是004010CC.
再次使用ProcDump的PE Editor功能, 打开已脱壳的notepad.exe.

在"Header Infos"一项, 你会看见程序入口值是0001454F,这当然是错误的. 如果你试着
不改动这个入口值而运行脱壳后的notepad.exe,程序将无法运行.

改变入口值为Entry Poin=004010CC-基址(ImageBase ),点击"OK".

现在, 运行脱壳后的notepad.exe吧,它应该正常运行了. 8)
2004-8-4 11:39
0
雪    币: 106728
活跃值: (202444)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
81
日期:2003年6月20日  出处:嬴政天下整理收藏  作者:嬴政天下整理收藏  人气:2461
4、ASPack v1.083

压缩文件:下载。

如用TRW2000调试,装载后,下命令:pnewsec就可中断到入口点。为了提高跟踪水平,下面以SOFTICE为例,讲述跟踪过程。

_________________________________________________________________________

寻找程序的入口点( Entry Point)

用Symbol Loader打开Notepad-ASPACK.exe,点击Symbol loader的第二个图标("Load the currently open module")

如SOFTICE 装载成功,它应中断在起始程序入口处。

当跟踪时,你会经过许多条件跳转指令及循环指令,要用点技巧跳出这些圈子,其形式一般这样:

*************************************
aaaaaaaa
...
wwwwwwww
xxxxxxxx JNZ zzzzzzzz <-- 循环返回到aaaaaaaa
yyyyyyyy JMP aaaaaaaa
zzzzzzzz 新的指令

如果你跟踪时,你将跳转到 aaaaaaa处多次,你可将光标移到 zzzzzzzz一行,按F7让指令直接跳到此处,可省不少时间。
*************************************

在跟踪过程会来到:
167:0040D558 POPAD
0167:0040D559 JNZ 0040D563 (JUMP)
0167:0040D55B MOV EAX,00000001
0167:0040D560 RET 000C
0167:0040D563 PUSH EAX<--EAX的值就是入口点的值=4010CC
0167:0040D564 RET <--返回到记事本的真正的入口点

*************************************
0167:004010CC PUSH EBP <--真正的入口点
0167:004010CD MOV EBP,ESP
0167:004010CF SUB ESP,00000044
0167:004010D2 PUSH ESI

经过0167:0040D564 RET 一行,程序将来到0167:004010CC刚完全解压的真正程序第一条指令处。
*************************************
当我们跟踪时发现POPAD或POPFD,就要提高警惕,一般入口点就在附近了,在此程序的原始入口点是004010CC
在0167:0040D564 RET一行键入:
a eip (然后按回车)
jmp eip (然后按回车)
F5

这个方法是让程序挂起,按F5回到windows下。
运行 Procdump,在Task的列表中的第一个list上点击鼠标右键,然后选择"Refresh
list". 在Task列表中找到notepad.exe,在它的上面点击鼠标右键.
然后,选中"Dump (Full)",给脱壳的程序起名存盘.
再在notepad.exe上点击鼠标右键,然后选中"Kill Task".

_________________________________________________________________________

修正入口点

脱壳的notepad.exe程序入口是004010CC.
再次使用ProcDump的PE Editor功能, 打开已脱壳的notepad.exe.

修正入口点值=4010CC-00400000(基址)=10CC
点击"OK".

现在, 运行脱壳后的notepad.exe吧,它应该正常运行了。
2004-8-4 11:40
0
雪    币: 106728
活跃值: (202444)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
82
日期:2003年6月22日  出处:赢政天下收集整理  作者:leo_cyl1  人气:4025
虽然已经有petite v2.2的脱壳机,但我认为手动脱壳是一个cracker必须掌握的基本技能之一,有必要学习ImportREC重建IAT的技巧。
就拿embird[bcg]在论坛贴的问题做例子吧!
目标软件:af3K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3k6@1M7q4)9J5k6h3g2%4j5i4u0W2i4K6u0W2j5$3!0E0i4K6u0W2j5$3&6Q4x3V1k6H3N6h3u0Q4x3V1k6#2N6r3W2D9K9i4c8&6i4K6u0r3M7X3g2S2k6r3g2J5i4K6u0r3f1V1u0Q4y4h3k6e0k6i4c8#2M7q4j5I4i4K6u0W2y4o6k6Q4x3X3g2*7K9i4l9`.
工具:trw2000,ImportREC v1.3,冲击波2000

一,找OEP
很简单,用冲击波2000可看到OEP在426F67处。

二,保存主程序
在426F67处设断点,中断后下命令:“makepe c:\dump.exe”。

三,重建IAT
下命令“suspend”挂起进程。回到window,运行ImportREC,选ReadBook.exe,
输入OEP(4526f67-40000 = 26f67),   
"IAT AutoSearch",可得到IAT,但还有一些指针未解决,点击“Get Import”,“AUTO TRACE”后,全部解决。
“fix dump”后生成dump_.exe。运行它非法操作。用trw2000跟踪找到非法操作的地方:

017F:0044DCF4 33DB            XOR      EBX,EBX
017F:0044DCF6 385814          CMP      [EAX+14],BL
017F:0044DCF9 7409            JZ      0044DD04
017F:0044DCFB 838E14010000FF  OR      DWORD [ESI+0114],BYTE -01
017F:0044DD02 EB63            JMP      SHORT 0044DD67
017F:0044DD04 53              PUSH    EBX
017F:0044DD05 FF15FC364500    CALL    [4536FC] <----这是非法操作的地方
017F:0044DD0B 3BC3            CMP      EAX,EBX
017F:0044DD0D 7D0A            JNL      0044DD19
017F:0044DD0F 53              PUSH    EBX
017F:0044DD10 E863000000      CALL    0044DD78

查看[4536FC]的内容发现该地址指向ole32.dll。看来ImportREC并没有完全修复IAT,重新运行ImportREC
输入OEP,点击"IAT AutoSearch",发现默认的RVA是:00052FFC,Size是00000394。
但是00052FFC+00000394=53390小于4536FC!原来petite 的外壳欺骗了ImportREC,使它得不到完全的IAT
那么我们就手动输入一个范围给它。我把Size改为00000709,加大查找范围。(00000709是个经验值,可以自己试出来)。"Get Import",“AUTO TRACE”后,还有一个指针未解决,它指向Cxxxxxxx,不太合理,而且程序也位使用它,那就随便给它一个函数名吧(我选GetTickCount)。“fix dump”后再次生成dump_.exe。
这样dump_.exe可以运行了。但还有暗桩:
017F:00417CE6 C6470165        MOV      BYTE [EDI+01],65
017F:00417CEA FF75F0          PUSH    DWORD [EBP-10]
017F:00417CED FF75D8          PUSH    DWORD [EBP-28]
017F:00417CF0 FF75E8          PUSH    DWORD [EBP-18]
017F:00417CF3 E8BB060000      CALL    004183B3    <-----此call是暗桩,F8进入
017F:00417CF8 83C40C          ADD      ESP,BYTE +0C
017F:00417CFB 85C0            TEST    EAX,EAX
017F:00417CFD 0F8516010000    JNZ      NEAR 00417E19
017F:00417D03 53              PUSH    EBX
017F:00417D04 53              PUSH    EBX

017F:004183B3 FF742408        PUSH    DWORD [ESP+08]
017F:004183B7 FF742408        PUSH    DWORD [ESP+08]
017F:004183BB E80CF1FFFF      CALL    004174CC  <-----,F8进入
017F:004183C0 2B442414        SUB      EAX,[ESP+14]
017F:004183C4 59              POP      ECX
017F:004183C5 59              POP      ECX
017F:004183C6 F7D8            NEG      EAX
017F:004183C8 1BC0            SBB      EAX,EAX
017F:004183CA 40              INC      EAX
017F:004183CB C3              RET   

017F:004174CC 8B4C2408        MOV      ECX,[ESP+08]  ----------+
017F:004174D0 83C8FF          OR      EAX,BYTE -01            |            
017F:004174D3 8BD1            MOV      EDX,ECX                |            
017F:004174D5 49              DEC      ECX                    |
017F:004174D6 85D2            TEST    EDX,EDX                |  
017F:004174D8 7423            JZ      004174FD                |
017F:004174DA 56              PUSH    ESI                    |
017F:004174DB 8D5101          LEA      EDX,[ECX+01]            |  典型的crc32
017F:004174DE 8B4C2408        MOV      ECX,[ESP+08]            |   
017F:004174E2 57              PUSH    EDI                    |      
017F:004174E3 0FB631          MOVZX    ESI,BYTE [ECX]          |         
017F:004174E6 0FB6F8          MOVZX    EDI,AL                  |  
017F:004174E9 33F7            XOR      ESI,EDI                |  
017F:004174EB C1E808          SHR      EAX,08                  |  
017F:004174EE 8B34B590594600  MOV      ESI,[ESI*4+00465990]    |  
017F:004174F5 33C6            XOR      EAX,ESI                |      
017F:004174F7 41              INC      ECX                    |   
017F:004174F8 4A              DEC      EDX                    |   
017F:004174F9 75E8            JNZ      004174E3 ---------------|
017F:004174FB 5F              POP      EDI
017F:004174FC 5E              POP      ESI
2004-8-4 11:42
0
雪    币: 261
活跃值: (230)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
83
很难得的大哥~~~~~~~:D
2004-8-4 15:28
0
雪    币: 202
活跃值: (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
84
好 !!文章


好帖

很好帖

确实好帖

少见的好帖

真 TMD 好帖

难得一见的好帖

千年等一回的好帖

好得不能再好的好帖

惊天地且泣鬼神的好帖

让人阅毕击掌三叹的好帖

让人佩服得五体投地的好帖

让人奔走相告曰须阅读的好帖

让斑竹看后决定加精固顶的好帖

让人看后在各论坛纷纷转贴的好帖

让人看后连成人网站都没兴趣的好帖

让人看完后就要往上顶往死里顶的好帖

让人看后不断在各种场合重复引用的好帖

让人一见面就问你看过某某好帖没有的好帖

让人半夜上厕所都要打开电脑再看一遍的好帖

让个读过后都下载在硬盘里详细研究欣赏的好帖

让人走路吃饭睡觉干什么事连做梦都梦到它的好帖

让人翻译成36种不同外语流传国内外世界各地的好帖

让人纷纷唱道过年过节不送礼要送就送某某帖子的好帖

让国家领导人命令将该帖刻在纯金版上当国礼送人的好帖

让网络上纷纷冒出该帖的真人版卡通版搞笑版成人版的好帖

让人在公共厕所里不再乱涂乱化而是纷纷对它引经据典的好帖

让某位想成名的少女向媒体说她与该帖作者发生过性关系的好帖

让人根据它写成小说又被不同导演拍成48个不同版本的电影的好帖

让某名导演跟据此帖改拍的电影在奥斯卡上一连拿了11个奖项的好帖

让人大代表们看完后联名要求根据该帖的内容对宪法做适当修改的好帖

让人为了谁是它的原始作者纷纷地闹上法院打官司要争得它的版权的好帖

让各大学府纷纷邀请该帖作者去就如何发表优秀网络文学为题目演讲的好帖

让人为了该帖而成立了各种学会来研究并为不同的理解争得眼红脖子粗的好帖

让美国警察于今后逮捕人说你有权保持沉默还有权阅读某某帖子要不要啊的好帖

让本拉登躲在山洞里还命令他手下冒着被美军发现的危险去上网下载来阅读的好帖

让萨达姆被捕时被发现他随身携带的除了一把手枪之外还有的就是它的复印件的好帖

让比尔盖茨在懂事会上发给与会者人手一份该帖命令仔细阅读后才讨论其他事宜的好帖

让诺贝儿奖理事会破天荒地因该帖的出现而开会讨论一直决定今后设立最佳帖子奖的好帖

让联合国安理会决定将它译成宇宙语由中国神州六号升空后不断播放看有没有外星人的好帖

让人看完后IE锁死连瑞星诺顿都没法修复只好格式化硬盘重装启动后主页显示的还是它的好帖
2004-8-4 19:07
0
雪    币: 279
活跃值: (375)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
85
老兄真有耐心,
不过还不如搞一个chm
2004-8-4 22:24
0
雪    币: 234
活跃值: (160)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
86
现在这里真是乌烟瘴气。
2004-8-4 22:32
0
雪    币: 106728
活跃值: (202444)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
87
非明码软件的入门教学
破解软件:CalcVoice计算器
破解人:PowerBoy

下载地址:电力系统网,“软件下载乐园”
软件介绍:该软件是一个语音计算器,可以进行二进制、十进制、八进制、十六进制的转换和三角函数的
计算,注册保护为软件自生成一个序列号,然后根据序列号算出注册码。(每台机器序列号都不相同)
并且有30次限制所以有2种选择:一种是暴力破解,另外一种是分析出算法写成注册机。
*************************************************************************************************************************
1.爆破
首先用language侦测发现是用aspack加的壳。选择用CASPR脱壳(效果好)。
运行软件弹出要求注册的对话框随便输入注册码弹出:

"对不起!您的注册码不正确,请与作者联系! "

接下来用w32dsam反汇编查找“串式参考”
发现此句,用左键双击来到程序中。
向上查找发现是由00476AE0(C)跳转来得(用右键双击)
查看程序发现如果00476AE0不跳转就可以来到:

"恭喜您,注册成功!谢谢您支持本软件,请保存好序列?

因此将3BC2757OB201改为
      ××7470××  je或
      ××9090××  nop  成功!!!!!!!!!!!!!!!
*************************************************************************************************************************
2.算法分析
因为该软件是非明码比较,这就要求破解者要有一定的算法破解基础了。废话不说了开始!

下断点:BPX HMEMCPY 按F12共N次来到下面...........
这时就要用F10了,并且要求要成用D和?命令查看个寄存器的数值,(要有宁可错杀一千不放过一个的态度才行啊!)

:00476AA3 55                      push ebp
:00476AA4 687D6B4700              push 00476B7D
:00476AA9 64FF30                  push dword ptr fs:[eax]
:00476AAC 648920                  mov dword ptr fs:[eax], esp
:00476AAF 8D55FC                  lea edx, dword ptr [ebp-04]
:00476AB2 8B8634040000            mov eax, dword ptr [esi+00000434]
:00476AB8 E87FFFFBFF              call 00436A3C
:00476ABD 8B45FC                  mov eax, dword ptr [ebp-04]
:00476AC0 83CAFF                  or edx, FFFFFFFF
:00476AC3 E8C41CF9FF              call 0040878C-------------------->经过此CALL后,我们输入的SN变成十六进制,并保存倒EAX中;
:00476AC8 35630AB302              xor eax, 02B30A63---------------->EAX=EAX XOR 0x2B30A63
:00476ACD 35C5AC3703              xor eax, 0337ACC5---------------->EAX=EAX XOR 0x337ACC5
:00476AD2 8B15489D4700            mov edx, dword ptr [00479D48]---->EDX=0x13215B=1253723
:00476AD8 81F2630AB302            xor edx, 02B30A63---------------->EDX=EDX XOR 0x2B30A63//这时EDX的值就是机器码MN;
:00476ADE 3BC2                    cmp eax, edx--------------------->比较EAX和EDX
:00476AE0 7570                    jne 00476B52*********************关键跳转,不相等则跳,跳则死
:00476AE2 B201                    mov dl, 01
:00476AE4 A174CC4600              mov eax, dword ptr [0046CC74]
:00476AE9 E88662FFFF              call 0046CD74
:00476AEE 8BD8                    mov ebx, eax
:00476AF0 BA02000080              mov edx, 80000002
:00476AF5 8BC3                    mov eax, ebx
:00476AF7 E81863FFFF              call 0046CE14
:00476AFC 33C9                    xor ecx, ecx

* Possible StringData Ref from Code Obj ->"\Software\Microsoft\Active Setup\Installed "
                                        ->"Components"
                                  |
:00476AFE BA946B4700              mov edx, 00476B94
:00476B03 8BC3                    mov eax, ebx
:00476B05 E86E63FFFF              call 0046CE78

* Possible StringData Ref from Code Obj ->"1.0"
                                  |
:00476B0A B9D46B4700              mov ecx, 00476BD4

* Possible StringData Ref from Code Obj ->"Version"
                                  |
:00476B0F BAE06B4700              mov edx, 00476BE0
:00476B14 8BC3                    mov eax, ebx
:00476B16 E8F964FFFF              call 0046D014
:00476B1B 8BC3                    mov eax, ebx
:00476B1D E836CAF8FF              call 00403558
:00476B22 6A00                    push 00000000
:00476B24 668B0DE86B4700          mov cx, word ptr [00476BE8]
:00476B2B B202                    mov dl, 02

* Possible StringData Ref from Code Obj ->"恭喜您,注册成功!谢谢您支持本软件,请保存好序列?
                                        ->"庞胱⒉崧?便于作者为您提供服务! "
                                        ->"  联系邮箱:JRYCL@163.COM"
                                  |
:00476B2D B8F46B4700              mov eax, 00476BF4
:00476B32 E85999FBFF              call 00430490
:00476B37 33D2                    xor edx, edx
:00476B39 8B8618040000            mov eax, dword ptr [esi+00000418]
:00476B3F E818FEFBFF              call 0043695C
:00476B44 A18C9C4700              mov eax, dword ptr [00479C8C]
:00476B49 C6802D02000001          mov byte ptr [eax+0000022D], 01
:00476B50 EB15                    jmp 00476B67

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00476AE0(C)
|
:00476B52 6A00                    push 00000000
:00476B54 668B0DE86B4700          mov cx, word ptr [00476BE8]
:00476B5B B201                    mov dl, 01

* Possible StringData Ref from Code Obj ->"对不起!您的注册码不正确,请与作者联系! "
                                        ->"联系邮箱:JRYCL@163.COM"
                                  |
:00476B5D B8646C4700              mov eax, 00476C64
:00476B62 E82999FBFF              call 00430490

*******************************************************************************************************************
算法整理:
这是典型的非明码比较的注册码形式;
1.:00476ADE处比较EAX和EDX.如果相等就注册成功,不相等则注册失败;
  我们来看:EAX中保存着我们输入的假SN变成十六进制形式在经过与常数XOR计算所得的数值,而EDX中保存着MN的十六进制形式;
  如果想注册成功就要使EAX等于EDX;

2.好既然这样我们就令:EAX=EDX;然后,逆推;
(这里我们要知道一些必要的知识即:A XOR B = C 等价于 A XOR C = B 或 B XOR C = A);
如果知道这些就简单了啊!
用MN先与常数0x2B30A63异或,在与常数0x337ACC5异或;
最后,将所得的数变成十进制就是正确的注册码了啊!
例如:
MN=44051256
44051256=0x2A02B38
0x2A02B38 XOR 0x2B30A63 = 0x13215B
0x13215B XOR 0x337ACC5 = 0x3248D9E
0x3248D9E=52727198
SN=52727198
输入52727198显示成功!!!!!!!!
*********************************************************************************************************************
另外这个软件有个缺陷
如果在[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components]
建立主键"Version"="1.0"
那么就不用注册就可以成功了啊!
2004-8-5 18:52
0
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
88
真能灌:D
2004-8-5 20:25
0
雪    币: 110
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
89
2004-8-5 21:18
0
雪    币: 200
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
90
啊收藏先
2004-8-5 23:16
0
雪    币: 199
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
91
不胜感激
2004-8-6 10:20
0
雪    币: 211
活跃值: (50)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
92
又见一牛人~
我顶
2004-8-6 12:10
0
雪    币: 261
活跃值: (230)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
93
大哥能给一篇关于 脱PELock 的文章吗?:)
2004-8-6 14:57
0
雪    币: 106728
活跃值: (202444)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
94
***** ***** by crUsAdEr ***** ****

This tutorial aims to discuss about PElock 1.06 protection. Various techniques are employed to prevent crackers from fooling with this protector, so in this tutorial I hope to reverse some interesting features of PELock and eventually remove the protection layer. PELock is highly OS dependent and this tutorial is done purely on win2k so some protection features discussed here will be different on other OS.

TOOLS used :
IDA 4.15
Soft Ice on Win2k  SP3
LordPE Deluxe
Superbpm for NT/2k
Imprec 1.4.2

Targets : PELock 1.06
Included : PElock.idc

Prologue

PELock is a very interesting protection with many features similar to SVKProtector especially IAT redirection, code decryption after OEP. PELock is also able to detect icedump on win98 by exploiting the fact that icedump leaves kernel32.dll memory unprotected (as discussed by SplAj on Fravia Message Board). Though I try to make this essay as reader-friendly as possible, I assume that readers have some background in unpacking, have thorough knowledge of Structured Exception Handling and are able to use the tools listed above comfortably. PELock does extensive bpx checking by checking opcodes for "CC" so throughout this exercise, do not use bpx on API or PELock will throw a tantrum and exit silently. Also, PELock clears debug register with via SEH so you should have SuperBPM running at all time.

(Finally, though it is not essential, I recommend readers to read my two previous essays on AsProtect 1.2 and Armadillo 2.6 to gain some background knowledge as I will not be repeating the same points covered in those essays.)

1. Playing with the lock

OK, I hope you have already downloaded PELock and discovered that it wont run together with softice. We will worry about it later! The heart of PELock or as many other protector, lies in its loader that performs the target file decryption, import loading and we will set out obtaining a valid dump of PELock loader first. Load Superbpm for NT/2k with softice and do "bpm VirtualAlloc x". Run PELock, once softice breaks, you will land here

00431682     push 4
00431684     push 3000h
00431689     push 0F000h                ; loader size
0043168E     push ecx
0043168F     mov edx, [ebp+VirtualAlloc]
00431692     cmp byte ptr [edx], 0CCh   ; check opcodes for bpx
00431695     setz cl                        ; if bpx found then
00431698     add edx, ecx               ; change value of edx and causes error
0043169A     call edx
0043169C     lea edx, [ebp+756h]   <===  YOU SHOULD LAND HERE
004316A2     push eax                        ; here eax is the address of VirtualAlloc memory
004316A3     push edx                        ; where the main PELock loader will be decrypted to
004316A4     push eax
004316A5     pusha
<-----------snip------------->
<--loader decryption routine-->
00431768     mov [esp+1Ch], edi
0043176C     popa
0043176D     retn                ; jumps to PELock loader code from here

As you have seen above, this is where PELock loader is decrypted into memory. The long decryption routine is removed but you can simply scroll down in softice windows to find the "ret" instruction. We need to put a break point at this address 43176D and make a dump of this PELock loader, you can look in stack to find out the base address of our new decrypted loader. Once dumped, we can load this loader into IDA to disassemble and study. I trust you know how to do this by building a simple PE Header for our dump or cut and paste into PELock.exe and uses Reload Input File in IDA.

Once you manage to load PELock loader into IDA, you will see this:

00401000     call near ptr PE_Lock_start+24h
00401005
00401005 GetAPIAddress proc near       ; CODE XREF: ...
00401005
00401005 var_4= byte ptr -4
00401005 arg_0= dword ptr  8
00401005 arg_4= dword ptr  0Ch
00401005 arg_8= dword ptr  10h
00401005 arg_C= byte ptr  14h
00401005 arg_104= dword ptr  10Ch
00401005
00401005     push ebp
00401006     mov ebp, esp
00401008     pusha
<---------continue---------->

The snippet above are a few first instruction of PELock loader, starting with a "home-made" GetProcAddress routine that read system dll PE Header and traverse its export directory to find API address. API names are hashed and compared with tables (we will discuss more about this in API redirection section). Once each API address is found, the first byte is checked against "CC" and if bpx is detected then the execution flow will be changed slightly causing PELock to eventually exit in silence. As the whole loader is not fully decrypted yet, various parts of the loader are still encrypted and would only be decrypted later as PELock proceed to loading its main exe so as you debug and run PElock, if you find that IDA disassembly is different from softice screen then you will need to make a new dump of the loader and paste the newly decrypted loader code over the encrypt code for IDA to disassemble them properly.

As you start tracing PELock loader, you will realize that there are a lot garbage code inserted in the loader to make tracing and disassembling difficult. Here are a few typical examples of garbage code:

0040159F C1 F7 00              sal edi, 0
004015A2 C1 F2 00              sal edx, 0                ; do nothing
004015A5 EB 02                 jmp short loc_4015A9        ; jump over
004015A5                   ; -----------------------------------------------------------
004015A7 CD                    db 0CDh ; -
004015A8 20                    db  20h ;  
004015A9                   ; -----------------------------------------------------------
004015A9                  
004015A9                   loc_4015A9:                   ; CODE XREF: ...
004015A9 C1 F0 00              sal eax, 0
004015AC EB 02                 jmp short loc_4015B0
004015AC                   ; -----------------------------------------------------------
004015AE C9                    db 0C9h ; +
004015AF 22                    db  22h ; "
004015B0                   ; -----------------------------------------------------------
004015B0                  
004015B0                   loc_4015B0:                   ; CODE XREF: ...
004015B0 E8 01 00 00 00        call loc_4015B6                ; call over head
004015B0                   ; -----------------------------------------------------------
004015B5 42                    db  42h ; B
004015B6                   ; -----------------------------------------------------------
004015B6                  
004015B6                   loc_4015B6:                   ; CODE XREF: ...
004015B6 8D 64 24 04           lea esp, [esp+4]                ; correct stack
        OR THIS
004015F1 E8 01 00 00 00        call loc_4015F7
004015F1                   ; -----------------------------------------------------------
004015F6 3B                    db  3Bh ; ;
004015F7                   ; -----------------------------------------------------------
004015F7                  
004015F7                   loc_4015F7:                   ; CODE XREF: ...
004015F7 8F 44 24 FC           pop dword ptr [esp-4]        ; correct stack
        OR THIS
004015D6 7A 03                 jp  short loc_4015DB        ; doesn't matter the status of EFlags
004015D8 7B 01                 jnp short loc_4015DB        ; one of these jumps will jump
004015D8                   ; -----------------------------------------------------------
004015DA 7E                    db  7Eh ; ~
004015DB                   ; -----------------------------------------------------------
004015DB                  
004015DB                   loc_4015DB:                   ; CODE XREF: ...
004015DB EB 02                 jmp short loc_4015DF        ; garbage code
004015DB                   ; -----------------------------------------------------------
004015DD 8B                    db  8Bh ; ï
004015DE 8D                    db  8Dh ; ì
004015DF                   ; -----------------------------------------------------------
004015DF                  
004015DF                   loc_4015DF:                   ; CODE XREF: ...
004015DF C1 F6 00              sal esi, 0

It is very important to remove these garbage codes that do nothing from our disassembly so that we can have a better over view of the loader codes as well as save us time from correcting the disassembly in IDA. You can try using various tools like MOW, Imhotep etc or code your own tool to clean out the garbage. I coded myself a simple idc script which checks the opcodes pattern for these garbage code and NOP them out, displaying them as single line array. Further code snippet of this tutorial are taken after most garbage code had been removed. I have attached my idc script above for reference purpose, you can try coding your own script to suit your need.
2004-8-6 17:53
0
雪    币: 106728
活跃值: (202444)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
95
2. Softice detection

Once you have cleaned out most of the garbage code of PELock, you can then comfortably proceed on to study PELock but first we need PELock to run in the presence of Softice. Under win2k, PELock has too effective softice detection which is int1 detection and UnhandledExceptionFilter byte check.

When softice is loaded, softice replaces the first byte of kernel32!UnhandledExceptionFilter API with a "CC" instead of the usual "55". PELock checks this byte for "CC" as follow

004010D4 80 38 CC              cmp byte ptr [eax], 0CCh ; '¦'
004010D7 75 0F                 jnz short OK
004010D9 74 01                 jz  short near ptr bad

Thus, to bypass this check, we place a memory READ breakpoint on UnhandledExceptionFilter and change the Zero flag.
bpm UnhandledExceptionFilter r do "r fl z"

When Windows 2000 is running without softice, INT01 descriptor entry in IDT has DPL=0. So if a ring-3 task attempts to call INT01 with DPL=0, a GP=INT0D fault will occur and Windows INT0D handler will report C0000005 (EXCEPTION_ACCESS_VIOLATION) as the exception code and Eip as address where exception occur. When ntice is loaded, it sets DPL=3 for INT01 descriptor entry in IDT and now INT01 can be accessed by normal ring-3 task. Now if an INT01 is encountered, the next instruction address is stored on stack instead and Windows will check for any breakpoints placed, if not found then Windows will report a 80000004 (EXCEPTION_SINGLE_STEP) exception. In short, if softice is loaded, then the exception code is 80000004 and exception address is EIP+2 when int1 is encountered while if softice is not loaded, the exception code would be C0000005 and exception address would be EIP. (For detail reference, please refer to Intel Manual Volume 3).         Thanks [Yates] for the explanation!

PELock uses the fact that exception addresses differ to check if softice is loaded. An normal SEH handler is set up!

004044A3 CD 01                 int 1    ; exception address here if softice is not loader
004044A5 C3                    retn        ; exception address here if softice loaded
004044A6                   ; -----------------------------------------------------------
004044A6 EB 36                 jmp short near sice_not_present
004044A6                   ; -----------------------------------------------------------
004044A8 90 90 90 90 90 90+    Softice_detected db 35h dup(90h)
004044DD                   ; -----------------------------------------------------------
004044DD C3                    retn
004044DD                   ; -----------------------------------------------------------
004044DE 90 90 90 90 90 90+sice_not_present db 40h dup(90h)

<--- Inside SEH handler --->
004040E4 83 A8 B8 00 00 00+    sub [eax+CONTEXT.Eip], 0FFFFFFFDh ; add Eip by 3 bytes
004040E4 FD                                     ; if sice is present, int1 exception
004040E4                                        ; will move Eip ahead by 2 bytes already
Hence, if softice is detected, the execution flow will change and soon PELock will exit silently. To overcome this detection, we need to patch IDT entry for INT01 descriptor so that DPL=0 again. In win2k do
idt            ; to obtain address of Interrupt Descriptors Table
d <address of IDT>
Change the 0Dh byte from IDT on the table from EE to 8E    Thanks SiNTaX and Nikolatesla for the tip
For more detailed explanation, you can refer to Art Of Assembly about IDT format.

3. Import Rebuilding

Once you are done with IDT patching, UnhandedExceptionFilter will break twice but PELock will happily run with softice loaded. Our next task is then to obtain valid import data. Run PELock, at the first UnhandledExceptionFilter breakpoint, you will be inside the "home-made" GetProcAddress described above, do "bpm Eip x" to place a breakpoint in this routine, when softice breaks at this breakpoint, press F12 once and you will be in the middle of IAT loading and redirecting process.

00405350 EB 2A                 jmp short near ptr ImportLoadingStart
00405350                   ; ------------------------------------------------------
00405352 90 90 90 90 90 90+next_dll_entry db 27h dup(90h) ; CODE XREF: seg000:004059C3j
00405379                   ; ------------------------------------------------------
00405379 8D 7E 01              lea edi, [esi+1]
00405379                   ; ------------------------------------------------------
0040537C 90 90 90 90 90 90+ImportLoadingStart db 24h dup(90h) ; CODE XREF: seg000:00405350j
004053A0                   ; ------------------------------------------------------
004053A0 57                    push edi        ; edi -> DLL name
004053A1 FF 55 00              call [ebp+API.LoadLibrary]
004053A1                   ; ------------------------------------------------------
004053A4 90 90 90 90 90 90+    db 2Ch dup(90h)
004053D0                   ; ------------------------------------------------------
004053D0 85 C0                 test eax, eax
004053D2 0F 84 13 1A 00 00     jz  Library_loading_fail
004053D2                   ; ------------------------------------------------------
004053D8 90 90 90 90 90 90+    db 26h dup(90h)
004053FE                   ; ------------------------------------------------------
004053FE 8B D0                 mov edx, eax    ; edx = DLL handle
004053FE                   ; ------------------------------------------------------
00405400 90 90 90 90 90 90+    db 2Dh dup(90h)
0040542D                   ; ------------------------------------------------------
0040542D 8B F7                 mov esi, edi    ; import data block pointer
0040542D                   ; ------------------------------------------------------
0040542F 90 90 90 90 90 90+    db 2Dh dup(90h)
0040545C                   ; ------------------------------------------------------
0040545C                   string_scan_loop:   ; CODE XREF: seg000:00405461j
0040545C 8A 06                 mov al, [esi]   ; simple loop scan along Import Data block
0040545E 46                    inc esi         ; to mov pointer to the end of DLL name
0040545F 84 C0                 test al, al     ; by checking for null byte
00405461 75 F9                 jnz short string_scan_loop
00405461                   ; ------------------------------------------------------
00405463 90 90 90 90 90 90+not_end_of_thunk db 4Eh dup(90h) ; CODE XREF: seg000:00405925j
004054B1                   ; ------------------------------------------------------
004054B1 8B 46 01              mov eax, [esi+1] ; get API name hash from Import Data Block
004054B1                   ; ------------------------------------------------------
004054B4 90 90 90 90 90 90+    db 2Ah dup(90h)
004054DE                   ; ------------------------------------------------------
004054DE B9 B2 06 00 00        mov ecx, 6B2h   ; initialize counter for CRC loop below
004054DE                   ; ------------------------------------------------------
004054E3 90 90 90 90 90 90+    db 23h dup(90h)
00405506                   ; ------------------------------------------------------
00405506                   CRC_import_decrypt_loop: ; CODE XREF: seg000:00405510j
00405506 2B 84 8D 0A 3D 00+    sub eax, [ebp+ecx*4+3D0Ah] ; loop decrypting API name hash
0040550D D3 C0                 rol eax, cl     ; using CRC of the code area around here
0040550F 49                    dec ecx         ; to prevent patching
00405510 75 F4                 jnz short CRC_import_decrypt_loop
00405510                   ; ------------------------------------------------------
00405512 90 90 90 90 90 90+    db 28h dup(90h)
0040553A                   ; ------------------------------------------------------
0040553A 8A 0E                 mov cl, [esi]   ; get the first char of API name
0040553C 83 C6 05              add esi, 5
0040553C                   ; ------------------------------------------------------
0040553F 90 90 90 90 90 90+    db 23h dup(90h)
00405562                   ; ------------------------------------------------------
00405562 51                    push ecx        ; push first_char
00405562                   ; ------------------------------------------------------
00405563 90 90 90 90 90 90+    db 23h dup(90h)
00405586                   ; ------------------------------------------------------
00405586 50                    push eax        ; push API_name_hash
00405586                   ; ------------------------------------------------------
00405587 90 90 90 90 90 90+    db 32h dup(90h)
004055B9                   ; ------------------------------------------------------
004055B9 52                    push edx               ; push DLL handle
004055B9                   ; ------------------------------------------------------
004055BA 90 90 90 90 90 90+    db 29h dup(90h)
004055E3                   ; ------------------------------------------------------
004055E3 FF 75 00              push dword ptr [ebp+0]
004055E3                   ; ------------------------------------------------------
004055E6 90 90 90 90 90 90+    db 33h dup(90h)
00405619                   ; ------------------------------------------------------
00405619 E8 E7 B9 FF FF        call GetAPIAddress ; The home-made GetProcAddress
00405619                   ; ------------------------------------------------------
0040561E 90 90 90 90 90 90+    db 30h dup(90h)   <=== YOU SHOULD LAND HERE
                                but these garbage code are removed by my idc script
0040564E                   ; ------------------------------------------------------
0040564E 85 C0                 test eax, eax   ; check API address found
0040564E                   ; ------------------------------------------------------
00405650 90 90 90 90 90 90+    db 1Dh dup(90h)
0040566D                   ; ------------------------------------------------------
0040566D 0F 84 92 17 00 00     jz  API_add_not_found
0040566D                   ; ------------------------------------------------------
00405673 90 90 90 90 90 90+    db 5Bh dup(90h)
004056CE                   ; ------------------------------------------------------
004056CE F6 C1 80              test cl, 80h    ; check redirection flag
004056CE                                       ; if cl=80 then API is to be redirected
004056CE                   ; ------------------------------------------------------
004056D1 90 90 90 90 90 90+    db 2Bh dup(90h)
004056FC                   ; ------------------------------------------------------
004056FC 8B 0E                 mov ecx, [esi]
004056FC                   ; ------------------------------------------------------
004056FE 90 90 90 90 90 90+    db 47h dup(90h)
00405745                   ; ------------------------------------------------------
00405745 0F 84 87 00 00 00     jz  near ptr redirect_import+2Bh ; our CRUCIAL JUMP
00405745                   ; ------------------------------------------------------
0040574B 90 90 90 90 90 90+    db 55h dup(90h)
004057A0                   ; ------------------------------------------------------
004057A0 89 01                 mov [ecx], eax  ; update First Thunk of Import Directory
004057A2 E9 1F 01 00 00        jmp next_entry_in_thunk ; with original API address
004057A2                   ; ------------------------------------------------------
004057A7 90 90 90 90 90 90+redirect_import db 8Bh dup(90h) ; CODE XREF: seg000:00405745j
00405832                   ; ------------------------------------------------------
00405832 89 19                 mov [ecx], ebx  ; update First Thunk with redirected API address
00405832                   ; ------------------------------------------------------
00405834 90 90 90 90 90 90+    db 5Dh dup(90h)
00405891                   ; ------------------------------------------------------
00405891 E8 51 01 00 00        call near ptr redirect_API+1Fh
00405891                   ; ------------------------------------------------------
00405896 90 90 90 90 90 90+    db 30h dup(90h)
004058C6                   ; ------------------------------------------------------
004058C6                   next_entry_in_thunk: ; CODE XREF: seg000:004057A2j
004058C6 83 C6 04              add esi, 4
004058C6                   ; ------------------------------------------------------
004058C9 90 90 90 90 90 90+    db 30h dup(90h)
004058F9                   ; ------------------------------------------------------
004058F9 B1 FE                 mov cl, 0FEh ; '¦' ; check for stopping byte
004058F9                   ; ------------------------------------------------------
004058FB 90 90 90 90 90 90+    db 28h dup(90h)
00405923                   ; ------------------------------------------------------
00405923 38 0E                 cmp [esi], cl   ; if found then it is the end of thunk
00405925 0F 85 60 FB FF FF     jnz near ptr not_end_of_thunk+28h
00405925                   ; ------------------------------------------------------
0040592B 90 90 90 90 90 90+    db 32h dup(90h)
0040595D                   ; ------------------------------------------------------
0040595D 38 4E 01              cmp [esi+1], cl ; check for stopping byte again
0040595D                   ; ------------------------------------------------------
00405960 90 90 90 90 90 90+    db 28h dup(90h)
00405988                   ; ------------------------------------------------------
00405988 0F 84 FC 17 00 00     jz  import_done ; if  2 stopping byte together
00405988                                       ; it is the end of Import Data
00405988                   ; ------------------------------------------------------
0040598E 90 90 90 90 90 90+    db 35h dup(90h)
004059C3                   ; ------------------------------------------------------
004059C3 E9 8A F9 FF FF        jmp near ptr next_dll_entry

I hope the comments are sufficient. Basically, Import Data is stored in a big block with "FE" used as a stopping byte or marker. Each DLL import entry is started with DLL name in plain ASCII, followed by import entries table and ended with "FE". Each import entry in the table comprises of 5 bytes, the first byte is first ASCII char of API name, the next dword is the API name hash. Here is an example of  Import Data block :

00407E21 6B 65 72 6E 65 6C+aKernel32_dll_0 db 'kernel32.dll',0
00407E2E 56                    db  56h ; V
00407E2F B5 F2 31 F6           dd 0F631F2B5h
00407E33 56                    db  56h ; V
00407E34 22 0A AC 32           dd 32AC0A22h
<-------------SNIP------------->
00407E60 47                    db  47h ; G
00407E61 E4 0D 06 DE           dd 0DE060DE4h
00407E65 FF                    db 0FEh ;          stopping byte
00407E66 75 73 65 72 33 32+aUser32_dll db 'user32.dll',0
00407E71 4D                    db  4Dh ; M
00407E72 71 A2 D2 A8           dd 0A8D2A271h
00407E76 FF                    db 0FEh ;        stopping byte  
00407E77 FF                    db 0FEh ;  
Each import entry above is then passed as parameters for the "home-made" GetProcAddress which (assumes that system DLL export directories are alphabetically sorted) will then parse the export directory until it finds a match on the first char. It will then start performing hash on each API name of the Export Directory until a match for the required hash is found, this API address found will then be check for bpx then return to eax by the routine. As you can see, the compare at 4056CE and the conditional jump at 405745 are key decider on whether an API should be redirected or not. We would like PELock not to redirect any API at all but patching the jump wont do simply because the code CRC is used to calculate our import hash values. There are two solution to this, patching the "home-made" GetProcAddress to change value of ecx to 0 so that the jz at 405745 will always not jump or switching the zero flag at 405745 if zero flag is set. I opted for the second method by using this simple command below in softice.
bpm 405745 x if ZFL==1 do "r fl z; x"

Softice screen will flicker a lot as the breakpoint is hit pretty often (wonder why :) and there are quite a lot of imports so if you stand up, do a bit of stretching away from the monitor for a minute or so, when you come back PELock will already be running as if nothing had changed. BUT run Imprec now, enter OEP as 1000 and it will automatically find IAT for you at 28000. Click Get Import and Import will be able to resolve all import normally except 1. It is left as an exercise for readers to find out which API it is and why it is still redirected.
2004-8-6 17:54
0
雪    币: 106728
活跃值: (202444)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
96
4. Decrypting the target EXE

Once you have fixed the IAT redirection routine and obtain a valid Import tree for Imprec, save it and put it aside. It is time to fully decrypt PElock.exe and obtain a full working dump. Run PELock again and launch LordPE, select Partial Dump and enter dump size as PELock.exe image size. Disassemble the dump in IDA you will realize that there are lots of code which are still encrypted and decrypted only when needed. Here is a snippet example of code still encrypted after OEP is reached :

00401ECA E8 33 5A EF FF        call near ptr 2F7902h   ; CALL Decryptor
00401ECA                   ; ----------------------------------------------------------
00401ECF E8 02 00 00           dd 2E8h                        ; code block property
00401ED3 66 7B 6B 3C 47 89+    db 66h, 7Bh, 6Bh, 3Ch, 47h, 89h, 0EDh, 39h, 53h, 0EFh, 83h,
00401ED3 ED 39 53 EF 83 00+    db 72h, 6Fh, 5Dh, 3Ch, 0EEh, 26h, 0B0h, 78h, 0AEh, 29h, 98h
00401ED3 B7 A1 AD 9D E8 B2+    db 0FBh, 0EBh, 0FAh, 0EBh, 0FCh, 0EBh, 6, 0CDh, 20h, 0EBh,
00401F40                   ; -------------------------------------------------------------
00401F40 E8 F1 61 EF FF        call near ptr 2F8136h  ;  CALL Re-encryptor
00401F40                   ; -------------------------------------------------------------
00401F45 E8 02 00 00           dd 2E8h                      ; code block property
00401F49                   ; -------------------------------------------------------------

As you can see, there are a lot of block of codes as above in our dump.exe and the Decryptor and Re-encryptor address are not within the image of the exe but in PE loader memory instead. Basically, to prevent unpacking and dumping, PELock inserted a lot of these blocks of encrypted code into the original exe, when these codes need to be executed, the Decryptor will be called first, which read the code block property then decrypt the block accordingly, then return from the Decrypt call, execute the code block, call Re-encryptor to re-crypt the code block back again before moving onto normal execution again. Further investigation of dump.exe  shows that there are 3 different pairs of Decrypt-Encrypt call with different addresses and different algorithms employed.

Checking these routines in our loader, we will see that the dword below each CALL commented as "code block property" is an encrypted value of the code block length. Though a thorough understanding of Decryptors algorithm is not required to obtain good dump of the target exe, it is useful to go through them to understand roughly how they work. To keep this essay within reasonable length, I will not discussed the algorithm here.

In order to obtain a good dump, we need to force PELock loader to decrypt all these code blocks before reaching OEP. We can patch the Decryptor to decrypt the code blocks and overwrite call to encryptor with simple jump over but how do we know we have decrypted ALL the encrypted blocks left behind after OEP is reached? I was thinking about this problem and decided that PELock loader will need to know where to insert these Call to Decryptor and Re-encryptor as the loader offset will be different in different computer, hence PELock loader will need to calculate the call distance each time it loads up and insert these distances into the target exe so there must be a kind of table that store the offset of where these Calls should be inserted. Indeed that was the case. Re-run PELock and place bpm write one of these calls to Decryptor in the original EXE image and softice will break right in the middle of these routine.

0040DBA8                   insert_crypt_engine_3: ; CODE XREF: seg000:00407578p
0040DBA8 60                    pusha
0040DBA9 E8 A3 FF FF FF        call mov_ebp_40DB56        ; set ebp the necessary base
0040DBAE 8D 75 F7              lea esi, [ebp-9]
0040DBAE                   ; -----------------------------------------------------------
0040DBB1 90 90 90 90 90 90+    db 30h dup(90h)
0040DBE1                   ; -----------------------------------------------------------
0040DBE1 8D 95 6C 03 00 00     lea edx, [ebp+36Ch]        ; get address of Decryptor
0040DBE1                   ; -----------------------------------------------------------
0040DBE7 90 90 90 90 90 90+    db 21h dup(90h)
0040DC08                   ; -----------------------------------------------------------
0040DC08 B9 03 00 00 00        mov ecx, 3      ; size of table, only 3 entries
0040DC08                   ; -----------------------------------------------------------
0040DC0D 90 90 90 90 90 90+loop_inserting_all_engine_loc db 24h dup(90h) ;
0040DC31                   ; -----------------------------------------------------------
0040DC31 8B 06                 mov eax, [esi]        ; read one dword from table
0040DC31                   ; -------------------; each dword is address where Call are
0040DC33 90 90 90 90 90 90+    db 25h dup(90h)  ; to be inserted
0040DC58                   ; -----------------------------------------------------------
0040DC58 83 EE 04              sub esi, 4        ; mov pointer on table backwards
0040DC58                   ; -----------------------------------------------------------
0040DC5B 90 90 90 90 90 90+    db 2Dh dup(90h)
0040DC88                   ; -----------------------------------------------------------
0040DC88 C6 00 E8              mov byte ptr [eax], 0E8h ; set up the CALL byte
0040DC88                   ; -----------------------------------------------------------
0040DC8B 90 90 90 90 90 90+    db 2Dh dup(90h)
0040DCB8                   ; -----------------------------------------------------------
0040DCB8 40                    inc eax
0040DCB9 8B FA                 mov edi, edx                ; edi -> address of Decryptor
0040DCBB 2B F8                 sub edi, eax                ; calculate the Call distance
0040DCBB                   ; -----------------------------------------------------------
0040DCBD 90 90 90 90 90 90+    db 2Bh dup(90h)
0040DCE8                   ; -----------------------------------------------------------
0040DCE8 83 EF 04              sub edi, 4                ; minus instruction length
0040DCEB 89 38                 mov [eax], edi                  ; insert CAll distance after E8
0040DCEB                   ; -----------------------------------------------------------
                                                PATCHES made to force decrypt code
0040DCED 90 90 90 90 90 90+    db 28h dup(90h) ; push dword ptr [eax+4]
0040DCED 90 90 90 90 90 90+                    ; pushad
0040DCED 90 90 90 90 90 90+                    ; dec eax
0040DCED 90 90 90 90 90 90+                    ; call eax=>decrypt routine which is patched
0040DCED 90 90 90 90 90 90+                    ; popad
0040DCED 90 90 90 90 90 90+                    ; pop dword ptr [eax+4]
0040DCED 90 90 90 90                           ; mov word [eax-1], 7EB
0040DD15                   ; -----------------------------------------------------------
0040DD15 83 C0 08              add eax, 8                ;
0040DD18 03 40 FC              add eax, [eax-4]                ; add code block length
0040DD1B 83 C0 10              add eax, 10h                ; eax -> where Call Re-encryptor
                                                          should be placed
0040DD1B                   ; -----------------------------------------------------------
0040DD1E 90 90 90 90 90 90+    db 2Eh dup(90h)                ; Here another call is set up
0040DD4C                   ; -----------------------------------------------------------
0040DD4C C6 00 E8              mov byte ptr [eax], 0E8h ; 'F' ; mov byte ptr [eax], E9
0040DD4C                   ; -----------------------------------------------------------
0040DD4F 90 90 90 90 90 90+    db 2Fh dup(90h)                ; to call Re-encryptor
0040DD7E                   ; -----------------------------------------------------------
0040DD7E 40                    inc eax
0040DD7E                   ; -----------------------------------------------------------
0040DD7F 90 90 90 90 90 90+    db 2Ch dup(90h)                ; edi -> address of Re-encryptor
0040DDAB                   ; -----------------------------------------------------------
0040DDAB 8D BD 4E 07 00 00     lea edi, [ebp+74Eh] ; lea edi, [eax+8]
0040DDAB                   ; -----------------------------------------------------------
0040DDB1 90 90 90 90 90 90+    db 28h dup(90h)
0040DDD9                   ; -----------------------------------------------------------
0040DDD9 2B F8                 sub edi, eax                ; calculate Call distance
0040DDD9                   ; -----------------------------------------------------------
0040DDDB 90 90 90 90 90 90+    db 23h dup(90h)
0040DDFE                   ; -----------------------------------------------------------
0040DDFE 83 EF 04              sub edi, 4                ; minus instruction length
0040DDFE                   ; -----------------------------------------------------------
0040DE01 90 90 90 90 90 90+    db 25h dup(90h)
0040DE26                   ; -----------------------------------------------------------
0040DE26 89 38                 mov [eax], edi                ; insert call distance
0040DE26                   ; -----------------------------------------------------------
0040DE28 90 90 90 90 90 90+    db 2Eh dup(90h)                ; to finalise the Call
0040DE56                   ; -----------------------------------------------------------
0040DE56 49                    dec ecx                        ; decrease counter along the table
0040DE56                   ; -----------------------------------------------------------
0040DE57 90 90 90 90 90 90+    db 36h dup(90h)                ; if not end of table, loop back
0040DE8D                   ; -----------------------------------------------------------
0040DE8D 0F 85 7A FD FF FF     jnz near ptr loop_inserting_all_engine_loc
0040DE8D                   ; -----------------------------------------------------------
0040DE93 90 90 90 90 90 90+    db 23h dup(90h)
0040DEB6                   ; -----------------------------------------------------------
0040DEB6 8D 7D 52              lea edi, [ebp+52h]
0040DEB9 B9 16 03 00 00        mov ecx, 316h                ; overwrite code area above
0040DEBE F3 AA                 repe stosb                ; with garbage
0040DEC0 61                    popa
0040DEC1 C3                    retn
The comments are pretty clear. Address of encrypted code are stored in tables, where each entry is read, then E8xxxxxxxx is placed there to Call Decryptor and location of Call to Re-encryptor is calculated based on the encrypted code block length. We need to patch these routine so that they will decrypt all code blocks listed on the table of addresses and not place Call to Decryptor/Encryptor into these address. I have made the necessary patches in orange as commented above. "Call eax" is used to simulate execution of the original exe and hence will trigger Call Decryptor which will then decrypt the code block following that address. However, we need to patch the Decryptor routine not to return execution to original exe like normal but to return execution to our patched loop. This can be done simply by correcting the stack.

We need to find the end of the Decryptor routine which looks like this
ret             ; return execution to just decrypted code block
and patch it to correct stack like this
pop eax     ; eax = address of decrypted code block
ret             ; return from our "Call eax" to our patched loop
2004-8-6 17:57
0
雪    币: 106728
活跃值: (202444)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
97
4. The CRC trap

As mentioned above, there are 3 different set of Decryptor/Encryptor and hence each has a separate routine inserting those Calls into the target exe with a separate table containing address where those calls should be inserted to. In order to obtain a good dump, we need to patch all 3 routines to force decrypt the whole code section of the target exe. However, problem arises when one of these Calls Insertion routine has an encrypted table of address which uses the routine CRC to decrypt these table entries. Attempts to patch it will cause table entries to be decrypted incorrectly. Here is how the routine look like :

00408368                   Insert_Crypt_Engine_1: ;
00408368 B9 4A 00 00 00        mov ecx, 4Ah         ;  size of table 1
00408368                   ; -----------------------------------------------------------
0040836D 90 90 90 90 90 90+    db 27h dup(90h)
00408394                   ; -----------------------------------------------------------
00408394 8D 75 E8              lea esi, [ebp-18h] ; start of Table 1
00408394                   ; -----------------------------------------------------------
00408397 90 90 90 90 90 90+    db 27h dup(90h)
004083BE                   ; -----------------------------------------------------------
004083BE 8D 95 68 0B 00 00     lea edx, [ebp+0B68h]        ; edx -> Decryptor address
004083BE                   ; -----------------------------------------------------------
004083C4 90 90 90 90 90 90+get_crypted_offset db 55h dup(90h) ; CODE XREF: ...
00408419                   ; -----------------------------------------------------------
00408419 8B 06                 mov eax, [esi]                ; read encrypted entry from table
0040841B EB 31                 jmp short near ptr prepare_CRC_data_pointer
0040841B                   ; -----------------------------------------------------------
0040841D 90 90 90 90 90 90+set_no_of_loop db 27h dup(90h) ; CODE XREF: ...
00408444                   ; -----------------------------------------------------------
00408444 BB 1F 01 00 00        mov ebx, 11Fh
00408449 E9 25 01 00 00        jmp near ptr calculate_insertion_address
00408449                   ; -----------------------------------------------------------
0040844E 90 90 90 90 90 90+prepare_CRC_data_pointer db 2Eh dup(90h) ; CODE XREF: ...
0040847C                   ; -----------------------------------------------------------
0040847C 83 EE 04              sub esi, 4
0040847F EB 9C                 jmp short near ptr set_no_of_loop
0040847F                   ; -----------------------------------------------------------
00408481 90 90 90 90 90 90+get_call_distance db 2Fh dup(90h) ; CODE XREF: ...
004084B0                   ; -----------------------------------------------------------
004084B0 2B F8                 sub edi, eax
004084B2 E9 84 00 00 00        jmp near ptr minus_length_4_bytes
004084B2                   ; -----------------------------------------------------------
004084B7 90 90 90 90 90 90+set_up_CALL_decrypt db 2Eh dup(90h) ; CODE XREF: ...
004084E5                   ; -----------------------------------------------------------
004084E5 C6 00 E8              mov byte ptr [eax], 0E8h ; 'F' ; set up CALL
004084E8 E9 09 01 00 00        jmp near ptr minus_1_byte
004084E8                   ; -----------------------------------------------------------
004084ED 90 90 90 90 90 90+decrease_counter db 1Bh dup(90h) ; CODE XREF: ...
00408508                   ; -----------------------------------------------------------
00408508 49                    dec ecx                ; decrease counter to check end of table
00408509 E9 C1 02 00 00        jmp check_end_of_table?
00408509                   ; -----------------------------------------------------------
0040850E 90 90 90 90 90 90+get_CALL_to_address db 26h dup(90h) ; CODE XREF: ...
00408534                   ; -----------------------------------------------------------
00408534 8B FA                 mov edi, edx
00408536 E9 46 FF FF FF        jmp near ptr get_call_distance
00408536                   ; -----------------------------------------------------------
0040853B 90 90 90 90 90 90+minus_length_4_bytes db 30h dup(90h) ; CODE XREF: ...
0040856B                   ; -----------------------------------------------------------
0040856B 83 EF 04              sub edi, 4        ; decrease pointer to table entries by 4
0040856E E9 F3 01 00 00        jmp near ptr store_jump_distance
0040856E                   ; -----------------------------------------------------------
00408573 90 90 90 90 90 90+calculate_insertion_address db 27h dup(90h) ; CODE XREF: ...
0040859A                   ; -----------------------------------------------------------
0040859A                   CRC_loop:           ; CODE XREF: ...
0040859A 03 84 9D F6 05 00+    add eax, [ebp+ebx*4+5F6h]
004085A1 D1 C8                 ror eax, 1      ; loop calculating the address
004085A3 4B                    dec ebx         ; where CALL to decrypt code
004085A4 75 F4                 jnz short CRC_loop ; can be inserted to
004085A6 E9 0C FF FF FF        jmp near ptr set_up_CALL_decrypt ; <===   HERE do bpm
004085A6                   ; -----------------------------------------------------------
004085AB 90 90 90 90 90 90+get_distance_call db 44h dup(90h) ; CODE XREF: ...
004085EF                   ; -----------------------------------------------------------
004085EF 2B F8                 sub edi, eax
004085F1 E9 E1 01 00 00        jmp near ptr byte_4087D7
004085F1                   ; -----------------------------------------------------------
004085F6 90 90 90 90 90 90+minus_1_byte db 29h dup(90h) ; CODE XREF: ...
0040861F                   ; -----------------------------------------------------------
0040861F 40                    inc eax
00408620 E9 E9 FE FF FF        jmp near ptr get_CALL_to_address
00408620                   ; -----------------------------------------------------------
00408625 90 90 90 90 90 90+byte_408625 db 24h dup(90h) ; CODE XREF: ...
00408649                   ; -----------------------------------------------------------
00408649 89 38                 mov [eax], edi
0040864B E9 9D FE FF FF        jmp near ptr decrease_counter
0040864B                   ; -----------------------------------------------------------
00408650 90 90 90 90 90 90+calculate_block_length db 1Eh dup(90h) ; CODE XREF: ...
0040866E                   ; -----------------------------------------------------------
0040866E 83 C0 08              add eax, 8      ; points to encrypted code
00408671 EB 00                 jmp short $+2
00408673 8B 58 FC              mov ebx, [eax-4] ; get crypted_length
00408673                   ; -----------------------------------------------------------
00408676 90 90 90 90 90 90+    db 2Eh dup(90h)
004086A4                   ; -----------------------------------------------------------
004086A4 C1 CB 03              ror ebx, 3        ; ror ebx, 3
004086A4                   ; -----------------------------------------------------------
004086A7 90 90 90 90 90 90+    db 28h dup(90h)
004086CF                   ; -----------------------------------------------------------
004086CF 03 C3                 add eax, ebx        ; eax -> where to insert Call Encryptor
004086D1 E9 C1 00 00 00        jmp near ptr get_end_pointer
004086D1                   ; -----------------------------------------------------------
004086D6 90 90 90 90 90 90+get_reencrypt_call_address db 26h dup(90h) ; CODE XREF: ...
004086FC                   ; -----------------------------------------------------------
004086FC 8D BD 9C 13 00 00     lea edi, [ebp+139Ch]
00408702 E9 A4 FE FF FF        jmp near ptr get_distance_call
00408702                   ; -----------------------------------------------------------
00408707 90 90 90 90 90 90+insert_encrypt_call db 2Dh dup(90h) ; CODE XREF: ...
00408734                   ; -----------------------------------------------------------
00408734 C6 00 E8              mov byte ptr [eax], 0E8h ; 'F'
00408737 EB 00                 jmp short $+2
00408737                   ; -----------------------------------------------------------
00408739 90 90 90 90 90 90+    db 27h dup(90h)
00408760                   ; -----------------------------------------------------------
00408760 40                    inc eax
00408761 E9 70 FF FF FF        jmp near ptr get_reencrypt_call_address
00408761                   ; -----------------------------------------------------------
00408766 90 90 90 90 90 90+store_jump_distance db 2Ah dup(90h) ; CODE XREF: ...
00408790                   ; -----------------------------------------------------------
00408790 89 38                 mov [eax], edi
00408792 E9 B9 FE FF FF        jmp near ptr calculate_block_length
00408792                   ; -----------------------------------------------------------
00408797 90 90 90 90 90 90+get_end_pointer db 30h dup(90h) ; CODE XREF: ...
004087C7                   ; -----------------------------------------------------------
004087C7 83 C0 10              add eax, 10h
004087CA E9 38 FF FF FF        jmp near ptr insert_encrypt_call
004087CF                   ; -----------------------------------------------------------
004087CF                   check_end_of_table?: ; CODE XREF: ...
004087CF 0F 85 1C FC FF FF     jnz near ptr get_crypted_offset+2Dh ; loop if not finished
004087D5 EB 3C                 jmp short _done_ ;
004087D5                   ; -----------------------------------------------------------
004087D7 90 90 90 90 90 90+byte_4087D7 db 34h dup(90h) ; CODE XREF: ...
0040880B                   ; -----------------------------------------------------------
0040880B 83 EF 04              sub edi, 4
0040880E E9 12 FE FF FF        jmp near ptr byte_408625
00408813                   ; -----------------------------------------------------------
00408813                   _done_:             ; bpm here to wait till it finishes

I know this is hard to follow because the code flow is not linear but hey it is not my fault, it was the intention of PELock author to make our lives harder, I hope the coloring helps a bit. The algorithm is similar to the insertion algo in the previous code snippet, only differences are code block length calculation. and tables entries are decrypted on the fly. Basically the decryption of table entries to addresses of encrypted code block is done by the CRC_loop at 40859A. If you place a breakpoint at 4085A6 you will see that the decrypted address is stored in eax. Here I can think of two solutions to overcome CRC check, either we copy the whole original block of code into another memory location and patch the CRC routine to perform CRC check on that new location or we can again use softice breakpoints features. I opted for the latter, though your softice screen will flicker a lot, it is simpler to perform.

Basically, I let PELock loader goes on executing as normal, decrypt each table entry then insert the appropriate calls in front and after the encrypted code blocks. However, I will place a breakpoint at 4085A6 and store the decrypted addresses into the table so we will at least have a decrypted table in the end.
bpm 408813 x        ; the ending breakpoint for us when the whole insertion loop is finished!
bpm 4085A6 x do "dd esi+4 eax; x"    ; store decrypted value eax back into table
                                                ; esi pointer is already decremented by 4 so we have plus 4

Once softice screen stop flickering and our final breakpoint is reached, you will see in data window of softice our newly decrypted table of address of encrypted code block. All we have left to do is then insert some code by softice window to force decrypt all the codes block listed in this last table.
a eip

        mov ecx, 4A                ; size of table
load_        lodsd                        ; read 1 entry from table
        push dword ptr [eax+5]        ; preserve code block property values
        pushad
        call eax                ; simulate original exe execution
        popad
        pop dword ptr [eax+5]        ; restore code block property values
        mov word ptr [eax], 7EB        ; patch Call Decryptor with a Jump Over
        mov ebx, word ptr [eax+5] ; read code block property
        ror ebx, 3                ; get code block length
        add eax, ebx
        add eax, 19                ; calculate address of Call Encryptor
        mov word ptr [eax], 7EB        ; replace Call Encryptor with a Jump Over
        dec ecx                        ; decrease size of table
        test ecx, ecx
        jne load_                ; get next entry of table if not done
        jmp eip                        ; infinite loop, DUMP here

Now, this procedure described above should be done last, after you have patched the other two insertion routine do force decrypt those code blocks listed in those two corresponding tables. This is so that when we let PELock run again and reach our infinite jump, ALL the encrypted codes block inside target EXE are fully decrypted and Calls to Decryptors and Re-encryptors and patched with simple Jumps Over.

5. Finding OEP

Now that we have obtained a good dump with all codes decrypted and fixed, it is time to run Imprec again and fix the Import Directory of our dump. The final task is of course finding OEP which is relatively simple for PElock. Looking at the disassembly and hex display of our dump.exe, we see that the first section is started with a lot of strings then followed by code so we can simply guess that OEP is right at the end of those strings.

Another and more generic of finding OEP in PELock protected apps would be finding where PELock jumps to OEP. This occurs soon after the three Insertion Routine above are performed to insert those Calls to Decryptors and Encryptors into the target exe.

00407578 E8 2B 66 00 00        call insert_crypt_engine_3 ; our insertion routine call
00407578                   ; -----------------------------------------------------------
0040757D 90 90 90 90 90 90+    db 28h dup(90h)                ; that is responsible for inserting
004075A5                   ; -----------------------------------------------------------
004075A5 E8 0C 73 00 00        call insert_crypt_engine_2 ; those Call Decryptor/Encryptor
004075A5                   ; -----------------------------------------------------------
004075AA 90 90 90 90 90 90+    db 28h dup(90h)           ; into the target exe main code section
004075D2                   ; -----------------------------------------------------------
004075D2 E8 C5 07 00 00        call unknown_import_stuff_and_insert_crypt_engine_1
004075D2                   ; -----------------------------------------------------------
004075D7 90 90 90 90 90 90+    db 28h dup(90h)        ; these code would still be encrypted
<-------------SNIP-------------->                ; and decrypted last right before reaching
00407AA1 5D                    pop ebp                ; OEP.
00407AA1                   ; -----------------------------------------------------------
00407AA2 90 90 90 90 90 90+    db 124h dup(90h)
00407BC6                   ; -----------------------------------------------------------
00407BC6 68 1E 1D 40 00        push 401D1Eh    ; OEP!!!
00407BC6                   ; -----------------------------------------------------------
00407BCB 90 90 90 90 90 90+    db 23h dup(90h)
00407BEE                   ; -----------------------------------------------------------
00407BEE C3                    retn

That is it, phew. Hence once you find any of the Insertion Routine, you can then check on stack to find where they are called from and place the appropriate bpm. Of course you should dump the loader there and look inside IDA for better view. From then onwards OEP, there would be simple loop decryption and SEH to prevent manual tracing but with IDA I am sure you can find the last bit of pushing OEP as above :).

6. Final thought

WOW, a hell of a protector. There are actually more things I wish to discuss about but this tutorial has become too long and I am sure if you reach here, you would not wanna read any more of my words. I am also tired of writing so maybe another time.

Overall, PELock is a pretty good protection and it was really fun reversing it. If PELock has inserted those Calls to Decryptor and Encryptor at packing time and removed the tables containing addresses of encrypted code block, it would be much harder to decrypt ALL code blocks as we cant be so sure if we have decrypt all blocks. There would be a problem because the loader will always be loaded at different offset so PElock would know the Call distance at packing time but she =) can always uses CALL dword ptr [xxxxxxxx] instead where xxxxxxx is some fixed address. Ah well, just an idea.

I hope you enjoy the tutorial. Again, comments are welcome and if you feel that I should improve or correct certain things about this tutorial, feel free me drop me a message on Fravia Message Board.

                                                        --------------------------------------------------------

This tutorial would not have been possible without the help of all my friends and previous tutorials writers. so a BIG thank you to ALL!

Last Edited : 30 Jan 2003

Cheers,  

   crUsAdEr
2004-8-6 17:58
0
雪    币: 244
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
98
经典,收了学习!
2004-8-6 23:53
0
雪    币: 211
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
99
顶,牛人!已经没多少人和你一样了!
应该可以收录精华6吧![期待中。。。]
2004-8-7 02:31
0
雪    币: 106728
活跃值: (202444)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
100
概述:

    用‘花指令’来进行静态加密是很有效的,这会使解密者无法一眼看到全部指令,杜绝了先把程序打印下来再慢慢分析的做法。我们知道,一条指令的长度是不等长的,假使有一条指令为 3 字节长,然后你从它的第二个字节开始反汇编,你照样会看到一条面目全非的指令,‘花指令’就是在指令流中插入很多‘垃圾’,使静态反汇编无法进行,如何实现你把以下程序编译出来用 Debug 的 U 指令看一下,跟踪一下就能理解了。

汇编编程示例:

XX1        MACRO
local      _next1
           jmp    short _next1
           db    0e8h
_next1:
           ENDM
;--------------------------------------
XX2        MACRO
local      _next2
           jmp    short _next2
           db    0e9h
_next2:
           ENDM
;--------------------------------------
XX3        MACRO
local      _next3
           jmp    short _next3
           db    09ah
           db    0e8h
_next3:
        ENDM
;--------------------------------------
XX4        MACRO
local      _next4
           jmp    short _next4
           db    09ah
           db    0e8h
_next4:
        ENDM
;--------------------------------------
.286
CODE    SEGMENT
        ASSUME    CS:CODE,DS:CODE
        ORG    100H
start:
        db    20 dup (90h)
        
        xx3
        mov    ax,0201h
        xx3
        mov    bx,0200h
        xx3
        mov    cx,0001h
        xx3
        mov    dx,0080h
        xx2
        int    13h
        xx2
        int    20h

CODE    ENDS
        END    START
2004-8-7 18:42
0
游客
登录 | 注册 方可回帖
返回