首页
社区
课程
招聘
某ExeCryptor二次加密的软件无KEY脱壳
发表于: 2006-10-23 12:46 13486

某ExeCryptor二次加密的软件无KEY脱壳

2006-10-23 12:46
13486

朋友说有个二次加密的软件需要解决,PEID看一下是EXECryptor 2.X的,论坛上说EXECryptor 2.X无KEY可以脱去的,所以参考了相关文章后写出了过程。运行界面:


一、跳过输入表加密:
EXECryptor专用OD或advancedolly插件设置ANTI-DEBUG后再载入原程序:
0055F2AA    E8 EBFEFFFF     CALL keygen.0055F19A                     ; 载入后停在这里
0055F2AF    05 25180000     ADD EAX,1825
0055F2B4    FFE0            JMP NEAR EAX
0055F2B6    E8 04000000     CALL keygen.0055F2BF
0055F2BB    FFFF            ???                                      ; Unknown command
0055F2BD    FFFF            ???                                      ; Unknown command
0055F2BF    5E              POP ESI
0055F2C0    C3              RETN
ALT+B打开断点查看窗口,发现系统自动设置了一个断点One-shot,删除断点。
Breakpoints, item 0
Address=0055F29E keygen.<ModuleEntryPoint>
Module=keygen
Active=One-shot
Disassembly=CALL keygen.0055F19A
ALT+M打开内存镜像,CODE段F2下断,SHIFT+F9运行:
0055C660    F3:A4           REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>; 停在这里,
0055C662    31DB            XOR EBX,EBX
0055C664    5E              POP ESI
0055C665  ^ EB 9D           JMP SHORT keygen.0055C604
0055C667    89F0            MOV EAX,ESI
0055C669    5B              POP EBX
CTRL+N打开导入表,右击GetProcAddress,在导入表中跟随,双击:
0055F0C2    FF15 BC804D00   CALL NEAR DWORD PTR DS:[<&kernel32.GetPr>; 来到这里,下硬件执行断点
0055F0C8    09C0            OR EAX,EAX
0055F0CA    0F84 0D000000   JE keygen.0055F0DD
0055F0D0    8907            MOV DWORD PTR DS:[EDI],EAX
0055F0D2    8345 F4 04      ADD DWORD PTR SS:[EBP-C],4
0055F0D6  ^ E9 A6FFFFFF     JMP keygen.0055F081
0055F0DB    0000            ADD BYTE PTR DS:[EAX],AL
0055F0DD    53              PUSH EBX
0055F0DE    89D8            MOV EAX,EBX
0055F0E0    E8 09000000     CALL keygen.0055F0EE
0055F0E5    5B              POP EBX
0055F0E6    5F              POP EDI
0055F0E7    5E              POP ESI
0055F0E8    8BE5            MOV ESP,EBP
0055F0EA    5D              POP EBP
0055F0EB    C3              RETN
CTRL+F2重新载入原程序,ALT+B打开断点查看窗口,删除断点后F9,断在硬件执行断点处,取消硬件执行断点,F4到0055F0E5:
0055F0C2    FF15 BC804D00   CALL NEAR DWORD PTR DS:[<&kernel32.GetPr>; 来到这里,下硬件执行断点
0055F0C8    09C0            OR EAX,EAX
0055F0CA    0F84 0D000000   JE keygen.0055F0DD
0055F0D0    8907            MOV DWORD PTR DS:[EDI],EAX
0055F0D2    8345 F4 04      ADD DWORD PTR SS:[EBP-C],4
0055F0D6  ^ E9 A6FFFFFF     JMP keygen.0055F081
0055F0DB    0000            ADD BYTE PTR DS:[EAX],AL
0055F0DD    53              PUSH EBX
0055F0DE    89D8            MOV EAX,EBX
0055F0E0    E8 09000000     CALL keygen.0055F0EE
0055F0E5    5B              POP EBX                                  ; 走到这里后IAT就填充完毕了,在这里F4
0055F0E6    5F              POP EDI
0055F0E7    5E              POP ESI
0055F0E8    8BE5            MOV ESP,EBP
0055F0EA    5D              POP EBP
0055F0EB    C3              RETN
F4下来后我们就可以转储了,为了测试IAT是否完整,我们CTRL+B,搜索FF 25,在内存地址中可以看到完整的IAT表,关于转储,这里要讲一下,我起先用LOADPE转储,居然发现IAT表中有三个函数丢失,后来换用PETools就能完成的得到IAT表。不知是何原因。
LOADPE转储的:

00470228  77DA7883  advapi32.RegQueryValueExA
0047022C  77DA761B  advapi32.RegOpenKeyExA
00470230  77DA6BF0  advapi32.RegCloseKey
00470234  00000000
00470238  770F4850                            //这个没了
0047023C  7711C99D                           //这个没了
00470240  770F4B59                            //这个也没了
00470244  00000000
00470248 >7C809BF5  kernel32.TlsSetValue
0047024C >7C809750  kernel32.TlsGetValue
00470250 >7C8099BD  kernel32.LocalAlloc

PETools转储:
00470228 >77DA7883  advapi32.RegQueryValueExA
0047022C >77DA761B  advapi32.RegOpenKeyExA
00470230 >77DA6BF0  advapi32.RegCloseKey
00470234  00000000
00470238 >770F4850  oleaut32.SysFreeString
0047023C >7711C99D  oleaut32.SysReAllocStringLen
00470240 >770F4B59  oleaut32.SysAllocStringLen
00470244  00000000
00470248 >7C809BF5  kernel32.TlsSetValue
0047024C >7C809750  kernel32.TlsGetValue
00470250 >7C8099BD  kernel32.LocalAlloc

二、寻找OEP
从区段中的BBS区段可以判断该程序应该为DELHI程序,那就根据这个语言的特点找寻OEP。
用WINHEX载入转储的文件DUMP.EXE程序,搜索文本“runtime”:
00446544   E1 E3 00 E4 E5 8D 40 00  52 75 6E 74 69 6D 65 20   徙.溴?.Runtime
00446560   65 72 72 6F 72 20 20 20  20 20 61 74 20 30 30 30   error     at 000
向上查找最近的十六进制数字“55 8B EC”:
0006C760   55 8B EC 83 C4 F0 B8 78  C4 46 00 E8 74 A1 F9 FF   U??鸶x钠.梏※
0006C770   A1 E4 EC 46 00 8B 00 E8  88 C1 FE FF A1 E4 EC 46   ′炱.??窿?潇F
所以,OEP为0046C760。
更改转储后的程序的OEP为004C760即可。
0046C760 > $  55            PUSH EBP                                 ;  OEP
0046C761   .  8BEC          MOV EBP,ESP
0046C763   .  83C4 F0       ADD ESP,-10
0046C766   .  B8 78C44600   MOV EAX,复件_dum.0046C478
0046C76B   .  E8 74A1F9FF   CALL 复件_dum.004068E4
0046C770   .  A1 E4EC4600   MOV EAX,DWORD PTR DS:[46ECE4]
0046C775   .  8B00          MOV EAX,DWORD PTR DS:[EAX]

这时程序已经可以正常运行。由于没有OEP被偷,这个脱壳过程比较简单。

关于用lord-PE把数据目录(Directories)中TLS表的回调表VA一项置0,然后保存,我试了下,这样修改后用OD载入脱壳后的程序可以直接停在OEP处,并且断点表中没有断点。而没有清0则停在壳的EP处,并自动设置一个断点,也就是说,这个项的作用就是在壳的EP处自动做个断点。我们可以看看那个回调地址为004D813C,OD中CTRL+G到004D813C:
004D813C    AA              STOS BYTE PTR ES:[EDI]                   ; 这里就是回调地址,内存中的值正好是壳的OEP值
作用就是使这个地址比ep先获得执行权(不包括98)。


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (24)
雪    币: 319
活跃值: (2439)
能力值: ( LV12,RANK:980 )
在线值:
发帖
回帖
粉丝
2
坐沙发
2006-10-23 14:27
0
雪    币: 0
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
3
坐板凳...
2006-10-23 14:39
0
雪    币: 238
活跃值: (12)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
4
学习,如果被偷了OEP,该如何找oep?55 8B EC 应该没有了吧,请指教!
2006-10-23 15:02
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
5
oep用同类编译器编译的程序来参照。猜出OEP.
2006-10-23 15:24
0
雪    币: 560
活跃值: (359)
能力值: ( LV13,RANK:1370 )
在线值:
发帖
回帖
粉丝
6
最初由 cxlrb 发布
学习,如果被偷了OEP,该如何找oep?55 8B EC 应该没有了吧,请指教!


delphi的程序都有个初始化例程(函数).

delphi入口:
push ebp      
mov ebp,esp
sub esp,imm32
mov eax,imm32
call xxxxxxxx      //这个就是初始化例程

而这个初始化函数call xxxxxxxx里面都是这样的:
push ebx
mov ebx,eax
XOR EAX,EAX
MOV [imm32],EAX
call GetModuleHandleA          //关键是这个

我们只要下He GetModuleHandleA断点,利用堆栈找回OEP地址.
2006-10-23 15:45
0
雪    币: 417
活跃值: (475)
能力值: ( LV9,RANK:1250 )
在线值:
发帖
回帖
粉丝
7
收藏后学习。
2006-10-23 16:04
0
雪    币: 338
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
学习了!!
2006-10-23 16:14
0
雪    币: 233
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
9
支持  
2006-10-23 16:44
0
雪    币: 238
活跃值: (12)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
10
最初由 laomms 发布
delphi的程序都有个初始化例程(函数).

delphi入口:
push ebp
mov ebp,esp
sub esp,imm32
mov eax,imm32
call xxxxxxxx //这个就是初始化例程


再次请教老兄, 第一个imm32有时是-10,有时是-C,能否通用?
第二个imm32看了一下是一个存放ascii字符的地址,有时是v,有时是=,又有什么不同,自己找个地址放一个v补上去行不行?
2006-10-23 17:07
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
11
第二个imm32是dephi的初始化类表
类表第一项是纪录此表的长度
2006-10-23 17:35
0
雪    币: 250
活跃值: (11)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
12
学习中,支持一下~!~
2006-10-23 17:40
0
雪    币: 250
活跃值: (11)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
13
最初由 laomms 发布
CTRL+N打开导入表,右击GetProcAddress,在导入表中跟随,双击:
0055F0C2 FF15 BC804D00 CALL NEAR DWORD PTR DS:[<&kernel32.GetPr>; 来到这里,下硬件执行断点
0055F0C8 09C0 OR EAX,EAX
0055F0CA 0F84 0D000000 JE keygen.0055F0DD
0055F0D0 8907 MOV DWORD PTR DS:[EDI],EAX
0055F0D2 8345 F4 04 ADD DWORD PTR SS:[EBP-C],4
0055F0D6 ^ E9 A6FFFFFF JMP keygen.0055F081
0055F0DB 0000 ADD BYTE PTR DS:[EAX],AL
0055F0DD 53 PUSH EBX
0055F0DE 89D8 MOV EAX,EBX
0055F0E0 E8 09000000 CALL keygen.0055F0EE
0055F0E5 5B POP EBX
0055F0E6 5F POP EDI
0055F0E7 5E POP ESI
0055F0E8 8BE5 MOV ESP,EBP
0055F0EA 5D POP EBP
0055F0EB C3 RETN
CTRL+F2重新载入原程序,ALT+B打开断点查看窗口,删除断点后F9,断在硬件执行断点处,取消硬件执行断点,F4到0055F0E5:
0055F0C2 FF15 BC804D00 CALL NEAR DWORD PTR DS:[<&kernel32.GetPr>; 来到这里,下硬件执行断点

我在这里下了硬件断点,却断不下来,也不知道为什么,请楼主指教
2006-10-23 21:11
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
14
断GetProcAddressA
2006-10-23 21:14
0
雪    币: 250
活跃值: (11)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
15
也断不下来,我的这里CTRL+N打开导入表,右击GetProcAddress,在导入表中跟随,双击:出现的代码不是以CALL的形式出现的,面是054520BC >  28AC80 7CA2CA81 SUB BYTE PTR DS:[EAX+EAX*4+81CAA27C],CH

这种形式,两个函数都是这样,晕了
2006-10-23 21:25
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
16
He GetProcAddressA
2006-10-23 22:41
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
17
那就在API的尾巴上断
2006-10-24 00:24
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
谢谢,参考一下
2006-10-24 21:05
0
雪    币: 214
活跃值: (70)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
19
强帖留名..用到再详细看
2006-10-27 21:27
0
雪    币: 5
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
不错不错不错
2007-4-22 09:48
0
雪    币: 5
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
顶你一下呵呵
2007-4-22 09:49
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
收藏了学习.......
2007-8-9 11:48
0
雪    币: 200
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
ALT+B打开断点查看窗口,发现系统自动设置了一个断点One-shot,删除断点。
Breakpoints, item 0
Address=0055F29E keygen.<ModuleEntryPoint>
Module=keygen
Active=One-shot
Disassembly=CALL keygen.0055F19A
ALT+M打开内存镜像,CODE段F2下断,SHIFT+F9运行:

这些是不是要在输入框里,输入以上的命令?


CTRL+N打开导入表,右击GetProcAddress,在导入表中跟随,双击:
0055F0C2 FF15 BC804D00 CALL NEAR DWORD PTR DS:[<&kernel32.GetPr>; 来到这里,下硬件执行断点
0055F0C8 09C0 OR EAX,EAX
0055F0CA 0F84 0D000000 JE keygen.0055F0DD
0055F0D0 8907 MOV DWORD PTR DS:[EDI],EAX
0055F0D2 8345 F4 04 ADD DWORD PTR SS:[EBP-C],4
0055F0D6 ^ E9 A6FFFFFF JMP keygen.0055F081
0055F0DB 0000 ADD BYTE PTR DS:[EAX],AL
0055F0DD 53 PUSH EBX
0055F0DE 89D8 MOV EAX,EBX
0055F0E0 E8 09000000 CALL keygen.0055F0EE


我的好像也不是断在最上面的CALL中,而且硬件断点也不能设?为什么呢?
2007-8-9 15:27
0
雪    币: 200
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
楼主大哥。我的程序就是这壳。。可是我没那技术脱。 可以帮我脱下么。 。
谢谢  QQ174327320
2007-9-21 21:37
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
你们用的od是哪一个版本的,我的什么不了异常,下了硬件断点,跑半小时也是处理不了~~
上传的附件:
2007-10-24 11:02
0
游客
登录 | 注册 方可回帖
返回
//