在学习反调试时,我赞叹他们的OllyDbg反调试为何能绕过反附加,反调试。于是开始了简易调试器的编写,可是我并不能满足止步于此。我好奇经典的OllyDbg界面是怎样去实现的,还有其他功能又是怎样实现的,我们知道他不仅界面友好,而且支持插件丰富。想本身通过逆向去发实际现原理,并最终实现本身的调试器。从本年大三下学期疫情在家上网课,陆陆续续,零零散散耗时二月份到本年九月份,对OllyDbg 1.10的逆向还原终于有了进展,特此纪录一下。
如今开始正题。
一、窗口绘制的实现
OD的自绘窗口分为告急分为4种 dump窗口,table窗口,寄存器窗口,对话框窗口。
所有自绘窗口的绘制函数都由Painttable函数来完成。Paint会根据t_table指定的各种属性来进行来绘制,调用时需要传入数据解析函数(后面会提到)

大量的数据布局如t_table、t_dll、t_sorted数据布局可以在OllyDbg的插件编写帮助文档与提供的插件开发代码例子中找到。

在创建table窗口时,都会初始化上面的布局体

工具条的实现,是一开始遇到的难点。后来逆向出来告终构体,也不难发现只不过也是通过MoveToEx(hdcDst, rct.left + 2, rct.bottom - 2, NULL); LineTo(hdcDst, rct.right - 2, rct.bottom - 2);
画出来一个小方框,然后再通过LoadBitmap加载位图进去。如果是发生了点击则把方框线的颜色使用其他颜色,模拟产生了点击了结果。


二、数据的解析
数据的解析是由Painttable的getline参数来指定的,该函数的原型是
typedef int DRAWFUNC(char *s, char *mask, int *select, t_sortheader *ps, int column);
几乎每个自绘窗口都有本身的数据解析函数,除开反汇编窗口、栈窗口、数据窗口共用一个解析函数。
每个窗口基本都有本身的数据布局,如t_thread、t_module、t_memory等。解析时对应布局体解析就可以了。


三、逆向还原的难点
逆向还原时最复杂莫过于Win32消息循环的处置惩罚。OD的作者定义了众多的自定义消息来处置惩罚系统默认窗口消息,大部分的窗体事件都是由
Tablefunction来完成的。


一个窗口过程函数复杂的话基本就是千行代码,此中内容最多的还是菜单消息的处置惩罚,OllyDbg会根据当前窗口的句柄进行动态创建右键菜单,然后直接在里面处置惩罚菜单的单击事件,看到的就是函数体巨大。
cpu的窗口使用了两套数据来维护窗口大小,一个是还原模式,一个是最大化模式。如果使用一份数据,那么会遇到5个子窗口大小十分难以处置惩罚。当然逆向这里时耗费了我很多时间,没体验过窗口大小的bug就不知道有多痛楚。
其次就是5个窗口的resize的窗口大小伸缩时会有一定的鼠标光标的切换,早先是以为MFC中的分割条原理相似,cpu窗口是通太过割条割出来的,实在否则其确实创建了5个子窗口,并不是分割条控件分出来的。鼠标的切换在于相应了WM_SETCURSOR消息,然后加载相应的光标,再设置光标。

还有就是OD的大量可配置性导致全局变量很多,比如说字体颜色、分割线颜色、是否显示滚动条等, 这也是其界面雅观的告急原因了。
四、复现的结果
主界面

cpu窗口

内存块窗口

线程窗口

其他窗口的实现是大同小异的。
五、总结
逆向的乐趣在于发现其内部原理,类似ctf解出来了flag,而我则是发现了od查找数据时使用了二分查找、位图双缓存技术防止窗口闪耀。如今基本界面实现已不是困难,接下来继续完善调试器的功能!
来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |