【破解作者】 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设置,我这里选项中如果选了新建输入表中的三项任一项,都修复不成功,不知什么原因,我把这三项去掉修复即成功了
--------------------------------------------------------------------------------
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!