Unpacking SafeDisc v2.90.40 -- 樱花大战3简体中文标准版(如果你的HP不是满的话,还是先去喝几个血瓶吧)
[工具]:ODbyDYK,ImportREC,LordPE
大家都知道SafeDisc好一个用驱动来欺负我们的OD,但是我们真的会让OD被他欺负吗?
用OD载入Sakura3.exe。
020B305E > 55 push ebp <-OD停在了这里
020B305F 8BEC mov ebp, esp
020B3061 60 pushad <-大家看,多么友好的提示。
020B3062 BB 5E300B02 mov ebx, offset Sakura3.<ModuleEntryPoint>
020B3067 33C9 xor ecx, ecx
020B3069 8A0D 3D300B02 mov cl, byte ptr ds:[20B303D]
020B306F 85C9 test ecx, ecx
向下找POPAD。一共找到了三个大家可以看看哪个比较象。
020B30BA 85C9 test ecx, ecx
020B30BC 74 09 je short Sakura3.020B30C7
020B30BE 61 popad
020B30BF 5D pop ebp
020B30C0 B8 00000000 mov eax, 0
020B30C5 ^ EB 97 jmp short Sakura3.<ModuleEntryPoint>
020B30CD FFD0 call eax
020B30CF 61 popad
020B30D0 5D pop ebp
020B30D1 EB 46 jmp short Sakura3.020B3119
020B30D3 807C24 08 00 cmp byte ptr ss:[esp+8], 0
020B3115 61 popad
020B3116 1360 0D adc esp, dword ptr ds:[eax+D]
020B3119 - E9 09BF5FFE jmp Sakura3.006AF027
020B311E CC int3
然后你小按几下F8,就会发现刚才的入口点被修正成了
020B305E >- E9 C4BF5FFE jmp Sakura3.006AF027
020B3063 5E pop esi
020B3064 300B xor byte ptr ds:[ebx], cl
020B3066 0233 add dh, byte ptr ds:[ebx]
然而,事实证明,真正有用的是020B3119那里的跳转。
先说一下safedisc的运做过程,先把自己需要的连接库解压到临时目录,写为*.tmp文件。然后LoadLibrary。
再跳到载入的~df394b.tmp模块进行调试器检测,加载光盘检测模块,解压缩大部分主程序,再进行光盘检测向主程序写入剩下的一些数据,返回。
下面进入正题:
对 IsDebuggerPresent 下断(软件/硬件断点都行,但是我选择硬件断点,感觉保险些。下面相同)。显得有些多此一举,用插件能避开的还搞那么麻烦,而且我也用插件避开了,但是我们需要定位后面的调试器检测。
断下后取消硬件断点返回到这里:
100099EC 8BF0 mov esi, eax
100099EE 66:85F6 test si, si
100099F1 74 13 je short ~df394b.10009A06
100099F3 E8 8278FFFF call ~df394b.1000127A
100099F8 66:8BF0 mov si, ax
100099FB 66:F7DE neg si
100099FE 1BF6 sbb esi, esi
10009A00 46 inc esi
10009A01 66:85F6 test si, si
10009A04 75 13 jnz short ~df394b.10009A19
10009A06 8B4424 08 mov eax, dword ptr ss:[esp+8]
10009A0A 8B08 mov ecx, dword ptr ds:[eax]
10009A0C 81E1 EA894267 and ecx, 674289EA
10009A12 8908 mov dword ptr ds:[eax], ecx
10009A14 66:8BC6 mov ax, si
10009A17 5E pop esi
10009A18 C3 retn <-继续返回
到这里:
1000457A 83C4 04 add esp, 4
1000457D 66:85C0 test ax, ax
10004580 0F85 02010000 jnz ~df394b.10004688
10004586 F6C3 04 test bl, 4
10004589 76 12 jbe short ~df394b.1000459D
1000458B 56 push esi
1000458C E8 3F530000 call ~df394b.100098D0
10004591 83C4 04 add esp, 4
10004594 66:85C0 test ax, ax
10004597 0F85 EB000000 jnz ~df394b.10004688
1000459D F6C3 08 test bl, 8
100045A0 76 12 jbe short ~df394b.100045B4
100045A2 56 push esi
100045A3 E8 58520000 call ~df394b.10009800
100045A8 83C4 04 add esp, 4
100045AB 66:85C0 test ax, ax
100045AE 0F85 D4000000 jnz ~df394b.10004688
100045B4 F7C3 00080000 test ebx, 800
100045BA 76 12 jbe short ~df394b.100045CE
100045BC 56 push esi
100045BD E8 5E510000 call ~df394b.10009720
100045C2 83C4 04 add esp, 4
100045C5 66:85C0 test ax, ax
100045C8 0F85 BA000000 jnz ~df394b.10004688 <-我们需要避开的是这个,不要让他跳转就行了。
100045CE F7C3 00100000 test ebx, 1000
100045D4 76 12 jbe short ~df394b.100045E8
100045D6 56 push esi
100045D7 E8 84500000 call ~df394b.10009660
100045DC 83C4 04 add esp, 4
100045DF 66:85C0 test ax, ax
100045E2 0F85 A0000000 jnz ~df394b.10004688
100045E8 F7C3 00200000 test ebx, 2000
100045EE 76 12 jbe short ~df394b.10004602
100045F0 56 push esi
100045F1 E8 BA4F0000 call ~df394b.100095B0
100045F6 83C4 04 add esp, 4
100045F9 66:85C0 test ax, ax
100045FC 0F85 86000000 jnz ~df394b.10004688
10004602 F6C3 01 test bl, 1
10004605 76 0E jbe short ~df394b.10004615
10004607 56 push esi
10004608 E8 834E0000 call ~df394b.10009490
1000460D 83C4 04 add esp, 4
10004610 66:85C0 test ax, ax
10004613 75 73 jnz short ~df394b.10004688
10004615 F6C3 02 test bl, 2
10004618 76 0E jbe short ~df394b.10004628
1000461A 56 push esi
1000461B E8 504D0000 call ~df394b.10009370
10004620 83C4 04 add esp, 4
10004623 66:85C0 test ax, ax
10004626 75 60 jnz short ~df394b.10004688
10004628 F6C3 10 test bl, 10
1000462B 76 0E jbe short ~df394b.1000463B
1000462D 56 push esi
1000462E E8 DD4C0000 call ~df394b.10009310
10004633 83C4 04 add esp, 4
10004636 66:85C0 test ax, ax
10004639 75 4D jnz short ~df394b.10004688
1000463B F6C3 20 test bl, 20
1000463E 76 0E jbe short ~df394b.1000464E
10004640 56 push esi
10004641 E8 1A4C0000 call ~df394b.10009260
10004646 83C4 04 add esp, 4
10004649 66:85C0 test ax, ax
1000464C 75 3A jnz short ~df394b.10004688
1000464E F6C3 40 test bl, 40
10004651 76 0E jbe short ~df394b.10004661
10004653 56 push esi
10004654 E8 D74A0000 call ~df394b.10009130
10004659 83C4 04 add esp, 4
1000465C 66:85C0 test ax, ax
1000465F 75 27 jnz short ~df394b.10004688
10004661 F7C3 80000000 test ebx, 80
10004667 76 0E jbe short ~df394b.10004677
10004669 56 push esi
1000466A E8 B1490000 call ~df394b.10009020
1000466F 83C4 04 add esp, 4
10004672 66:85C0 test ax, ax
10004675 75 11 jnz short ~df394b.10004688
10004677 F7C3 00400000 test ebx, 4000
1000467D 76 09 jbe short ~df394b.10004688
1000467F 56 push esi
10004680 E8 CB480000 call ~df394b.10008F50
10004685 83C4 04 add esp, 4
10004688 5E pop esi
10004689 5B pop ebx
1000468A C3 retn
注意:由于我的OD是修改版,所以只需要改一个跳转。你自己调试时,务必不能让其中任何一个jnz跳下去。改的时候,只能修改标志位Z=1。因为后面这个库还有模块完整性的检查。
然后,我们走啊走,走到这里:
1000357D FF75 F8 push dword ptr ss:[ebp-8] ; ~df394b.10000000
10003580 E8 20750100 call ~df394b.1001AAA5 <-进入这个call
10003585 8B43 14 mov eax, dword ptr ds:[ebx+14]
10003588 59 pop ecx
1001AAA5 55 push ebp
1001AAA6 8BEC mov ebp,esp
1001AAA8 81EC 10020000 sub esp,210
1001AAAE 833D 3C220610 00 cmp dword ptr ds:[1006223C],0 <-我们修改这里,把1006223c处的内存清0。
1001AAB5 53 push ebx
1001AAB6 0F84 EF000000 je ~df394b.1001ABAB
走啊走,继续一路返回就可以到入口点了:
006AF027 55 push ebp
006AF028 8BEC mov ebp, esp
006AF02A 6A FF push -1
006AF02C 68 607DF101 push Sakura3.01F17D60
006AF031 68 780A6B00 push Sakura3.006B0A78
006AF036 64:A1 00000000 mov eax, dword ptr fs:[0]
006AF03C 50 push eax
006AF03D 64:8925 0000000>mov dword ptr fs:[0], esp
006AF044 83EC 58 sub esp, 58
006AF047 53 push ebx
006AF048 56 push esi
006AF049 57 push edi
006AF04A 8965 E8 mov dword ptr ss:[ebp-18], esp
006AF04D FF15 6081EC01 call dword ptr ds:[1EC8160]
006AF053 33D2 xor edx, edx
006AF055 8AD4 mov dl, ah
006AF057 8915 04BD0A02 mov dword ptr ds:[20ABD04], edx
006AF05D 8BC8 mov ecx, eax
006AF05F 81E1 FF000000 and ecx, 0FF
006AF065 890D 00BD0A02 mov dword ptr ds:[20ABD00], ecx
006AF06B C1E1 08 shl ecx, 8
006AF06E 03CA add ecx, edx
006AF070 890D FCBC0A02 mov dword ptr ds:[20ABCFC], ecx
006AF076 C1E8 10 shr eax, 10
006AF079 A3 F8BC0A02 mov dword ptr ds:[20ABCF8], eax
006AF07E 6A 01 push 1
006AF080 E8 A47BD5FF call Sakura3.00406C29
小结:现在我们第一次的路程结束了。我们得到了什么?
我们得到了避开调试器检测的方法和调用驱动的过程以及入口点的位置,但是我们却没有得到dump文件和完美的IAT。
继续。
我们现在需要正确代码段。因为如果你细心的看下代码的话,你会发现一些这种代码。
00688CF2 85C0 test eax,eax
00688CF4 CC int3 <-正常的程序会有这种东西吗?
00688CF5 CC int3
00688CF6 8B4424 10 mov eax,dword ptr ss:[esp+10]
00688CFA 8B4D 04 mov ecx,dword ptr ss:[ebp+4]
00688CFD 3BC1 cmp eax,ecx
00688CFF ^ 0F8C D4FEFFFF jl sakuara3.00688BD9
但是怎么得到呢?不能通过调试器,OD不能进驱动,SI被防得又太严。
其实非常的简单,我们只需要运行游戏,在进入游戏后按下windows徽标键强行弹出,再用LordPE把他的代码段dump下来就行了。因为这样做,我们没有对他作过任何手脚,所以它就会安心的写下所有的代码。上面的两个CC也会被一个短距跳转所取代。但后我们只要在OD到达入口点前一点的位置把他作为备份载入即可。
下面是IAT了。在现在的入口点我们可以看到部分Call []后面并没有写出是什么函数。入口点之后第一个这种调用应该是GetVision。那么我们进入看看:
02F43CE4 68 A310EABF push BFEA10A3
02F43CE9 9C pushfd
02F43CEA 60 pushad
02F43CEB 54 push esp
02F43CEC 68 243DF402 push 2F43D24
02F43CF1 E8 9F06110D call ~df394b.10054395 <-进入
02F43CF6 83C4 08 add esp,8
02F43CF9 6A 00 push 0
02F43CFB 58 pop eax
02F43CFC 61 popad
02F43CFD 9D popfd
02F43CFE C3 retn
10054744 FF15 50700510 call near dword ptr ds:[<&KERNEL32.SetEvent>>; kernel32.SetEvent
1005474A 8B65 0C mov esp,dword ptr ss:[ebp+C]
1005474D 61 popad
1005474E 9D popfd
1005474F C3 retn
我们在第二个SetEcent后的retn处下断,运行。停下后看看堆栈:
0012FF44 77E5D142 kernel32.GetVersion <-果然
0012FF48 006AF053 返回到 sakuara3.006AF053 来自 02F43CE4
0012FF4C 77F517E6 返回到 ntdll.77F517E6 来自 ntdll.77F78C4E
0012FF50 77F51778 返回到 ntdll.77F51778 来自 ntdll.77F517B5
这就是SafeDisc对IAT加密形式中一种。尽管这种方法很难手工修复,但是我们发现还是有些IAT是没有被加密的。所以我们就要从这里下手。
重新开始。我们先对其中一个没加密的IAT的位置下硬件断点(软件断点不能下在内存单元上,内存断点会被它在修改内存属性的时候废掉)。运行,避开检测,得到了地址。然后再重来跟踪这个地址,最后我们得到了这些代码。
(这串代码并不好找,这里给大家一个带有人品问题的找法。用你的停在上面提到的要修改的避开调试器检测的跳转的地址+4FAC0,然后g 这个地址之后,在上下的代码段中找一找,一般就能找到了。用NFSU2试了下,还是比较接近的。)
10054088 8B45 F4 mov eax,dword ptr ss:[ebp-C]
1005408B 40 inc eax
1005408C 8945 F4 mov dword ptr ss:[ebp-C],eax
1005408F 8B45 F4 mov eax,dword ptr ss:[ebp-C]
10054092 3B45 14 cmp eax,dword ptr ss:[ebp+14]
10054095 73 55 jnb short ~df394b.100540EC
10054097 8B45 F4 mov eax,dword ptr ss:[ebp-C]
1005409A C1E8 03 shr eax,3
1005409D 8B4D F8 mov ecx,dword ptr ss:[ebp-8]
100540A0 8B15 6C490810 mov edx,dword ptr ds:[1008496C]
100540A6 8B0C8A mov ecx,dword ptr ds:[edx+ecx*4]
100540A9 0FB60401 movzx eax,byte ptr ds:[ecx+eax]
100540AD 8B4D F4 mov ecx,dword ptr ss:[ebp-C]
100540B0 83E1 07 and ecx,7
100540B3 6A 01 push 1
100540B5 5A pop edx
100540B6 D3E2 shl edx,cl
100540B8 23C2 and eax,edx
100540BA 85C0 test eax,eax <-关键,下面不跳的话就会完美很多。。。
100540BC 75 2C jnz short ~df394b.100540EA
100540BE 8B45 F8 mov eax,dword ptr ss:[ebp-8]
100540C1 69C0 8D000000 imul eax,eax,8D
100540C7 8B0D 70490810 mov ecx,dword ptr ds:[10084970]
100540CD 8B4401 4C mov eax,dword ptr ds:[ecx+eax+4C]
100540D1 8B4D F4 mov ecx,dword ptr ss:[ebp-C]
100540D4 FF3488 push dword ptr ds:[eax+ecx*4]
100540D7 FF75 F8 push dword ptr ss:[ebp-8]
100540DA E8 DB000000 call ~df394b.100541BA
100540DF 59 pop ecx
100540E0 59 pop ecx
100540E1 8B4D F4 mov ecx,dword ptr ss:[ebp-C]
100540E4 8B55 18 mov edx,dword ptr ss:[ebp+18]
100540E7 89048A mov dword ptr ds:[edx+ecx*4],eax
100540EA ^ EB 9C jmp short ~df394b.10054088
于是我们修改100540B8修改为Xor eax,eax,然后运行到入口点,我们发现了几乎完美的IAT。。。
打开ImortREC取得IAT,发现还有1个无效的指针:[1ec8064]=02f310e7。
我们查找命令Call [1ec8064]。找到006ac1c7。新建EIP跟的这个是GetTickCount。
现在IAT修复了。似乎所有的任务都完成了。但是现实却不是这样,SafeDisc还用jmp [eax],jmp ********加密了一些函数和过程的调用。
小结:到这里第二步也完成了,我们得到了几乎完美的文件。
下面就剩文件的修复了,继续。
今天下午,我着手开始修复代码,一开始我以为要修复的代码不会很多,所以就手工一个个的修复。
我们打开两个OD,一个直接走到入口点(一下简称B),另一个修复IAT后再走到入口点(一下简称A)。
然后我们进入B的入口点之后的第一个调用,就是前面提到的GetVision的调用,到达这里
1005472F E8 AA14FDFF call ~df394b.10025BDE
10054734 59 pop ecx
10054735 F0:FF0D 646C0610 lock dec dword ptr ds:[10066C64]
1005473C 78 0C js short ~df394b.1005474A <-我们在这里Patch
1005473E FF35 D8490810 push dword ptr ds:[100849D8]
10054744 FF15 50700510 call near dword ptr ds:[<&KERNEL32.SetE>; kernel32.SetEvent
1005474A 8B65 0C mov esp,dword ptr ss:[ebp+C]
1005474D 61 popad
1005474E 9D popfd
1005474F C3 retn
10054750 F0:FF0D 646C0610 lock dec dword ptr ds:[10066C64]
10054757 78 0C js short ~df394b.10054765
10054759 FF35 D8490810 push dword ptr ds:[100849D8]
1005475F FF15 50700510 call near dword ptr ds:[<&KERNEL32.SetE>; kernel32.SetEvent
10054765 5F pop edi
Patch之后
1005473C 8B65 0C mov esp,dword ptr ss:[ebp+C]
1005473F 61 popad
10054740 9D popfd
10054741 83C4 04 add esp,4<-在这里下断点(软件断点就够了)
10054744 C3 retn
10054745 90 nop
10054746 90 nop
10054747 90 nop
10054748 90 nop
10054749 90 nop
然后运行,暂停时堆栈的第一行就是IAT的名称和地址。
我们在进入A,比较一下这两个IAT是不是一样,不一样就在IAT表中找一个和他一样的,再把这个调用的内存地址修改成我们需要的。为什么要这样呢?因为SafeDisc加密的部分IAT调用不具有唯一性。就是说在不同的地方调用同一个内存地址,所获得的IAT并不一定是一样的。
我们就从00401000的地方开始。查找二进制字符FF15,然后开他调用的内存地址,如果是01EC8XXX那就是我们要的。在B中的那里新建EIP,然后运行,断下时和A中显示的IAT作一下比较,不同的就在A的IAT表中找一个和B中是计算出来的IAT一样的内存地址改写到A中的调用里去。然后循环处理整个代码段知道找不到为止。然后还有E9????01(要是跨段跳的那种),和一个Call的重定向。
不过做了几个之后,我发现自己错了,结果我一下午的时间就这样报销了。不过大家可以看看修复过的地方吧,应该会有某种比较深刻的印象的。。。
Call加密系列
006AF080 call sakuara3.006B0CE0
可能还有,但是我没心情看代码了,下一次测试一下就知道了。
Call []加密系列
0057830A call near dword ptr ds:[1EC8054] ; GDI32.CreateDIBSection
005804CA call near dword ptr ds:[1EC8258] ; ole32.CoCreateInstance
00583BCA call near dword ptr ds:[1EC8054] ; GDI32.CreateDIBSection
0058808A call near dword ptr ds:[1EC8150] ; ntdll.RtlUnwind
0058C9CA call near dword ptr ds:[1EC8038] ; GDI32.GetObjectA
0058EF3A call near dword ptr ds:[1EC81CC] ; USER32.GetDC
005A91CA call near dword ptr ds:[1EC81EC] ; USER32.ShowWindow
005ABE4A call near dword ptr ds:[1EC8260] ; ole32.CoTaskMemAlloc
005C7D3A call near dword ptr ds:[1EC8258] ; ole32.CoCreateInstance
005D99AA call near dword ptr ds:[1EC8048] ; GDI32.SelectObject
0061566A call near dword ptr ds:[1EC8170] ; kernel32.TlsAlloc
006156AA call near dword ptr ds:[1EC8260] ; ole32.CoTaskMemAlloc
00615BCA call near dword ptr ds:[1EC81CC] ; USER32.GetDC
0061B61A call near dword ptr ds:[1EC803C] ; GDI32.DeleteObject
0063D47A call near dword ptr ds:[1EC820C] ; USER32.GetQueueStatus
0063FCEA call near dword ptr ds:[1EC802C] ; GDI32.GetDeviceCaps
00641A2A call near dword ptr ds:[1EC80B0] ; kernel32.WaitForMultipleObjects
00642E8A call near dword ptr ds:[1EC8268] ; ole32.CoInitialize
00648E5A call near dword ptr ds:[1EC8048] ; GDI32.SelectObject
0064B96A call near dword ptr ds:[1EC80D0] ; kernel32.LCMapStringA
0064C72A call near dword ptr ds:[1EC8268] ; ole32.CoInitialize
0064E77A call near dword ptr ds:[1EC80D0] ; kernel32.LCMapStringA
0064EE0A call near dword ptr ds:[1EC8258] ; ole32.CoCreateInstance
00659AEA call near dword ptr ds:[1EC8090] ; kernel32.DeleteFileA
00666E3A call near dword ptr ds:[1EC80B0] ; kernel32.WaitForMultipleObjects
0066703A call near dword ptr ds:[1EC8258] ; ole32.CoCreateInstance
0066899A call near dword ptr ds:[1EC80B0] ; kernel32.WaitForMultipleObjects
00668CBA call near dword ptr ds:[1EC8268] ; ole32.CoInitialize
00668DDA call near dword ptr ds:[1EC8204] ; USER32.DrawTextW
0066948A call near dword ptr ds:[1EC8044] ; GDI32.CreateCompatibleDC
0066AFB0 call near dword ptr ds:[1EC8128] ; kernel32.ReadFile
0066B0A0 call near dword ptr ds:[1EC80B4] ; kernel32.SetFilePointer
0066DD4A call near dword ptr ds:[1EC8024] ; GDI32.SetBkColor
00671078 call near dword ptr ds:[1EC81F4] ; USER32.SetCursorPos
00671418 call near dword ptr ds:[1EC80AC] ; kernel32.MultiByteToWideChar
006717CA call near dword ptr ds:[1EC81E4] ; USER32.SetFocus
0068167A call near dword ptr ds:[1EC80B0] ; kernel32.WaitForMultipleObjects
00682FAA call near dword ptr ds:[1EC81CC] ; USER32.GetDC
006880C4 call near dword ptr ds:[1EC8128] ; kernel32.ReadFile
00688142 call near dword ptr ds:[1EC8098] ; kernel32.CreateFileA
0068817E call near dword ptr ds:[1EC80A4] ; kernel32.CloseHandle
00688265 call near dword ptr ds:[1EC8098] ; kernel32.CreateFileA
006882AA call near dword ptr ds:[1EC80B8] ; kernel32.GetFileTime
006882BA call near dword ptr ds:[1EC80BC] ; kernel32.FileTimeToSystemTime
006882F4 call near dword ptr ds:[1EC80A4] ; kernel32.CloseHandle
00688362 call near dword ptr ds:[1EC8098] ; kernel32.CreateFileA
0068837F call near dword ptr ds:[1EC8094] ; kernel32.GetFileSize
00688395 call near dword ptr ds:[1EC80A4] ; kernel32.CloseHandle
006884A6 call near dword ptr ds:[1EC8078] ; kernel32.FindClose
006884C1 call near dword ptr ds:[1EC8074] ; kernel32.FindFirstFileA
0068859F call near dword ptr ds:[1EC8078] ; kernel32.FindClose
00688951 call near dword ptr ds:[1EC8128] ; kernel32.ReadFile
006889A8 call near dword ptr ds:[1EC809C] ; kernel32.WriteFile
00688CEC call near dword ptr ds:[1EC808C] ; kernel32.FindNextFileA
00688EA1 call near dword ptr ds:[1EC8098] ; kernel32.CreateFileA
00688F4A call near dword ptr ds:[1EC8260] ; ole32.CoTaskMemAlloc
006894C4 call near dword ptr ds:[1EC8080] ; kernel32.WaitForSingleObject
0068A230 call near dword ptr ds:[1EC8064] ; kernel32.GetTickCount
0068A2A0 call near dword ptr ds:[1EC8064] ; kernel32.GetTickCount
0068A3C0 call near dword ptr ds:[1EC8064] ; kernel32.GetTickCount
0068A430 call near dword ptr ds:[1EC8064] ; kernel32.GetTickCount
0068A490 call near dword ptr ds:[1EC822C] ; USER32.DestroyWindow
0068A508 call near dword ptr ds:[1EC806C] ; ntdll.RtlGetLastWin32Error
0068A5AD call near dword ptr ds:[1EC8268] ; ole32.CoInitialize
0068A5B4 call near dword ptr ds:[1EC81CC] ; USER32.GetDC
0068A5ED call near dword ptr ds:[1EC821C] ; USER32.ReleaseDC
0068A65B call near dword ptr ds:[1EC8220] ; USER32.AdjustWindowRect
0068A6C1 call near dword ptr ds:[1EC8228] ; USER32.UpdateWindow
0068A8B6 call near dword ptr ds:[1EC81C8] ; USER32.PostQuitMessage
0068A95F call near dword ptr ds:[1EC81E8] ; USER32.DefWindowProcA
0068A992 call near dword ptr ds:[1EC81E8] ; USER32.DefWindowProcA
0068E3D9 call near dword ptr ds:[1EC803C] ; GDI32.DeleteObject
0068F50F call near dword ptr ds:[1EC800C] ; ADVAPI32.RegOpenKeyA
0068F78C call near dword ptr ds:[1EC8100] ; kernel32.IsProcessorFeaturePresent
0068FBE8 call near dword ptr ds:[1EC8048] ; GDI32.SelectObject
0068FD10 call near dword ptr ds:[1EC8024] ; GDI32.SetBkColor
0068FD2D call near dword ptr ds:[1EC8048] ; GDI32.SelectObject
0068FE34 call near dword ptr ds:[1EC8204] ; USER32.DrawTextW
0068FE3C call near dword ptr ds:[1EC8200] ; USER32.DrawTextA
0068FF73 call near dword ptr ds:[1EC8048] ; GDI32.SelectObject
0069000B call near dword ptr ds:[1EC8200] ; USER32.DrawTextA
006A6F2B call near dword ptr ds:[1EC8104] ; kernel32.SetEvent
006A71EB call near dword ptr ds:[1EC8118] ; kernel32.ResetEvent
006A71FA call near dword ptr ds:[1EC8104] ; kernel32.SetEvent
006A72BF call near dword ptr ds:[1EC820C] ; USER32.GetQueueStatus
006A72DA call near dword ptr ds:[1EC8208] ; USER32.PostThreadMessageA
006A739E call near dword ptr ds:[1EC8104] ; kernel32.SetEvent
006A73AE call near dword ptr ds:[1EC8118] ; kernel32.ResetEvent
006A7491 call near dword ptr ds:[1EC810C] ; ntdll.RtlDeleteCriticalSection
006A785C call near dword ptr ds:[1EC8104] ; kernel32.SetEvent
006A7A60 call near dword ptr ds:[1EC8118] ; kernel32.ResetEvent
006A7E35 call near dword ptr ds:[1EC8104] ; kernel32.SetEvent
006A92DA call near dword ptr ds:[1EC8124] ; kernel32.MulDiv
006A9663 call near dword ptr ds:[1EC8258] ; ole32.CoCreateInstance
006A9E38 call near dword ptr ds:[1EC8258] ; ole32.CoCreateInstance
006A9E5F call near dword ptr ds:[1EC8254] ; ole32.CoUninitialize
006A9EA9 call near dword ptr ds:[1EC8258] ; ole32.CoCreateInstance
006A9ED4 call near dword ptr ds:[1EC8254] ; ole32.CoUninitialize
006AA0A8 call near dword ptr ds:[1EC80C0] ; kernel32.InterlockedIncrement
006AA47A call near dword ptr ds:[1EC812C] ; kernel32.InterlockedDecrement
006AA612 call near dword ptr ds:[1EC8260] ; ole32.CoTaskMemAlloc
006ABA68 call near dword ptr ds:[1EC80C0] ; kernel32.InterlockedIncrement
006ABA85 call near dword ptr ds:[1EC812C] ; kernel32.InterlockedDecrement
006ABA99 call near dword ptr ds:[1EC80CC] ; kernel32.FreeLibrary
006ABB69 call near dword ptr ds:[1EC80C0] ; kernel32.InterlockedIncrement
006AC0E1 call near dword ptr ds:[1EC8064] ; kernel32.GetTickCount
006AC101 call near dword ptr ds:[1EC80B0] ; kernel32.WaitForMultipleObjects
006AC22E call near dword ptr ds:[1EC80B0] ; kernel32.WaitForMultipleObjects
006AC250 call near dword ptr ds:[1EC8148] ; kernel32.GetThreadPriority
006AC2C0 call near dword ptr ds:[1EC811C] ; kernel32.GetCurrentThreadId
006AC37B call near dword ptr ds:[1EC806C] ; ntdll.RtlGetLastWin32Error
006AC3D6 call near dword ptr ds:[1EC806C] ; ntdll.RtlGetLastWin32Error
006ACFD2 call near dword ptr ds:[1EC8108] ; kernel32.InitializeCriticalSection
006AD73F call near dword ptr ds:[1EC8260] ; ole32.CoTaskMemAlloc
006AF0FB call near dword ptr ds:[1EC80FC] ; kernel32.GetModuleHandleA
006AF3EA call near dword ptr ds:[1EC8168] ; kernel32.TerminateProcess
006B04D2 call near dword ptr ds:[1EC8170] ; kernel32.TlsAlloc
006B050B call near dword ptr ds:[1EC811C] ; kernel32.GetCurrentThreadId
006B0578 call near dword ptr ds:[1EC811C] ; kernel32.GetCurrentThreadId
006B058F call near dword ptr ds:[1EC8178] ; ntdll.RtlSetLastWin32Error
006B0749 call near dword ptr ds:[1EC8154] ; ntdll.RtlAllocateHeap
006B07A0 call near dword ptr ds:[1EC8180] ; ntdll.RtlReAllocateHeap
006B08B1 call near dword ptr ds:[1EC8154] ; ntdll.RtlAllocateHeap
006B0A49 call near dword ptr ds:[1EC8184] ; ntdll.RtlSizeHeap
006B0B75 call near dword ptr ds:[1EC80FC] ; kernel32.GetModuleHandleA
006B0C4C call near dword ptr ds:[1EC8188] ; kernel32.GetModuleFileNameA
006B0CF1 call near dword ptr ds:[1EC8194] ; kernel32.HeapCreate
006B1458 call near dword ptr ds:[1EC8134] ; kernel32.VirtualAlloc
006B14E4 call near dword ptr ds:[1EC8134] ; kernel32.VirtualAlloc
006B18A5 call near dword ptr ds:[1EC8154] ; ntdll.RtlAllocateHeap
006B19A4 call near dword ptr ds:[1EC80C4] ; kernel32.VirtualFree
006B19D7 call near dword ptr ds:[1EC80C4] ; kernel32.VirtualFree
006B5800 call near dword ptr ds:[1EC81A0] ; kernel32.UnhandledExceptionFilter
006B5C70 call near dword ptr ds:[1EC81A8] ; kernel32.FreeEnvironmentStringsW
006B5DDD call near dword ptr ds:[1EC81BC] ; kernel32.GetFileType
006B5E4E call near dword ptr ds:[1EC81BC] ; kernel32.GetFileType
006B5E85 call near dword ptr ds:[1EC81B4] ; kernel32.SetHandleCount
006B5F36 call near dword ptr ds:[1EC8188] ; kernel32.GetModuleFileNameA
006B600C call near dword ptr ds:[1EC81B8] ; kernel32.GetStdHandle
006B67A9 call near dword ptr ds:[1EC80C0] ; kernel32.InterlockedIncrement
006B6E98 call near dword ptr ds:[1EC8174] ; kernel32.SetUnhandledExceptionFilter
006B724C call near dword ptr ds:[1EC806C] ; ntdll.RtlGetLastWin32Error
006B73B4 call near dword ptr ds:[1EC809C] ; kernel32.WriteFile
006B742E call near dword ptr ds:[1EC806C] ; ntdll.RtlGetLastWin32Error
006B7651 call near dword ptr ds:[1EC80C0] ; kernel32.InterlockedIncrement
006B76E7 call near dword ptr ds:[1EC80E8] ; kernel32.WideCharToMultiByte
006B7760 call near dword ptr ds:[1EC80DC] ; kernel32.GetStringTypeA
006B7794 call near dword ptr ds:[1EC80DC] ; kernel32.GetStringTypeA
006B77CC call near dword ptr ds:[1EC80AC] ; kernel32.MultiByteToWideChar
006B7834 call near dword ptr ds:[1EC80D8] ; kernel32.GetStringTypeW
006B7DFD call near dword ptr ds:[1EC80C0] ; kernel32.InterlockedIncrement
006B7F07 call near dword ptr ds:[1EC80AC] ; kernel32.MultiByteToWideChar
006B84AC call near dword ptr ds:[1EC80F8] ; kernel32.LoadLibraryA
006B891E call near dword ptr ds:[1EC80D0] ; kernel32.LCMapStringA
006B8967 call near dword ptr ds:[1EC80D0] ; kernel32.LCMapStringA
006B899F call near dword ptr ds:[1EC80AC] ; kernel32.MultiByteToWideChar
006B89F7 call near dword ptr ds:[1EC80AC] ; kernel32.MultiByteToWideChar
006B8F69 call near dword ptr ds:[1EC80C0] ; kernel32.InterlockedIncrement
006B917C call near dword ptr ds:[1EC8108] ; kernel32.InitializeCriticalSection
006B920D call near dword ptr ds:[1EC810C] ; ntdll.RtlDeleteCriticalSection
006B96F3 call near dword ptr ds:[1EC8128] ; kernel32.ReadFile
006B97CD call near dword ptr ds:[1EC806C] ; ntdll.RtlGetLastWin32Error
006B9920 call near dword ptr ds:[1EC806C] ; ntdll.RtlGetLastWin32Error
JMP加密系列
0066B050 call near dword ptr ds:[1EC8128] ; kernel32.ReadFile
00688177 call near dword ptr ds:[1EC8128] ; kernel32.ReadFile
00688709 call near dword ptr ds:[1EC8074] ; kernel32.FindFirstFileA
0068A4FE call near dword ptr ds:[1EC8068] ; kernel32.CreateMutexA
0068A56B call near dword ptr ds:[1EC81D4] ; USER32.LoadCursorA
0068A6B5 call near dword ptr ds:[1EC81EC] ; USER32.ShowWindow
0068A930 call near dword ptr ds:[1EC81E8] ; USER32.DefWindowProcA
0068AC10 call near dword ptr ds:[1EC8038] ; GDI32.GetObjectA
00690003 call near dword ptr ds:[1EC8204] ; USER32.DrawTextW
006A72DA call near dword ptr ds:[1EC8208] ; USER32.PostThreadMessageA
006A7361 call near dword ptr ds:[1EC8104] ; kernel32.SetEvent
006A788D call near dword ptr ds:[1EC8118] ; kernel32.ResetEvent
006A9E90 call near dword ptr ds:[1EC8268] ; ole32.CoInitialize
006AA0CA call near dword ptr ds:[1EC812C] ; kernel32.InterlockedDecrement
006AF839 call near dword ptr ds:[1EC80F4] ; kernel32.GetProcAddress
006B0567 call near dword ptr ds:[1EC816C] ; kernel32.TlsSetValue
006B08F2 call near dword ptr ds:[1EC8180] ; ntdll.RtlReAllocateHeap
006B0BEC call near dword ptr ds:[1EC818C] ; kernel32.GetEnvironmentVariableA
006B5978 call near dword ptr ds:[1EC8188] ; kernel32.GetModuleFileNameA
006B7401 call near dword ptr ds:[1EC806C] ; ntdll.RtlGetLastWin32Error
006B7419 call near dword ptr ds:[1EC809C] ; kernel32.WriteFile
全部搞完之后,我决定,如果下次还要搞这种东西话,我一定要写Patch代码。还好樱花大战3的代码段只有2C700H。。。(如果哪位高手写出来的话,我也想要一份^_^)
现在我们要把A的00401000段和01EC8000段备份下来。不然以后要在用的话会死人的。
小结:第三部分完成了,我们把能看到的代码全部修补了,下面就等我硬盘有空间的时候把游戏装上测试了,毕竟这个游戏还是有3G那么大的。
神啊,祝福我把~~~~!!!
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!