Enigma Protector脱壳

标 题: 【原创】Enigma Protector脱壳
作 者: smokewind
时 间: 2011-09-27,00:19:36
链 接: http://bbs.pediy.com/showthread.php?t=140629

【文章标题】: Enigma Protector脱壳

【文章作者】: Smoke
【编写语言】: delphi7
【操作平台】: windows xp sp3
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  Enigma Protector脱壳
  OllyDBG插件 PhantOm
  勾住protect DRx 选项 来方便下断点
  设置完毕后重新载入OllyDBG
   0041A3DA >  55              push    ebp
  0041A3DB    8BEC            mov     ebp, esp
  0041A3DD    83C4 F0         add     esp, -10
  0041A3E0    B8 00104000     mov     eax, 00401000
  0041A3E5    E8 01000000     call    0041A3EB
  0041A3EA    9A 83C4108B E55>call    far 5DE5:8B10C483
  0041A3F1  - E9 A2910900     jmp     004B3598
  0041A3F6  ^ E0 D9           loopdne short 0041A3D1
用二次断点
 Ctrl+G 输入 VirtualAlloc
7C809AE1 > 8BFF mov edi, edi
7C809AE3 55 push ebp
7C809AE4 8BEC mov ebp, esp
7C809AE6 FF75 14 push dword ptr [ebp+14]
7C809AE9 FF75 10 push dword ptr [ebp+10]
7C809AEC FF75 0C push dword ptr [ebp+C]
7C809AEF FF75 08 push dword ptr [ebp+8]
7C809AF2 6A FF push -1
7C809AF4 E8 09000000 call VirtualAllocEx //F2下断 F9运行 断下之后在到数据窗口 到401000 处下硬件写入断点 找解码处
7C809AF9 5D pop ebp

下面应该就是解码过程了
005502AF FC cld
005502B0 B2 80 mov dl, 80
005502B2 8A06 mov al, byte ptr [esi]
005502B4 46 inc esi
005502B5 8807 mov byte ptr [edi], al
005502B7 47 inc edi ; UnpackMe.00401000
005502B8 00D2 add dl, dl
005502BA 75 05 jnz short 005502C1
005502BC 8A16 mov dl, byte ptr [esi]
005502BE 46 inc esi
005502BF 10D2 adc dl, dl
005502C1 ^ 73 EF jnb short 005502B2

往下拉 来到
005503C8 F3:A4 rep movs byte ptr es:[edi], byte ptr>
005503CA 5E pop esi
005503CB ^ E9 E8FEFFFF jmp 005502B8
005503D0 5D pop ebp
005503D1 2B7D 40 sub edi, dword ptr [ebp+40]
005503D4 897C24 1C mov dword ptr [esp+1C], edi
005503D8 61 popad
005503D9 5D pop ebp
005503DA C3 retn //F2下断 F9运行 发现数据窗口已经解码完了

接下来就来找OEP
 跟随到00401000 搜索特征码 A3??????00A1??????00A3??????0033C0A3??????0033C0A3??????00 (delphi程序的第一个call)
 来到以下地方
00405BC8 53 push ebx 第一个call
00405BC9 8BD8 mov ebx, eax
00405BCB 33C0 xor eax, eax
00405BCD A3 9CD04400 mov dword ptr [44D09C], eax
00405BD2 6A 00 push 0
00405BD4 E8 FF4A0000 call 0040A6D8 第一个函数
00405BD9 A3 64F64400 mov dword ptr [44F664], eax
00405BDE A1 64F64400 mov eax, dword ptr [44F664]
00405BE3 A3 A8D04400 mov dword ptr [44D0A8], eax
00405BE8 33C0 xor eax, eax
00405BEA A3 ACD04400 mov dword ptr [44D0AC], eax
00405BEF 33C0 xor eax, eax
00405BF1 A3 B0D04400 mov dword ptr [44D0B0], eax

ALT+M在
Memory map, 条目 22
地址=00401000
大小=0004C000 (311296.)
属主=UnpackMe 00400000
区段=
包含=SFX,代码
类型=Imag 01001002
访问=R
初始访问=RWE
下内存写入断点 F9运行
删除内存断点 来到

0055026B 294C0F 01 sub dword ptr [edi+ecx+1], ecx
0055026F 83C1 05 add ecx, 5
00550272 83E8 04 sub eax, 4
00550275 ^ EB D7 jmp short 0055024E
00550277 29540F 02 sub dword ptr [edi+ecx+2], edx
0055027B 83C1 06 add ecx, 6
0055027E 83EA 04 sub edx, 4
00550281 83E8 05 sub eax, 5
00550284 ^ EB C8 jmp short 0055024E
00550286 61 popad
00550287 5D pop ebp
00550288 C2 0800 retn 8
0055028B 90 nop

00550281 83E8 05 sub eax, 5
00550284 ^ EB C8 jmp short 0055024E
00550286 61 popad
00550287 5D pop ebp
00550288 C2 0800 retn 8 //F2下断 F9运行

继续来到
00405BC8 53 push ebx
00405BC9 8BD8 mov ebx, eax
00405BCB 33C0 xor eax, eax
00405BCD A3 9CD04400 mov dword ptr [44D09C], eax
00405BD2 6A 00 push 0
00405BD4 E8 2BFFFFFF call 00405B04 //F7跟进
00405BD9 A3 64F64400 mov dword ptr [44F664], eax
00405BDE A1 64F64400 mov eax, dword ptr [44F664]
00405BE3 A3 A8D04400 mov dword ptr [44D0A8], eax

来到
00405B04 FF25 E4014500 jmp dword ptr [4501E4]
00405B0A 8BC0 mov eax, eax
00405B0C FF25 E0014500 jmp dword ptr [4501E0]
00405B12 8BC0 mov eax, eax
00405B14 FF25 DC014500 jmp dword ptr [4501DC]
00405B1A 8BC0 mov eax, eax
00405B1C FF25 D8014500 jmp dword ptr [4501D8]
发现已经解密完毕 不再是开始那样

返回EIP
搜索特征码 ctrl+F
mov dword ptr ds:[edx+eax*4+4],ecx
把找到的特征码全部下硬件执行断点
搜索完及下完硬件点段后 直接F9
把找到的地方nop掉
0054C9EA 90 nop
0054C9EB 90 nop
0054C9EC 90 nop
0054C9ED 90 nop

删掉0054C9EA硬件执行断点


0054C9F8 33C0 xor eax, eax //F2下断 F9运行
0054C9FA 5A pop edx
0054C9FB 59 pop ecx
0054C9FC 59 pop ecx
撤消0054C9EA修改后的代码 并下硬件执行断点

来到OEP发现有些函数已经解密了
重新载入OllyDBG
硬件执行断点都在
F9运行 来到

0054C9EA 894C82 04 mov dword ptr [edx+eax*4+4], ecx 
0054C9EE 47 inc edi
0054C9EF FF4D D0 dec dword ptr [ebp-30]
先nop填充掉
0054C9EA 90 nop
0054C9EB 90 nop
0054C9EC 90 nop
0054C9ED 90 nop

删除硬件断点
0054C9F8    33C0            xor     eax, eax  //F2下断 F9运行
在0054C9F8断下后 撤销0054C9EA修改后的代码 重新下硬件执行断点 再F9 
来到

0054BDBD 894C82 04 mov dword ptr [edx+eax*4+4], ecx ; UnpackMe.0054E204
0054BDC1 83C3 04 add ebx, 4
0054BDC4 66:8B3B mov di, word ptr [ebx]
nop掉 
0054BDBD 90 nop
0054BDBE 90 nop
0054BDBF 90 nop
0054BDC0 90 nop

删除硬件断点 0054BDBD
往下拉 来到
0054BE30 83F8 FF cmp eax, -1
0054BE33 ^ 0F85 24FDFFFF jnz 0054BB5D
0054BE39 33C0 xor eax, eax //F2下断 F9运行
0054BE3B 5A pop edx

断下之后取消断点 撤销修改的地方0054BDBD 并下硬件执行断点 再F9
来到
0054C9EA 894C82 04 mov dword ptr [edx+eax*4+4], ecx

继续重复上一次操作 
取消掉硬件执行断点 004EF086  0054BC97
跟随到00405BC8 下个硬件执行断点 F9运行
来到

00405BC8 53 push ebx
00405BC9 8BD8 mov ebx, eax
00405BCB 33C0 xor eax, eax
00405BCD A3 9CD04400 mov dword ptr [44D09C], eax
00405BD2 6A 00 push 0
00405BD4 E8 2BFFFFFF call 00405B04 ; jmp 到 kernel32.GetModuleHandleA //F7跟进
00405BD9 A3 64F64400 mov dword ptr [44F664], eax
00405BDE A1 64F64400 mov eax, dword ptr [44F664]
 
00405AD6 /EB 20 jmp short 00405AF8
00405AD8 |E8 9FB7FFFF call 0040127C ; jmp 到 kernel32.GetThreadLocale
00405ADD |E8 86FEFFFF call 00405968
00405AE2 |A3 BCF54400 mov dword ptr [44F5BC], eax
00405AE7 |EB 0F jmp short 00405AF8
00405AE9 |E8 8EB7FFFF call 0040127C ; jmp 到 kernel32.GetThreadLocale
00405AEE |E8 75FEFFFF call 00405968
00405AF3 |A3 BCF54400 mov dword ptr [44F5BC], eax
00405AF8 \E8 FFB7FFFF call 004012FC ; jmp 到 kernel32.GetCurrentThreadId
00405AFD A3 30F04400 mov dword ptr [44F030], eax
00405B02 C3 retn
00405B03 90 nop
00405B04 - FF25 646FC600 jmp dword ptr [C66F64] ; kernel32.GetModuleHandleA
00405B0A 8BC0 mov eax, eax
00405B0C - FF25 586FC600 jmp dword ptr [C66F58] ; kernel32.LocalAlloc
00405B12 8BC0 mov eax, eax
00405B14 - FF25 4C6FC600 jmp dword ptr [C66F4C] ; kernel32.TlsGetValue
00405B1A 8BC0 mov eax, eax
00405B1C - FF25 406FC600 jmp dword ptr [C66F40] ; kernel32.TlsSetValue
看到函数已经解密了

CPU窗口跟随到00C37CA0
来到

00C37C86 0000 add byte ptr [eax], al
00C37C88 0000 add byte ptr [eax], al
00C37C8A 0000 add byte ptr [eax], al
00C37C8C BA 00000055 mov edx, 55000000
00C37C91 8BEC mov ebp, esp
00C37C93 83C4 F0 add esp, -10
00C37C96 B8 B8C84400 mov eax, 44C8B8
00C37C9B E8 28DF7CFF call UnpackMe.00405BC8
00C37CA0 8B05 B8DF4400 mov eax, dword ptr [44DFB8] ; UnpackMe.0044FBB0
00C37CA6 8B40 00 mov eax, dword ptr [eax]
00C37CA9 E8 A23481FF call UnpackMe.0044B150
00C37CAE 8B0D 94E04400 mov ecx, dword ptr [44E094] ; UnpackMe.0044FBD0
00C37C8C BA 00000055 mov edx, 55000000 //nop掉
00C37C90 90 nop //撤销修改代码

复制保存
push ebp
mov ebp, esp
add esp, -10
mov eax, 44C8B8
call UnpackMe.00405BC8
mov eax, dword ptr [44DFB8]
mov eax, dword ptr [eax]
call UnpackMe.0044B150
mov ecx, dword ptr [44E094]
mov eax, dword ptr [44DFB8]
mov eax, dword ptr [eax]
mov edx, dword ptr [44C6F0]
call UnpackMe.0044B168
mov eax, dword ptr [44DFB8]
mov eax, dword ptr [eax]
call UnpackMe.0044B1E8
call UnpackMe.00403D20
lea eax, dword ptr [eax]

返回到eip
00405BC8 53 push ebx
00405BC9 8BD8 mov ebx, eax
00405BCB 33C0 xor eax, eax
00405BCD A3 9CD04400 mov dword ptr [44D09C], eax
00405BD2 6A 00 push 0
00405BD4 E8 2BFFFFFF call 00405B04 ; jmp 到 kernel32.GetModuleHandleA
00405BD9 A3 64F64400 mov dword ptr [44F664], eax
00405BDE A1 64F64400 mov eax, dword ptr [44F664]

搜索 558BEC33C05568??????0064FF3064892033C05A595964891068??????00C3E9 (OEP特征码)
来到

0044C890 55 push ebp
0044C891 8BEC mov ebp, esp
0044C893 33C0 xor eax, eax
0044C895 55 push ebp
0044C896 68 AFC84400 push 0044C8AF
0044C89B 64:FF30 push dword ptr fs:[eax]
0044C89E 64:8920 mov dword ptr fs:[eax], esp
继续搜索90C84400
0044CA93 90 nop
0044CA94 90 nop
0044CA95 90 nop
0044CA96 90 nop
0044CA97 90 nop
0044CA98 51 push ecx //新建EIP
0044CA99 06 push es
0044CA9A 7A 12 jpe short 0044CAAE
0044CA9C 5C pop esp
0044CA9D 42 inc edx
复制刚才保存的代码
push ebp
mov ebp, esp
add esp, -10
mov eax, 44C8B8
call UnpackMe.00405BC8
mov eax, dword ptr [44DFB8]
mov eax, dword ptr [eax]
call UnpackMe.0044B150
mov ecx, dword ptr [44E094]
mov eax, dword ptr [44DFB8]
mov eax, dword ptr [eax]
mov edx, dword ptr [44C6F0]
call UnpackMe.0044B168
mov eax, dword ptr [44DFB8]
mov eax, dword ptr [eax]
call UnpackMe.0044B1E8
call UnpackMe.00403D20
lea eax, dword ptr [eax]
粘贴完毕后为
0044CA98 55 push ebp
0044CA99 8BEC mov ebp, esp
0044CA9B 83C4 F0 add esp, -10
0044CA9E B8 B8C84400 mov eax, 0044C8B8
0044CAA3 E8 2091FBFF call 00405BC8
0044CAA8 A1 B8DF4400 mov eax, dword ptr [44DFB8]
0044CAAD 8B00 mov eax, dword ptr [eax]
0044CAAF E8 9CE6FFFF call 0044B150
0044CAB4 8B0D 94E04400 mov ecx, dword ptr [44E094] ; UnpackMe.0044FBD0
0044CABA A1 B8DF4400 mov eax, dword ptr [44DFB8]
0044CABF 8B00 mov eax, dword ptr [eax]
0044CAC1 8B15 F0C64400 mov edx, dword ptr [44C6F0] ; UnpackMe.0044C73C
0044CAC7 E8 9CE6FFFF call 0044B168
0044CACC A1 B8DF4400 mov eax, dword ptr [44DFB8]
0044CAD1 8B00 mov eax, dword ptr [eax]
0044CAD3 E8 10E7FFFF call 0044B1E8
0044CAD8 E8 4372FBFF call 00403D20
0044CADD 8D00 lea eax, dword ptr [eax]
0044CADF 90 nop

然后即可DUMP 
使用LordPE 选取进程 修正镜像大小 完整转存
再ImportREC 选取进程 oep为 4CA98 RVA为85AEA0 大小为2050
剪切到无效指针 修复转存
脱壳后为Borland Delphi 6.0 - 7.0
正常运行!
--------------------------------------------------------------------------------
【版权声明】: 本文原创于Smoke, 转载请注明作者并保持文章的完整, 谢谢! 
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【文章标题】: 绕过 Enigma Protector 2.xx 注册保护 【文章作者】: CodeGame 【作者邮箱】: CodeGame@Yeah.Net 【作者主页】: http://blog.csdn.net/codegame 【作者QQ号】: 441673604 【软件名称】: windows 计算器 【软件大小】: 669kb 【下载地址】: windows xp 系统自带 【加壳方式】: The Enigma Protector 2.20 正版 【保护方式】: The Enigma Protector 2.20 正版 【编写语言】: VC 【使用工具】: OllyDBG 【操作平台】: Windows XP sp3 【软件介绍】: 1+1=2 【作者声明】: 文笔菜的很请谅解,只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教! -------------------------------------------------------------------------------- 【详细过程】 参考了 http://unpack.cn/thread-59541-1-2.html 定位方式,迅速定位到了 Enigma 注册授权位置: 010F2CBF E8 CC76F3FF call calc_em.0102A390 010F2CC4 8B45 E8 mov eax,dword ptr ss:[ebp-0x18] 010F2CC7 E8 FC78F3FF call calc_em.0102A5C8 010F2CCC 50 push eax 010F2CCD E8 DE90FFFF call calc_em.010EBDB0 ; Check Registration Key Info 010F2CD2 85C0 test eax,eax ; Eax =1 Success! 010F2CD4 0F95C0 setne al 这里010EBDB0 这个CALL负责检测注册码是否正确,正确返回1 否则返回0,由于 Enigma有多线程内联补丁保护因此不能 直接硬写此处代码,所以我们采用了硬件断点HOOK来实现。 1:定位PatchAddress: 先看此块内存信息: 地址=01026000 大小=002F4000 (3096576.) 属主=calc_em 01000000 区段= 类型=Imag 01001002 访问=R 初始访问=RWE 这块内存实际是Enigma的内置DLL授权模块,此块DLL是被加密压缩过,因此也无法直接patch,通过对比加不同的程序 发现这块区域解压后的代码都不变: $+CCCBF > E8 CC76F3FF call calc_em.0102A390 $+CCCC4 > 8B45 E8 mov eax,dword ptr ss:[ebp-0x18] $+CCCC7 > E8 FC78F3FF call calc_em.0102A5C8 $+CCCCC > 50 push eax $+CCCCD > E8 DE90FFFF call calc_em.010EBDB0 ; Check Registration Key Info $+CCCD2 > 85C0 test eax,eax ; Eax =1 Success! $+CCCD4 > 0F95C0 setne al 因此PatchAddress = BaseAddress+PatchOffsetAddress,通过上面分析得到 Enigma Protector 2.20 的 PatchOffsetAddress = 0xCCCD2 ,不同版本的PatchOffsetAddress 有可能不一样,BaseAddress 的获取就更简单了, 直接搜索区段判断VirtualSize为0x002F4000的VirtualAddress+GetModuleHandle(0)即为BaseAddress,整理公式: PatchAddress = GetModuleHandle(0)+VirtualAddress+0xCCCD2 定完毕。 2.硬件Hook: 这里我们采用AddVectoredExceptionHandler向量化异常API来实现,具体细节请自己google,重点讲下Hook触发后的过程 由于我们Patch点为$+CCCD2 > 85C0 test eax,eax ,因此只需要模拟操作EFlags然后跳过此段指令即可: pException^.ContextRecord^.EFlags := $202; //TEST eax,eax pException^.ContextRecord^.Eax := 1; //TEST eax,eax PException^.ContextRecord^.Eip := PException^.ContextRecord^.Eip + 2; //Nex 3.整体封装: 这里我们采用是把硬件HOOK和处理的过程都封装成DLL 然后导出一个GoPatch的函数供目标程序调用,那么如何使目标程序 加载并执行我们的GoPatch函数呢,我想办法很多注入,远线程等等。。这里我采用了劫持EIP的方式使目标程序加载我们的 DLL并执行GoPatch函数。 到这里已经全部完成,执行GoPatch后任意输入或者不输入用户名、注册码都可以直接绕过Enigma 的注册保护直接执行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值