dryzh 发表于 2008-1-1 01:10:43

手脱PowerArchiverr的ExeCryprtor V2.XX

【文章标题】: 手脱PowerArchiverr的ExeCryprtor V2.XX
【文章作者】: dryzh(B.S)
【作者邮箱】: dryzh163.com
【作者主页】: http://www.pediy.com/
【作者QQ号】: 最近没条件上Q :(
【软件名称】: PowerArchiver2007
【软件大小】: 138 KB (141,352 字节)
【下载地址】: http://www.powerarchiver.com/download/
【加壳方式】: ExeCryprtor V2.XX
【保护方式】: ExeCryprtor V2.XX
【编写语言】: Borland Delphi 6.0 - 7.0
【使用工具】: OLLYICE or OLLYDBG_Execryptor,PeID,ProtectionID_v5.2c,LordPE,ImpREC
【操作平台】: WinXP
【软件介绍】: 自己去看吧!
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
一, 了解程序相关信息:

用PeID查看是什么壳
EXECryptor 2.xx (compressed resources) -> www.strongbit.com

连接器版本Linker:2.25

可能是Borland Delphi 6.0 - 7.0写的程序

用ProtectionID_v5.2c查得
> Ready

Scanning -> D:\Program Files\PowerArchiver\POWERARC.EXE
File Type : Exe, Size : 7806752 (0771F20h) Bytes
-> File has 5408 (01520h) bytes of appended data starting at offset 0770A00h
[!] EXE Cryptor v2.3.0 - v2.3.9 protected !
[!] Possible CD/DVD-Check String -> InsertDisk
[!] Possible CD/DVD-Key or Serial Check -> evaluation copy
- Scan Took : 0.516 Seconds


二, 找OEP+IAT:

打开OD,ALT+O
在异常选项卡里,忽略所有异常和00000001-FFFFFFFE的范围异常
在事件选项卡里,设置第一次暂停于系统断点.
插件Hide OD 全勾,选mothed1(好像mothed2也可以)

OD载入停在系统断点处

7C921231    C3            retn
7C921232    8BFF            mov   edi, edi
7C921234    90            nop
7C921235    90            nop
7C921236    90            nop
7C921237    90            nop
7C921238    90            nop
7C921239 >CC            int3
7C92123A    C3            retn
7C92123B    90            nop
7C92123C    8BFF            mov   edi, edi

ALT+B删掉"仅一次"的断点(如还有别的断点,也删掉吧)

Breakpoints, 条目 0
地址=00CF9F16 POWERARC.<模块入口点>
模块=POWERARC
激活=仅一次
反汇编=jmp   00CDCA2E

从这里断下的语句代码JMP XXXXXXXX可以看出是DELPHI,如果是C++的话,这句应该是CALLXXXXXXXX.

ALT+M在.CODE区段下断F2,SHIFT+F9停在下面

7C948515    8B06            mov   eax, dword ptr              ; POWERARC.00CCDBCB
7C948517    3BC3            cmp   eax, ebx
7C948519    0F85 3A2F0100   jnz   7C95B459
7C94851F    834D FC FF      or      dword ptr , FFFFFFFF
7C948523    E8 DA68FEFF   call    7C92EE02
7C948528    C2 0800         retn    8

找到下面的retn 8 下断F2,再SHIFT+F9或F9断在retn 8处,F2取消断点
ALT+M在.CODE区段下断F2,F9停在下面

009AD305    8BD0            mov   edx, eax                         ; 断在这里
009AD307    C1C8 10         ror   eax, 10
009AD30A    66:C1C2 03      rol   dx, 3
009AD30E    81F2 47D8B0B2   xor   edx, B2B0D847
009AD314- E9 041A3500   jmp   00CFED1D
009AD319    870424          xchg    dword ptr , eax
009AD31C    58            pop   eax
009AD31D    57            push    edi
009AD31E    68 2E56BE50   push    50BE562E
009AD323- E9 D4153500   jmp   00CFE8FC
009AD328    E8 ECF03200   call    00CDC419
009AD32D- E9 B14F3400   jmp   00CF22E3
009AD332- E9 F42A3300   jmp   00CDFE2B
009AD337- E9 1DB73400   jmp   00CF8A59
009AD33C- E9 447A3400   jmp   00CF4D85
009AD341    8845 F3         mov   byte ptr , al
009AD344    57            push    edi
009AD345    E8 17FF3300   call    00CED261
009AD34A    A6            cmps    byte ptr , byte ptr es:[edi>
009AD34B    CA D98B         retf    8BD9


CTRL+G到00401000处,查找->所有模块间调用
输入GetModuleHandleA,按目标文件排列后先第2个GetModuleHandleA,跟随到反汇编ENTER

00407986    C3            retn
00407987    90            nop
00407988    53            push    ebx
00407989    8BD8            mov   ebx, eax
0040798B    33C0            xor   eax, eax
0040798D    A3 C400A000   mov   dword ptr , eax
00407992    6A 00         push    0
00407994    E8 2BFFFFFF   call    <jmp.&kernel32.GetModuleHandleA>
00407999    A3 6866A200   mov   dword ptr , eax
0040799E    A1 6866A200   mov   eax, dword ptr
004079A3    A3 D000A000   mov   dword ptr , eax

004078C4=<jmp.&kernel32.GetModuleHandleA>

先记住这个头处的地址00407988
   
跟随这个call    <jmp.&kernel32.GetModuleHandleA>来到
004078C4- FF25 7013CA00   jmp   dword ptr [<&kernel32.GetModuleH>; kernel32.GetModuleHandleA
即:jmp   dword ptr


现在可以在命令行d CA1370,可向上向下找IAT开始和结束的地址(你也可以在F9009AD305处时,在.idata段F2再F9)

00CA1370 >7C80B6A1kernel32.GetModuleHandleA
00CA137400000000
00CA1378 >77DA77B3advapi32.SetSecurityDescriptorDacl
00CA137C >77DAD7CCadvapi32.RegSetValueExW
00CA1380 >77DAEBE7advapi32.RegSetValueExA
00CA1384 >77DBC8D6advapi32.RegSetKeySecurity
00CA1388 >77DA6FC8advapi32.RegQueryValueExW
00CA138C >77DA7883advapi32.RegQueryValueExA
00CA1390 >77DCC1B5advapi32.RegQueryInfoKeyA
00CA1394 >77DA6A78advapi32.RegOpenKeyExW

确定IAT表

00CA126800000000
00CA126C >7C93188Antdll.RtlDeleteCriticalSection
00CA1270 >7C9210EDntdll.RtlLeaveCriticalSection
00CA1274 >7C921005ntdll.RtlEnterCriticalSection
00CA1278 >7C809EF1kernel32.InitializeCriticalSection
00CA127C >7C809AE4kernel32.VirtualFree
00CA1280 >7C809A51kernel32.VirtualAlloc
00CA1284 >7C80992Fkernel32.LocalFree
00CA1288 >7C80998Dkernel32.LocalAlloc

......

00CA1F04 >71A22BF4WS2_32.inet_addr
00CA1F08 >71A22B66WS2_32.ntohs
00CA1F0C >71A2951EWS2_32.getsockname
00CA1F10 >71A2406AWS2_32.connect
00CA1F14 >71A29639WS2_32.closesocket
00CA1F18 >71A23E00WS2_32.bind
00CA1F1C00000000
00CA1F20 >77D1BFF3user32.NotifyWinEvent
00CA1F2400000000
00CA1F28 >74BFDC93oleacc.LresultFromObject
00CA1F2C00000000
00CA1F30 >77EFD7E6GDI32.GetRandomRgn
00CA1F3400000000
00CA1F38 >765EC256crypt32.CertDuplicateCertificateContext
00CA1F3C >765F085Acrypt32.CertFreeCertificateContext
00CA1F4000000000
00CA1F44 >77DB8546advapi32.CryptReleaseContext
00CA1F48 >77DBA544advapi32.CryptDestroyKey
00CA1F4C00000000
00CA1F506E72656B
00CA1F5432336C65
00CA1F586C6C642E
00CA1F5C00000000

得到后面修复要用的:
RVA=IAT_START-00400000=00cA1268-00400000=008A1268
IAT_SIZE=IAT_START-IAT_END
=(00CA1F50-00400000)-(00CA1268-00400000)=008A1F50-008A1268=00000CE8


呵呵,输入表没有加密处理,幸运哟.


在00407988这行(开头处)CTRL+F查找命令call 00407988看是哪里调用这里的,来到

注意:本来您是可以通过 Ctrl +↑ 或 Ctrl+↓ 对数据窗口翻动一个字节的,这里如果在你的OD失效,请你加上SHIFT三键一起按^_^

直到出现JMP <ModuleEntryPoint>,这里就是真真的OEP了.呵呵...开心吧....

009FF6C8- E9 49A82F00   jmp   <模块入口点>                        ; real OEP
009FF6CD    2D 24946A00   sub   eax, 006A9424
009FF6D2    6A 00         push    0
009FF6D4    49            dec   ecx
009FF6D5^ 75 F9         jnz   short 009FF6D0
009FF6D7    51            push    ecx
009FF6D8    53            push    ebx
009FF6D9    56            push    esi
009FF6DA    57            push    edi
009FF6DB    B8 E8E79F00   mov   eax, 009FE7E8
009FF6E0    E8 A382A0FF   call    00407988                         ; 找到这里
   
可是上面的OEP被偷了:(


三, 还原OEP+DUMP:

现在我们来找OEP还原,在第一个PUSH 0处(009FF6D0)下断,F9跑,断下后看寄存器ECX的值为0E(这个还原OEP有用)
找个DELHPI未加壳程序来看一下就会明白了,程序目录里还有一个叫_PASETUP.EXE它没有加壳,就用这个作OEP参考吧

参考程序:
      
0040E084 > $55            push    ebp
0040E085   .8BEC          mov   ebp, esp
0040E087   .B9 45000000   mov   ecx, 45
0040E08C   >6A 00         push    0
0040E08E   .6A 00         push    0
0040E090   .49            dec   ecx
0040E091   .^ 75 F9         jnz   short 0040E08C
0040E093   .51            push    ecx
0040E094   .53            push    ebx
0040E095   .56            push    esi
0040E096   .57            push    edi
0040E097   .B8 B4DF4000   mov   eax, 0040DFB4
0040E09C   .E8 1766FFFF   call    004046B8
0040E0A1   .33C0          xor   eax, eax

壳程序:

009FF6CE    24 94         and   al, 94
009FF6D0    6A 00         push    0                              ; 这里断下后.看ECX的值
009FF6D2    6A 00         push    0
009FF6D4    49            dec   ecx
009FF6D5^ 75 F9         jnz   short 009FF6D0
009FF6D7    51            push    ecx
009FF6D8    53            push    ebx
009FF6D9    56            push    esi
009FF6DA    57            push    edi
009FF6DB    B8 E8E79F00   mov   eax, 009FE7E8
009FF6E0    E8 A382A0FF   call    00407988                         ; 找到这里
009FF6E5    33C0            xor   eax, eax

还原后的OEP在下面

009FF6C8    55            push    ebp                              ; real OEP
009FF6C9    8BEC            mov   ebp, esp
009FF6CB    B9 0E000000   mov   ecx, 0E
009FF6D0    6A 00         push    0
009FF6D2    6A 00         push    0
009FF6D4    49            dec   ecx
009FF6D5^ 75 F9         jnz   short 009FF6D0
009FF6D7    51            push    ecx
009FF6D8    53            push    ebx
009FF6D9    56            push    esi
009FF6DA    57            push    edi
009FF6DB    B8 E8E79F00   mov   eax, 009FE7E8
009FF6E0    E8 A382A0FF   call    00407988
009FF6E5    33C0            xor   eax, eax

下面是二进制代码,复制去用吧^_^
55 8B EC B9 0E 00 00 00

还原好后,还用说吗,去掉009FF6D0处的断点,赶快新建EIP,DUMP啦......

就用OLLY DUMP插件吧,记住不要选重建输入表项(Rebuile Import),存为5FF6C8.exe

OD不要关,下面要修复用.


四, 修复IAT:

用ImpREC修复,选中进程,填上
OEP=009FF6C8-00400000=5FF6C8
RVA=00cA1268-00400000=008A1268
SIZE=(00CA1F50-00400000)-(00CA1268-00400000)=008A1F50-008A1268=00000CE8

因为输入表没有加密,你也可以点IAT AutoSearch
Get Import 后 Show Invalid 没有无效函数指针
Fix Dump! OK!

PeID查一下(你也可以用别的查壳工具,如ProtectionID_v5.2c,RDG Packer Detector v0.6.5 Beta,CFF Explorer VI等等)

Borland Delphi 6.0 - 7.0

运行修复后的5FF6C8_.exe文件,一切正常.
完工......



感谢:
kienmanowar
Teddy Roggers
haggar
why not bar
EvOiUtloN

kanxue
fly
VolX
linhanshi
machenglin
Isaiah
wynney

所有直接或间接帮助我和支持我的朋友和你

--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2008年01月01日 0:54:44

cc7x 发表于 2008-1-8 22:55:08

very good,it good for me,thanks

zongmin 发表于 2008-1-21 16:50:57

这个壳变态的很/:good

baby520 发表于 2008-1-23 19:34:49

学习 能不能发上来个能调试这壳的OD
页: [1]
查看完整版本: 手脱PowerArchiverr的ExeCryprtor V2.XX