kissy 发表于 2008-7-21 20:54

RLPack1.21加壳calc.exe脱壳过程

【文章标题】: RLPack1.21加壳calc.exe脱壳过程
【文章作者】: faint88
【作者QQ号】: 没QQ
【软件名称】: calc.exe
【软件大小】: 67.3KB
【下载地址】: 论坛搜索下载
【加壳方式】: RLPack1.21
【保护方式】: 代码变形,VM,OEP偷取
【编写语言】: VC++
【使用工具】: OllyDebug LoadPE ImportREC
【操作平台】: xp
【软件介绍】: XP计算器
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
第一次写文章,写得不好请大家见谅

HideOD: 选择HideNtDebugBit和CheckRemoteDebuggerPresent

OD载入,停在
01001000 > $ /EB 06 jmp short 01001008
01001002 . |68 2EA80000 push 0A82E
01001007 . |C3 retn
01001008 > \9C pushfd
01001009 . 60 pushad
0100100A . E8 02000000 call 01001011
0100100F . 33C0 xor eax, eax
01001011 $ 8BC4 mov eax, esp

然后单步,为了速度,这里直接CTRL+G 0102E97E 下硬件执行断点
0102E97E 35 AE718865 xor eax, 658871AE ; 运行到这里是为了让下面的代码先解下码
0102E983 E6 B0 out 0B0, al
0102E985 0000 add byte ptr , al
0102E987 0000 add byte ptr , al
0102E989 0000 add byte ptr , al
0102E98B 0000 add byte ptr , al

SHIFT+F9,删除硬件断点
0102E97E E8 831F0000 call <根据加密参数的不同,取得不同的API地址> ; 取得MessageBoxA地址
0102E983 B8 75240101 mov eax, 01012475
0102E988 2B85 7A470000 sub eax, dword ptr
0102E98E 0385 7E470000 add eax, dword ptr
0102E994 C700 33C090C3 mov dword ptr , C390C033
0102E99A FFD0 call eax
0102E99C 8D85 D3230000 lea eax, dword ptr
0102E9A2 8985 A5530000 mov dword ptr , eax
0102E9A8 89AD A9530000 mov dword ptr , ebp
0102E9AE 8D85 E7230000 lea eax, dword ptr
0102E9B4 8928 mov dword ptr , ebp
0102E9B6 8D85 DF230000 lea eax, dword ptr
0102E9BC 50 push eax
0102E9BD 64:FF35 0000000>push dword ptr fs:
0102E9C4 89A5 92470000 mov dword ptr , esp
0102E9CA 64:8925 0000000>mov dword ptr fs:, esp
0102E9D1 33C0 xor eax, eax
0102E9D3 8700 xchg dword ptr , eax //SEH陷阱
0102E9D5 64:8F05 0000000>pop dword ptr fs:
0102E9DC 83C4 04 add esp, 4 //F2 SHIFT+F9,取消断点,避开SEH陷阱,这个陷阱会检测硬件断点
0102E9DF 61 popad
0102E9E0 C3 retn

F8

0102C646 8DB5 AD530000 lea esi, dword ptr //到这里
0102C64C 8D9D 17030000 lea ebx, dword ptr
0102C652 33FF xor edi, edi
0102C654 E8 3B3D0000 call <调试器检测>
0102C659 EB 03 jmp short 0102C65E
0102C65B 2D 0000EB1B sub eax, 1BEB0000
0102C660 8B85 7E470000 mov eax, dword ptr
0102C666 FF7437 04 push dword ptr
0102C66A 010424 add dword ptr , eax
0102C66D FF3437 push dword ptr
0102C670 010424 add dword ptr , eax
0102C673 FFD3 call ebx ; 解码
0102C675 83C4 08 add esp, 8
0102C678 83C7 08 add edi, 8
0102C67B 833C37 00 cmp dword ptr , 0
0102C67F ^ 75 DF jnz short 0102C660 ; 循环解码
0102C681 83BD 8D530000 0>cmp dword ptr , 0
0102C688 74 0E je short 0102C698
0102C68A 83BD 91530000 0>cmp dword ptr , 0
0102C691 74 05 je short 0102C698
0102C693 E8 F30B0000 call <还原一部分指定的代码>
0102C698 8D7437 04 lea esi, dword ptr
0102C69C E8 660B0000 call 0102D207
0102C6A1 8B85 5C4C0000 mov eax, dword ptr
0102C6A7 0BC0 or eax, eax
0102C6A9 74 0B je short 0102C6B6
0102C6AB 0385 7E470000 add eax, dword ptr
0102C6B1 E8 C2030000 call <代码变形> //硬件执行断点,F9 取消断点,F7

0102CA78 > 60 pushad //来到这里
0102CA79 83BD 7E470000 0>cmp dword ptr , 0
0102CA80 75 0E jnz short 0102CA90
0102CA82 8BB5 7A470000 mov esi, dword ptr
0102CA88 89B5 7E470000 mov dword ptr , esi
0102CA8E 03C6 add eax, esi
0102CA90 8BF0 mov esi, eax
0102CA92 6A 40 push 40
0102CA94 68 00100000 push 1000
0102CA99 FFB5 604C0000 push dword ptr
0102CA9F 6A 00 push 0
0102CAA1 FF95 FD030000 call dword ptr ; VirtualAlloc
0102CAA7 8BF8 mov edi, eax
0102CAA9 50 push eax
0102CAAA 56 push esi
0102CAAB FFD3 call ebx
0102CAAD 83C4 08 add esp, 8
0102CAB0 8B85 604C0000 mov eax, dword ptr
0102CAB6 6BC0 32 imul eax, eax, 32
0102CAB9 6A 40 push 40

这部分就是代码变形,经分析,代码变形如下
01: push xxxxxxxx
02: call
03: mov , eax
04: mov , ecx
05: mov , edx
06: mov , edi
07: mov ecx,
08: push
09: mov , esi
0A: cmp ebx,
0B: cmp eax,
0C: cmp ecx,
0D: cmp edx,
0E: cmp esi,
0F: cmp edi,
10: mov eax,
11: mov eax, xxxxxxxx
12: mov ebx, xxxxxxxx
13: mov ecx, xxxxxxxx
14: mov edx, xxxxxxxx
15: call xxxxxxxx
16: mov ebx,
17: mov edx,
18: mov esi,
19: mov edi,
1A: add eax, xxxxxxxx
1B: sub eax, xxxxxxxx
1C: xor eax, xxxxxxxx
1D: or eax, xxxxxxxx
1E: add ebx, xxxxxxxx
1F: sub ebx, xxxxxxxx
20: xor ebx, xxxxxxxx
21: or ebx, xxxxxxxx
22: add ecx, xxxxxxxx
23: sub ecx, xxxxxxxx
24: xor ecx, xxxxxxxx
25: or ecx, xxxxxxxx
26: add edx, xxxxxxxx
27: sub edx, xxxxxxxx
28: xor edx, xxxxxxxx
29: or edx, xxxxxxxx
2A: add esi, xxxxxxxx
2B: sub esi, xxxxxxxx
2C: xor esi, xxxxxxxx
2D: or esi, xxxxxxxx
2E: add edi, xxxxxxxx
2F: sub edi, xxxxxxxx
30: xor edi, xxxxxxxx
31: or edi, xxxxxxxx

0102CAF2 C606 9C mov byte ptr , 9C
0102CAF5 46 inc esi
0102CAF6 837F 04 01 cmp dword ptr , 1 ; 分支:比较是否等于1
0102CAFA 75 30 jnz short 0102CB2C
0102CAFC 3385 5B4D0000 xor eax, dword ptr //从这行开始粘贴以下数据,饶开代码变形
0102CB02 C706 83EC04C7 mov dword ptr , C704EC83
0102CB08 66:C746 04 0424 mov word ptr , 2404
0102CB0E 8946 06 mov dword ptr , eax
0102CB11 C646 0A E8 mov byte ptr , 0E8
0102CB15 8D5E 0A lea ebx, dword ptr
0102CB18 8BC2 mov eax, edx
0102CB1A 2BC3 sub eax, ebx
0102CB1C 83E8 05 sub eax, 5
0102CB1F 8946 0B mov dword ptr , eax

56 3E 8B 74 24 04 C7 06 68 00 00 00 89 46 01 5E 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 E9 AE 05 00 00 83 7F 04 02 75 40 56 3E 8B 74 24 04 C7 06 FF 15
00 00 89 46 02 5E 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 E9 68 05 00 00 83 7F 04 03 72 68 83 7F 04 06
77 62 56 3E 8B 74 24 04 83 7F 04 03 75 05 C6 06 A3 EB 2C 83 7F 04 04 75 07 66 C7 06 89 0D EB 18
83 7F 04 05 75 07 66 C7 06 89 15 EB 0B 83 7F 04 06 75 05 66 C7 06 89 3D 89 46 02 5E EB 21 90 89
46 01 5E 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 E9
FA 04 00 00 83 7F 04 07 74 12 83 7F 04 10 74 0C 83 7F 04 16 72 7F 83 7F 04 19 77 79 56 3E 8B 74
24 04 83 7F 04 07 75 29 66 C7 06 8B 0D EB 56 83 7F 04 16 75 28 66 C7 06 8B 1D EB 49 90 2B C3 83
E8 05 89 46 0E 83 7F 04 07 75 06 C6 46 12 59 EB 3A 83 7F 04 10 75 D8 C6 06 A1 90 EB 2E 83 7F 04
17 75 07 66 C7 06 8B 15 EB 1B 83 7F 04 18 75 07 66 C7 06 8B 35 EB 0E 83 7F 04 19 75 13 66 C7 06
8B 3D EB 01 90 89 46 02 5E EB 05 89 46 01 5E 90 E9 69 04 00 00 83 7F 04 08 75 55 56 3E 8B 74 24
04 C7 06 FF 35 00 00 89 46 02 5E 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 E9 0E 04 00 00 83 7F 04 09 75 72 52 3E 8B 54 24 04 66 C7 02 89
35 89 42 02 5A 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 E9 96 03 00 00 83 7F 04 0A 0F 82 E4 00 00 00 83 7F 04 0F 0F 87 DA 00 00 00 56 3E 8B 74
24 04 EB 70 90 90 90 90 89 46 02 5E E9 C0 00 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 83 7F 04 0A 75 09 C7 06 39 1D 00 00
90 EB 49 83 7F 04 0B 75 09 C7 06 39 05 00 00 90 EB 3A 83 7F 04 0C 75 09 C7 06 39 0D 00 00 90 EB
2B 83 7F 04 0D 75 09 C7 06 39 15 00 00 90 EB 1C 83 7F 04 0E 75 09 C7 06 39 35 00 00 90 EB 0D 83
7F 04 0F 75 07 C7 06 39 3D 00 00 90 E9 37 FF FF FF E9 A8 02 00 00 83 7F 04 11 75 26 2B 85 7E 47
00 00 56 3E 8B 74 24 04 C7 06 B8 00 00 00 89 46 01 5E 90 90 90 90 90 90 90 90 90 90 90 E9 7C 02
00 00 83 7F 04 12 75 28 2B 85 7E 47 00 00 56 3E 8B 74 24 04 C7 06 BB 00 00 00 89 46 01 5E 90 90
90 90 90 90 90 90 90 90 90 90 90 E9 4E 02 00 00 83 7F 04 13 75 28 2B 85 7E 47 00 00 56 3E 8B 74
24 04 C7 06 B9 00 00 00 89 46 01 5E 90 90 90 90 90 90 90 90 90 90 90 90 90 E9 20 02 00 00 83 7F
04 14 75 28 2B 85 7E 47 00 00 56 3E 8B 74 24 04 C7 06 BA 00 00 00 89 46 01 5E 90 90 90 90 90 90
90 90 90 90 90 90 90 E9 F2 01 00 00 83 7F 04 15 75 37 56 3E 8B 74 24 04 C7 06 E8 00 00 00 2B C6
83 E8 05 89 46 01 5E 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 E9 B5 01 00 00 83 7F 04 1A 0F 82 AB 01 00 00 83 7F 04 31 0F 87 A1 01 00 00 56 3E 8B
74 24 04 2B 85 7E 47 00 00 83 7F 04 1A 75 11 C6 06 05 90 90 90 90 90 89 46 01 5E E9 64 01 00 00
83 7F 04 1B 75 05 C6 06 2D EB EC 83 7F 04 1C 75 05 C6 06 35 EB E1 83 7F 04 1D 75 05 C6 06 0D EB
D6 83 7F 04 1E 75 0A 66 C7 06 81 C3 E9 2F 01 00 00 83 7F 04 1F 75 0A 66 C7 06 81 EB E9 1F 01 00
00 83 7F 04 20 75 0A 66 C7 06 81 F3 E9 0F 01 00 00 83 7F 04 21 75 0A 66 C7 06 81 CB E9 FF 00 00
00 83 7F 04 22 75 0A 66 C7 06 81 C1 E9 EF 00 00 00 83 7F 04 23 75 0A 66 C7 06 81 E9 E9 DF 00 00
00 83 7F 04 24 75 0A 66 C7 06 81 F1 E9 CF 00 00 00 83 7F 04 25 75 0A 66 C7 06 81 C9 E9 BF 00 00
00 83 7F 04 26 75 0A 66 C7 06 81 C2 E9 AF 00 00 00 83 7F 04 27 75 0A 66 C7 06 81 EA E9 9F 00 00
00 83 7F 04 28 75 0A 66 C7 06 81 F2 E9 8F 00 00 00 83 7F 04 29 75 0A 66 C7 06 81 CA E9 7F 00 00
00 83 7F 04 2A 75 0A 66 C7 06 81 C6 EB 72 90 90 90 83 7F 04 2B 75 0A 66 C7 06 81 EE EB 62 90 90
90 83 7F 04 2C 75 0A 66 C7 06 81 F6 EB 52 90 90 90 83 7F 04 2D 75 0A 66 C7 06 81 CE EB 42 90 90
90 83 7F 04 2E 75 0A 66 C7 06 81 C7 EB 32 90 90 90 83 7F 04 2F 75 0A 66 C7 06 81 EF EB 22 90 90
90 83 7F 04 30 75 0A 66 C7 06 81 F7 EB 12 90 90 90 83 7F 04 31 75 0A 66 C7 06 81 CF 90 90 90 90
89 46 02 5E EB 18 8B 9D 63 4D 00 00 8D 5B 10 66 C7 46 29 FF 35 89 5E 2B 8D 5E FA 83 C6 2F 58 80
7B FF 9C EB 41 83 7F 04 01 74 06 83 7F 04 08 75 30 C6 06 50 46 C7 06 FF 74 24 08 C7 46 04 8B 44
24 08 C7 46 08 89 44 24 0C C7 46 0C 8B 04 24 00 C7 46 0F 89 44 24 08 C7 46 13 83 C4 04 58 83 C6
17 C6 06 9D 46 4B 53 2B D8 83 EB 05 90 90 90 90 90 90 50 2B C6 83 7F 04 02 90 90 83 7F 04 0F 90
90 83 7F 04 03 90 90 40 EB 44 83 7F 04 16 72 2C 83 7F 04 19 77 26 40 8B 1C 24 66 C7 03 FF 25 89
73 02 83 43 02 02 66 C7 06 EB 04 83 C6 02 8B 5C 24 04 89 1E 83 C6 04 83 E8 06 EB 12 83 7F 04 1E
72 0C 83 7F 04 31 77 06 40 8B 1C 24 FE 0B 5B 5B 90 90 90 90 90 90

因为代码太长,这里就不帖粘贴后的代码了

粘贴后

0102D1C1 C1C2 07 rol edx, 7
0102D1C4 46 inc esi
0102D1C5 49 dec ecx
0102D1C6 83F9 00 cmp ecx, 0
0102D1C9 ^ 77 F4 ja short 0102D1BF
0102D1CB 8913 mov dword ptr , edx
0102D1CD 61 popad
0102D1CE C3 retn //F2 SHIFT+F9
0102D1CF 56 push esi
0102D1D0 8BB0 B4000000 mov esi, dword ptr
0102D1D6 83BE 82470000 0>cmp dword ptr , 0

之后撤消修改,这样就避开了代码变形

0102C7D0 85C0 test eax, eax
0102C7D2 0F84 5B200000 je 0102E833
0102C7D8 E8 FF360000 call <检测取得的函数是否需要加密> //下硬件执行断点,F9 删除断点,nop填充
0102C7DD E8 85350000 call <存放输入表>
0102C7E2 83C7 04 add edi, 4
0102C7E5 8B85 A5530000 mov eax, dword ptr
0102C7EB 8938 mov dword ptr , edi
0102C7ED 8385 A5530000 0>add dword ptr , 4
0102C7F4 8B85 A5530000 mov eax, dword ptr

停的位置的call是输入表函数的加密call 直接nop

0102C853 E8 B0350000 call 0102FE08
0102C858 68 00400000 push 4000
0102C85D 68 87020000 push 287
0102C862 FFB5 A9530000 push dword ptr
0102C868 FF95 05040000 call dword ptr ; 硬件断点,F9,删除断点

之后撤消修改,因为nop掉了加密的call,所以输入表全部可见

到这里代码全解码,输入表全解压,LOADPE dump importrec修复输入表IAT地址是00001000,长度1000,减掉无效

0102C892 61 popad
0102C893 - E9 DD5BFEFF jmp 01012475 //入口点地址,入口点填这个
0102C898 90 nop
0102C899 60 pushad
0102C89A 6A 40 push 40
0102C89C 68 00100000 push 1000
0102C8A1 68 00000800 push 80000

dump的位置下面有代码校验,怕修改了没及时撤消修改的话,从新运行程序,不要修改任何代码,下面的工作只是找被偷的OEP

下面是从虚拟机中拿回偷掉的5句OEP

0102C868 FF95 05040000 call dword ptr ; <calc.释放空间>
0102C86E E8 D0220000 call <文件校验> //有校验,要及时撤消修改的地方和下的断点
0102C873 E8 CC340000 call 0102FD44
0102C878 E8 DF0B0000 call <还原区段属性>
0102C87D E8 850A0000 call 0102D307
0102C882 83BD 944C0000 0>cmp dword ptr , 0
0102C889 74 07 je short 0102C892
0102C88B E9 10100000 jmp <VM Start> ; VM开始跳 //硬件断点,F9,删除断点

F7

0102D8A0 > 896C24 1C mov dword ptr , ebp ; VM start
0102D8A4 61 popad
0102D8A5 > 8980 A44C0000 mov dword ptr , eax ; 初始化虚拟机寄存器的值
0102D8AB 8998 A84C0000 mov dword ptr , ebx
0102D8B1 8988 AC4C0000 mov dword ptr , ecx
0102D8B7 8990 B04C0000 mov dword ptr , edx
0102D8BD 89B0 B44C0000 mov dword ptr , esi
0102D8C3 89B8 B84C0000 mov dword ptr , edi
0102D8C9 89A0 C04C0000 mov dword ptr , esp
0102D8CF 89A0 C44C0000 mov dword ptr , esp
0102D8D5 89A8 BC4C0000 mov dword ptr , ebp

记好这些内存地址,这些就是虚拟机中寄存器的地址

因为被偷的代码是在VM中执行,所以牵扯到VM寄存器和堆栈的操作很有可能就是被偷的代码

下面就是虚拟机执行的主体代码,是个分支结构

0102D8E9 /E9 F0040000 jmp 0102DDDE
0102D8EE |833E 01 cmp dword ptr , 1 ; == 1 ???
0102D8F1 |75 1E jnz short 0102D911
0102D8F3 |60 pushad
0102D8F4 |33C9 xor ecx, ecx
0102D8F6 |6A 08 push 8
0102D8F8 |E8 F80C0000 call 0102E5F5
0102D8FD |50 push eax
0102D8FE |6A 07 push 7
0102D900 |E8 B80A0000 call 0102E3BD
0102D905 |897C24 1C mov dword ptr , edi
0102D909 |61 popad

这里开始就是虚拟机了,中放的就是pCode,这里是

其中格式如下

00FE0000 02 00 00 00 70 00 00 00 00 00 00 00 02 00 00 00 ...p..........
00FE0010 E0 15 00 01 00 00 00 00 0C 00 00 00 C8 27 01 01 ?.........?
00FE0020 00 00 00 00 06 00 00 00 02 00 00 00 00 00 00 00 ..............
00FE0030 03 00 00 00 02 00 00 00 00 00 00 00 ..........

每条PCODE占3个DWORD,第一个DWORD是PCODE代码,第2个是参数。这个软件只用到了4条虚拟机代码
00000002 push+值
00000003 call+地址
00000006 xor
0000000C push+寄存器

很明显可以得到第一条被偷的是push 70,第2条是push 010015E0 第3条是call 010127C8,另外2条不好判断

那就继续单步

下面是第一次循环代码

0102E7DB /75 02 jnz short 0102E7DF
0102E7DD |8BCD mov ecx, ebp
0102E7DF \55 push ebp
0102E7E0 8BEC mov ebp, esp
0102E7E2 8B45 08 mov eax, dword ptr
0102E7E5 8907 mov dword ptr , eax //停在这里
0102E7E7 6A FC push -4
0102E7E9 6A 08 push 8
0102E7EB E8 4EFBFFFF call 0102E33E
0102E7F0 C9 leave
0102E7F1 C2 0400 retn 4
0102E7F4 0BC9 or ecx, ecx

eax=00000070
ds:=00000000

是虚拟机的堆栈,70放到虚拟机的堆栈中,所以被偷的第一句就是 push 70

第2次循环的代码

0102E7DD 8BCD mov ecx, ebp
0102E7DF 55 push ebp
0102E7E0 8BEC mov ebp, esp
0102E7E2 8B45 08 mov eax, dword ptr
0102E7E5 8907 mov dword ptr , eax ; calc.010015E0 //还是在这里
0102E7E7 6A FC push -4
0102E7E9 6A 08 push 8
0102E7EB E8 4EFBFFFF call 0102E33E
0102E7F0 C9 leave
0102E7F1 C2 0400 retn 4
0102E7F4 0BC9 or ecx, ecx
0102E7F6 75 02 jnz short 0102E7FA

eax=010015E0 (calc.010015E0)
ds:=00000000

把010015E0放到中,是栈底,放的是70,所以被偷的第2句就是push 010015E0

第3次循环代码

0102DAA1 8B85 A44C0000 mov eax, dword ptr ; calc.0102C602 //1。这里开始把VM的寄存器放回到真实CPU寄存器中
0102DAA7 8B9D A84C0000 mov ebx, dword ptr
0102DAAD 8B8D AC4C0000 mov ecx, dword ptr
0102DAB3 8B95 B04C0000 mov edx, dword ptr
0102DAB9 8BB5 B44C0000 mov esi, dword ptr
0102DABF 8BBD B84C0000 mov edi, dword ptr
0102DAC5 8BA5 C04C0000 mov esp, dword ptr
0102DACB 89A5 C84C0000 mov dword ptr , esp
0102DAD1 8BAD BC4C0000 mov ebp, dword ptr
0102DAD7 E8 EC4CFEFF call 010127C8 //3。在虚拟call这条指令的时候,先把VM的context放回到CPU,再执行,然后在context放回到VM寄存器中
0102DADC 55 push ebp
0102DADD BD 02C60201 mov ebp, 0102C602
0102DAE2 8985 A44C0000 mov dword ptr , eax //2。这里开始又把真实CPU寄存器值放回到VM寄存器的地址
0102DAE8 899D A84C0000 mov dword ptr , ebx
0102DAEE 898D AC4C0000 mov dword ptr , ecx
0102DAF4 8995 B04C0000 mov dword ptr , edx
0102DAFA 89B5 B44C0000 mov dword ptr , esi
0102DB00 89BD B84C0000 mov dword ptr , edi
0102DB06 83C4 04 add esp, 4
0102DB09 89A5 C04C0000 mov dword ptr , esp
0102DB0F 83EC 04 sub esp, 4
0102DB12 8BC5 mov eax, ebp
0102DB14 5D pop ebp

由上1,2,3点注释可以看出,被偷的第3句代码是 call 010127C8

第4次循环代码

0102E41A 53 push ebx
0102E41B 6A 01 push 1
0102E41D E8 D3010000 call 0102E5F5
0102E422 5B pop ebx
0102E423 66:8BC3 mov ax, bx
0102E426 8985 A44C0000 mov dword ptr , eax
0102E42C E9 BF010000 jmp 0102E5F0
0102E431 83F8 02 cmp eax, 2
0102E434 75 0B jnz short 0102E441
0102E436 899D A84C0000 mov dword ptr , ebx //停在这里
0102E43C E9 AF010000 jmp 0102E5F0
0102E441 83F8 0C cmp eax, 0C
0102E444 75 16 jnz short 0102E45C
0102E446 53 push ebx
0102E447 6A 02 push 2
0102E449 E8 A7010000 call 0102E5F5
0102E44E 5B pop ebx
0102E44F 8AC3 mov al, bl
0102E451 8985 A84C0000 mov dword ptr , eax
0102E457 E9 94010000 jmp 0102E5F0
0102E45C 83F8 0D cmp eax, 0D

ebx=00000000
ss:=7FFD8000

还记得我们记录的地址吗 这个地址是VM中对应ebx的地址

这条pcode的虚拟机我没怎么仔细看,也不是很明白其中其他跳转的意思,但是执行到这里的意思就是把0放到vm的ebx中去
我本来以为是mov ebx, 0 但是发现mov ebx, 0字节数太多了,入口点不够,所以就换成了xor ebx,ebx,结果一看XP自带的计算器,果然是xor ebx, ebx ^_^!!~~~~

所以被偷的第4句是xor ebx,ebx


第5次循环代码

0102E643 /75 12 jnz short 0102E657
0102E645 |8B9D A44C0000 mov ebx, dword ptr
0102E64B |8BC3 mov eax, ebx
0102E64D |33DB xor ebx, ebx
0102E64F |66:8BD8 mov bx, ax
0102E652 |E9 7B010000 jmp 0102E7D2
0102E657 \83F8 02 cmp eax, 2
0102E65A 75 0B jnz short 0102E667
0102E65C 8B9D A84C0000 mov ebx, dword ptr //停在这里
0102E662 E9 6B010000 jmp 0102E7D2
0102E667 83F8 0C cmp eax, 0C
0102E66A 75 11 jnz short 0102E67D
0102E66C 8B9D A84C0000 mov ebx, dword ptr
0102E672 8BC3 mov eax, ebx
0102E674 33DB xor ebx, ebx
0102E676 8AD8 mov bl, al
0102E678 E9 55010000 jmp 0102E7D2
0102E67D 83F8 0D cmp eax, 0D

ss:=00000000
ebx=010128E2 (calc.010128E2)

把vm中ebx的值放回到ebx中去

0102E7CD 33DB xor ebx, ebx
0102E7CF 66:8BD8 mov bx, ax
0102E7D2 5D pop ebp
0102E7D3 8BC3 mov eax, ebx //ebx放到eax中去
0102E7D5 C9 leave
0102E7D6 C2 0400 retn 4

0102E7DB /75 02 jnz short 0102E7DF
0102E7DD |8BCD mov ecx, ebp
0102E7DF \55 push ebp
0102E7E0 8BEC mov ebp, esp
0102E7E2 8B45 08 mov eax, dword ptr
0102E7E5 8907 mov dword ptr , eax //停在这里
0102E7E7 6A FC push -4
0102E7E9 6A 08 push 8
0102E7EB E8 4EFBFFFF call 0102E33E
0102E7F0 C9 leave
0102E7F1 C2 0400 retn 4
0102E7F4 0BC9 or ecx, ecx
0102E7F6 75 02 jnz short 0102E7FA
0102E7F8 8BCD mov ecx, ebp
0102E7FA 55 push ebp
0102E7FB 8BEC mov ebp, esp
0102E7FD FF75 08 push dword ptr

eax=00000000
ds:=00000000

把eax放到栈顶,eax来自ebx ebx来自VM中的ebx,所以被偷的第5句是push ebx

这5句一共是

push 70
push 010015E0
call 010127C8
xor ebx,ebx
push ebx

补上,运行正常

因为虚拟机的其他部分这个软件没用到,所以没研究过

--------------------------------------------------------------------------------
【经验总结】
第一次写文章,写的不好,大家见谅,写的不对的,希望大家多多包涵。

--------------------------------------------------------------------------------
【版权声明】: 转载请注明作者并保持文章的完整, 谢谢!

Hmily 发表于 2008-7-21 22:00

强文,学习~!

kissy 发表于 2008-7-21 22:25

转载而已 不过的确是篇好文

mycsy 发表于 2008-7-21 21:45

【保护方式】: 代码变形,VM,OEP偷取

强悍 。。。。

膜拜大牛! 顶起

ximo 发表于 2008-7-21 20:56

这教程太强大了,学习一下

zx278212442 发表于 2008-7-21 20:55

沙发~
好复杂的东西~!
看不懂,但是还要支持楼主大大!~

kissy 发表于 2008-7-21 22:26

变形代码放的变形的代码在如

004B0000D5 17 00 00 10 00 00 00 48 4A 01 00 DA 17 00 00?.....HJ.?..
004B001001 00 00 00 5C 12 00 00 FE 17 00 00 02 00 00 00...\..?.....
004B00202C 11 00 00 0D 18 00 00 02 00 00 00 28 11 00 00,........(..
004B003018 18 00 00 02 00 00 00 24 11 00 00 36 18 00 00.....$..6..
004B004002 00 00 00 20 11 00 00 34 1A 00 00 15 00 00 00... ..4.....
004B00504D 18 00 00 39 1A 00 00 10 00 00 00 2C 40 01 00M..9.....,@.
004B006040 1A 00 00 01 00 00 00 2C 40 01 00 48 1A 00 00@.....,@.H..
004B007010 00 00 00 38 40 01 00 4D 1A 00 00 01 00 00 00...8@.M.....
004B0080C0 12 00 00 55 1A 00 00 10 00 00 00 00 40 01 00?..U......@.
004B00905A 1A 00 00 01 00 00 00 AC 12 00 00 5F 1A 00 00Z.....?.._..

每处变形的代码也分3个DWORD第一个是要变形的原代码的位置第2个是变形的ID第3个是变形时所用到的参数

如004B0000D5 17 00 00 10 00 00 00 48 4A 01 00 这是变形的第一句

这句变形的原代码位置在0017D5 + 01000000 = 010017D5变形的ID是10对照我的分析结果 可以知道是mov eax,

参数是00104A48所以这句变形的代码原来是在010017D5这个地址指令是mov eax,

具体的分析如下:

0102CBE6837F 04 10cmp dword ptr , 10; 分支:比较是否等于10
0102CBEA74 0C jeshort 0102CBF8
0102CBEC837F 04 16cmp dword ptr , 16; 分支:比较是否等于16
0102CBF072 7F jbshort 0102CC71
0102CBF2837F 04 19cmp dword ptr , 19; 分支:比较是否等于19
0102CBF677 79 jashort 0102CC71
0102CBF88B9D 5B4D0000 mov ebx, dword ptr
0102CBFE66:C706 FF35mov word ptr , 35FF //10这个ID跳下来 代码变形开始在这句
0102CC038946 02 mov dword ptr , eax
0102CC06C746 06 8134240>mov dword ptr , 243481
0102CC0D895E 09 mov dword ptr , ebx
0102CC10C646 0D E8mov byte ptr , 0E8
0102CC148D5E 0D lea ebx, dword ptr
0102CC178BC2mov eax, edx
0102CC192BC3sub eax, ebx

ds:=0000
就是 就是010017D5这地址代码变形出来放在 中可以在数据窗口中跟随看下变形后的代码

00E500149Cpushfd
00E50015FF35 484A0101 pushdword ptr //A
00E5001B813424 0000694E xor dword ptr , 4E690000 //第1句对变形后的数据进行加密
00E50022E8 D9FFFFFF call00E50000//第2句 里放的函数就是把第1句加密后的数据进行还原说白了就是还原到A这个位置的数据
00E5002758pop eax
00E500289Dpopfd
00E50029- E9 AC171B00 jmp calc.010017DA

所以这个代码变形后的指令其实是
pushdword ptr
pop eax
jmp calc.010017DA

合并第1句和第2句不就是mov eax, 01014A48不就是第3个DWORD的值吗

我2进制粘贴后这个位置的代码是

0102CBE4 /74 12 jeshort 0102CBF8
0102CBE6 |837F 04 10cmp dword ptr , 10; 分支:比较是否等于10
0102CBEA |74 0C jeshort 0102CBF8
0102CBEC |837F 04 16cmp dword ptr , 16; 分支:比较是否等于16
0102CBF0 |72 7F jbshort 0102CC71
0102CBF2 |837F 04 19cmp dword ptr , 19; 分支:比较是否等于19
0102CBF6 |77 79 jashort 0102CC71
0102CBF8 \56pushesi
0102CBF93E:8B7424 04mov esi, dword ptr ds:
0102CBFE837F 04 07cmp dword ptr , 7
0102CC0275 29 jnz short 0102CC2D
0102CC0466:C706 8B0Dmov word ptr , 0D8B
0102CC09EB 56 jmp short 0102CC61
0102CC0B837F 04 16cmp dword ptr , 16
0102CC0F75 28 jnz short 0102CC39
0102CC1166:C706 8B1Dmov word ptr , 1D8B
0102CC16EB 49 jmp short 0102CC61
0102CC1890nop
0102CC192BC3sub eax, ebx
0102CC1B83E8 05 sub eax, 5
0102CC1E8946 0E mov dword ptr , eax
0102CC21837F 04 07cmp dword ptr , 7 ; 分支:比较是否等于7
0102CC2575 06 jnz short 0102CC2D
0102CC27C646 12 59mov byte ptr , 59
0102CC2BEB 3A jmp short 0102CC67
0102CC2D837F 04 10cmp dword ptr , 10; 分支:比较是否等于10
0102CC31^ 75 D8 jnz short 0102CC0B
0102CC33C606 A1 mov byte ptr , 0A1
0102CC3690nop
0102CC37EB 2E jmp short 0102CC67
0102CC39837F 04 17cmp dword ptr , 17; 分支:比较是否等于16
0102CC3D75 07 jnz short 0102CC46
0102CC3F66:C706 8B15mov word ptr , 158B
0102CC44EB 1B jmp short 0102CC61
0102CC46837F 04 18cmp dword ptr , 18
0102CC4A75 07 jnz short 0102CC53
0102CC4C66:C706 8B35mov word ptr , 358B
0102CC51EB 0E jmp short 0102CC61 ; 分支:比较是否等于18
0102CC53837F 04 19cmp dword ptr , 19
0102CC5775 13 jnz short 0102CC6C
0102CC5966:C706 8B3Dmov word ptr , 3D8B
0102CC5EEB 01 jmp short 0102CC61
0102CC6090nop
0102CC618946 02 mov dword ptr , eax
0102CC645Epop esi
0102CC65EB 05 jmp short 0102CC6C
0102CC678946 01 mov dword ptr , eax
0102CC6A5Epop esi
0102CC6B90nop
0102CC6CE9 69040000 jmp <分支出口1>

这段代码的含义就是直接把 mov eax, 这句写回到010017D5其他几个ID同理得出这样就还原了变形的代码绕开了代码变形

1A:add eax, xxxxxxxx
1B:sub eax, xxxxxxxx
1C:xor eax, xxxxxxxx
1D:or eax, xxxxxxxx
1E:add ebx, xxxxxxxx
1F:sub ebx, xxxxxxxx
20:xor ebx, xxxxxxxx
21:or ebx, xxxxxxxx
22:add ecx, xxxxxxxx
23:sub ecx, xxxxxxxx
24:xor ecx, xxxxxxxx
25:or ecx, xxxxxxxx
26:add edx, xxxxxxxx
27:sub edx, xxxxxxxx
28:xor edx, xxxxxxxx
29:or edx, xxxxxxxx
2A:add esi, xxxxxxxx
2B:sub esi, xxxxxxxx
2C:xor esi, xxxxxxxx
2D:or esi, xxxxxxxx
2E:add edi, xxxxxxxx
2F:sub edi, xxxxxxxx
30:xor edi, xxxxxxxx
31:or edi, xxxxxxxx

这部分的会有一个函数call

00E5077D50pusheax
00E5077E83EC 04 sub esp, 4
00E50781C70424 0000394E mov dword ptr , 4E390000
00E50788E8 73F8FFFF call00E50000
00E5078D50pusheax
00E5078EA1 0000F97F mov eax, dword ptr
00E50793314424 04 xor dword ptr , eax
00E50797B8 04000000 mov eax, 4
00E5079CE8 73F8137F call7FF90014
00E507A158pop eax
00E507A283C4 04 add esp, 4
00E507A558pop eax
00E507A6FF35 1000F97F pushdword ptr
00E507AC9Dpopfd
00E507AD- E9 14141B00 jmp calc.01001BC6

这是其中一个1D指令生成的
关键在
00E50797B8 04000000 mov eax, 4
00E5079CE8 73F8137F call7FF90014这两句

4是1D - 19 = 4这部分变形是
0102D004 /EB 04 jmp short 0102D00A
0102D006 |836E 1B 04sub dword ptr , 4//是ID号
0102D00A \837E 1B 04cmp dword ptr , 4
0102D00E^ 77 F6 jashort 0102D006

就是说 这个值只能是从1-41是ADD2是SUB3是XOR4是OR这个可以从7FF90014得出

7FF9005983F8 01 cmp eax, 1//如果是1
7FF9005C75 0A jnz short 7FF90068
7FF9005E9Dpopfd
7FF9005F90nop
7FF9006003CBadd ecx, ebx//ADD指令
7FF90062894C24 2C mov dword ptr , ecx
7FF90066EB 2B jmp short 7FF90093
7FF9006883F8 02 cmp eax, 2// 是2
7FF9006B75 0A jnz short 7FF90077
7FF9006D9Dpopfd
7FF9006E90nop
7FF9006F2BCBsub ecx, ebx//SUB
7FF90071894C24 2C mov dword ptr , ecx
7FF90075EB 1C jmp short 7FF90093
7FF9007783F8 03 cmp eax, 3 //是3
7FF9007A75 0A jnz short 7FF90086
7FF9007C9Dpopfd
7FF9007D90nop
7FF9007E33CBxor ecx, ebx //XOR
7FF90080894C24 2C mov dword ptr , ecx
7FF90084EB 0D jmp short 7FF90093
7FF9008683F8 04 cmp eax, 4//是4
7FF9008975 08 jnz short 7FF90093
7FF9008B9Dpopfd
7FF9008C90nop
7FF9008D0BCBorecx, ebx //OR
7FF9008F894C24 2C mov dword ptr , ecx
7FF900939Cpushfd
7FF900948F46 10 pop dword ptr

00E5077D50pusheax //从这个看出是EAX参与运算的
00E507A558pop eax从这句可以看出这个最后值是放在EAX的

所以才得出上面的的变形列表修复同上

qwsk 发表于 2012-8-3 16:43

支持楼主大大!~

晨臭臭 发表于 2013-3-14 21:33

怎么感觉就是看不懂呢???

fuqiangd 发表于 2013-8-2 13:48

太麻烦了 不知道软件简单操作不
页: [1]
查看完整版本: RLPack1.21加壳calc.exe脱壳过程