实例下载:附件
在Windows XP中利用万能断点找出关键跳转
大家都知道我们通常在Windows
98下做软件调试时有一个API函数HMEMCPY(俗称为万能断点),这个函数在KERNEL32.DLL中,其原形如下:
void hmemcpy(hpvDest, hpvSource, cbCopy)
void
_huge* hpvDest; // 目的数据地址
const
void _huge* hpvSource; // 源数据地址
long
cbCopy; // 数据大小 (Bytes)
它的工作原理就是将内存中的一块数据拷贝到另一个地方,大家每每使用SOFTICE、OD等调试工具时它都成了首选的断点,但在2000以后版本的系统里它却失去了原有的意义,下面我就总结介绍一下如何在XP中利用万能断点去调试出一个Crackme的关键跳转。
在Windows
XP系统中找万能断点的方法有很多,看雪学院外文翻译区里就有一篇Point-h in WinXP tutorial的文章,写的不错,但不适合初学者,有兴趣却没看过的朋友可以去读读,网上还有一种方法,就是在USER32模块中搜索十六进制字符F3 A5 8B C8 83 E1 03 F3 A4
E8,找到的地址就是你XP系统唯一的一处万能断点,好下面我们一步一步的做。
(1)用OD打开所要调试的crac.exe,右键单击汇编区域在“查看”菜单里选择“模块USER32”。
(图一)
(2)利用Ctrl+B快捷键,查找F3 A5 8B C8 83 E1 03 F3 A4 E8,点击确定。
(图二)
(3)由上步操作可以进入下图,好了记录万能断点。
(图三)
77D3353D
F3:A5 REP MOVS DWORD PTR ES:[EDI], DWORD PTR [ESI]
这个就是我系统的万能断点point-h,接下来我们就利用万能断点来寻找Crackme的关键比较,Crackme是OCN的lfq168做的,^_^不要怪我盗用啊!好,CTRL+F2重新加载一下程序,F9运行。
(1)首先填写好注册信息,不要点注册。
(图四)
(2)然后我们再按照找point-h的第一步进入USER32模块中(应该会做吧),然后快捷键CTRL+G,在出现窗口的COMBOBOX控件中填入我的point-h-〉“77D3353D”,点击确定。
(图五)
(3)在万能断点上F2下断。
(图六)
(4)回到Crackme窗口点击注册,程序被OD断了下来,看右上的寄存器窗口出现了我的用户名。
(图七)
(5)点击F9键直到第一次出现注册码为止,在EDI寄存器上单击右键,选择“在转存中跟随”。
(6)按F8到point-h下面第一个CALL处(图九),看转存中数据(图十)。
(图九)
(图十)
(7)在伪注册码(789789789)上下内存访问断点,F9运行。
(图十一)
程序被OD断在66061223处。
(8)下面我们F8,回到主进程空间。
到这里回到了主进程空间,也是回到了算法里,让我们F2记录一下断点,CTRL+F2重新加载程序,F9运行,填好信息后注册,被OD断在00402CE4,然后F8单步继续。
00402CE4 . 3BC7
cmp eax, edi
; 被断在这里
00402CE6 . DBE2
fclex
00402CE8
7D 12 jge
short crac.00402CFC
; 跳转
00402CFC >
\8B85 78FEFFFF mov eax, dword ptr ss:[ebp-188]
; 跳到这里
00402D02
. 50
push eax
; eax=789789789
00402D03
. FF15 10104000 call dword ptr ds:[<&MSVBVM60.__vbaLenBstr>] ; 计算长度放在eax中
......(省略)
00402D50
. FF15 38104000 call dword ptr ds:[<&MSVBVM60.__vbaVarForInit>] ; For循环,这里根据题目主要找
00402D56
. 8D8D 78FEFFFF lea ecx, dword ptr ss:[ebp-188]
; 关键跳转,就不研究算法了
00402D5C . 8985 3CFDFFFF mov dword ptr ss:[ebp-2C4],
eax
00402D62
. FF15 F8104000 call dword ptr ds:[<&MSVBVM60.__vbaFreeStr>] 00402D68
. 8D8D 70FEFFFF lea ecx, dword ptr ss:[ebp-190]
00402D6E . FF15 FC104000 call dword ptr ds:[<&MSVBVM60.__vbaFreeObj>] 00402D74
. 8B35 08104000 mov esi, dword ptr ds:[<&MSVBVM60.__vbaVarMove>] 00402D7A > 39BD 3CFDFFFF cmp dword ptr ss:[ebp-2C4],
edi
00402D80
. 0F84 89010000 je crac.00402F0F
; 条件满足跳出循环
......(省略)
00402EFE . FF15 F0104000 call dword ptr ds:[<&MSVBVM60.__vbaVarForNext>] ; Next对应For循环
00402F04 . 8985 3CFDFFFF mov dword ptr ss:[ebp-2C4],
eax
00402F0A .^
E9 6BFEFFFF jmp crac.00402D7A
; 向上循环
00402F0F > 8D85 5CFFFFFF lea eax, dword ptr ss:[ebp-A4]
; 鼠标点击这里F4跳过jmp
......(省略)
00402FA4 . 52
push edx
; edx=Moodsky[OCN],看来算法来了
00402FA5 . FF15 10104000 call dword ptr ds:[<&MSVBVM60.__vbaLenBstr>] ; 用户名长度入eax
......(省略)
00402FF2 . FF15 38104000 call dword ptr ds:[<&MSVBVM60.__vbaVarForInit>] ; For循环
00402FF8 . 8D8D 78FEFFFF lea ecx, dword ptr ss:[ebp-188]
00402FFE . 8985 34FDFFFF mov dword ptr ss:[ebp-2CC],
eax
00403004 . FF15 F8104000 call dword ptr ds:[<&MSVBVM60.__vbaFreeStr>] 0040300A
. 8D8D 70FEFFFF lea ecx, dword ptr ss:[ebp-190]
00403010 . FF15 FC104000 call dword ptr ds:[<&MSVBVM60.__vbaFreeObj>] 00403016
. 8B3D 7C104000 mov edi, dword ptr ds:[<&MSVBVM60.__vbaVarAnd>] 0040301C > 8B85 34FDFFFF mov eax, dword ptr ss:[ebp-2CC]
00403022 . 85C0
test eax, eax
00403024 . 0F84 BD050000 je crac.004035E7
; 条件满足跳出循环
......(省略)
004035D6
. FF15 F0104000 call dword ptr ds:[<&MSVBVM60.__vbaVarForNext>] ; Next对应For循环
004035DC . 8985 34FDFFFF mov dword ptr ss:[ebp-2CC],
eax
004035E2 .^
E9 35FAFFFF jmp crac.0040301C
; 向上跳转
004035E7 > 8D85 ECFDFFFF lea eax, dword ptr ss:[ebp-214]
; 鼠标点击这里F4跳过jmp
......(省略)
00403638 . FF15 38104000 call dword ptr ds:[<&MSVBVM60.__vbaVarForInit>] ; 又是一个For循环
0040363E >
85C0
test eax, eax
00403640 . 0F84 AF020000 je crac.004038F5
; 条件满足跳出
......(省略)
004038EA . FF15 F0104000 call dword ptr ds:[<&MSVBVM60.__vbaVarForNext>] ; Next对应For循环
004038F0 .^
E9 49FDFFFF jmp crac.0040363E
; 向上跳转
004038F5 > 8B45 08 mov eax,
dword ptr ss:[ebp+8]
; 鼠标点击这里F4跳过jmp
004038F8 . 50
push eax
004038F9 . 8B08
mov ecx, dword ptr ds:[eax]
004038FB . FF91 FC020000 call dword ptr ds:[ecx+2FC]
00403901 . 8D95 70FEFFFF lea edx, dword ptr ss:[ebp-190]
00403907 . 50
push eax
00403908 . 52
push edx
00403909 . FF15 3C104000 call dword ptr ds:[<&MSVBVM60.__vbaObjSet>] 0040390F
. 8BF0
mov esi, eax
00403911 . 8D8D 78FEFFFF lea ecx, dword ptr ss:[ebp-188]
00403917 . 51
push ecx
00403918 . 56
push esi
00403919 . 8B06
mov eax, dword ptr ds:[esi]
0040391B . FF90 A0000000 call dword ptr ds:[eax+A0]
00403921 . 85C0
test eax, eax
00403923 . DBE2
fclex
00403925 . 7D 12 jge
short crac.00403939
; 跳转
......(省略)
00403939 > 8B85 78FEFFFF mov eax, dword ptr ss:[ebp-188]
; 跳到这里
0040393F . 8D95 5CFEFFFF lea edx, dword ptr ss:[ebp-1A4]
00403945 . 8985 64FEFFFF mov dword ptr ss:[ebp-19C],
eax
; 出明码了,先不管了,继续(UNICODE "58737C4CD0436DC7381D325E")
0040394B . 8D85 BCFEFFFF lea eax, dword ptr ss:[ebp-144]
00403951 . 52
push edx
00403952 . 50
push eax
00403953 . C785 78FEFFFF>mov dword ptr ss:[ebp-188],
0
0040395D . C785 5CFEFFFF>mov dword ptr ss:[ebp-1A4],
8008
00403967 . FF15 68104000 call dword ptr ds:[<&MSVBVM60.__vbaVarTstEq>] ; vbaVarTstEq明面解释就可以看出,算变量是否相等
0040396D . 8D8D 70FEFFFF lea ecx, dword ptr ss:[ebp-190]
00403973 . 8BF0
mov esi, eax
00403975 . FF15 FC104000 call dword ptr ds:[<&MSVBVM60.__vbaFreeObj>] 0040397B
. 8D8D 5CFEFFFF lea ecx, dword ptr ss:[ebp-1A4]
00403981 . FF15 0C104000 call dword ptr ds:[<&MSVBVM60.__vbaFreeVar>] 00403987
. 66:85F6 test si,
si
0040398A .
/0F84 9F000000 je crac.00403A2F
; ****关键跳转****原来在这里
00403990 .
|B9 04000280 mov ecx, 80020004
; 关键跳如跳则OVER了,所以Nop掉就好了
00403995 .
|B8 0A000000 mov eax, 0A
0040399A .
|898D 34FEFFFF mov dword ptr ss:[ebp-1CC], ecx
004039A0 .
|898D 44FEFFFF mov dword ptr ss:[ebp-1BC], ecx
004039A6 .
|898D 54FEFFFF mov dword ptr ss:[ebp-1AC], ecx
004039AC .
|8D95 ECFDFFFF lea edx, dword ptr ss:[ebp-214]
004039B2 .
|8D8D 5CFEFFFF lea ecx, dword ptr ss:[ebp-1A4]
004039B8 .
|8985 2CFEFFFF mov dword ptr ss:[ebp-1D4], eax
004039BE .
|8985 3CFEFFFF mov dword ptr ss:[ebp-1C4], eax
004039C4 .
|8985 4CFEFFFF mov dword ptr ss:[ebp-1B4], eax
004039CA .
|C785 F4FDFFFF>mov dword ptr ss:[ebp-20C], crac.004026C4
004039D4
. |C785 ECFDFFFF>mov
dword ptr ss:[ebp-214], 8
004039DE .
|FF15 DC104000 call dword ptr ds:[<&MSVBVM60.__vbaVarDup>] 004039E4
. |8D8D 2CFEFFFF lea ecx, dword ptr ss:[ebp-1D4]
004039EA .
|8D95 3CFEFFFF lea edx, dword ptr ss:[ebp-1C4]
004039F0 .
|51
push ecx
004039F1 .
|8D85 4CFEFFFF lea eax, dword ptr ss:[ebp-1B4]
004039F7 .
|52
push edx
004039F8 .
|50
push eax
004039F9 .
|8D8D 5CFEFFFF lea ecx, dword ptr ss:[ebp-1A4]
004039FF .
|6A 00 push
0
00403A01 .
|51
push ecx
00403A02 .
|FF15 40104000 call dword ptr ds:[<&MSVBVM60.#595>]
; rtcMsgBox,正确弹出对话框
00403A08 .
|8D95 2CFEFFFF lea edx, dword ptr ss:[ebp-1D4]
00403A0E .
|8D85 3CFEFFFF lea eax, dword ptr ss:[ebp-1C4]
00403A14 .
|52
push edx
00403A15 .
|8D8D 4CFEFFFF lea ecx, dword ptr ss:[ebp-1B4]
00403A1B .
|50
push eax
00403A1C .
|8D95 5CFEFFFF lea edx, dword ptr ss:[ebp-1A4]
00403A22 .
|51
push ecx
00403A23 .
|52
push edx
00403A24 .
|6A 04 push
4
00403A26 .
|FF15 14104000 call dword ptr ds:[<&MSVBVM60.__vbaFreeVarList>] 00403A2C . |83C4 14 add esp,
14
00403A2F >
\33FF
xor edi, edi
00403A31 >
897D FC
mov dword ptr ss:[ebp-4], edi
到了这里,这篇文章也就到了结尾,希望能带给大家更多的启发,我们已经通过了WindowsXP万能断点的亲身体验,其实方法与工具的结合要灵活运用,由于每款软件的编制手法不同,所以调试方法有很多种,但终究有一种应该适合您的。
[参考]
Point-h
in WinXP tutorial
[附件]
crac.exe
[作者] Moodsky
[日期] 2005-11-6