【破解作者】 layper
【作者邮箱】 layper2002@yahoo.com.cn
【作者主页】 http://free4.e-168.cn/layper
【使用工具】 PEID,OD,LordPE,ImportREC
【破解平台】 Win9x/NT/2000/XP
【软件名称】 天骄2登陆精灵1.2版
【下载地址】 http://down1.77wg.com/tj2/tj2login1.2.exe
【软件大小】 547k
【加壳方式】 Armadillo 1.xx - 2.xx -> Silicon Realms Toolworks [重叠]
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------
【破解内容】
这段时间蛮多脱Armadillo的文章,我也凑凑热闹来一篇,高手略过了。
OD载入,忽略所有异常,隐藏OD
004B6E10 > 55 push ebp ;停在入口处
004B6E11 8BEC mov ebp,esp
004B6E13 6A FF push -1
004B6E15 68 A01A4D00 push loginTJ2.004D1AA0
004B6E1A 68 E86A4B00 push loginTJ2.004B6AE8
脱Armadillo我喜欢先dump,然后在修复IAT查找Magic Jump,这样的好处是向我这样的的菜鸟能够分步进行,一旦出错能少走几步
(1)查找OEP
在命令行中先下he WaitForDebugEvent断点,这个函数有两个参数,其中一个指向接收调试事件信息DEBUG_ENENT的指针,
Shift+F9运行
77E8F13C > 55 push ebp ;来到这里,注意此时的堆栈处
77E8F13D 8BEC mov ebp,esp
77E8F13F 83EC 68 sub esp,68
77E8F142 56 push esi
77E8F143 FF75 0C push dword ptr ss:[ebp+C]
堆栈处如下
0012BCAC 004A7015 /CALL 到 WaitForDebugEvent 来自 loginTJ2.004A700F
0012BCB0 0012CD84 |pDebugEvent = 0012CD84 ;这个就是指针了,在数据窗口跟随,取消he WaitForDebugEvent断点
0012BCB4 000003E8 \Timeout = 1000. ms
继续在命令行下he WriteProcessMemory断点,Shift+F9运行
77E41A94 > 55 push ebp ;来到这里,看看堆栈处
77E41A95 8BEC mov ebp,esp
77E41A97 51 push ecx
77E41A98 51 push ecx
77E41A99 8B45 0C mov eax,dword ptr ss:[ebp+C]
0012BB4C 004AAFA5 /CALL 到 WriteProcessMemory 来自 loginTJ2.004AAF9F
0012BB50 0000004C |hProcess = 0000004C (window)
0012BB54 0046E000 |Address = 46E000 ;这里是欲写入区域的基地址
0012BB58 003A3C20 |Buffer = 003A3C20
0012BB5C 00001000 |BytesToWrite = 1000 (4096.)
0012BB60 0012BC68 \pBytesWritten = 0012BC68
刚才我们下he WaitForDebugEvent断点之后在数据窗口跟随到 0012CD84,我们现在在数据窗口处来回转动可以在0012cd9c处看到
0012CD9C 0046E70C loginTJ2.0046E70C ;0046E70C就是我们要找的OEP了,取消断点
(2)dump
重新在OD中载入程序,重新下he WaitForDebugEvent
Shift+F9运行,取消断点Alt+F9返回
004A7015 85C0 test eax,eax ;返回这里
004A7017 0F84 23270000 je loginTJ2.004A9740
004A701D 8B95 FCFDFFFF mov edx,dword ptr ss:[ebp-204]
004A7023 81E2 FF000000 and edx,0FF
在这里右键-搜索-全部常数,输入常数FFFFFFF8搜索,来到参考窗口
004A7015 test eax,eax ;这是我们刚才对应地方
004A75DD or eax,FFFFFFF8 ;双击跟随
004A7591 83BD CCF5FFFF 0>cmp dword ptr ss:[ebp-A34],0 ;找到这里,下硬件断点运行到这里
004A7598 0F8C A8020000 jl loginTJ2.004A7846 ;注意这里
004A759E 8B8D CCF5FFFF mov ecx,dword ptr ss:[ebp-A34]
004A75A4 3B0D 802A4D00 cmp ecx,dword ptr ds:[4D2A80] ;注意这里
004A75AA 0F8D 96020000 jge loginTJ2.004A7846
004A75B0 8B95 40F6FFFF mov edx,dword ptr ss:[ebp-9C0]
004A75B6 81E2 FF000000 and edx,0FF
004A75BC 85D2 test edx,edx
004A75BE 0F84 AD000000 je loginTJ2.004A7671
004A75C4 6A 00 push 0
004A75C6 8BB5 CCF5FFFF mov esi,dword ptr ss:[ebp-A34]
004A75CC C1E6 04 shl esi,4
004A75CF 8B85 CCF5FFFF mov eax,dword ptr ss:[ebp-A34]
004A75D5 25 07000080 and eax,80000007
004A75DA 79 05 jns short loginTJ2.004A75E1
004A75DC 48 dec eax
004A75DD 83C8 F8 or eax,FFFFFFF8 ;来到这里,以此为根据,先向上找cmp dword ptr ss:[ebp-A34],0
;然后向下找
;and eax,0FF
;test eax,eax
;je loginTJ2.004A7846序列
004A75E0 40 inc eax
004A75E1 33C9 xor ecx,ecx
004A75E3 8A88 9C084D00 mov cl,byte ptr ds:[eax+4D089C]
004A75E9 8B95 CCF5FFFF mov edx,dword ptr ss:[ebp-A34]
004A75EF 81E2 07000080 and edx,80000007
004A75F5 79 05 jns short loginTJ2.004A75FC
004A75F7 4A dec edx
004A75F8 83CA F8 or edx,FFFFFFF8
004A75FB 42 inc edx
004A75FC 33C0 xor eax,eax
004A75FE 8A82 9D084D00 mov al,byte ptr ds:[edx+4D089D]
004A7604 8B3C8D 10C34C00 mov edi,dword ptr ds:[ecx*4+4CC310]
004A760B 333C85 10C34C00 xor edi,dword ptr ds:[eax*4+4CC310]
004A7612 8B8D CCF5FFFF mov ecx,dword ptr ss:[ebp-A34]
004A7618 81E1 07000080 and ecx,80000007
004A761E 79 05 jns short loginTJ2.004A7625
004A7620 49 dec ecx
004A7621 83C9 F8 or ecx,FFFFFFF8
004A7624 41 inc ecx
004A7625 33D2 xor edx,edx
004A7627 8A91 9E084D00 mov dl,byte ptr ds:[ecx+4D089E]
004A762D 333C95 10C34C00 xor edi,dword ptr ds:[edx*4+4CC310]
004A7634 8B85 CCF5FFFF mov eax,dword ptr ss:[ebp-A34]
004A763A 99 cdq
004A763B B9 1C000000 mov ecx,1C
004A7640 F7F9 idiv ecx
004A7642 8BCA mov ecx,edx
004A7644 D3EF shr edi,cl
004A7646 83E7 0F and edi,0F
004A7649 03F7 add esi,edi
004A764B 8B15 642A4D00 mov edx,dword ptr ds:[4D2A64]
004A7651 8D04B2 lea eax,dword ptr ds:[edx+esi*4]
004A7654 50 push eax
004A7655 8B8D CCF5FFFF mov ecx,dword ptr ss:[ebp-A34]
004A765B 51 push ecx
004A765C E8 2F210000 call loginTJ2.004A9790
004A7661 83C4 0C add esp,0C
004A7664 25 FF000000 and eax,0FF ;从这里开始修改
004A7669 85C0 test eax,eax
004A766B 0F84 D5010000 je loginTJ2.004A7846
在004A7591处下硬件执行断点,F9运行到004A7591处,取消断点,得到[ebp-A30]=12cd70,把12cd4c的数据改为0,
再把
004A7664 25 FF000000 and eax,0FF ;从这里开始修改
004A7669 85C0 test eax,eax
004A766B 0F84 D5010000 je loginTJ2.004A7846
修改为
004A7664 FF05 70CD1200 inc dword ptr ds:[12CD70] ;004A7591处看到的12cd70
004A766A C705 842A4D00 0>mov dword ptr ds:[4D2A84],1 ;004A75A4处的4D2A80+4=4D2A84
004A7674 ^ E9 18FFFFFF jmp loginTJ2.004A7591 ;跳回004A7591
接着在004A7591下一行处可看到jl 004A7846,跟随到004a7846处下硬件执行断点,Shift+F9运行,取消断点,
这时所有代码都强制解压完成,运行LordPE,选择第二个进程完整脱壳,修改脱壳后的dumped的OEP为6E70C,保存进入下一步
(3)修复IAT,修改Magic Jump
手动寻找IAT
另外开OD,载入dump.exe
0046E70C > 55 push ebp ;停在这里,F8走
0046E70D 8BEC mov ebp,esp
0046E70F 83C4 F0 add esp,-10
0046E712 B8 3CE44600 mov eax,dumped.0046E43C
0046E717 E8 4475F9FF call dumped.00405C60 ;跟进
0046E71C A1 105B4700 mov eax,dword ptr ds:[475B10]
00405C60 53 push ebx ;进入这里,继续
00405C61 8BD8 mov ebx,eax
00405C63 33C0 xor eax,eax
00405C65 A3 9CF04600 mov dword ptr ds:[46F09C],eax
00405C6A 6A 00 push 0
00405C6C E8 2BFFFFFF call dumped.00405B9C ;跟进
00405C71 A3 64664700 mov dword ptr ds:[476664],eax
00405B9C - FF25 0CE24700 jmp dword ptr ds:[47E20C] ;进到这里
在数据窗口Ctrl+G,47E20C
0047E13C 00000000
0047E140 77F525CA ntdll.RtlDeleteCriticalSection
0047E144 77F75690 ntdll.RtlLeaveCriticalSection
0047E148 77F755DE ntdll.RtlEnterCriticalSection
0047E14C 77E5A745 kernel32.InitializeCriticalSection
0047E150 77E615CB kernel32.VirtualFree
0047E154 77E5AC72 kernel32.VirtualAlloc
0047E158 77E560A0 kernel32.LocalFree
0047E15C 77E5A682 kernel32.LocalAlloc
0047E160 00B5ED78
0047E164 77E5A7DF kernel32.GetCurrentThreadId
0047E168 77E5A671 kernel32.InterlockedDecrement
0047E16C 77E5A660 kernel32.InterlockedIncrement
0047E170 77E57F44 kernel32.VirtualQuery
0047E174 77E5A949 kernel32.WideCharToMultiByte
0047E178 77E5A7FC kernel32.MultiByteToWideChar
0047E17C 77E560E1 kernel32.lstrlenA
0047E180 77E5274E kernel32.lstrcpynA
0047E184 00B5B400
0047E188 77E5DA41 kernel32.GetThreadLocale
0047E18C 77E4177E kernel32.GetStartupInfoA
0047E190 00B5A4EB
0047E194 00B5E2DA
0047E198 77E5ADA9 kernel32.GetModuleFileNameA
0047E19C 77E57362 kernel32.GetLocaleInfoA
0047E1A0 00B5ED84
0047E1A4 00B5B82A
0047E1A8 00B5DCF6
0047E1AC 77E5EE9D kernel32.FindClose
0047E1B0 00B5BDB8
0047E1B4 00B5CA49
0047E1B8 77E730C0 kernel32.UnhandledExceptionFilter
0047E1BC 77F60C44 ntdll.RtlUnwind
0047E1C0 77E53837 kernel32.RaiseException
0047E1C4 77E5E494 kernel32.GetStdHandle
0047E1C8 00B5AF8E
0047E1CC 77D38A76 USER32.GetKeyboardType
0047E1D0 77D16E00 USER32.LoadStringA
0047E1D4 00B5E353
0047E1D8 77D1A310 USER32.CharNextA
0047E1DC 00B5AF22
0047E1E0 77DA2410 ADVAPI32.RegQueryValueExA
0047E1E4 77DA229A ADVAPI32.RegOpenKeyExA
0047E1E8 00B5E403
0047E1EC 00B5AF22
0047E1F0 770F174B
0047E1F4 770FF42E
0047E1F8 770F1674
0047E1FC 00B5AEE5
0047E200 77E5AA4F kernel32.TlsSetValue
0047E204 77E5ABF1 kernel32.TlsGetValue
0047E208 77E5A682 kernel32.LocalAlloc
0047E20C 00B5E2DA
在0047E13C处已无数据,则RAV=47e13c-40000=7e13c,关闭OD,接着进行另外一步了
重新把原程序载入OD,下断bp DebugActiveProcess,Shift+F9运行,注意堆栈处
0012BCB0 004A6E60 /CALL 到 DebugActiveProcess 来自 loginTJ2.004A6E5A
0012BCB4 00000B14 \ProcessId = B14 ;这个是子进程ID,你的不一定相同
另开一个OD,在附加处选择B14这个进程,Alt+F9返回
004B6E10 >- EB FE jmp short loginTJ2.<ModuleEntryPoint> ;停在这里,修改为55 8b
004B6E12 EC in al,dx
下断BP OpenMutexA运行(先不要取消断点),断下后前往00401000处
填充以下欺骗代码
00401000 60 pushad
00401001 9C pushfd
00401002 68 E0DD1200 push 12DDE0 ; 堆栈处看到的ASCII "B14::DA7D1B79B5"
00401007 33C0 xor eax,eax
00401009 50 push eax
0040100A 50 push eax
0040100B E8 2FDB407C call kernel32.CreateMutexA
00401010 9D popfd
00401011 61 popad
00401012 - E9 04DC407C jmp kernel32.OpenMutexA
60 9C 68 E0 DD 12 00 33 C0 50 50 E8 B5 A6 A5 77 9D 61 E9 7A 13 A6 77
新建EIP,Shift+F9运行,取消BP OpenMutexA断点,再次来到00401000处,取消取消上面修改
下断BP GetModuleHandleA+5,Shift+F9,注意观察堆栈!
0012CECC 77C059FC 返回到 msvcrt.77C059FC 来自 kernel32.GetModuleHandleA
0012CED0 77BE31AC ASCII "kernel32.dll"
0012CED4 77C2CA20 msvcrt.77C2CA20
0012CF90 772A8663 返回到 SHLWAPI.772A8663 来自 kernel32.GetModuleHandleA
0012CF94 772AF8FC ASCII "KERNEL32.DLL"
0012CF98 00000000
0012CEB8 770FB124 返回到 OLEAUT32.770FB124 来自 kernel32.GetModuleHandleA
0012CEBC 771722E4 ASCII "KERNEL32.DLL"
0012CEB4 770FB124 返回到 OLEAUT32.770FB124 来自 kernel32.GetModuleHandleA
0012CEB8 771722E4 ASCII "KERNEL32.DLL"
00127B98 00B71B31 返回到 00B71B31 来自 kernel32.GetModuleHandleA
00127B9C 00B86364 ASCII "kernel32.dll"
00127BA0 00B87588 ASCII "VirtualAlloc"
00127B98 00B71B4E 返回到 00B71B4E 来自 kernel32.GetModuleHandleA
00127B9C 00B86364 ASCII "kernel32.dll"
00127BA0 00B8757C ASCII "VirtualFree"
00127908 00B59CD7 返回到 00B59CD7 来自 kernel32.GetModuleHandleA
0012790C 00127A4C ASCII "kernel32.dll"
不断Shft+F9直到经过VirtualAlloc、VirtualFree再次在堆栈中看见kernel32.dll,是返回的时机了,取消断点,ALT+F9返回
00B59CD7 8B0D 74B7B800 mov ecx,dword ptr ds:[B8B774]
00B59CDD 89040E mov dword ptr ds:[esi+ecx],eax
00B59CE0 A1 74B7B800 mov eax,dword ptr ds:[B8B774]
00B59CE5 391C06 cmp dword ptr ds:[esi+eax],ebx
00B59CE8 75 16 jnz short 00B59D00
00B59CEA 8D85 B4FEFFFF lea eax,dword ptr ss:[ebp-14C]
00B59CF0 50 push eax
00B59CF1 FF15 DC00B800 call dword ptr ds:[B800DC] ; kernel32.LoadLibraryA
00B59CF7 8B0D 74B7B800 mov ecx,dword ptr ds:[B8B774]
00B59CFD 89040E mov dword ptr ds:[esi+ecx],eax
00B59D00 A1 74B7B800 mov eax,dword ptr ds:[B8B774]
00B59D05 391C06 cmp dword ptr ds:[esi+eax],ebx
00B59D08 0F84 3B010000 je 00B59E49 ;LoadLibraryA下来的第一个跳转就是传说中的Magic Jump!修改成jmp!
F9直接运行了
打开ImportREC选择B14这个进程
OEP=6e70c
RAV=7e13c
SIZE=1000
直接点击获取输入表,CUT掉无效的指针修复dumped即可以了,这里注意一个问题,看看你的ImportREC设置,我这里选项中如果选了新建输入表中的三项任一项,都修复不成功,不知什么原因,我把这三项去掉修复即成功了
--------------------------------------------------------------------------------
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)