wgz001 发表于 2009-1-5 02:21

RLPack 加壳的 Armadillo find protected 1.8

RLPack 加壳的 Armadillo find protected 1.8
【文章标题】: RLPack 加壳的 Armadillo find protected 1.8
【文章作者】: CCDebuger
【下载地址】: 自己搜索下载
【作者声明】: 只是调试时的笔记,权当灌水,有啥错误的话,还望见谅。
--------------------------------------------------------------------------------
【详细过程】
原版加了 RLPack Full Edition 的壳,啥版本我不大清楚。在我的 Symantec AntiVirus 企业版下会报毒,只好脱掉。
虽然 RLPack Full Edition 应该是个压缩壳,不过这个 Armadillo Find Protected 1.8 加的壳在 OD 里跑的话还会出错,原来是检测到了调试器。来看看怎么把这个壳去掉吧。这玩意我还试用了 Syser Debugger 来脱的,本来也想把用 Syser Debugger 脱的过程加进去,不过嫌烦,就没写了。改天有空再写吧。

一、寻找 OEP
先用 OD 载入程序看看,因为是压缩壳,OEP应该很好找,根据成对的 PUSHAD、POPAD,上下翻翻就行了:

00415532 >60            PUSHAD                                 ; 加壳程序的EP
00415533    E8 00000000   CALL 00415538
00415538    8B2C24          MOV EBP,DWORD PTR SS:
省略代码若干...
0041567D    A9 00000080   TEST EAX,80000000
00415682    74 1A         JE SHORT 0041569E
00415684    35 00000080   XOR EAX,80000000
00415689    50            PUSH EAX
0041568A    8985 0A140000   MOV DWORD PTR SS:,EAX
00415690    8B85 431F0000   MOV EAX,DWORD PTR SS:
00415696    C700 20202000   MOV DWORD PTR DS:,202020
0041569C    EB 06         JMP SHORT 004156A4
0041569E    FFB5 431F0000   PUSH DWORD PTR SS:
004156A4    FFB5 3F1F0000   PUSH DWORD PTR SS:
004156AA    FF95 F6030000   CALL DWORD PTR SS:
004156B0    85C0            TEST EAX,EAX
004156B2    0F84 17030000   JE 004159CF
004156B8    E8 F20E0000   CALL 004165AF                            ; 这个CALL是用来加密输入表的,NOP掉
004156BD    C785 0A140000 0>MOV DWORD PTR SS:,0
004156C7    8907            MOV DWORD PTR DS:,EAX
004156C9    83C7 04         ADD EDI,4
省略代码若干...
00415721    FF95 FE030000   CALL DWORD PTR SS:
00415727    E8 06050000   CALL 00415C32
0041572C    E8 A7000000   CALL 004157D8
00415731    61            POPAD
00415732- E9 A5DDFEFF   JMP 004034DC                           ; 跳到程序的OEP 004034DC
00415737    83BD FE130000 0>CMP DWORD PTR SS:,0
0041573E    74 16         JE SHORT 00415756
--------------------------------------------------------------------------------------------------
二、干掉调试器检测
程序检测到调试器时应该有个对话框,不过这个对话框你看不到,只听见一声响,就是个系统常见的应用程序错误,然后退出。现在重新载入程序,设断 BP MessageBoxA,F9 运行,会被断下,看堆栈:

0012FF6C   004167F0/CALL 到 MessageBoxA 来自 ArmaFP18.004167EA
0012FF70   00000000|hOwner = NULL
0012FF74   00416DE4|Text = "Debugger detected- please close it down and restart!
Windows NT users: Please note that having the WinIce/SoftIce
service installed means that you are running a debugger!"
0012FF78   00416989|Title = "Error:"
0012FF7C   00000030\Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL

我们在汇编窗口中转到 004167F0 处,往上看看,很容易就知道哪里能跳过这个对话框:

00416794    60            PUSHAD
00416795    83BD B3170000 0>CMP DWORD PTR SS:,1            ; 在这设个硬件执行断点,重新载入程序
0041679C    74 09         JE SHORT 004167A7
0041679E    83BD B7170000 0>CMP DWORD PTR SS:,1
004167A5    75 4D         JNZ SHORT 004167F4                     ; 这里一定要跳,不必改代码,修改一下标志位,或者运行到上面那条指令时,改一下上面 中的值,让它跳。否则就完蛋
004167A7    8D9D 46140000   LEA EBX,DWORD PTR SS:
004167AD    53            PUSH EBX
004167AE    FF95 F2030000   CALL DWORD PTR SS:
004167B4    8985 1A140000   MOV DWORD PTR SS:,EAX
004167BA    81BD 36140000 0>CMP DWORD PTR SS:,ABBC680D
004167C4    75 12         JNZ SHORT 004167D8
004167C6    FFB5 36140000   PUSH DWORD PTR SS:
004167CC    50            PUSH EAX
004167CD    E8 07010000   CALL 004168D9
004167D2    8985 36140000   MOV DWORD PTR SS:,EAX
004167D8    6A 30         PUSH 30
004167DA    8D85 51140000   LEA EAX,DWORD PTR SS:
004167E0    50            PUSH EAX
004167E1    8D85 AC180000   LEA EAX,DWORD PTR SS:
004167E7    50            PUSH EAX
004167E8    6A 00         PUSH 0
004167EA    FF95 36140000   CALL DWORD PTR SS:             ; 这就是检测到调试器的对话框
004167F0    61            POPAD
004167F1    58            POP EAX
004167F2    61            POPAD
004167F3    C3            RETN
004167F4    61            POPAD
004167F5    C3            RETN

到这壳的调试器检测应该就解决了。

检测调试器的代码:

004166F8    8D85 B7170000   LEA EAX,DWORD PTR SS:
004166FE    50            PUSH EAX                                 ; 放置调试标志位的地址
004166FF    6A FF         PUSH -1
00416701    FF95 A7170000   CALL DWORD PTR SS:             ; kernel32.CheckRemoteDebuggerPresent
00416707    8B85 A7170000   MOV EAX,DWORD PTR SS:          ; kernel32.CheckRemoteDebuggerPresent
0041670D    8138 8B442408   CMP DWORD PTR DS:,824448B         ; 检测 CheckRemoteDebuggerPresent 函数的开头几个字节
00416713    75 0A         JNZ SHORT 0041671F                     ; 不跳则有调试器
00416715    C785 B7170000 0>MOV DWORD PTR SS:,1            ; 置标志位
0041671F    64:A1 30000000MOV EAX,DWORD PTR FS:
00416725    83C0 68         ADD EAX,68
00416728    8B00            MOV EAX,DWORD PTR DS:
0041672A    83F8 70         CMP EAX,70
0041672D    75 0A         JNZ SHORT 00416739
0041672F    C785 B3170000 0>MOV DWORD PTR SS:,1            ; 第二个置标志位的地方
00416739    64:A1 18000000MOV EAX,DWORD PTR FS:
--------------------------------------------------------------------------------------------------
三、去除输入表加密
这个壳还会加密输入表,我们先去掉调试器检测,跑到 OEP 去看看:

004034DC    55            PUSH EBP                                 ; OEP
004034DD    8BEC            MOV EBP,ESP
004034DF    6A FF         PUSH -1
004034E1    68 48904000   PUSH 00409048
004034E6    68 10404000   PUSH 00404010
004034EB    64:A1 00000000MOV EAX,DWORD PTR FS:
004034F1    50            PUSH EAX
004034F2    64:8925 0000000>MOV DWORD PTR FS:,ESP
004034F9    83EC 58         SUB ESP,58
004034FC    53            PUSH EBX
004034FD    56            PUSH ESI
004034FE    57            PUSH EDI
004034FF    8965 E8         MOV DWORD PTR SS:,ESP
00403502    FF15 10614000   CALL DWORD PTR DS:               ; 这里可以看出输入表被加密了
00403508    33D2            XOR EDX,EDX
0040350A    8AD4            MOV DL,AH

我们在数据窗口中转到 00406110 处,上下翻翻,就知道输入表是从 00406000 处开始的。现在用 OD 重新载入程序,在数据窗口中转到 00406000,设内存写入断点,F9运行,会被断下:

00415858    33DB            XOR EBX,EBX
0041585A    A4            MOVS BYTE PTR ES:,BYTE PTR DS:      ; 断在这里
0041585B    B3 02         MOV BL,2
0041585D    E8 6D000000   CALL 004158CF
00415862^ 73 F6         JNB SHORT 0041585A
00415864    33C9            XOR ECX,ECX

继续 F9,输入表会解开,跑到了前面我们设的检测调试器的那个硬件断点那。修改一下标志位,不让壳检测到调试器,继续 F9:

0041567D    A9 00000080   TEST EAX,80000000
00415682    74 1A         JE SHORT 0041569E
00415684    35 00000080   XOR EAX,80000000
00415689    50            PUSH EAX
0041568A    8985 0A140000   MOV DWORD PTR SS:,EAX
00415690    8B85 431F0000   MOV EAX,DWORD PTR SS:
00415696    C700 20202000   MOV DWORD PTR DS:,202020
0041569C    EB 06         JMP SHORT 004156A4
0041569E    FFB5 431F0000   PUSH DWORD PTR SS:
004156A4    FFB5 3F1F0000   PUSH DWORD PTR SS:
004156AA    FF95 F6030000   CALL DWORD PTR SS:
004156B0    85C0            TEST EAX,EAX
004156B2    0F84 17030000   JE 004159CF
004156B8    E8 F20E0000   CALL 004165AF                                 ; 这个CALL是用来加密输入表的,NOP掉
004156BD    C785 0A140000 0>MOV DWORD PTR SS:,0
004156C7    8907            MOV DWORD PTR DS:,EAX                  ; 断在这里,这里就是加密输入表了
004156C9    83C7 04         ADD EDI,4
004156CC    8B85 431F0000   MOV EAX,DWORD PTR SS:

这时候有两种方法:
1、知道了加密输入表 CALL 的位置,重新用 OD 载入程序,NOP掉加密的 CALL,就可以得到完整的输入表,然后到 OEP dump,用 ImportREC 重建输入表。不过这种方法我不大推荐,我推荐下面第二种方法。
2、当我们断在 004156C7 处时,我们在数据窗口中看一下 00406000 处的内容,查看方式选“长型->地址”:

0040600000009590
004060040000959C
00406008000095AA
0040600C000095B6
00406010000095C2
00406014000095D4
00406018000095E2
0040601C000095F6
0040602000009604
004060240000961A
004060280000962A
0040602C0000963E
省略若干...

这个一看就是原始的输入表,那还等啥?直接用 LordPE 修正镜像大小,然后 dump。用 PETools 的编辑工具把 dump 程序的 OEP 改成 00034DC,再用 010editor 之类的16进制编辑工具定位到偏移 6000 处,根据 IAT 最后以20个0结束,就可以确定输入表的开始地址和大小了。往下搜索有二十个 HEX 值 0,根据找到的最近位置,很容易就确定了 IAT 的 RVA 是 000093AC,大小是 50。在PE 编辑工具中填上我们上面得到的值,现在输入表就修复好了,根本不需要使用 ImportREC。同样发现输入表都解开后才检测调试器的,这样一来,连避开调试器检测都不需要了,到检测调试器前就可以 dump 来修正了。
--------------------------------------------------------------------------------------------------
三、脱壳后的优化
要了解一下原来没加壳的程序有几个区段的话,只要重新载入程序,BP VirtualProtect,F9 运行,注意看堆栈就可以了:

1、.text 段
0012FF70   004155B4/CALL 到 VirtualProtect 来自 ArmaFP18.004155AE
0012FF74   00401000|Address = ArmaFP18.00401000
0012FF78   00004A1E|Size = 4A1E (18974.)
0012FF7C   00000020|NewProtect = PAGE_EXECUTE_READ
0012FF80   00416EEA\pOldProtect = ArmaFP18.00416EEA

2、.rdata 段
0012FF70   004155B4/CALL 到 VirtualProtect 来自 ArmaFP18.004155AE
0012FF74   00406000|Address = ArmaFP18.00406000
0012FF78   00003BE4|Size = 3BE4 (15332.)
0012FF7C   00000040|NewProtect = PAGE_EXECUTE_READWRITE
0012FF80   00416EEA\pOldProtect = ArmaFP18.00416EEA

3、.data 段
0012FF70   004155B4/CALL 到 VirtualProtect 来自 ArmaFP18.004155AE
0012FF74   0040A000|Address = ArmaFP18.0040A000
0012FF78   0000349C|Size = 349C (13468.)
0012FF7C   00000040|NewProtect = PAGE_EXECUTE_READWRITE
0012FF80   00416EEA\pOldProtect = ArmaFP18.00416EEA

4、.rsrc 段
0012FF70   004155B4/CALL 到 VirtualProtect 来自 ArmaFP18.004155AE
0012FF74   0040E000|Address = ArmaFP18.0040E000
0012FF78   00000EE8|Size = EE8 (3816.)
0012FF7C   00000020|NewProtect = PAGE_EXECUTE_READ
0012FF80   00416EEA\pOldProtect = ArmaFP18.00416EEA

剩下其他的都是垃圾了,按上面显示的重建一下各个区段,按 1000 对齐,偏移 F000 后面的都可以删掉。顺便传一个脱过壳的版本。

--------------------------------------------------------------------------------
【版权声明】: 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!

A-new 发表于 2009-1-6 11:56

强悍,偶也搞一下试试:lol

llaobao 发表于 2009-1-22 19:35

支持一下~~~~~~~·
页: [1]
查看完整版本: RLPack 加壳的 Armadillo find protected 1.8