脱壳 SLVcodeProtector v1.12 (全保护)

admin 2024年4月1日11:48:30评论4 views字数 5381阅读17分56秒阅读模式

工具:OllyDbg 1.10 , ImpREC , LordPE

SLVcodeProtector v1.12 :

  • 偷 OEP 代码

  • 多态保护

  • IAT 加密

  • 自身 CRC 检测

用 LordPE 改变 NumOfRvaAndSizes(40-->10)

我们用 OD 载入加壳程序时,会提示错误,那是因为壳改变了 NumOfRvaAndSizes,所以我们需要将他改为10,如图所示 :

脱壳 SLVcodeProtector v1.12 (全保护)

然后保存,现在用 OD 载入正常了。 

脱壳

  1. 打开 OD 忽略所有异常,载入程序,点击确定。 

脱壳 SLVcodeProtector v1.12 (全保护)

  1. 来到程序的入口点:

00401000 E8 00000000 call Protect.00401005
00401005 58 pop eax
00401006 C600 EB mov byte ptr ds:[eax],0EB
00401009 C640 01 08 mov byte ptr ds:[eax+1],8
0040100D FFE0 jmp eax
0040100F E9 52D00000 jmp Protect.0040E066
00401014 C2 33BC retn 0BC33
  1. 用 ESP 定律找 CRC 检测

  • F7 来到 pop eax,观察寄存器窗口的 ESP 值变化了,所以现在对 ESP 下硬件访问断点, Shift+F9 来到这里:

0040E0A9 60 pushad
0040E0AA C1EB E5 shr ebx,0E5 ;停在这里
0040E0AD 81C3 D88DE433 add ebx,33E48DD8
0040E0B3 03E9 add ebp,ecx
0040E0B5 83C5 01 add ebp,1
  • 我们观察到 ESP 的值变为 0012FFA4,所以我们需要删除前面的硬件断点, 重新对 ESP 下硬件访问断点。同时我们在反汇编窗口中 Ctrl+G 搜索:VirtualAlloc 函数,并在函数结尾处 Retn 10 下 F2 断点:

7C809AF1 8BFF mov edi,edi
7C809AF3 55 push ebp
7C809AF4 8BEC mov ebp,esp
7C809AF6 FF75 14 push dword ptr ss:[ebp+14]
7C809AF9 FF75 10 push dword ptr ss:[ebp+10]
7C809AFC FF75 0C push dword ptr ss:[ebp+C]
7C809AFF FF75 08 push dword ptr ss:[ebp+8]
7C809B02 6A FF push -1
7C809B04 E8 09000000 call kernel32.VirtualAllocEx
7C809B09 5D pop ebp
7C809B0A C2 1000 retn 10 ;在这里下 F2 断点
  • Shift+F9 运行,来到 retn 10,然后移除 F2 断点, F8 单步一下,来到这里:

0040E353 8BD0 mov edx,eax
0040E355 EB 04 jmp short Protect.0040E35B
0040E357 0000 add byte ptr ds:[eax],al
0040E359 0000 add byte ptr ds:[eax],al
  • F8 一小会,来到这里:

0040E3A7 3BC2 cmp eax,edx
0040E3A9 74 08 je short Protect.0040E3B3 ;将 je 改为 jmp
0040E3AB 6A 00 push 0
0040E3AD FF95 A62C4000 call dword ptr ss:[ebp+402CA6]

此时我们注意寄存器窗口 EAX 和 EDX 的值:

EAX ED58920E
ECX 00000000
EDX E7421FFA

CMP EAX,EDX 是比较原始的 CRC 和新的 CRC, EDX 是正确的 CRC and EAX 是我们新的 CRC, 如果 EAX 和 EDX相等, 则 CRC 正确, 否则 CRC 错误, 并且 后面程序就直接调用 ExitProcess 函数退出, 所以我们需要将JE 改为 JMP,这样就可以通过 CRC 检测. 现在 Ctrl+F 查找第二个 CRC 检测:

call dword ptr ss:[ebp+402CA6];我们会停在0040E49E 这里:
0040E49A 0BC0 or eax,eax
0040E49C 74 06 je short Protect.0040E4A4 ;将 je 改为 jmp0040E49E |FF95 A62C4000 call dword ptr ss:[ebp+402CA6]

同样的我们需要将 je 改为 jmp,

  1. 找 Magic jmp

  • Ctrl+B 搜索:FF 25 ,来到这里:

0040EE6C 66:3D FF25 cmp ax,25FF
0040EE70 E0 F8 loopdne short Protect.0040EE6A
0040EE72 74 02 je short Protect.0040EE76 ;这里就是 Magic jmp,将 je 用90 nop 掉
0040EE74 EB 31 jmp short Protect.0040EEA7
  • 现在再次下 VirtualAlloc 断点, Shift+F9,来到函数断点:

7C809AF1 8BFF mov edi,edi //删除函数断点
7C809AF3 55 push ebp
7C809AF4 8BEC mov ebp,esp
7C809AF6 FF75 14 push dword ptr ss:[ebp+14]
7C809AF9 FF75 10 push dword ptr ss:[ebp+10]
7C809AFC FF75 0C push dword ptr ss:[ebp+C]
7C809AFF FF75 08 push dword ptr ss:[ebp+8]
7C809B02 6A FF push -1
7C809B04 E8 09000000 call kernel32.VirtualAllocEx
7C809B09 5D pop ebp
7C809B0A C2 1000 retn 10
  • ALT+F9 返回到用户代码:

0040EA32 8907 mov dword ptr ds:[edi],eax
0040EA34 EB 01 jmp short Protect.0040EA37
0040EA36 6989 47045EE9 Eimul ecx,dword ptr ds:[ecx+E95E0447],1E9
0040EA40 8B1E mov ebx,dword ptr ds:[esi]
0040EA42 81C3 00004000 add ebx,Protect.00400000
  • 我们现在来找一下 E8 型的 CALL,Ctrl+B:E8 ?? 00 00 00

0040EB76 E8 25000000 call Protect.0040EBA0 ;下 F2 断点, Shift+f9 来到这里
0040EB7B 95 xchg eax,ebp
0040EB7C E8 0D000000 call Protect.0040EB8E
0040EB81 59 pop ecx
0040EB82 E8 01000000 call Protect.0040EB88
  • 删除断点, F7 一会儿来到 0040EBB2 这里:

0040EBB2 83F0 01 xor eax,1
0040EBB5 EB 01 jmp short Protect.0040EBB8
0040EBB7 40 inc eax
0040EBB8 83F0 01 xor eax,1

现在我们注意寄存器窗口 EAX 是 API:EAX 7D611170 shell32.ShellExecuteA

ECX 004063C4 ASCII "Td"
EDX 004060C4 Protect.004060C4
EBX 7D590000 offset shell32.#599
ESP 0012FB84
EBP 0000C609
ESI 00910000
EDI 0040F5EF Protect.0040F5EF

因为 EDX 里面存放的是 API,所以在这里我们需要将 EAX 的值放到 EDX 里面,我们将xor eax,1 改为 mov [edx],eax修改之后:

0040EBB0 8F02 pop dword ptr ds:[edx]
0040EBB2 8902 mov dword ptr ds:[edx],eax ; shell32.ShellExecuteA
0040EBB4 90 nop
0040EBB5 EB 01 jmp short Protect.0040EBB8

OK, IAT 现在处理完了

  1. 找 Stolen Code OEP

  • 现在你可以打开硬件断点,看看是否还有一个 0012FFA4 断点,还在吧,现在我们 Shift+F9,来到这里:

0040E58E 83C4 0C add esp,0C
0040E591 F71424 not dword ptr ss:[esp]
0040E594 68 92484000 push Protect.00404892
0040E599 B8 F8544000 mov eax,Protect.004054F8
0040E59E FFD0 call eax
0040E5A0 68 77794000 push Protect.00407977
0040E5A5 6A 01 push 1
0040E5A7 6A 00 push 0
0040E5A9 B8 80544000 mov eax,Protect.00405480
0040E5AE FFD0 call eax
0040E5B0 B8 AA544000 mov eax,Protect.004054AA
0040E5B5 FFD0 call eax
0040E5B7 35 B7000000 xor eax,0B7
0040E5BC 60 pushad
0040E5BD 9C pushfd

上面绿色标记的部分就是被偷的 OEP 代码将他们的二进制代码复制:

68 92 48 40 00 B8 F8 54 40 00 FF D0 68 77 79 40 00 6A 01 6A 00 B8 80 54 40 00 FF D0 B8 AA 54 40
00 FF D0 35 B7 00 00 00

第一个地址 0040E594 是 push Protect.00404892,所以我们需要 Ctrl+G 搜索:00404892,来到这里:

00404892 6A 10 push 10
00404894 68 70794000 push Protect.0040797000404899 68 57794000 push Protect.00407957
0040489E 6A 00 push 0
004048A0 E8 D70C0000 call Protect.0040557C
004048A5 6A FF push -1
004048A7 E8 E60B0000 call Protect.00405492
004048AC C3 retn
004048AD 90 nop
004048AE 90 nop
004048AF 90 nop
004048B0 90 nop
004048B1 90 nop
004048B2 90 nop
004048B3 90 nop
004048B4 90 nop
004048B5 90 nop
004048B6 90 nop
004048B7 90 nop
004048B8 90 nop
004048B9 90 nop
004048BA 90 nop
004048BB 90 nop
004048BC 90 nop
004048BD 90 nop
004048BE 90 nop
004048BF 90 nop
004048C0 90 nop
004048C1 90 nop
004048C2 90 nop
004048C3 90 nop
004048C4 90 nop
004048C5 90 nop
004048C6 90 nop
004048C7 90 nop
004048C8 90 nop
004048C9 90 nop
004048CA 90 nop
004048CB 90 nop
004048CC 90 nop
004048CD 90 nop
004048CE 90 nop

我们注意到上面的 nop(90)共有 34 个字节,二我们被偷代码共有 40 个字节,那么怎么装得下呢???当然这里大家可能会想到,我们可以找一块可用空地,将这段代码复制过去,再有 jmp 指令跳转回来,这种办法也是可行的,但是我们在注意一下我们被偷的 OEP 是不是被多态引擎处理了:

0040E594 68 92484000 push Protect.00404892
0040E599 B8 F8544000 mov eax,Protect.004054F8
0040E59E FFD0 call eax
0040E5A0 68 77794000 push Protect.00407977
0040E5A5 6A 01 push 1
0040E5A7 6A 00 push 0
0040E5A9 B8 80544000 mov eax,Protect.00405480
0040E5AE FFD0 call eax
0040E5B0 B8 AA544000 mov eax,Protect.004054AA
0040E5B5 FFD0 call eax
0040E5B7 35 B7000000 xor eax,0B7

上面的

mov eax,xxxxxxx
Call eax

是不是就是 call xxxxx 的变化呀???

我们将上面的这几句转换为下面的结构

push 00404892
Call 004054F8
push 00407977
push 1
push 0
Call 00405480
Call 004054AA
xor eax,0B7

二进制代码:

68 92 48 40 00 E8 41 0C 00 00 68 77 79 40 00 6A 01 6A 00 E8 BB 0B 00 00 E8 E0 0B 00 00 35 B7 00
00 00

然后将上面的二进制代码复制到 004048AD 。在 004048AD 处新建 EIP.5.Dump and Rebuild IAT

  • 用 LordPE DUMP 程序

  • 用 ImpREC 修复

  • 运行修复之后的程序,发现能运行

====

本文所示的技术 仅供学习研究安全技术使用 请勿做其他用途

学习参考:Tortoiser脱壳培训学习笔记

原文始发于微信公众号(0x00实验室):脱壳 SLVcodeProtector v1.12 (全保护)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年4月1日11:48:30
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   脱壳 SLVcodeProtector v1.12 (全保护)http://cn-sec.com/archives/2618993.html

发表评论

匿名网友 填写信息