自定义 UI 按钮

逆向工程 艾达 ollydbg C++
2021-06-28 20:03:28

我刚开始使用 IDA 和 OllyDbg,虽然我是经验丰富的开发人员,但在此之前我只对 Java 和 .Net 代码进行逆向工程,与我现在需要做的事情相比,这要容易得多。

我有一个应用程序,其中有一些按钮无法通过 Spy++ 和 WinInspector 以及我尝试过的所有其他工具访问。Spy++ 只能看到selectorclass放置按钮的整个面板。我已经设法找到了WndProc这个选择器的位置,甚至是SelectorControlGetPropA方法中获取 hwnd 的方法,但是我无法识别点击本身,所以我不知道实际按钮被点击的位置以及应用程序知道的位置单击的确切按钮以及要使用的处理程序。

我想问一些提示,这些提示可能有用,但像我这样的新手不知道。这里可以使用哪些策略?

也许有一些方法可以识别使用的框架,所以我可以使用该框架来了解要查找的内容。

1个回答

如果周围的窗口似乎是一个真正的窗口,但单个按钮不是,我会假设

  • 周围的窗口显示位图,或执行其他任何需要显示单个按钮的操作
  • 周围的窗口对鼠标点击做出反应
  • 并且,周围的窗口通过查看鼠标单击时的鼠标坐标来确定使用哪个“按钮”。

所以,我们要做的是,在调试器中启动程序,并使用鼠标点击时触发的断点。问题是,窗口过程被多次调用,包含所有类型的消息,而您想中断其中的一些(例如,WM_LBUTTONDOWN),而不是大多数其他消息(例如,WM_PAINT)。

  • Ollydbg 可以直接做到这一点——放置一个根据窗口消息触发的条件断点。
  • 如果,无论出于何种原因,您无法使用该功能,您需要反汇编(并部分理解)窗口过程。它将接收堆栈上的 4 个参数,其中第二个是窗口消息(请参阅使用窗口过程)。窗口过程将在某个时候将此参数与众所周知的窗口消息 ID 的值进行比较。您可能对WM_LBUTTONDOWN( 0x0201) 或其他鼠标输入事件之一感兴趣检查代码在收到这些“有趣”消息之一时分支到的位置,并在该分支上放置一个断点。

放置合适的断点后,在调试器中运行您的应用程序,单击鼠标,并希望调试器真正命中断点。如果没有,请检查您犯了哪个错误。

单步执行您的代码。它可能会从堆栈中获取参数 4,它对鼠标的 X 和 Y 坐标进行编码,并将这些参数与某些东西进行比较 - 很可能,有一个定义矩形和跳转地址的结构数组,以及一个循环检查每个入口。

一旦你找到了,你就完成了。

听起来太容易了?这可能是因为,根据您的框架,实际的比较可能被深深地埋在原始源代码中一堆 C++ 类的东西中,并且可能有各种调用,其中一些是间接调用(在 C++ 类的情况下)方法),直到到达“有趣”的位置。

  • 有时使用 Ollydbg 更容易解决这个问题。在断点后单步执行源代码,使用“step over”来跳过函数调用。每当您看到函数调用中发生了有趣的事情时,请记下地址。重新启动你的程序,运行到你的断点,运行到你记下的地址,这次“步入”函数。这将允许你把手指放在有趣的代码比较快,而跨过所有的strcmp()malloc()WriteALotOfStuffToSomeFileIfDebuggingIsOn()功能。

  • 有时使用 IDA 更容易。从您的窗口过程生成一个调用树,关注前 3-5 个级别。在您的代码中搜索出现的幻数,0x0201如上所示。检查其中一个是否CMP XX, 0x0201在您的调用树中的其中一个函数中。这可能正是您正在寻找的职位。

  • 制作一个屏幕截图,并将其粘贴到某个图像查看器程序中(我喜欢Irfanview这样)。获取框架窗口内按钮的像素坐标。在数据部分中搜索那些被类似数据表包围的值。这可能是您的坐标/跳转表。如果你发现了一些东西,在它上面放置一个硬件断点以找出该内存何时被访问,或者使用 IDA 交叉引用列表来获取代码中的相应地址。