找回密码
 注册
搜索
热搜: 回贴

脱壳技术,Armadillov3.01加壳软件SoundEdit Pro的脱壳,Armadill

2010-1-30 18:19| 发布者: admin| 查看: 92| 评论: 0|原作者: 千年缘


脱壳技术,Armadillov3.01加壳软件SoundEdit Pro的脱壳,Armadill
2008年06月23日 星期一 下午 04:07
程序名:SoundEdit Pro V1.3.634



※软件简介※:SoundEdit Pro可以打开WAV、MPC、MP 、MP2、MP3、VOX、RAW、OGG、WMA、CDA 等

扩展名的音乐文件,进行声波编辑、剪裁、混音等工作;还有完整的录音功能,可以从 CD、麦克

风、立体混音装置、讯号线来源、影片等来源录音。



软件语言: 英文

软件类别: 国外软件/共享版/音频处理

运行环境: Win9x/Me/NT/2000/XP

界面预览: 无

软件大小: 10273KB

软件更新: 2003-7-8

下载页面: http://www.pcdog.com/soft/942.htm



※参考文章※:Armadillo标准加壳的程序的脱壳和引入表修复方案 作者:jwh51

脱Armadillo 3.01 壳 作者:yesky1

Armadillo V3.40标准加壳方式的脱壳——Win98的Notepad 作者:fly



※软件限制※:SoundEdit是一个声音编辑软件,采用了ARMADILLO的KEY加密,启动要你输入KEY,否则要

等几秒才能让你启动,还有30天试用期,所以,如果脱了壳,上述现象都将没有了.现在开始脱壳历程.!!



※破解工具※:Ollydbg1.09、FI 3.01

Armadillo是当今猛壳之一,加壳方式有两种,一种是标准方式(Standard Protections Only)加壳,

另一种是CopyMem-II Debug-Blocker的加壳,其标准加壳方式相对来说则容易的多.用COPYMEMII的

一般可用DILLODUMP脱,而用标准加壳用DILLODUMP是脱不了的。



※开始吧※

FI 3.01侦测知其用Armadilolo v3.01加壳,并且运行是没有两个进程,所以应该是标准加壳.



用Ollydbg载入SoundEdit Pro V1.3.634,设置忽略所有的异常选项,把Ollydbg的异常选择项全部勾上。



004F6000 > $Content$nbsp;60 PUSHAD

====>进入Ollydbg后断在这!



第一步,去掉Ollydbg的调试器标志:

[方法一]

用IsDebug 1.4插件去掉Ollydbg的调试器标志。

[方法二]

Bp IsDebuggerPresent

F9运行一下就会来到IsDebuggerPresent函数的入口地址:

77E52E92 > 64:A1 18000000 MOV EAX,DWORD PTR FS:[18] ; <--中断在这里

77E52E98 8B40 30 MOV EAX,DWORD PTR DS:[EAX 30]

77E52E9B 0FB640 02 MOVZX EAX,BYTE PTR DS:[EAX 2] ; <--运行到这里

77E52E9F C3 RETN

在77E52E9B地址处停下,看看DS:[EAX 2]指向的地址7FFDF002的指是01(这个地址可能和你的不同),

修改这个值为00 因为Armadillo通过IsDebuggerPresent函数来检查是不是被调试器调试,如果有调试

器就会赋EAX值为01没有就赋EAX值为00。修改这个值就是告诉他没有调试器,自然不会出错拉!记下

这个地址,以后经常会用到的.



第二步,DUMP出程序并修复:

[方法一]

首先一点是Armadillo是通过类似于调试的方法来运行程序的。

新版本Armadillo脱壳的一个难点是它的代码段是分页解密的,我估计它的做法是将代码段

锁定,即将其属性设为不可读、写、执行,当被执行到时会产生一个页面保护错误,而调

试程序就会捕获这个错误,将对应的页面解锁并解密,然后返回执行.



BP VirtualProtect,F9运行,这时会有异常,用SHIFT F9过程序会断下来,这时你不停按F9,一般在第6次会

出现注册框,OK后再次中断,这时你要注意堆栈开始记下F9的次数了.我这第24下时在堆栈出现如下信息:

0012EB78 7342F406 /CALL to VirtualProtect from MSVBVM60.7342F400

说明程序,已经运行了.(VB是先运行MSVBVM60.DLL的,在其中也用调用VirtualProtect)

现在重新载入程序,到出现这个信息的前一次中断停下来,然后按几次CTRL F9到程序中(也就是地址较低

的地方,一般都是004*****,005*****,本程序在这:



正常情况下,按上面的做法可以很顺利的走下来,但是会遇到警告修改系统时间而退出程序的情况,

如下方法可挫败它的这个保护。

先不要BP VirtualProtect,F9运行,这时会有异常,用SHIFT F9过,再按F9,直到出现注册

框,这时BP GetLocalTime,OK后中断两次,



0012C05C 00CAABA3 /CALL 到 GetLocalTime 来自 00CAAB9D

0012BDF4 00CAABA3 /CALL 到 GetLocalTime 来自 00CAAB9D

0012BDF8 0012BDFC \pLocaltime = 0012BDFC

最终返回到

00CB4672 E8 08060000 CALL 00CB4C7F

00CB4677 84C0 TEST AL,AL ====>走到这里将AL改为00000000即可

00CB4679 74 1C JE SHORT 00CB4697

00CB467B E8 56050000 CALL 00CB4BD6 ====>这个call警告修改系统时间

然后清除所有断点,下BP VirtualProtect,按F9中断,这时你要注意堆栈开始记下F9的次数了.我这

第24下时在堆栈出现如下信息:

0012EB78 7342F406 /CALL to VirtualProtect from MSVBVM60.7342F400

说明程序,已经运行了.(VB是先运行MSVBVM60.DLL的,在其中也用调用VirtualProtect)

现在重新载入程序,到出现这个信息的前一次中断停下来,然后按几次CTRL F9到程序中(也就是地址较低

的地方,一般都是004*****,005*****,本程序在这:

*****************

以下是jwh51的原文

*****************

004DA060 83C4 04 ADD ESP, 4

004DA063 8945 FC MOV DWORD PTR SS:[EBP-4], EAX

004DA066 837D B8 00 CMP DWORD PTR SS:[EBP-48], 0

004DA06A 74 0A JE SHORT SoundEdi.004DA076

004DA06C 8B45 B8 MOV EAX, DWORD PTR SS:[EBP-48]

004DA06F 50 PUSH EAX

004DA070 FF15 E8615000 CALL DWORD PTR DS:[<&USER32.DestroyWi>; USER32.DestroyWindow

004DA076 8B45 FC MOV EAX, DWORD PTR SS:[EBP-4]

004DA079 8BE5 MOV ESP, EBP

004DA07B 5D POP EBP

004DA07C C3 RETN

这时小心地用F8,因为有一堆的JMP,JNZ,JO等,不过也用不了多久的,大概20多次就可来到这:

004DB483 61 POPAD

004DB484 6A 00 PUSH 0

004DB486 E8 6E000000 CALL SoundEdi.004DB4F9

004DB48B 83C4 04 ADD ESP, 4

004DB48E 6A 00 PUSH 0

004DB490 E8 46830000 CALL SoundEdi.004E37DB

004DB495 83C4 04 ADD ESP, 4

004DB498 837D E4 01 CMP DWORD PTR SS:[EBP-1C], 1

004DB49C 75 11 JNZ SHORT SoundEdi.004DB4AF

004DB49E 68 E8965000 PUSH SoundEdi.005096E8

004DB4A3 FF15 0C975000 CALL DWORD PTR DS:[50970C] ,这个CALL用F7跟进

004DB4A9 83C4 04 ADD ESP, 4

004DB4AC 8945 E4 MOV DWORD PTR SS:[EBP-1C], EAX

004DB4AF 68 0C9E4D00 PUSH SoundEdi.004D9E0C

在4db4a3这个CALL用f7跟进,然后继续F8,几次后就来到这:

00D0B5E0 /75 29 JNZ SHORT 00D0B60B

00D0B5E2 |E8 A05AFFFF CALL 00D01087

00D0B5E7 |FF76 04 PUSH DWORD PTR DS:[ESI 4]

00D0B5EA |8BF8 MOV EDI, EAX

00D0B5EC |A1 CCEED100 MOV EAX, DWORD PTR DS:[D1EECC]

00D0B5F1 |FF76 08 PUSH DWORD PTR DS:[ESI 8]

00D0B5F4 |8B48 70 MOV ECX, DWORD PTR DS:[EAX 70]

00D0B5F7 |3348 50 XOR ECX, DWORD PTR DS:[EAX 50]

00D0B5FA |6A 00 PUSH 0

00D0B5FC |3348 34 XOR ECX, DWORD PTR DS:[EAX 34]

00D0B5FF |03F9 ADD EDI, ECX

00D0B601 |E8 815AFFFF CALL 00D01087

00D0B606 |50 PUSH EAX

00D0B607 |FFD7 CALL EDI ; SoundEdi.004059B0

看到最后这个CALL EDI吗,004059B0就是程序的OEP了,我们F7跟进:

00405996 - FF25 3C114000 JMP DWORD PTR DS:[40113C]

0040599C - FF25 8C104000 JMP DWORD PTR DS:[40108C]

004059A2 - FF25 B0104000 JMP DWORD PTR DS:[4010B0]

004059A8 - FF25 E8114000 JMP DWORD PTR DS:[4011E8]

004059AE 0000 ADD BYTE PTR DS:[EAX], AL

004059B0 68 787D4000 PUSH SoundEdi.00407D78 ,这是OEP了,

004059B5 E8 EEFFFFFF CALL SoundEdi.004059A8

呵,典型的VB代码.拿出LOADPE,快快DUMP吧.我们把DUMP的程序保存为DUMPED.EXE

以前总以为它的修复很难,但实际上只要修改程序流程,完全可得到正确的引入表的.

1.可先用importREC试试,有一个指针无效,如果CUT程序退出时会出错,所以要修复它.通过它我们可看到iat的

rva为1000,错误指针为1030,(如果很多指针无效,只要记住一个无效的RVA就可以了)

2.重新载入程序,BP VirtualProtect,断下后f9,注意堆栈的变化,当出现如下信息时要注意了:

0012DB28 00D0887E /CALL to VirtualProtect from 00D08878

0012DB2C 00401000 |Address = SoundEdi.00401000

0012DB30 000CB000 |Size = CB000 (831488.)

0012DB34 00000004 |NewProtect = PAGE_READWRITE

0012DB38 0012F034 \pOldProtect = 0012F034

它将往401000也就是IAT所在的地方写入信息:这是再按一下F9,又停下来,D 401000,我们可看到,IAT所在的位置

已经写入了东西,还不是dll的地址,还记得那个无效指针的地址吗:401030,我们清掉断点,然后在在内存定位到

401030处,"右键-->breakpoint-->hardware on write-->dword",然后按F9运行,程序停了下来:

00D0942F 8B85 5CFBFFFF MOV EAX, DWORD PTR SS:[EBP-4A4]

00D09435 8B8D 48F9FFFF MOV ECX, DWORD PTR SS:[EBP-6B8]

00D0943B 8908 MOV DWORD PTR DS:[EAX], ECX

00D0943D 8B85 5CFBFFFF MOV EAX, DWORD PTR SS:[EBP-4A4] ; 停在这

00D09443 83C0 04 ADD EAX, 4

00D09446 8985 5CFBFFFF MOV DWORD PTR SS:[EBP-4A4], EAX

00D0944C ^ E9 78FEFFFF JMP 00D092C9

看到上述二行:MOV ECX,DWORD PRT [EBP-6B8],我们再往上找几行可看到这个语句:

00D093E3 E8 F8C0FEFF CALL 00CF54E0

00D093E8 8985 48F9FFFF MOV DWORD PTR SS:[EBP-6B8], EAX

00D093EE 83BD 48F9FFFF 0>CMP DWORD PTR SS:[EBP-6B8], 0

00D093F5 75 38 JNZ SHORT 00D0942F

在第二行也有个[EBP-6B8],注意前面这个CALL,我们去看一看

00CF54E0 55 PUSH EBP

00CF54E1 8BEC MOV EBP, ESP

00CF54E3 53 PUSH EBX

00CF54E4 56 PUSH ESI

00CF54E5 57 PUSH EDI

00CF54E6 33FF XOR EDI, EDI

00CF54E8 33DB XOR EBX, EBX

00CF54EA 66:F745 0E FFFF TEST WORD PTR SS:[EBP E], 0FFFF

00CF54F0 75 03 JNZ SHORT 00CF54F5

00CF54F2 8B5D 0C MOV EBX, DWORD PTR SS:[EBP C]

00CF54F5 57 PUSH EDI

00CF54F6 FF15 A430D100 CALL DWORD PTR DS:[D130A4] ; kernel32.GetModuleHandleA

00CF54FC 3945 08 CMP DWORD PTR SS:[EBP 8], EAX

00CF54FF 75 07 JNZ SHORT 00CF5508

00CF5501 BE C053D100 MOV ESI, 0D153C0

00CF5506 EB 60 JMP SHORT 00CF5568

00CF5508 393D 9859D100 CMP DWORD PTR DS:[D15998], EDI

00CF550E B9 9859D100 MOV ECX, 0D15998

00CF5513 74 3C JE SHORT 00CF5551

00CF5515 8B35 B8B1D100 MOV ESI, DWORD PTR DS:[D1B1B8]

00CF551B A1 CCEED100 MOV EAX, DWORD PTR DS:[D1EECC]

00CF5520 F641 08 01 TEST BYTE PTR DS:[ECX 8], 1

00CF5524 74 0E JE SHORT 00CF5534

00CF5526 8B50 70 MOV EDX, DWORD PTR DS:[EAX 70]

00CF5529 3350 60 XOR EDX, DWORD PTR DS:[EAX 60]

00CF552C 3350 3C XOR EDX, DWORD PTR DS:[EAX 3C]

00CF552F F6C2 80 TEST DL, 80

00CF5532 75 13 JNZ SHORT 00CF5547

00CF5534 8B50 70 MOV EDX, DWORD PTR DS:[EAX 70]

00CF5537 3350 64 XOR EDX, DWORD PTR DS:[EAX 64]

00CF553A 3350 58 XOR EDX, DWORD PTR DS:[EAX 58]

00CF553D 3350 20 XOR EDX, DWORD PTR DS:[EAX 20]

00CF5540 3316 XOR EDX, DWORD PTR DS:[ESI]

00CF5542 3955 08 CMP DWORD PTR SS:[EBP 8], EDX

00CF5545 74 1E JE SHORT 00CF5565

00CF5547 83C1 0C ADD ECX, 0C

00CF554A 83C6 04 ADD ESI, 4

00CF554D 3939 CMP DWORD PTR DS:[ECX], EDI

00CF554F ^ 75 CF JNZ SHORT 00CF5520

00CF5551 FF75 0C PUSH DWORD PTR SS:[EBP C]

这里面有几个跳转,其中最后一个CF554F是往上跳的.我们看一个就可发现:

00CF5513 74 3C JE SHORT 00CF5551,这个跳正好可跳出这个循环.只要改这个跳,就不会破

坏引入表了.

再次重新载入,BP VirtualProtect,出现注册框后OK,程序再断下来,这时清除断点(包括硬件断点),CTRL F9回程

序领空,把CF5513的74 3c改成eb 3c,按F9运行,程序运行后打开importREC,选中程序,入口填入59b0,-->IAT自动

搜索-->获得输入信息",如果还有无效的大可放心的cut,因为它们本来就不是有用指针了(也可能是importREC把

IAT的大小判断错了),.然后修复脱壳后的文件.OK,大功告成.

测试了下脱壳后的程序,运行正常,那个烦人的注册框没有,时间限制也注册了,别说30天,就是30年都没问题.



[方法二]

yesky1说:

1、 先在最后一个原始节(raw size为0)找个地方设硬件断点,如004CC000处。等其第一次中断时候,

即解密该节时,再下断GetModuleHandleA,不早不晚正合适 。如果先等提示注册框出来时候,再下

断GetModuleHandleA,有些早了,这样要中断好些次才能到magic jump。



2 设断GetModuleHandleA 断下后,

00C6A30F FF15 A850C700 CALL DWORD PTR DS:[C750A8] ; kernel32.GetModuleHandleA

00C6A315 3985 BCE9FFFF CMP DWORD PTR SS:[EBP-1644], EAX ; SoundEdi.00400000

00C6A31B 75 0F JNZ SHORT 00C6A32C

00C6A31D C785 B8E9FFFF E>MOV DWORD PTR SS:[EBP-1648], 0C783E0

00C6A327 E9 C4000000 JMP 00C6A3F0

00C6A32C 83A5 90E7FFFF 0>AND DWORD PTR SS:[EBP-1870], 0

00C6A333 C785 8CE7FFFF D>MOV DWORD PTR SS:[EBP-1874], 0C789D8

00C6A33D EB 1C JMP SHORT 00C6A35B

00C6A33F 8B85 8CE7FFFF MOV EAX, DWORD PTR SS:[EBP-1874]

00C6A345 83C0 0C ADD EAX, 0C

00C6A348 8985 8CE7FFFF MOV DWORD PTR SS:[EBP-1874], EAX

00C6A34E 8B85 90E7FFFF MOV EAX, DWORD PTR SS:[EBP-1870]

00C6A354 40 INC EAX

00C6A355 8985 90E7FFFF MOV DWORD PTR SS:[EBP-1870], EAX

00C6A35B 8B85 8CE7FFFF MOV EAX, DWORD PTR SS:[EBP-1874]

00C6A361 8338 00 CMP DWORD PTR DS:[EAX], 0

00C6A364 0F84 86000000 JE 00C6A3F0

; <=== magic jump,不过好像现在的arm不能直接改为jmp了,有校验?,不过这个是vb程序只引入了

一个dll,所以还是比较方便的。

fly说:此处下 硬件执行 断点,每次断下后改标志Z=1,使其JMP,就能得到未被破坏的输入表了



3. F9 继续运行,当GetModuleHandleA再次断下后,停在这里。

00C5A4F6 57 PUSH EDI

00C5A4F7 FF15 A850C700 CALL DWORD PTR DS:[C750A8] ; kernel32.GetModuleHandleA

00C5A4FD 8BF0 MOV ESI, EAX ; SoundEdi.00400000

00C5A4FF 6A 28 PUSH 28

00C5A501 8D45 D8 LEA EAX, DWORD PTR SS:[EBP-28]

00C5A504 57 PUSH EDI

00C5A505 50 PUSH EAX

00C5A506 E8 45400100 CALL 00C6E550

00C5A50B 8D85 D8FEFFFF LEA EAX, DWORD PTR SS:[EBP-128]

00C5A511 83C4 0C ADD ESP, 0C

00C5A514 8945 FC MOV DWORD PTR SS:[EBP-4], EAX

00C5A517 8D45 D8 LEA EAX, DWORD PTR SS:[EBP-28]

00C5A51A 50 PUSH EAX

00C5A51B 897D D8 MOV DWORD PTR SS:[EBP-28], EDI

00C5A51E C745 DC 44A5C50>MOV DWORD PTR SS:[EBP-24], 0C5A544

00C5A525 897D E0 MOV DWORD PTR SS:[EBP-20], EDI

00C5A528 897D E4 MOV DWORD PTR SS:[EBP-1C], EDI

00C5A52B 8975 E8 MOV DWORD PTR SS:[EBP-18], ESI

00C5A52E 897D EC MOV DWORD PTR SS:[EBP-14], EDI

00C5A531 897D F0 MOV DWORD PTR SS:[EBP-10], EDI

00C5A534 897D F4 MOV DWORD PTR SS:[EBP-C], EDI

00C5A537 897D F8 MOV DWORD PTR SS:[EBP-8], EDI

00C5A53A FF15 0453C700 CALL DWORD PTR DS:[C75304] ; USER32.RegisterClassA

00C5A540 5F POP EDI

00C5A541 5E POP ESI

00C5A542 C9 LEAVE

00C5A543 C3 RETN



3. 然后OD中

TC EIP<0C00000

停下来的地方就是入口了,TC命令很有用,不用你单步挪了。

imprec修复一下,没什么问题,把最后一个未识别函数cut即OK,好像都不用注册了.



或者接着下断:BP GetCurrentThreadId 断下后取消断点,Ctrl F9执行到返回



总结:好像我的olly有问题,老是断不下来,只有总结一下各位大虾的各自绝招了。


最新评论

QQ|小黑屋|最新主题|手机版|微赢网络技术论坛 ( 苏ICP备08020429号 )

GMT+8, 2024-9-29 23:38 , Processed in 0.271471 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

返回顶部