【脱文作者】 simonzh2000[US]
【使用工具】 Ollydbg1.10, UnPECompact, LordPE, ImportREC
【破解平台】 Win2000SP4 English
【软件名称】 苍鹰象棋 1.0
【软件简介】 象棋苍鹰软件是中国大陆大连金星工作室生产的一款人工智能软件。
本程序的特点是功能多,棋力强,集人机对弈和打谱软件于一身,是学习象棋,提高象棋水平的好帮手。
本程式的联众对弈功能是采用了联众外挂软件的方式实现的,一旦联众的内部协议改变了,本系统也会正常运行。
【软件主页】 http://www.cangying.com
【加壳方式】 主程序用 PECompact 1.84 加壳, 用 UnPECompact 脱壳即可, 破文见我发表在 "软件调试论坛" 的文章
联众外挂 GLOCX.OCX 也是一样的壳, 但 UnPECompact 不支持 OCX , 只好手脱.
OCX 类似于 DLL, 也需要处理 重定位表.
PECompact 对重定位表做了加密变形, 看雪老大有个工具修复, 但今天我们用更简单的方法修复.
【作者声明】 本笔记只用于学习交流, 初学Crack,只是感兴趣技术,没有其他目的, 如有不妥之处, 希望作者谅解.
用 OD 载入 GLOCX.OCX
代码:
1000D000 > /EB 06 JMP SHORT GLOCX.1000D008 1000D002 |68 694A0000 PUSH 4A69 1000D007 |C3 RETN 1000D008 \9C PUSHFD 1000D009 60 PUSHAD // PECompact 可用 ESP 定律直接到 OEP // 但 OCX 需要处理重定位表, 需要跟踪一下 // BP virtualFree, F9, 断下, Ctrl+F9, F7 回到 1000E381 ..... 1000E1F2 6A 04 PUSH 4 1000E1F4 68 00100000 PUSH 1000 1000E1F9 FFB5 51974000 PUSH DWORD PTR SS:[EBP+409751] 1000E1FF 6A 00 PUSH 0 1000E201 FF95 41974000 CALL DWORD PTR SS:[EBP+409741] ;// KERNEL32.VirtualAlloc 1000E207 8BF8 MOV EDI,EAX 1000E373 68 00400000 PUSH 4000 1000E378 6A 00 PUSH 0 1000E37A 57 PUSH EDI 1000E37B FF95 45974000 CALL DWORD PTR SS:[EBP+409745] ;// KERNEL32.VirtualFree 1000E381 8BBD 3C964000 MOV EDI,DWORD PTR SS:[EBP+40963C] ;// F7 走 1000E387 03BD E6904000 ADD EDI,DWORD PTR SS:[EBP+4090E6] 1000E38D 8B8D 40964000 MOV ECX,DWORD PTR SS:[EBP+409640] 1000E393 51 PUSH ECX 1000E394 57 PUSH EDI 1000E395 33D2 XOR EDX,EDX 1000E397 33DB XOR EBX,EBX 1000E399 33F6 XOR ESI,ESI 1000E39B 03FE ADD EDI,ESI 1000E39D 03DE ADD EBX,ESI 1000E39F 49 DEC ECX 1000E3A0 74 72 JE SHORT GLOCX.1000E414 ;// 1000E414 是循环出口, F4 到那里 1000E3A2 78 70 JS SHORT GLOCX.1000E414 1000E3A4 66:8B07 MOV AX,WORD PTR DS:[EDI] 1000E3A7 2C E8 SUB AL,0E8 1000E3A9 3C 01 CMP AL,1 1000E3AB 76 38 JBE SHORT GLOCX.1000E3E5 1000E3AD 66:3D 1725 CMP AX,2517 1000E3B1 74 51 JE SHORT GLOCX.1000E404 1000E3B3 3C 27 CMP AL,27 1000E3B5 75 0A JNZ SHORT GLOCX.1000E3C1 1000E3B7 80FC 80 CMP AH,80 1000E3BA 72 05 JB SHORT GLOCX.1000E3C1 1000E3BC 80FC 8F CMP AH,8F 1000E3BF 76 05 JBE SHORT GLOCX.1000E3C6 1000E3C1 47 INC EDI 1000E3C2 43 INC EBX 1000E3C3 ^ EB DA JMP SHORT GLOCX.1000E39F 1000E414 5F POP EDI 1000E415 59 POP ECX 1000E416 33C0 XOR EAX,EAX 1000E418 85C9 TEST ECX,ECX 1000E41A 74 3B JE SHORT GLOCX.1000E457 1000E41C 8BF7 MOV ESI,EDI 1000E41E 33C0 XOR EAX,EAX 1000E420 83F9 04 CMP ECX,4 1000E423 72 32 JB SHORT GLOCX.1000E457 1000E425 87DB XCHG EBX,EBX 1000E427 87DB XCHG EBX,EBX 1000E429 87DB XCHG EBX,EBX 1000E42B 87DB XCHG EBX,EBX 1000E42D 87DB XCHG EBX,EBX 1000E42F 8B1E MOV EBX,DWORD PTR DS:[ESI] 1000E431 03C3 ADD EAX,EBX 1000E433 D1E3 SHL EBX,1 1000E435 83D3 01 ADC EBX,1 1000E438 33C3 XOR EAX,EBX 1000E43A 83C6 04 ADD ESI,4 1000E43D 83E9 04 SUB ECX,4 1000E440 74 15 JE SHORT GLOCX.1000E457 ;// 1000E457 又是循环出口, F4 到那里 1000E442 83F9 04 CMP ECX,4 1000E445 ^ 73 E8 JNB SHORT GLOCX.1000E42F 1000E447 BA 04000000 MOV EDX,4 1000E44C 2BD1 SUB EDX,ECX 1000E44E 2BF2 SUB ESI,EDX 1000E450 B9 04000000 MOV ECX,4 1000E455 ^ EB D8 JMP SHORT GLOCX.1000E42F 1000E457 3B85 67974000 CMP EAX,DWORD PTR SS:[EBP+409767] 1000E45D 74 4D JE SHORT GLOCX.1000E4AC ;// F7 1000E45F ^ E9 4FFEFFFF JMP GLOCX.1000E2B3 1000E4AC E8 A1010000 CALL GLOCX.1000E652 ;// 处理重定位的CALL, F7 1000E4B1 E8 A3000000 CALL GLOCX.1000E559 ;// F8 // PEcompact 对重定位表做了变形加密, 下面这段代码就是根据变形的重定位表处理 重定位项 // 看雪老大写了一个工具, 可修复 PECompact 变形的重定位表 // 今天我们用更简单的办法来修复重定位表, Let's go 1000E652 8B9D E6904000 MOV EBX,DWORD PTR SS:[EBP+4090E6] ;// [1000E1B5]=10000000 1000E658 3B9D 5F974000 CMP EBX,DWORD PTR SS:[EBP+40975F] ;// [1000E825]=10000000 1000E65E 75 01 JNZ SHORT GLOCX.1000E661 ;// 修改 Z 标志位=0, 强行跳入 1000E660 C3 RETN 1000E661 8BB5 63974000 MOV ESI,DWORD PTR SS:[EBP+409763] ;// ESI=B000, 重定位表的开始 RVA 1000E667 03F3 ADD ESI,EBX 1000E669 33C0 XOR EAX,EAX 1000E66B 66:8B43 3C MOV AX,WORD PTR DS:[EBX+3C] 1000E66F 03C3 ADD EAX,EBX 1000E671 8B80 C0000000 MOV EAX,DWORD PTR DS:[EAX+C0] 1000E677 85C0 TEST EAX,EAX 1000E679 75 08 JNZ SHORT GLOCX.1000E683 1000E67B 2B9D 5F974000 SUB EBX,DWORD PTR SS:[EBP+40975F] 1000E681 EB 0F JMP SHORT GLOCX.1000E692 1000E683 03C3 ADD EAX,EBX 1000E685 2B9D 5F974000 SUB EBX,DWORD PTR SS:[EBP+40975F] 1000E68B 0118 ADD DWORD PTR DS:[EAX],EBX 1000E68D 83C0 04 ADD EAX,4 1000E690 0118 ADD DWORD PTR DS:[EAX],EBX 1000E692 AD LODS DWORD PTR DS:[ESI] ; // 开始处理一段 1000E693 0BC0 OR EAX,EAX 1000E695 74 6F JE SHORT GLOCX.1000E706 ; // 为 0 则所有段处理完毕 1000E697 8BD0 MOV EDX,EAX 1000E699 0395 E6904000 ADD EDX,DWORD PTR SS:[EBP+4090E6] ; // RVA -> VA, EDX=每一段的 BASE VA 1000E69F AD LODS DWORD PTR DS:[ESI] ; // 每一段的长度 1000E6A0 8BC8 MOV ECX,EAX 1000E6A2 83E9 08 SUB ECX,8 1000E6A5 D1E9 SHR ECX,1 ; // (长度 - 8)/2 = 每一段的重定位项数 1000E6A7 66:C785 55974000 0000 MOV WORD PTR SS:[EBP+409755],0 ; // 初始值, 变形的关键 1000E6B0 33C0 XOR EAX,EAX 1000E6B2 66:AD LODS WORD PTR DS:[ESI] ; // 一项两个字节 1000E6B4 0BC0 OR EAX,EAX 1000E6B6 74 49 JE SHORT GLOCX.1000E701 ; // 如该项 = 0 直接跳过 1000E6B8 66:0385 55974000 ADD AX,WORD PTR SS:[EBP+409755] 1000E6BF 66:8985 55974000 MOV WORD PTR SS:[EBP+409755],AX 1000E6C6 50 PUSH EAX ; // 变形值已还原 1000E6C7 C1E8 0C SHR EAX,0C ; // 开始常规处理 1000E6CA 83F8 01 CMP EAX,1 1000E6CD 75 0E JNZ SHORT GLOCX.1000E6DD 1000E6CF 58 POP EAX 1000E6D0 25 FF0F0000 AND EAX,0FFF 1000E6D5 03C2 ADD EAX,EDX 1000E6D7 66:0158 02 ADD WORD PTR DS:[EAX+2],BX 1000E6DB EB 24 JMP SHORT GLOCX.1000E701 1000E6DD 83F8 02 CMP EAX,2 1000E6E0 75 0D JNZ SHORT GLOCX.1000E6EF 1000E6E2 58 POP EAX 1000E6E3 25 FF0F0000 AND EAX,0FFF 1000E6E8 03C2 ADD EAX,EDX 1000E6EA 66:0118 ADD WORD PTR DS:[EAX],BX 1000E6ED EB 12 JMP SHORT GLOCX.1000E701 1000E6EF 83F8 03 CMP EAX,3 1000E6F2 75 0C JNZ SHORT GLOCX.1000E700 1000E6F4 58 POP EAX 1000E6F5 25 FF0F0000 AND EAX,0FFF 1000E6FA 03C2 ADD EAX,EDX 1000E6FC 0118 ADD DWORD PTR DS:[EAX],EBX 1000E6FE EB 01 JMP SHORT GLOCX.1000E701 1000E700 58 POP EAX ; // 不符合 EAX=1,2,3 则不处理 1000E701 49 DEC ECX 1000E702 ^ 75 AC JNZ SHORT GLOCX.1000E6B0 ; // 该段还没结束, 处理下一项 1000E704 ^ EB 8C JMP SHORT GLOCX.1000E692 ; // 该段结束, 处理下一段 1000E706 C3 RETN // 到 1000E6C6 后, 修改代码段如下, 可修复重定位表 1000E6C6 66:8946 FE MOV WORD PTR DS:[ESI-2],AX 1000E6CA 49 DEC ECX 1000E6CB ^ 75 E3 JNZ SHORT 1000E6B0 1000E6CD ^ EB C3 JMP SHORT 1000E692 // 修改好后, F4 到 1000E706, Undo Selection 1000E706 C3 RETN ; // ret to 1000E4B1, 这时 ESI = 1000B75C // 所以重定位表长度为 1000B75C-4-1000B000 = 758 1000E4B1 E8 A3000000 CALL GLOCX.1000E559 ;// F8, 应该是处理 IAT 的 CALL 1000E4B6 /73 6B JNB SHORT GLOCX.1000E523 ;// F7 1000E523 \80BD 6B9F4000 C3 CMP BYTE PTR SS:[EBP+409F6B],0C3 1000E52A 74 22 JE SHORT GLOCX.1000E54E ;// F7 1000E54E 61 POPAD 1000E54F 9D POPFD 1000E550 50 PUSH EAX 1000E551 68 694A0010 PUSH GLOCX.10004A69 1000E556 C2 0400 RETN 4 ;// To OEP 10004A69 55 PUSH EBP ;// OllyDump 10004A6A 8BEC MOV EBP,ESP 10004A6C 53 PUSH EBX
ImportREC, OEP=4A69, IAT AutoSearch, RVA=4FFC,Size=44C
实际上 RVA=5000, Size=448, Get Imports
FixDump, not add new section, RVA=6700, size=2B0
LordPE 修改重定位表为 RVA=B000, Size=758, OK.