欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

Armadillo保护壳单、双进程的简单脱法

程序员文章站 2022-07-03 08:22:25
文/图 浓咖啡这段时间和我的朋友“老海”学习脱壳技巧,偶有心得,现与大家分享,对那些正在为此壳感到困惑的朋友,提供一些参考。 Armadillo壳(被称作穿山甲保护壳)是一种加密壳,用前人发明...
文/图 浓咖啡
这段时间和我的朋友“老海”学习脱壳技巧,偶有心得,现与大家分享,对那些正在为此壳感到困惑的朋友,提供一些参考。
Armadillo壳(被称作穿山甲保护壳)是一种加密壳,用前人发明的ESP定律脱壳办法是无法完成脱壳工作的,属于界内的猛壳之一。Armadillo壳保护,通俗来讲可以这样简单的分类理解:保护系统授权等级、进程模式、程序所使用保护模式、其它设置。保护系统授权等级分为标准版、非标准版、专业版;进程模式分为:单进程、双进程;程序所使用保护模式分为:输入表乱序、策略代码衔接、Nanomites 处理程序等保护模式;其它设置可以进行Key和时间等设定。经过任意组合后,就会形成强大的保护机制,形式多样,变幻莫测!这样会使很多“初生牛犊”望而怯步!下面谈一下Armadillo保护壳单、双进程的简单脱法,使之不再成为难事。

Armadillo 1.xx - 2.xx 单进程的简单脱法
1)准备工作,收集所有信息
用PEiD侦壳为“Armadillo 1.xx - 2.xx -> Silicon Realms Toolworks”,用Armadillo Find Protected V1.4汉化版查看保护机制,得知目标经Armadillo保护,保护系统授权等级(标准版);程序所使用保护模式为标准保护或最小保护模式;备份密钥设置为固定的备份密钥;程序压缩设置为最小/最快的压缩方式;其它保护设置为版本号3.70。这可谓是最基本的保护设置了。运行目标程序,再运行LordPE,查看得知是单进程模式,如图1所示。至此,信息收集完毕!
Armadillo保护壳单、双进程的简单脱法
图1
2)OD定位
运行OD,载入目标程序czssgold.exe(在C:Program Filessmswriter彩尊圣手黄金版),停在这里。

004C9B19 >/$  55 push ebp 载入处
004C9B1A |. 8BEC  mov ebp, esp
004C9B1C |. 6A FF  push -1
004C9B1E |. 68 385A4E00  push 004E5A38
004C9B23 |. 68 00954C00  push 004C9500 ;SE 处理程序安装
004C9B28 |. 64:A1 0000000>mov eax, dword ptr fs:[0]
004C9B2E |. 50 push eax
004C9B2F |. 64:8925 00000>mov dword ptr fs:[0], esp
004C9B36 |. 83EC 58  sub esp, 58
004C9B39 |. 53 push ebx
004C9B3A |. 56 push esi
004C9B3B |. 57 push edi
004C9B3C |. 8965 E8  mov dword ptr [ebp-18], esp
004C9B3F |. FF15 4C014E00 call dword ptr [<&KERNEL32.GetVersion>; kernel32.GetVersion
004C9B45 |. 33D2  xor edx, edx

我们一般是下BP GetModuleHandleA断点,我是用Ctrl+G,输入GetModuleHandleA,点确定后,程序在OD中会停在下面的代码处。

7C80B529 > 8BFF mov edi, edi ;停在这里
7C80B52B 55  push ebp
7C80B52C 8BEC mov ebp, esp
7C80B52E 837D 08 00  cmp dword ptr [ebp+8], 0
7C80B532 74 18   je  short 7C80B54C ; F2断点
7C80B534 FF75 08  push dword ptr [ebp+8]
7C80B537 E8 682D0000 call 7C80E2A4
7C80B53C 85C0 test eax, eax
7C80B53E 74 08 je short 7C80B548
7C80B540 FF70 04 push dword ptr [eax+4]
7C80B543 E8 F4300000 call GetModuleHandleW
7C80B548 5D pop ebp
7C80B549 C2 0400 retn 4

在7C80B532 处下F2断点,然后按Shift+F9,之后看堆栈。
SHIFT + F9一次,堆栈结果:

0013FF34 /0013FFC0
0013FF38 |004C9BE1 ;返回到czssgold.<模块入口点>+0C8来自 kernel32.GetModuleHandleA

Shift+F9两次,堆栈结果:

0013EC68 /0013ECA0
0013EC6C |5D175324 ;返回到 5D175324 来自 kernel32.GetModuleHandleA
0013EC70 |5D175370 ASCII "kernel32.dll"
0013EC74 |5D1E3AB8
0013EC78 |00000000
0013EC7C |5D170000
0013EC80 |7C812972 ;返回到 kernel32.7C812972 来自 ntdll.RtlCreateHeap
0013EC84 |00001002
0013EC88 |0013EC74

Shift+F9三次,堆栈结果:
0013ED28 /0013ED44
0013ED2C |77F45BD8 ;返回到SHLWAPI.77F45BD8,来自 kernel32.GetModuleHandleA
0013ED30 |77F4501C ASCII "KERNEL32.DLL"
0013ED34 |00000001
0013ED38 |77F40000 SHLWAPI.77F40000

Shift+F9四次,堆栈结果:
0013F53C /0013F5A4
0013F540 |004B50E3 ;返回到 czssgold.004B50E3,来自 kernel32.GetModuleHandleA
0013F544 |00000000
0013F548 |0000FFFF
0013F54C |00BE6C6A
0013F550 |00536E5F czssgold.00536E5F
0013F554 |00000000
0013F558 |00500000 ASCII "PDATA000"
0013F55C |004E0500 ASCII """, error %d"

Shift+F9五次,堆栈结果:
0013BB1C /0013ED6C
0013BB20 |00BFF65E ;返回到 00BFF65E 来自 kernel32.GetModuleHandleA
0013BB24 |00C10B58 ASCII "kernel32.dll"
0013BB28 |00C11BB4 ASCII "VirtualAlloc"

Shift+F9六次,堆栈结果:
0013BB1C /0013ED6C
0013BB20 |00BFF67B ;返回到00BFF67B,来自 kernel32.GetModuleHandleA
0013BB24 |00C10B58 ASCII "kernel32.dll"
0013BB28 |00C11BA8 ASCII "VirtualFree"

Shift+F9七次,堆栈结果:
0013B894 /0013BB20
0013B898 |00BE97CD ;返回到 00BE97CD 来自 kernel32.GetModuleHandleA
0013B89C |0013B9D4 ASCII "kernel32.dll"

这时,再看一下寄存器窗口,代码如下。

EAX 0013B9D4 ASCII "kernel32.dll"
ECX 0013B9E0
EDX 0013B9D4 ASCII "kernel32.dll"
EBX 00C0FFC4
ESP 0013B894
EBP 0013B894

注意,在这里,取消了7C80B532处的断点,按Alt + F9,执行到用户代码,来到如下代码处。
00BE97CD 8B0D A04CC100  mov ecx, dword ptr [C14CA0]
00BE97D3 89040E  mov dword ptr [esi+ecx], eax
00BE97D6 A1 A04CC100 mov eax, dword ptr [C14CA0]
00BE97DB 393C06  cmp dword ptr [esi+eax], edi
00BE97DE 75 16   jnz short 00BE97F6
00BE97E0 8D85 B4FEFFFF  lea eax, dword ptr [ebp-14C]
00BE97E6 50  push eax
00BE97E7 FF15 E0B0C000  call dword ptr [C0B0E0] ; kernel32.LoadLibraryA
00BE97ED 8B0D A04CC100  mov ecx, dword ptr [C14CA0]
00BE97F3 89040E  mov dword ptr [esi+ecx], eax
00BE97F6 A1 A04CC100 mov eax, dword ptr [C14CA0]
00BE97FB 393C06  cmp dword ptr [esi+eax], edi
00BE97FE 0F84 AD000000  je  00BE98B1  ;传说中的魔法跳,修改成JMP
00BE9804 33C9 xor ecx, ecx
00BE9806 8B03 mov eax, dword ptr [ebx]
00BE9808 3938 cmp dword ptr [eax], edi
00BE980A 74 06   je  short 00BE9812
00BE980C 41  inc ecx
00BE980D 83C0 0C  add eax, 0C
00BE9810 ^ EB F6   jmp short 00BE9808
00BE9812 8BC1 mov eax, ecx

在00BE97CD处设断点,然后Shift+F9,就会停在00BE97CD处。00BE97E7处的函数kernel32.LoadLibraryA是判断返回时机的重要标志,如图2所示。在00BE97FE处,也就是传说中的魔法跳,把JE直接修改成JMP,即可。然后,取消所有断点,使用内存断点大法(当然,修改完魔法跳以后,直达OEP的方法很多),打开内存窗口,在401000处下F2断点。按Shift+F9运行,就会到达OEP(心中一定很激动吧!)。代码如下。
  Armadillo保护壳单、双进程的简单脱法

图2

0043DC0D 6A 60   push 60  ; OEP
0043DC0F 68 40A04800 push 0048A040
0043DC14 E8 BB0C0000 call 0043E8D4
0043DC19 BF 94000000 mov edi, 94
0043DC1E 8BC7 mov eax, edi
0043DC20 E8 DBF0FFFF call 0043CD00
0043DC25 8965 E8  mov dword ptr [ebp-18], esp
0043DC28 8BF4 mov esi, esp
0043DC2A 893E mov dword ptr [esi], edi
0043DC2C 56  push esi
0043DC2D FF15 04944700  call dword ptr [479404] ;kernel32.GetVersionExA
0043DC33 8B4E 10  mov ecx, dword ptr [esi+10]
0043DC36 890D 60DD4900  mov dword ptr [49DD60], ecx
0043DC3C 8B46 04  mov eax, dword ptr [esi+4]
0043DC3F A3 6CDD4900 mov dword ptr [49DD6C], eax
0043DC44 8B56 08  mov edx, dword ptr [esi+8]
0043DC47 8915 70DD4900  mov dword ptr [49DD70], edx
0043DC4D 8B76 0C  mov esi, dword ptr [esi+C]
0043DC50 81E6 FF7F0000  and esi, 7FFF
0043DC56 8935 64DD4900  mov dword ptr [49DD64], esi
0043DC5C 83F9 02  cmp ecx, 2
0043DC5F 74 0C   je  short 0043DC6D
0043DC61 81CE 00800000  or  esi, 8000

在0043DC0D处,就可以DUMP程序,到此OD的任务已经完成,但千万不要关闭OD。(这应该是医生对病人的病灶部位准确定位,如果定位的设备撤了,医生岂不是瞎子!刀子乱