在学习反调试时,我惊叹他们的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
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |