首页
社区
课程
招聘
[原创]对《3D定胆杀码霸主》壳的几点认识——痛苦的经历
发表于: 2007-7-3 13:37 8645

[原创]对《3D定胆杀码霸主》壳的几点认识——痛苦的经历

wulje 活跃值
14
2007-7-3 13:37
8645
声明:我对彩色球的投注一点兴趣都没有,更不幻想有个什么计算公式得到几个号码去中500万大奖。我对《3D定胆杀码霸主》壳的兴趣完全是学习加密思想,本文也只是学习后的一笔记,绝无盗版之意。何况我这个菜鸟,要破解这样的硬壳无异于以卵击石。请《3D定胆杀码霸主》作者放心。
        《3D定胆杀码霸主》加密壳(以下简称《3D》)最显著的特点是:超强反跟踪技术、反静态分析(乱码和乱序技术)、代码临时写入与覆盖技术。它基本放弃了断点SHE防范技术和CRC校验技术。其中任何一项技术都会让“菜鸟”陷入痛苦的深渊。《3D》综合了太多的加密技术,这是我放弃破解它的理由。或许我“太菜”,把一个技术平平的软件说成了“吃人妖怪”,让大侠见笑了!
        一、超强的反跟踪技术
        1.《3D》让“Olldbg”陷入不能自拔的痛苦境地:
        如果你试图用OD去打开《3D定胆杀码霸主》,那么你会立即得到windows发送错误报告的报歉通知。也不知OD程序是怎样设计的,加载一个还未运行的软件就死掉了,3D居然发现了OD这样的软肋?先看《3D》的入口代码:
00AD1014     B8 00000000         mov eax,0                        ;程序入口
00AD1019     60                  pushad
00AD101A     0BC0                or eax,eax
00AD101C     74 68               je short 00AD1086              ;必跳
00AD101E     E8 00000000         call 00AD1023                        ;以下代码不会执行
00AD1023     58                  pop eax
00AD1024     05 53000000         add eax,53
00AD1029     8038 E9             cmp byte ptr ds:[eax],0E9
00AD102C     75 13               jnz short 00AD1041               
00AD102E     61                  popad
00AD102F     EB 45               jmp short 00AD1076               
00AD1031     DB2D 3710AD00       fld tbyte ptr ds:[AD1037]        ;不会执行的实数入栈
00AD1037     FFFF                ???                              
00AD1039     FFFF                ???                              
00AD103B     FFFF                ???                              
00AD103D     FFFF                ???                              
00AD103F     3D 40E80000         cmp eax,0E840
00AD1044     0000                add byte ptr ds:[eax],al
00AD1046     58                  pop eax
00AD1047     25 00F0FFFF         and eax,FFFFF000
00AD104C     33FF                xor edi,edi
00AD104E     66:BB 195A          mov bx,5A19
00AD1052     66:83C3 34          add bx,34
00AD1056     66:3918             cmp word ptr ds:[eax],bx
00AD1059     75 12               jnz short 00AD106D                 
         如果你用OD加载,则屏幕显示到00AD1031就死机了。查看AD1031代码,原来它是一个压入实数的指令,但它指定的[AD1037]地址中是一个非法的实数表示法。我猜想OD装载程序时要分析代码,它试运行“fld tbyte ptr ds:[AD1037]”就死机了。这就是OD不能装载的原因。
        解决的办法是:用16进制编辑器将“00AD1031     DB2D 3710AD00”中的3710AD00改成3F10AD00或4E10AD00等,即改为“fld tbyte ptr ds:[AD104E]”,它指定的实数就有意义了。实际上从00AD101E到00AD1076中的代码是根本不会被执行的,随便改为什么或填0都可以。后面的解压也不会用这部分作为源码,在OD中用命令“HR 00AD1037”可以证实这一点。也不知为什么OD要自作多情?好了,现在OD可以正常调试《3D》了,但是你不要高兴得太早,你是不会得到结果的。除非你知道在什么地方有反anti转跳!
        2.看见别人在调试,《3D》就晕倒:
        《3D》在运行时,大概会扫描windows的全部的进程,只要有调试程序在运行而不管自己的父进程是不是“调试程序”,《3D》就会弹出警告框并且退出。也就是说,只要你打开了SoftICE或Olldbg调试器等,不管你加不加载任何其它被调试程序,运行《3D》也是不行的。跟踪《3D》表明,它发现SoftICE或Olldbg等也是用CreateFile去查找“\\.\SIWVID”或“\\.\NTICE”等字串的方式。但麻烦的是冗长的查找代码是临时生成的,你无法在《3D》运行前修改其代码。
        3.自编的调试软件也能被《3D》识破:
        现成的调试软件都有其特征字串或代码,只要《3D》收集得多,它的识别能力就越强。我自编一个怎样?看你怎么办?让我大跌眼镜的是《3D》居然也能识别!目前我只知道创建一个进程有一个API函数是CreateProcessA,如果参数选择为“NORMAL_PRIORITY_CLASS”,则加载《3D》道也相安无事。《3D》没有发现任何不妥,因该模式不会向调试器发送任何消息,你也得不到任何《3D》内部的消息。若参数选择为“DEBUG_PROCESS”且什么事都不做,则《3D》也会毫不犹豫地退出!奇了!
        原来,参数NORMAL_PRIORITY_CLASS和参数DEBUG_PROCESS的区别是调试进程中有无“stDE.u.Exception.pExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT”消息。在使用DEBUG_PROCESS参数时,当《3D》被加载且在运行前,调试程序会收到一个“int 3”中断。就是这个int 3被《3D》发现且利用的,它是怎样发现的却不得而知?现在就连单是用CreateProcessA加载《3D》,调试器什么都不做都不可能,更不说怎样调试了。(我真的觉得我是鸡蛋碰石头了!)
        4.对《软件加密技术内幕》(看雪学院著)“3.3.2 Debug API机制”中“调试寄存器”的改进:
        我是为调试《3D》才买的《软件加密技术内幕》,学到了不少过去不知道的知识。但是书中第98页所指出的“中断在程序入口”的流程,似乎有点小题大做?好象不需要调用Ntdll.NtContinue设断?(声明:我不知道Ntdll.NtContinue是干什么的)用下面的方法可以轻松地在程序入口(或任何地方)设断:
        (1)当收到CREATE_PROCESS_DEBUG_EVENT消息后(当程序加载时必然到达),写入Regs.Dr0=入口地址,Regs.Dr7=0x401(或0x101),Regs.ContextFlags=CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
        (2)当拦截到EXCEPTION_SINGLE_STEP消息时,程序就中断在入口处(Regs.Dr0)了。
        注:如果在EXCEPTION_DEBUG_EVENT消息后设断或在“第一次”EXCEPTION_BREAKPOINT消息后设断都是不能成功的。
        在我自己的调试程序中证实,这个方法是可行的且简便的。
        二、《3D》毫不在意你插入的int3断点和硬件断点
        当你按前面的方法修改了代码且能用OD加载后,《3D》毫不在意你在什么地方插入int 3断点和硬件断点。只要不是被它自己写入的代码覆盖不会用SHE方法去抹去你的硬件断点的。它是不会用CRC去检查文件的完整性的。真还有点大家风度!不过一切设断都没用,因为它早就知道该要退出了!
        三、实在令人头痛的乱码乱序技术
        所谓乱码乱序技术,是将一大段代码,分割成苦干小块,每块中又插入苦干花指令或可执行但没有实际意义的代码,或将一个简单的指令改写为十分复杂的代码形式,最后用没完没了的上下转跳连接起来。让跟踪者陷入迷魂阵中。随便举个例子:
00E4A3CA   ^\E9 B33BFFFF         jmp 00E3DF82                        
00E4A3CF     BE 1279ADBB         mov esi,BBAD7912
00E4A3D4   ^ E9 F8C7FEFF         jmp 00E36BD1                        
00E4A3D9     29D8                sub eax,ebx
00E4A3DB   ^ E9 6BCCFFFF         jmp 00E4704B                        
00E4A3E0     68 A457E020         push 20E057A4
00E4A3E5     FF3424              push dword ptr ss:[esp]
00E4A3E8     59                  pop ecx
00E4A3E9     68 342F0000         push 2F34
00E4A3EE     893424              mov dword ptr ss:[esp],esi
00E4A3F1   ^ E9 57F9FEFF         jmp 00E39D4D                        
00E4A3F6     01CB                add ebx,ecx
00E4A3F8     8B0C24              mov ecx,dword ptr ss:[esp]
00E4A3FB     83C4 04             add esp,4
00E4A3FE     331C24              xor ebx,dword ptr ss:[esp]
00E4A401   ^ E9 BD94FFFF         jmp 00E438C3                        
00E4A406   ^ 0F8E B3D4FEFF       jle 00E378BF                          
00E4A40C     C0E3 08             shl bl,8
00E4A40F     C0E3 08             shl bl,8
00E4A412   ^ 0F85 AC18FFFF       jnz 00E3BCC4                        
00E4A418   ^ E9 2F32FFFF         jmp 00E3D64C                        
00E4A41D     05 3F6BA441         add eax,41A46B3F
00E4A422   ^ E9 200AFFFF         jmp 00E3AE47                          
00E4A427     FECF                dec bh
00E4A429     81EC 02000000       sub esp,2
00E4A42F   ^ E9 3605FFFF         jmp 00E3A96A                          
00E4A434     BF 4050AA29         mov edi,29AA5040
00E4A439     29FD                sub ebp,edi
00E4A43B   ^ E9 3DEDFEFF         jmp 00E3917D                        
00E4A440     330424              xor eax,dword ptr ss:[esp]
00E4A443   ^ E9 45C8FFFF         jmp 00E46C8D                          
00E4A448     81F1 4AB8D5D5       xor ecx,D5D5B84A
00E4A44E     05 61012A6C         add eax,6C2A0161
00E4A453   ^ E9 E2F2FEFF         jmp 00E3973A                        
        这还只是它“乱序”的代表,要体会它的“乱码”技术,不要我来举例,你只要用OD打开稍加跟踪就知道了。
        四、绝不直接调用现存的API函数
        《3D》为了调用一个API函数,也费尽了心思。它加密了需要的API函数字串,需要时它也不解密出字串。它把kernel32.dll装入内存,从头开始查找字串,你可以在00EB8CA2设断,在状态栏中可以看到kernel32.dll中每一个函数都被扫描一遍,不清楚它按什么来确定所需要的函数(不是字串比较)。
        下面我想说的只是怎样到达它的核心代码部分,省去你从头跟踪的麻烦。
        1.在00AD1259设断:
        从00AD1132—00AD1254是一段写入到00E18400—011F6107代码的解压程序。在00AD1259设断可以很快从循环中跳出来。
        2.当第一个断点任务完成后,在00E6EB9F设断:
        00E6EB9F断点是一个重要的任务分配retn点,程序每完成一项任务后回到这里,再重新转跳到新的地址中去完成另一个任务。任务地址在堆栈中可以看到。它的转跳地址是:(这是在自编的调试程序中记录下来的)
00E1BF6B  7C801D77  7C801D77  00E1BF6B  7C801D77  00E1BF6B  7C80A7D4  
00EA5AC8  00E1BF6B  00E1BF6B  00E1BF6B  00E1BF6B  00E1BF6B  7C812ADE  
00E1BF6B  7C814EEA  00EAF8F5  00EB15B0  00EB15B0  00EB15B0  00E1BF6B  
7C809B47  7C809B47  7C809B47  00EA69F2  00EAF8F5  00EB7284  00EB8097  
00EAF8F5  01749178  00EAF8F5  00EB8097  00EB8097  00EB8097  00EBBB69  
00EBF0C2  00ED6B05  00EDC4E2  00E1BF6B  7C809E01  7C809E01  7C809E01  
7C809E01  7C809E01  7C809E01  00EE8B4B  00EB8097  01701EDE  00EB8097  
01702493  00E1D21A
        它第一个00E1BF6B转跳,好象是调用“LoadLibraryA”,和前面说的一样,它从kernel32的第一个函数字串开始查找,找到后再换算成地址后call,整个代码冗长,没完没了的转跳和一些莫明其妙的指令,会让你累到吐血(其实也是一种战术)!其最后一个00E1D21A转跳就是显示“请退出调试,重新启动本程序对话框”的程序。为了这个对话框,它也是从查找kernel32中的字串开始,最后转跳到ntdll中,在一段代码中千万次地转跳,这个对话框才“逐渐”显示出来,好象进入了API函数的最底层。(可能是它照搬了API中的MessageBoxA的最底层代码?)总之它绝不用API中的现存函数。
        3.用“HW  00EAEADB”命令,在00EAEADB地址写入时断下:
        设断后,内存地址打开在00EAEADB。运行程序,当发现该地址值变成FF 35时,打开代码段中相同的地址,将00EAEAEF: jz 00EAEB63改为jnz 00EAEB63;00EAEB15:jnz 00EAEB63改为jz 00EAEB63。这是为了跳过一个SHE的“非法指令”(00EAEB9F)异常(好象是3D中唯一一个SHE异常)。  
        4.在00EAF192设断:
        在00EAF192设断是为了让你看到在00EAF18C转跳的最后一刻,才把从00EAF196开始执行的代码准备好。绝对是把“遇山才开路,见水才搭桥”和“过河拆桥”的技术应用到极致。
        5.在00E6AB1F设断:
        在00E6AB1F设断是为了让你看到没完没了的转跳。00E6EB1F:jmp [edi+eax*4]是一个转跳地址分配器。好了,还有一段查找“\\.\SIWVID”或“\\.\NTICE”等字串的代码在什么地址实在是想不起来了,也不想从头跟踪去找了。它也是临时才解压出来,事前不可能设断和修改。在调试器中修改了也没用,因为它远不止一处地设置反跟踪代码。
        五、用WinHex程序将运行中《3D》从内存中dump出来
        将WinHex程序打开,再运行《3D》,它运行得很正常。你可以将main.exe(3D的主程序名)dump出来,删除最后部分的一些信息代码,保存为*.exe文件,基本上就是《3D》脱壳后的代码。可以用OD打开保存的*.exe文件,对401000开始的代码分析,只是不知道“入口地址”该设定在什么地方?从代码形式上看,它大概是用VC++写成的很通常的程序,调用API也很正规。只是IAT表已被装载无法还原。
        可能该软件就是用一个现在十分流行的“某某加壳软件”封装的,只是我太菜没接触过这个加壳软件而已。
        花了这么多时间,一无所获!…………一无所获吗?肯请高手指点迷津!

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 47147
活跃值: (20460)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
这个软件用的是thmedia的壳。
让OD崩溃的bug讨论见此帖:
http://bbs.pediy.com/showthread.php?threadid=33621
2007-7-3 13:43
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
初步学习中
不过感觉难度很大啊
只看懂少部分的代码而已
2007-7-10 01:29
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
我曾经看过一个帖,帖子的主题忘了,不过大意就是介绍未被破解过的一些软件,其中就有这个《3D定胆杀码霸主》,因为它从来没有被人被解过,也从来没有破解补丁,可能他不是什么加密技术平平的软件吧!
2007-7-13 23:10
0
游客
登录 | 注册 方可回帖
返回
//