我也来谈谈消息断点二(有新内容)
【文章标题】: 【原创】我也来谈谈消息断点二
【文章作者】: icefisher
【作者邮箱】: 181712814@qq.com
【软件下载】:
【软件名称】: echap518.exe(只是供学习的crackme)crackme6.rar [解压密码:pediy]
【加壳方式】: 里面直接有个unpacked.ExE,是脱过壳的
【保护方式】:
【使用工具】: OllyICE
【文章日期】: 20080813
大家可以看看http://bbs.pediy.com/showthread.php?t=70618,有Windows编程基础的就不用看了。
好了当我们大概理解消息处理函数后我们就可以来看看这个例子了,首先ollyice载入unpacked.exe。F8单步运行。

如图地方F7,进入后F8,

如图地方F7,进入后可以看到F8几步就可以看到

回想起上篇我提到过的DialogBox (
hInstance,
TEXT("AboutBox"),
hwnd,
AboutDlgProc
)
因为DialogBoxParamA比DialogBox 最后多一个参数用来做记录,不影响我们理解,
(当然我们也可以用Ctrl+N查找函数DialogBoxParamA来直接定位到这里

)
我们看到DLGProc=004015A1,那么我们明显可以理解4015A1处是消息处理函数所在。我们Ctrl+G跟过去看,
我们会看到cmp eax,110 或者cmp eax,111之类的比较,

回想起上篇,这就等同于
switch (message)
{
case WM_CREATE:
case WM_PAINT:
case WM_DESTROY:
}
而其中我们需要知道的是WM_COMMAD =111(用来定位按钮的消息)
WM_LBUTONUP =202(鼠标左键放开)
而且我们还要注意一个地方回想上次我提到的
WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
当我们产生一个消息时,必然是调用这个函数,那么根据windows函数调用进栈法则,我们不难得到在消息处理函数开头如果下断点,栈结果必然如此
{
返回地址
hwnd
message
wParam
lParam
}
好了,基础讲完,就再看程序(因为前面push ebp,所以后面在取message时,为ebp+C,大家应该能明白吧),好了我们先F9运行次程序,在查看->窗口明显我们可以看到Check的id值为1。

现在我们来仔细看看这个消息处理函数,他首先从ebp+C中取出了message,存入了eax中,然后开始switch的过程,他不断比较这些以确定是哪个消息,
好了,我们知道按下按钮会产生WM_COMMAD(111) 消息,那么当我们看到cmp eax,111,je跳走时,我们离目标已经很近了,跟踪je到目的地,我们会奇怪,怎么还比较啊,这是因为按钮有很多个,每一个按下都会产生WM_COMMAD(111),那么这时我们需要再次判断是哪个按钮?

我们利用的就是wParam的低四位,他记录了按下按钮的ID值,所以就有了movz eax,
[ebp+10],好了我们已经知道了Check的ID值为1,那么我们看到
cmp eax,1
je xxxxxxxx
跟过去下断点,这时我们就完成了对check的断点,只要一按check必然会来到此处,后续的也会从这里开始,一切就会光明无比
方法二
当我们面对一个很庞杂的系统时我们又该如何来找那关键的消息处理函数呢?茫茫多的程序中又如何去发现
cmp eax,111 与cmp eax,1呢
回到前题,我觉得消息处理函数无论他在那里,当他被调用时,栈中的内容必然是
{
返回地址
hwnd
message
wParam
lParam
}只要我们能抓住他时,我觉得我们就能抓住一切。
首先当我们无法找到消息处理函数时,也许代码太多我们遗漏了,也许有别的技巧可以隐藏。但是我们可以先F9运行起来,在查看->窗口中,我们选择他们的共有父窗口,点击跟随ClassProc

然后我们进入了系统领空,然后在第一句上下条件断点:
[ESP+8]==WM_COMMAND&&[ESP+c]==1

然后我们在对话框中输入数据,点击check,我们发现我们会中断在系统领空,并且注意观察栈


大家都明白了吧,然后在查看->内存,代码段下内存访问断点,F9运行下,直接到达消息处理函数

这时我们这需要静静的F8一路跟踪就可以了
