从零开始

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫码,快速开始

搜索
查看: 2165|回复: 0

OD-困难重重的追踪消息断点

[复制链接]
  • TA的每日心情
    擦汗
    10 小时前
  • 签到天数: 140 天

    [LV.7]常住居民III

    171

    主题

    465

    帖子

    35万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    354786
    QQ
    发表于 2018-10-4 21:57:08 | 显示全部楼层 |阅读模式
    最近逆向某捕鱼游戏,由于需求需要逆向他的封包数据,bp recv加给内存下断点,找到解密消息的地方(收包子线程里面),我要的是是怎们处理里封包,而不只是解密过程,接着向下追查,发现游戏先是把解密好的数据放在模块内存里面,然后给主线程(主窗口)发消息,告诉他,收到网络消息并给你解密好了,赶紧处理吧,发消息是使用的postmessage,窗口句柄参数是主窗口,消息ID0x4FF,以前看过郁金香的视频教程,好像可以用SPY++找到主窗口的窗口消息处理函数,在哪里下消息断点,一下就可以拦截了,无奈自己当时没有记录笔记,又找不到看的哪个视频,自己动手找窗口处理函数,找了半天还是不行,找不到哪个函数,只能百度了“OD消息断点”。大概收获如下:
    http://blog.csdn.net/liujiayu2/article/details/51789282
    按照教程,依然没有找到处理窗口消息的地方,哎,怪我太笨,,
    无奈我只自己写个工程,简单逆向学习下,工程代码如下(只列举自己写的,很简单)
    [mw_shl_code=cpp,true]
    #define MSG_TEST 0x4FF
    ON_MESSAGE(MSG_TEST, &Ctest2Dlg::msg)
    #include "ClogFile.h"
    LRESULT Ctest2Dlg::msg(WPARAM w, LPARAM l)
    {

    //输出字符串l
    gConsoleLog.WriteLogInfo("%s",(char*)l);

    return 0;
    }


    DWORD WINAPI func(LPVOID lpThreadParameter)
    {
    char *p = new char[20];
    ZeroMemory(p, 20);
    strcpy(p,"1234567890");
    :ostMessage(AfxGetApp()->GetMainWnd()->m_hWnd, MSG_TEST, 0, (LPARAM)p);

    return 0;
    }

    void Ctest2Dlg::OnBnClickedButton1()
    {
    // TODO:
    CreateThread(NULL, 0, func, NULL, 0, NULL);
    }
    [/mw_shl_code]



    按照上面的教程依然没有找到我自己写的msg(WPARAM w,LPARAM l)函数体,于是我进下了一下小研究,
    找到gConsoleLog.WriteLogInfo("%s",(char*)l);这句的反汇编代码,下断点,点击下按钮,让程序跑到断点出,看调用堆栈,如下:

    可以看到WinMain函数也在其中,这不是我们点击按按钮调用的,我们看到user32.DispatchMessageA
    和MSG(0x4FF)结构体,最终调用到了我们的msg(WPARAM w,LPARAM l)函数体,我决定亲自试一下,看看能不能调用到。
    1.在DispatchMessageA上下条件断点,[[esp+4]+4] == 0x4FF  (消息ID)
    2.点击按钮,程序成功在DispatchMessageA处断下
    3.F8单步走,走到user32.74E07BC5处的call,F7跟进去,因为堆栈是这么指示的
    4.一直跟着堆栈走确实最终走到了msg(WPARAM w,LPARAM l)函数体
    走到是走到了,这是一路走来真不容易,每个call里面都有几十个call,必须在指定的call跟进去,不能走过了,也不能早走,但是看看这些,全是在系统代码区,最终一走到用户代码区就正好到了我们想要的函数体,肯定有简便的方法吧,根据我们前面看到的文章(虽然没找到函数体,依然学到了东西)打开OD的内存窗口,找到可执行程序test2的代码段,.text

    右键F2下断点,这个断点表示,一旦程序运行了用户层代码,立即断下,并自动清除断点。
    我们按照这个方法试下test2程序,
    1.在DispatchMessageA上下条件断点,[[esp+4]+4] == 0x4FF  (消息ID)
    2.点击按钮,程序成功在DispatchMessageA处断下
    3.test2.text下F2断点,
    4.F9运行程序
    理论上来讲应该是直接就到了我们的msg(WPARAM w,LPARAM l)函数体,可惜,没到,到了下边这个地方

    瞬间心里难受,竟然有这种幺蛾子,怎么办?
    冷静过后,我们思考下,到了这里时候,我们真正想到的地方msg(WPARAM w,LPARAM l)函数体,到过还是没到过?再来一变,这次在步骤3上面加上,在我们最终目的地加上断点,执行步骤4之后发现直接走到了上面截图的地方,还没到我们最后的目的地,那就接着往下走走呗,F8单步运行,发现程序运行到了系统领空,那就继续给test2.text下F2断点,F9运行程序,到了下面,

    依然没有经过最终目的地,没事我们冲上面的步骤,经过再两次的重复,突然柳暗花明到了我们最终目的地,这是什么情况,我现在还是不清除,但是可以确定的是这种方式确实可以找到,我们最终的目的地,

    回想下我们看到的那几篇文章,发现他下的是TranslateMessage断点,我下的是DispatchMessageA断点,那咱就试试这个TranslateMessage断点法,经过测试,也可以找到最终的消息响应函数msg(WPARAM w,LPARAM l) ,历程和DispatchMessageA断点一样的。
    有了上面的实战经验我们就开始弄弄我们的游戏,为方便描述,我重新写这个具体步骤:

    1.在DispatchMessageA上下条件断点,[[esp+4]+4] == 0x4FF  (消息ID)
    2.点击按钮,程序成功在DispatchMessageA处断下
    3.test2.text下F2断点,
    4.F9运行程序
    5.程序断下,观看程序断的地方是不是最终想要的地方,是就结束,不是就执行F8,程序会再进入系统领空,
    6.重复执行步骤345直到我们找到最终的处理消息的地方

    ---------------------本文来自 H-KING 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/liujiayu2/ ... 794?utm_source=copy
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|小黑屋|手机版|Archiver|一切从零开始 ( 蜀ICP备15031375号-3 )

    GMT+8, 2024-4-19 18:00 , Processed in 0.237908 second(s), 22 queries , File On.

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表