目标软件:Style XP 0.9 beta RC2
目标文件:StyleXP.exe
使用环境:WINDOW XP
使用工具:WinDbg,wasm32
下载地址:http://www.tgtsoft.com/download.html
Style
XP是更改WINDOW XP“皮肤”的工具。通过使用皮肤,它可以改变Windows的外观界面,而且还提供
了皮肤制作软件。下载安装的过程非常简便,在机器重启后变可令你Win
XP外观焕然一新,整体感觉要比
Winblinds看上去要轻盈淡雅。未注册只能用30天。
Style XP的反跟踪代码做的很有特色,虽然比不上aspr等“大牌”程序,但只花费了很小的代价,就基本
达到的anit-debug的效果。
因为刚装好window xp,还没调试好soft-ice,只好用DDK工具集里的WinDbg了。(其实WinDbg的功能一点
也不比soft-ice逊色,还可以一边调试一边看MSDN的帮助文挡)
打开WinDbg,选File->Open
Executable,装入StyleXP.exe,f5执行后,被中断在一条int3的指令上:
* Reference To: COMCTL32.InitCommonControls,
Ord:0011h
|
:00422FA4 8B35E0404B00
mov esi, dword ptr [004B40E0]
:00422FAA
FFD6 call
esi
:00422FAC 57
push edi
:00422FAD E81DFA0200
call 004529CF
:00422FB2 59
pop ecx
:00422FB3 8B4508
mov eax, dword ptr [ebp+08]
:00422FB6 8B80C8000000 mov eax,
dword ptr [eax+000000C8]
:00422FBC 8945E0
mov dword ptr [ebp-20], eax
:00422FBF CC
int 03
《==========中断在这里
:00422FC0 FFD6
call esi
:00422FC2 57
push edi
:00422FC3
E807FA0200 call 004529CF
原来是用SEH来实现anti-debug的,那好办,下命令“SXD *”这条命令是让WinDbg忽略所有的异常,只在debug
窗口输出信息。类似与soft-ice中的“faults off”命令。再下命令“GN”,即“Go Unhandled Exception”
(执行,但不处理异常情况)满以为搞定了,谁知程序居然自动退出了!看来还有暗桩。重新装入StyleXP,一
步一步跟踪来到这里:
:00422AA4 8D86CC000000 lea
eax, dword ptr [esi+000000CC]
:00422AAA 8BCE
mov ecx, esi
:00422AAC 50
push eax
:00422AAD
E8DB200800 call 004A4B8D
* Reference To: KERNEL32.GetTickCount, Ord:0186h
|
:00422AB2 8B1D28444B00
mov ebx, dword ptr [004B4428]
:00422AB8 FFD3
call ebx
:00422ABA 8986C0000000
mov dword ptr [esi+000000C0], eax
以上代码call KERNEL32.GetTickCount 将当前的时间保存在[esi+000000C0]中
* Reference
To: ole32.CoUninitialize, Ord:0059h
|
:00422AC0 FF15F8494B00 Call dword
ptr [004B49F8]
:00422AC6 8D45DC
lea eax, dword ptr [ebp-24]
:00422AC9 50
push eax
:00422ACA
57
push edi
:00422ACB 56
push esi
:00422ACC 68722F4200
push 00422F72
:00422AD1 6800000100
push 00010000
:00422AD6 57
push edi
* Reference
To: KERNEL32.CreateThread, Ord:004Dh
|
:00422AD7 FF153C444B00 Call dword
ptr [004B443C]
:00422ADD 3BC7
cmp eax, edi
:00422ADF 8945F0
mov dword ptr [ebp-10], eax
:00422AE2
7416 je 00422AFA
:00422AE4 6AFF
push FFFFFFFF
:00422AE6 50
push eax
* Reference To: KERNEL32.WaitForSingleObject,
Ord:02FDh
|
:00422AE7 FF152C444B00
Call dword ptr [004B442C]
然后产生一个子线程(子线程地址为00422F72),再将本身的主线程挂起,直到子线程结束。(子线程的作用
后面有解释)
:00422AED 8D45E0
lea eax, dword ptr [ebp-20]
:00422AF0 50
push eax
:00422AF1 FF75F0
push [ebp-10]
* Reference To: KERNEL32.GetExitCodeThread, Ord:011Fh
|
:00422AF4 FF1538444B00
Call dword ptr [004B4438]
* Referenced
by a (U)nconditional or (C)onditional Jump at Address:
|:00422AE2(C)
|
:00422AFA 817DE0E8030000 cmp dword ptr
[ebp-20], 000003E8
:00422B01 7732
ja 00422B35
:00422B03 FFD3
call ebx
〈===KERNEL32.GetTickCount
:00422B05 2B86C0000000
sub eax, dword ptr [esi+000000C0]
:00422B0B 3D983A0000
cmp eax, 00003A98 〈== 3a98(hex)就是15000(dec)
:00422B10 7723
ja 00422B35
上面代码再次call KERNEL32.GetTickCount,将当前时间和刚才的比较,如果大于15秒就over。
:00422B12 E8EC1C0800
call 004A4803
:00422B17 8B4008
mov eax, dword ptr [eax+08]
:00422B1A 57
push edi
:00422B1B
50
push eax
:00422B1C 68BF304200
push 004230BF
:00422B21 6A09
push 00000009
* Reference To: USER32.SetWindowsHookExA,
Ord:0267h
|
:00422B23 FF155C484B00
Call dword ptr [004B485C]
:00422B29 817DE0E8030000
cmp dword ptr [ebp-20], 000003E8
:00422B30 8945F0
mov dword ptr [ebp-10],
eax
:00422B33 7607
jbe 00422B3C
产生“钩子”程序(WH_DEBUG)
*
Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004227A2(U),
:004229A6(U), :00422B01(C), :00422B10(C)
|
:00422B35 33C0
xor eax, eax
:00422B37
E971010000 jmp 00422CAD
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00422B33(C)
|
:00422B3C FFD3
call ebx
:00422B3E 2B86C0000000
sub eax, dword ptr [esi+000000C0]
:00422B44 3D983A0000
cmp eax, 00003A98
:00422B49 760E
jbe 00422B59
再次call KERNEL32.GetTickCount,将当前时间和刚才的比较,如果大于15秒就over。
将上面代码总结一下:
1)记录一个时间点。
2)产生一个子线程,并且再将本身的主线程挂起,直到子线程结束。
3)在子线程中计算是否注册以及是否过期,并且使用SEH技术,用int3断点指令触发debuger(如果有的话),
这时会有时间上的延迟。
4)当子线程退出,比较第一步的时间点,如果大于15秒,就说明本身被调试。(因为调试时要下断点,会有时
间延迟)
要去掉暗装也容易,将cmp eax, 00003A98该为xor eax,eax即可。这样就可以调试子线程了。
因为注册码比较部分挺复杂,我用爆破的方法使它永远不过期。
下断点“BP GetSystemTime”很容易找到关键:
:00478283 8B4C2410 mov
ecx, dword ptr [esp+10]
:00478287 83C0FC
add eax, FFFFFFFC
:0047828A 83C104
add ecx, 00000004
:0047828D
50
push eax
:0047828E 51
push ecx
:0047828F 8B4C241C
mov ecx, dword ptr [esp+1C]
:00478293 E8A8150000
call 00479840
:00478298 8B4C2410
mov ecx, dword ptr [esp+10]
:0047829C 3B01
cmp eax, dword ptr [ecx]
:0047829E 7412
je 004782B2 〈==这里判断是否将时间改回原来
:004782A0
BE090404C0 mov esi, C0040409
:004782A5 56
push esi
:004782A6 6A00
push 00000000
:004782A8 682A070000
push 0000072A
:004782AD E929040000
jmp 004786DB
以下代码计算过期的时间
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047829E(C)
|
:004782B2 668B4104
mov ax, word ptr [ecx+04]
:004782B6 668BD0
mov dx, ax
:004782B9 8BC8
mov ecx, eax
:004782BB
66C1EA09 shr dx, 09〈==dx为年份
:004782BF C1E905
shr ecx, 05
:004782C2 81C2D0070000
add edx, 000007D0 〈==年份加上2000
:004782C8 83E01F
and eax, 0000001F 〈===eax为天
:004782CB 83E10F
and ecx, 0000000F 〈ecx==为月
:004782CE 668954241C
mov word ptr [esp+1C], dx
:004782D3 6689442420
mov word ptr [esp+20], ax
:004782D8
8B542420 mov edx, dword
ptr [esp+20]
:004782DC 66894C241E
mov word ptr [esp+1E], cx
:004782E1 8B44241E
mov eax, dword ptr [esp+1E]
:004782E5 8B4C241C
mov ecx, dword ptr [esp+1C]
在:004782C2 处将edx的值该为一个很大的数就可以了。
- 标 题:关于StyleXP反跟踪代码的分析以及WinDbg简单教学 (7千字)
- 作 者:leo_cyl1
- 时 间:2002-4-1
17:57:25
- 链 接:http://bbs.pediy.com