能力值:
( LV2,RANK:10 )
|
-
-
26 楼
貌似图挂了端
|
能力值:
( LV2,RANK:10 )
|
-
-
27 楼
很好哦,支持一下。
|
能力值:
( LV2,RANK:10 )
|
-
-
28 楼
六个记号,慢慢看
|
能力值:
( LV2,RANK:10 )
|
-
-
29 楼
能不能直接贴上来
|
能力值:
( LV2,RANK:10 )
|
-
-
30 楼
这个好,正看之前的看的稀里糊涂的呢,多谢了^_^
|
能力值:
( LV2,RANK:10 )
|
-
-
31 楼
非常好,下载学习.
|
能力值:
( LV2,RANK:10 )
|
-
-
32 楼
谢谢了,这样新人就不会因下栽而扣KX了
|
能力值:
( LV3,RANK:20 )
|
-
-
33 楼
一直纳闷为什么我的Run跟踪就无法运行呢???
按照CCDebuger兄说的办法试了很多次都是这样。
跟踪到一条指令后就停止了再怎么也不走了不知道是怎么回事,请高手指点。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
34 楼
我也进来学习学习……
|
能力值:
( LV2,RANK:10 )
|
-
-
35 楼
学习了,老大辛苦!
|
能力值:
( LV2,RANK:10 )
|
-
-
36 楼
真的是很棒的学习材料,可惜图又挂了
|
能力值:
( LV2,RANK:10 )
|
-
-
37 楼
图片还是看不到哦.链接有问题哦
|
能力值:
( LV2,RANK:10 )
|
-
-
38 楼
好文章要頂一下
|
能力值:
( LV2,RANK:10 )
|
-
-
39 楼
可以对消息断点有些透彻的理解了
|
能力值:
( LV2,RANK:10 )
|
-
-
40 楼
谢谢楼主,辛苦了
|
能力值:
( LV2,RANK:10 )
|
-
-
41 楼
补充相当给力。
|
能力值:
( LV2,RANK:10 )
|
-
-
42 楼
为什么下不了啊
|
能力值:
( LV2,RANK:10 )
|
-
-
43 楼
先下载看看,谢谢楼主了.
|
能力值:
( LV2,RANK:10 )
|
-
-
44 楼
好资料啊,为什么看不见图片。。。还没有六。
|
能力值:
( LV2,RANK:10 )
|
-
-
45 楼
新人报道 先表示一下 楼主辛苦
|
能力值:
( LV2,RANK:10 )
|
-
-
46 楼
谢谢,学习!
|
能力值:
( LV2,RANK:10 )
|
-
-
47 楼
关于《OllyDBG 入门系列(五)-消息断点及 RUN 跟踪》的补充
作 者: hklzt
时 间: 2007-06-06,16:50
联 系: QQ:87784858
看完了《OllyDBG 入门系统(五)-消息断点及 RUN 跟踪》之后感觉如何?会否有如下问题:
1、 是否觉得不知道在哪下断?
2、 为什么要这样子下断?
3、 如何确定断下来后的位置就是正确的?
好,就本着这几个问题来分析一遍。
首先,先回顾下Windows的消息机制。要点:所有要处理的消息必然会由程序自己处理,不处理的消息都交由Windows处理。Windows的消息处理函数的格式,如下:
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle of window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
其中uMsg就是关键,它代表消息的类型,如:WM_COMMAND,WM_GETTEXT等。记好哦。
下面,我们来用实例讲解。
这个CrackMe是用对话框做的(你是怎么知道的?)。
1、 用OllyDbg加载,Crtl + N,找到函数:USER32.DialogBoxParamA,右击->“在每个参考上设置断点”。
2、 F9,运行。看,被拦了下来,如图:
3、 其中DlgProc的内容,就是我们需要找的东东。这个地址是消息处理函数的入口点。现在来解释为什么要在窗口那才有消息断点,看图,
要下消息断点,首先得找到具有Windows消息处理函数格式的函数,然后,再根据栈的数据来判断消息,如果符合下断的消息,那么,OllyDbg就会拦下来(还会觉得不知道在哪下消息断点了吗?知道该如何下消息断点了吧?)。很明显有一点,这个消息断点的功能是有限的,比如,要拦主窗口中的菜单消息呢?所以,消息断点的功能还是有限的。如何扩展?扯远了,下面再讲。
4、 Ctrl + G来到cyle.0041029,我们来到了消息处理函数了,但是,OllyDbg并未识别出这个函数是消息处理函数。所以,在cyle.0041029处,右击->“分析”->“假定参数”,如图:
弹出一个对话框,选择“WinProc(hWnd,msg,wParam,lParam)”。
点击“应用”后,如图。
5、在cyle.0041029处,右击->“断点”->“在WinProc上的消息断点”(平时是不是没见过这个菜单呀?呵呵)。
5、 在“消息”列表框中,选择你要下断的消息(Alt+B,删除以前的断点,以免影响心情)。
6、 F9,运行,程序运行起来了。这时没什么事情发生,当你在里面点了一个文本框之后(点它,是想让它获得Focus(焦点),以便能够输入数据),事情就发生了。现在没办法在文本框里输入注册码,也没办法点击按钮。这是怎么回事呢?仔细看一下Stack(栈)的那个窗口,噢!原来被文本框的通知EN_SETFOUCE搞坏了!停留在EN_SETFOCUS和EN_KILLFOCUS两个消息之间了。
7、 好,现在来扩展消息断点(消息断点是否是条件断点的特殊例子?),即使用条件断点(卖弄了一下,呵呵)。
看你需求,条件和条件记录,在这里是没什么区别的,因为不需要记录的内容。
8、 按Shitf+F2,输入 MSG ==WM_COMMAND && [ESP+C]==66(这个66是怎么来的?这个就是那个Check按钮的ID,意思就是“当收到WM_COMMAND,且是由ID为0x66发出的时候中断”),确定,F9,运行。
9、现在,输入Name和Serial之后,点”Check”按钮。
10、这次中断,位置上似乎没有变化,但是,明白了消息处理机制,应该知道这次中断的不同吧?(这次会流程会流到注册算法那哦)
00401029 >/. >enter 0, 0 ; 解码为 <WinProc>
0040102D |. >push ebx
0040102E |. >push edi
0040102F |. >push esi
00401030 |. >cmp [arg.2], 110
00401037 |. >je short cycle.0040105E
00401039 |. >cmp [arg.2], 111 //111=WM_COMMAND
00401040 |. >je short cycle.00401082 //肯定在这里跳(为什么?)
00401042 |. >cmp [arg.2], 10
00401046 |. >je short cycle.00401057
00401048 |. >cmp [arg.2], 2
0040104C |. >je short cycle.00401057
0040104E |. >xor eax, eax
11、来到 cycle.00401082,
00401082 |> \>cmp [arg.3], 67
00401086 |. >jnz short cycle.0040108D //这里肯定会跳
00401088 |. >call cycle.00401151
0040108D |> >cmp [arg.3], 66
00401091 |. >jnz short cycle.00401098 //这里肯定不会跳(又是为什么呢?)
00401093 |. >call cycle.0040109C //关键,
00401098 |> >xor eax, eax
12、蓝色部分,已经在CCDebuger那篇文章分析过了,这里就不分析了,我用红色字体来标明重点。
0040109C /$ >mov dword ptr ds:[402182], FEDCBA98
004010A6 |. >push 11 ; /Count = 11 (17.)
004010A8 |. >push cycle.00402171 ; |Buffer = cycle.00402171
004010AD |. >push 3E9 ; |ControlID = 3E9 (1001.)
004010B2 |. >push [arg.1] ; |hWnd
004010B5 |. >call <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA(Serial)
004010BA |. >or eax, eax
004010BC |. >je short cycle.0040111F
004010BE |. >push 11 ; /Count = 11 (17.)
004010C0 |. >push cycle.00402160 ; |Buffer = cycle.00402160
004010C5 |. >push 3E8 ; |ControlID = 3E8 (1000.)
004010CA |. >push [arg.1] ; |hWnd
004010CD |. >call <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA(name)
004010D2 |. >or eax, eax
004010D4 |. >je short cycle.0040111F
004010D6 |. >mov ecx, 10
004010DB |. >sub ecx, eax
004010DD |. >mov esi, cycle.00402160
004010E2 |. >mov edi, esi
004010E4 |. >add edi, eax
004010E6 |. >cld
004010E7 |. >rep movs byte ptr es:[edi], byte ptr>
004010E9 |. >xor ecx, ecx
004010EB |. >mov esi, cycle.00402171
004010F0 |> >/inc ecx
004010F1 |. >|lods byte ptr ds:[esi]
004010F2 |. >|or al, al
004010F4 |. >|je short cycle.00401100
004010F6 |. >|cmp al, 7E
004010F8 |. >|jg short cycle.00401100
004010FA |. >|cmp al, 30
004010FC |. >|jb short cycle.00401100
004010FE |.^ >\jmp short cycle.004010F0
00401100 |> >cmp ecx, 11
00401103 |. >jnz short cycle.0040111F //判断长度是否为16个有效字符,即16个字节,不是则跳
00401105 |. >call cycle.004011F1 //算法
0040110A |. >mov ecx, 0FF01
0040110F |. >push ecx
00401110 |. >call cycle.00401190 //算法
00401115 |. >cmp ecx, 1
00401118 |. >je short cycle.00401120 //需要跳
0040111A |> >call cycle.00401166
0040111F |> >retn
00401120 |> >mov eax, dword ptr ds:[402168]
00401125 |. >mov ebx, dword ptr ds:[40216C]
0040112B |. >xor eax, ebx
0040112D |. >xor eax, dword ptr ds:[402182]
00401133 |. >or eax, 40404040
00401138 |. >and eax, 77777777
0040113D |. >xor eax, dword ptr ds:[402179]
00401143 |. >xor eax, dword ptr ds:[40217D]
00401149 |.^ >jnz short cycle.0040111A //不可以跳
0040114B |. >call cycle.0040117B //提示注册成功!
00401150 \. >retn
终于写完了,现在来回顾下刚开始的问题:
1、 是否觉得不知道在哪下断?
答:在Windows消息处理函数的入口处下消息断点。
2、 为什么要这样子下断?
答:可能OllyDbg是根据栈的数据和函数原型来匹配,所以,一般来说,匹配条件都会是[Esp + XX] ==XXXXX
3、 如何确定断下来后的位置就是正确的?
答:这里是根据编程的思路以及Windows的消息处理机制来定位的,理论与实战相结合。
最后,总结下,由于windows是消息驱动的,很大一部分都是通过消息来完成的,所以,有很大一部分可以通过对消息下断来达到目的,但是,如何下消息断点?从大体上讲,是这样子的:1、找出消息循环处理的函数 2、在消息循环处理函数的入口处设断
写到这里,废话一下。赞扬CCDebuger的太多了,但是,在赞扬的同时,不知道大家有没仔细消化人家的成果?呵呵,其实,我也没有,因为我看不太懂,所以,还是照着自己的思路走。写这篇文章的目的是为了帮一位朋友,他想下消息断点,但是,不知道如何下,我就把CCDebuger的这那篇消息断点给他,可是,还是没解决,后来,自己也动了一下手,确实,对于WM_COMMAND消息来说,OD肯定会不停的拦下来的,所以,单纯的消息断点就行不通了,所以,再结合Run跟踪来记录下,刚好能解决问题,也就产生了CCDebuger的那篇文章(猜的,呵呵)。
最后,帮忙纠正下错误:
引用:
写到这准备跟踪算法时,才发现这个 crackme 还是挺复杂的,具体算法我就不写了,实在没那么多时间详细跟踪。有兴趣的可以跟一下,注册码是17位,用户名采用复制的方式扩展到 16 位,如我输入“CCDebuger”,扩展后就是“CCDebugerCCDebug”。大致是先取扩展后用户名的前 8 位和注册码的前 8 位,把用户名的前四位和后四位分别与注册码的前四位和后四位进行运算,算完后再把扩展后用户名的后 8 位和注册码的后 8 位分两部分,再与前面用户名和注册码的前 8 位计算后的值进行异或计算,最后结果等于 0 就成功。注册码的第 17 位我尚未发现有何用处。对于新手来说,可能这个 crackme 的难度大了一点。没关系,我们主要是学习 OllyDBG 的使用,方法掌握就可以了。
关于“位”的概念,“位”,是指二进制位,在这里,一个字节等于8位,一个字符等于一个字节。“注册码是17位”,应改成“注册码是17个字节”,如果你跟踪分析过,你可以发现,这样子还是不对的,最后应该是“注册码是16个字节”,
cmp ecx, 11,这里的11是16进制,即十进制数:17。从代码中可以看出这个十进制数17,还得减1才是字符串的真实长度,所以,应该改成“注册码是16个字节”,后面的“位”,需要改成“字节”。第一次看的时候,没注意看,都给蒙了。
|
能力值:
( LV2,RANK:10 )
|
-
-
48 楼
有一个问题,我换了一个程序,作用MSG ==WM_COMMAND && [ESP+C]==?时,就不能正常断下来,还是只有MSG ==WM_COMMAND起作用,后面对于句柄的断点没有作用,不知为什么?
|
能力值:
( LV2,RANK:10 )
|
-
-
49 楼
谢谢,下载学习了
|
能力值:
( LV2,RANK:10 )
|
-
-
50 楼
很重要的补充,必须支持!!
|