最初由 chinadev 发布
太过自信了吧?
你就那么确定一定是自校验造成的?
以下是我破解过程,肯定是存在自校验之类的暗桩,脱壳是没有问题的(因为脱壳没成功时,程序总是报错,根本运行不起来)
首先Peid查壳,为ASProtect 1.23 RC4 - 1.3.08.24 -> Alexey Solodovnikov
Ollydbg载入程序,隐藏OD,OD异常设置忽略除内存异常外的全部异常。
00401000 RagexeD.<Mod> 68 01A07400 push RagexeD.0074A001 // 加壳程序入口点
00401005 E8 01000000 call RagexeD.0040100B
0040100A C3 retn
0040100B C3 retn
一路Shift+F9,直至最后一个异常发生处(如果此时再按Shift+F9 程序将运行!)
010C39EC 3100 xor dword ptr ds:[eax],eax // 停在这里
010C39EE 64:8F05 00000000 pop dword ptr fs:[0]
010C39F5 58 pop eax
010C39F6 833D B07E0C01 00 cmp dword ptr ds:[10C7EB0],0
010C39FD 74 14 je short 010C3A13
010C39FF 6A 0C push 0C
010C3A01 B9 B07E0C01 mov ecx,10C7EB0
010C3A06 8D45 F8 lea eax,dword ptr ss:[ebp-8]
010C3A09 BA 04000000 mov edx,4
010C3A0E E8 2DD1FFFF call 010C0B40
010C3A13 FF75 FC push dword ptr ss:[ebp-4]
010C3A16 FF75 F8 push dword ptr ss:[ebp-8]
010C3A19 8B45 F4 mov eax,dword ptr ss:[ebp-C]
010C3A1C 8338 00 cmp dword ptr ds:[eax],0
010C3A1F 74 02 je short 010C3A23
010C3A21 FF30 push dword ptr ds:[eax]
010C3A23 FF75 F0 push dword ptr ss:[ebp-10]
010C3A26 FF75 EC push dword ptr ss:[ebp-14]
010C3A29 C3 retn // 这里下断,回到010D714C
010C3A2A 5F pop edi
010C3A2B 5E pop esi
在第一个retn语句下断,也就是010C3A29处。再次Shift+F9,取消断点!
接下来要小心跟进,查找OEP,非特殊情况,一律F7跟进,F4步过!
010D714C 8BC2 mov eax,edx
010D714E B8 D1129039 mov eax,399012D1
010D7153 8AE3 mov ah,bl
010D7155 E8 05000000 call 010D715F // F7 跟进
010D715F 0FB7F7 movzx esi,di
010D7162 59 pop ecx
010D7163 BF 6C01E67E mov edi,7EE6016C
010D7168 68 CAA3657B push 7B65A3CA
010D716D E9 06000000 jmp 010D7178 // F7 跟进
010D7178 5E pop esi
010D7179 81C1 4C160000 add ecx,164C
010D717F 81D0 88F78911 adc eax,1189F788
010D7185 E9 0B000000 jmp 010D7195 // F7 跟进
010D7195 BA 00000000 mov edx,0
010D719A 0FBFC6 movsx eax,si
010D719D 0F80 02000000 jo 010D71A5
010D71A3 8BF2 mov esi,edx
010D71A5 68 DA567D35 push 357D56DA
010D71AA 66:81EF E798 sub di,98E7
010D71AF 5E pop esi
010D71B0 FF340A push dword ptr ds:[edx+ecx]
010D71B3 68 00FEA94C push 4CA9FE00
010D71B8 68 DFBDBC37 push 37BCBDDF
010D71BD 68 8A2AC960 push 60C92A8A
010D71C2 5E pop esi
010D71C3 56 push esi
010D71C4 5E pop esi
010D71C5 5E pop esi
010D71C6 E8 13000000 call 010D71DE // F7 跟进
010D71DE /0F83 00000000 jnb 010D71E4
010D71E4 \50 push eax
010D71E5 58 pop eax
010D71E6 5F pop edi
010D71E7 5F pop edi
010D71E8 5B pop ebx
010D71E9 E9 0F000000 jmp 010D71FD // F7 跟进
010D71FD 52 push edx
010D71FE 0F88 1B000000 js 010D721F
010D7204 8AC6 mov al,dh
010D7206 57 push edi
010D7207 5E pop esi
010D7208 E8 11000000 call 010D721E // F7 跟进
010D721E 5E pop esi ; 010D720D
010D721F 58 pop eax
010D7220 81F3 74C32A14 xor ebx,142AC374
010D7226 57 push edi
010D7227 E8 07000000 call 010D7233 // F7 跟进
010D7233 50 push eax
010D7234 5F pop edi
010D7235 66:81C6 FEB9 add si,0B9FE
010D723A 58 pop eax
010D723B 5F pop edi
010D723C 66:B8 F35B mov ax,5BF3
010D7240 81DE DCD71641 sbb esi,4116D7DC
010D7246 81C3 9DC07A3D add ebx,3D7AC09D
010D724C 81EB 1209626A sub ebx,6A620912
010D7252 E9 0C000000 jmp 010D7263 // F7 跟进
010D7263 68 37F7E277 push 77E2F737
010D7268 8BF9 mov edi,ecx
010D726A 58 pop eax
010D726B 53 push ebx
010D726C 81C7 4129BA53 add edi,53BA2941
010D7272 81C8 72B38179 or eax,7981B372
010D7278 8F0411 pop dword ptr ds:[ecx+edx]
010D727B 80DC CA sbb ah,0CA
010D727E 50 push eax
010D727F B8 ED1AAC00 mov eax,0AC1AED
010D7284 8BF7 mov esi,edi
010D7286 5F pop edi
010D7287 E8 11000000 call 010D729D // F7 跟进
010D729D 81E0 F67E8947 and eax,47897EF6
010D72A3 5F pop edi
010D72A4 52 push edx
010D72A5 0F8C 09000000 jl 010D72B4
010D72AB 0FBFF0 movsx esi,ax
010D72AE 0F82 00000000 jb 010D72B4
010D72B4 5E pop esi
010D72B5 81E6 30DA9A7E and esi,7E9ADA30
010D72BB 83EA 04 sub edx,4
010D72BE 66:8BC6 mov ax,si
010D72C1 81FA 54EBFFFF cmp edx,-14AC
010D72C7 0F85 1A000000 jnz 010D72E7 // F7 跟进
010D72CD 0F81 05000000 jno 010D72D8
010D72D3 53 push ebx
010D72D4 66:8BC6 mov ax,si
010D72D7 58 pop eax
010D72D8 E9 21000000 jmp 010D72FE // F2下断,Shift+F9跟进,取消断点
010D72DD 9A CBA8C166 A754 call far 54A7:66C1A8CB
010D72E4 FD std
010D72E5 F2: prefix repne:
010D72E6 43 inc ebx
010D72E7 56 push esi //010D72C7跳到这里
010D72E8 BF D8A4AB3D mov edi,3DABA4D8
010D72ED 5F pop edi
010D72EE ^ E9 BDFEFFFF jmp 010D71B0 //发现跳回去了,往上一查看便知在010D72D8下断,跳出循环!
010D72FE 5B pop ebx
010D72FF 58 pop eax
010D7300 05 4FF5B67F add eax,7FB6F54F
010D7305 5C pop esp
010D7306 EB 44 jmp short 010D734C // F7 跟进
010D734C 03C3 add eax,ebx
010D734E BB A1000000 mov ebx,0A1
010D7353 0BDB or ebx,ebx
010D7355 75 07 jnz short 010D735E // F7 跟进
010D735E E8 00000000 call 010D7363 // F7 跟进
010D7363 5D pop ebp
010D7364 81ED 4DE14B00 sub ebp,4BE14D
010D736A 8D85 F2E04B00 lea eax,dword ptr ss:[ebp+4BE0F2]
010D7370 8D8D 94E14B00 lea ecx,dword ptr ss:[ebp+4BE194]
010D7376 03CB add ecx,ebx
010D7378 8941 01 mov dword ptr ds:[ecx+1],eax
010D737B 8D85 36E14B00 lea eax,dword ptr ss:[ebp+4BE136]
010D7381 8D8D FAE04B00 lea ecx,dword ptr ss:[ebp+4BE0FA]
010D7387 8901 mov dword ptr ds:[ecx],eax
010D7389 B8 5E140000 mov eax,145E
010D738E 8D8D FFE04B00 lea ecx,dword ptr ss:[ebp+4BE0FF]
010D7394 8901 mov dword ptr ds:[ecx],eax
010D7396 8D8D 94E14B00 lea ecx,dword ptr ss:[ebp+4BE194]
010D739C 8D85 94F34B00 lea eax,dword ptr ss:[ebp+4BF394]
010D73A2 51 push ecx
010D73A3 50 push eax
010D73A4 E8 76FFFFFF call 010D731F // 很明显这里差距太多指令,可以放心F8步过
010D73A9 61 popad
010D73AA F2: prefix repne:
010D73AB EB 01 jmp short 010D73AE // F7 跟进
010D73AE F3: prefix rep:
010D73AF EB 02 jmp short 010D73B3 // F7 跟进
010D73B3 52 push edx
010D73B4 F3: prefix rep:
010D73B5 EB 02 jmp short 010D73B9 // F7 跟进
010D73B9 81EA 247C1E4A sub edx,4A1E7C24
010D73BF EB 02 jmp short 010D73C3// F7 跟进
010D73C3 /36:EB 01 jmp short 010D73C7// F7 跟进
010D73C7 8D545A 89 lea edx,dword ptr ds:[edx+ebx*2-77]
010D73CB 26:EB 02 jmp short 010D73D0 // F7 跟进
010D73D0 BA CB730D01 mov edx,10D73CB
010D73D5 FF52 12 call dword ptr ds:[edx+12] // F7 跟进
010D73E5 5A pop edx
010D73E6 F2: prefix repne:
010D73E7 EB 01 jmp short 010D73EA// F7 跟进
010D73EA /EB 02 jmp short 010D73EE// F7 跟进
010D73EE 0FBDD7 bsr edx,edi
010D73F1 65:EB 02 jmp short 010D73F6// F7 跟进
010D73F6 035424 10 add edx,dword ptr ss:[esp+10]
010D73FA 64:EB 02 jmp short 010D73FF// F7 跟进
010D73FF 335424 00 xor edx,dword ptr ss:[esp]
010D7403 5A pop edx
010D7404 F2: prefix repne:
010D7405 EB 01 jmp short 010D7408// F7 跟进
010D7408 55 push ebp // 第一句
010D7409 8BEC mov ebp,esp // 第二句
010D740B 6A FF push -1 // 第三句
010D740D 68 28826700 push 678228 // 第四句
010D7412 68 30976400 push 649730 // 第五句
010D7417 64:A1 00000000 mov eax,dword ptr fs:[0] // 第六句
以上正是Stolen Code!!,我们把它抄下来
010D741D F2: prefix repne:
010D741E EB 01 jmp short 010D7421 // F7跟进
010D7421 50 push eax // 第七句
010D7422 64:8925 00000000 mov dword ptr fs:[0],esp // 第八句
010D7429 83EC 58 sub esp,58 // 第九句
010D742C F2: prefix repne:
010D742D EB 01 jmp short 010D7430 // F7 跟进
010D7430 53 push ebx // 第十句
010D7431 F2: prefix repne:
010D7432 EB 01 jmp short 010D7435 // F7 跟进
010D7435 56 push esi // 第十一句
010D7436 F2: prefix repne:
010D7437 EB 01 jmp short 010D743A //F7 跟进
010D743A 57 push edi // 第十二句
010D743B 8965 E8 mov dword ptr ss:[ebp-18],esp // 第十三句
010D743E F2: prefix repne:
010D743F EB 01 jmp short 010D7442
整理一下Stolen Code,一共十三句:
55 push ebp
8BEC mov ebp,esp
6A FF push -1
68 28826700 push 678228
68 30976400 push 649730
64:A1 00000000 mov eax,dword ptr fs:[0]
50 push eax
64:8925 0000000>mov dword ptr fs:[0],esp
83EC 58 sub esp,58
53 push ebx
56 push esi
57 push edi
8965 E8 mov dword ptr ss:[ebp-18],esp
既然找齐了Stolen Code 那么接下来一路F8 来到伪OEP即可!
0064E06E 0000 add byte ptr ds:[eax],al // 真正的OEP
0064E070 0000 add byte ptr ds:[eax],al
0064E072 0000 add byte ptr ds:[eax],al
0064E074 0000 add byte ptr ds:[eax],al
0064E076 0000 add byte ptr ds:[eax],al
0064E078 0000 add byte ptr ds:[eax],al
0064E07A 0000 add byte ptr ds:[eax],al
0064E07C 0000 add byte ptr ds:[eax],al
0064E07E 0000 add byte ptr ds:[eax],al
0064E080 0000 add byte ptr ds:[eax],al
0064E082 0000 add byte ptr ds:[eax],al
0064E084 0000 add byte ptr ds:[eax],al
0064E086 0000 add byte ptr ds:[eax],al
0064E088 0000 add byte ptr ds:[eax],al
0064E08A 0000 add byte ptr ds:[eax],al
0064E08C 0000 add byte ptr ds:[eax],al
0064E08E 0000 add byte ptr ds:[eax],al
0064E090 0000 add byte ptr ds:[eax],al
0064E092 0000 add byte ptr ds:[eax],al
0064E094 FF15 CCB26600 call dword ptr ds:[66B2CC] // 伪OEP
0064E09A 33D2 xor edx,edx
直接补上整理的Stolen Code,补好后复制代码到文件中,直接用Loadpe脱壳。
运行AsprDbgr_build_106,得到RVA:66B000 SIZE:620
D:\Program Files\Gravity\RagnarokOnline>AsprDbgr_build_106 RagexeD.exe
AsprDbgr v1.0beta (:P) Made by me... Manko.
iEP=401000 (D:\Program Files\Gravity\RagnarokOnline\RagexeD.exe)
IAT Start: 66B000
End: 66B620
Length: 620
IATentry 66B0F0 = 10C1CC0 resolved as GetCurrentProcessId
IATentry 66B224 = 10C1C64 resolved as GetModuleHandleA
IATentry 66B22C = 10C1CB8 resolved as GetCurrentProcess
IATentry 66B268 = 10C17A4 resolved as GetProcAddress
IATentry 66B2C8 = 10C1CD8 resolved as GetCommandLineA
IATentry 66B2CC = 10C1C8C resolved as GetVersion
IATentry 66B3D4 = 10C1D14 resolved as DialogBoxParamA
17 invalid entries erased.
Dip-Table at adress: 10C7AB4
0 0 0 0 0 0 0 0 0 0 0 0 0 0
Last SEH passed. (10C39EE) Searching for signatures. Singlestepping to OEP!
Call + OEP-jump-setup at: 10D633A ( Code: E8000000 5D81ED )
Mutated, stolen bytes at: 10D6386 ( Code: F2EB019A F3EB02CD )
Erase of stolen bytes at: 10D62E9 ( Code: 9CFCBF28 630D01B9 )
Repz ... found. Skipping erase of stolen bytes. ;)
possible (temp)OEP: 64E094 (Reached from preOEP: 10D62FA)
DebugProcess ended. (??)
运行ImportREC,输入OEP:0024E06E RVA:26B000 SIZE:620 [IAT AutoSearch] 修复无效函数[Fix Dump]
比如:ImportREC中一个失效函数
rva:0026B0D4 ptr:010D050C
OD中,Ctrl+G 转到 010D050C
010D0538 55 push ebp
010D0539 8BEC mov ebp,esp
010D053B 6A FF push -1
010D053D 68 3024E677 push 77E62430
010D0542 68 441FEB77 push 77EB1F44 // ~= kernel32.dll/02E1/UTUnRegister
010D0547 64:A1 00000000 mov eax,fs:[0]
010D054D 50 push eax
010D054E 64:8925 00000000 mov fs:[0],esp
010D0555 51 push ecx
010D0556 51 push ecx
010D0557 83EC 0C sub esp,C
010D055A 53 push ebx
010D055B 56 push esi
010D055C 57 push edi
010D055D 68 4A96E677 push 77E6964A // ~= kernel32.dll/01F2/LocalLock
010D0562 C3 retn
这一段代码是在外壳中,程序跑这段代码目的是跳到某个函数中去,其中最后2句:
010D055D 68 4A96E677 push 77E6964A // ~= kernel32.dll/01F2/LocalLock
010D0562 C3 retn
相当于:
jmp 77E6964A //即jmp kernel32.dll_LocalLock
也就是说,真正有效的是最后两句,其他全是垃圾代码,所以这个就是LocalLock函数。
运行破解完的程序,发生以下错误!
Module Name: D:\Program Files\Gravity\RagnarokOnline\Ragexe.exe
Time Stamp: 0x44640871 - Fri May 12 12:00:49 2006
Exception Type: 0xc0000005
0x004dfcc3 Ragexe.exe
0x00630af5 Ragexe.exe
0x0064e14e Ragexe.exe
0x77e8893d KERNEL32.DLL
eax: 0x00000000 ebx: 0x00133d1b
ecx: 0x0071c0c0 edx: 0x00744cb8
esi: 0x2012e490 edi: 0x2012e4b0
ebp: 0x0012fad8 esp: 0x0012f5c0
stack 0012f5c0 - 0012f9c0
0012F5C0 : 22 6A 4F 00 00 00 00 00 00 00 00 00 00 00 00 00
0012F5D0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0012F5E0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0012F5F0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0012F600 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0012F610 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0012F620 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0012F630 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0012F640 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0012F650 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0012F660 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0012F670 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0012F680 : 00 00 00 00 00 00 00 00 08 85 6B 00 08 85 6B 00
0012F690 : 5C 8C 6B 00 01 00 00 00 8C F6 12 00 B0 FF 12 00
0012F6A0 : B0 FF 12 00 44 1F EB 77 C0 23 E6 77 FF FF FF FF
0012F6B0 : 19 00 00 00 16 96 63 00 28 45 74 00 90 E4 12 20
Launch Info
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
Job : Novice
很明显此处有暗桩,载入破解程序,Ctrl + G : 004dfcc3
004DFCC3 C740 14 00000000 mov dword ptr ds:[eax+14],0
004DFCCA C701 00000000 mov dword ptr ds:[ecx],0
004DFCD0 \. C3 retn
这里自验证! NOP掉! 保存即可