MFC_调试器_源码

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/D_K_01/article/details/80756355

调试器

带MFC界面的简易调试器;
能实现常用基本调试功能;

功能

软件断点
硬件断点
内存访问断点
条件断点
API断点
汇编/反汇编
寄存器信息
堆栈信息
模块信息
单步步入/步过/运行
导入导出表信息
dump文件
symbol符号解析
打开/拖入
附加/脱离
命令行执行
快捷键操作

#编译环境

Win10 VS2015;

GitHub

https://github.com/dkni0/AE86_dbg

截图

主界面
主界面

模块信息

模块信息

菜单信息

菜单1
菜单2
菜单2
菜单3

#程序操作

##快捷键
普通断点 F2
单步步入 F7
单步步过 F8
运行 F9

##命令行格式

备注:
命令参考自windbg
所有命令不区分大小写;
地址不足八位必须前面补0;
命令和参数中间以一个空格隔开;
###普通指令

  • g 运行
    程序直接运行;
    遇到断点暂停;
    如无断点则不能再控制;

  • t 单步步入
    单步运行;
    遇有函数则会进入运行;

  • p 单步步过
    遇到call指令直接运行下一行指令;
    其他指令与单步步入模式相同;

  • s 脱离程序
    取消调试程序;
    被调试程序可正常运行;

  • q 结束被调试程序
    取消调试并结束被调试程序;

  • u 显示指定地址反汇编信息
    格式:u [address]
    示例:u 000a1005
    功能:在指定地址处设置int3普通断点

  • ml 显示模块列表
    格式:ml
    功能:显示模块列表

  • db 显示指定地址内存信息
    格式:db [address]
    示例:db 000a1050
    功能:显示指定位置内存信息;

  • dl Dll注入
    格式:dl [pid] [DllPath]
    示例:dl 12345 D:\TerminateProcess.dll
    功能:注入指定进程dll文件;
    此处pid为十进制;

  • df 卸载dll
    格式:dl
    功能:卸载已注入的dll文件;
    注入dll后才可使用该命令;

  • dump
    格式:dump [path]
    示例:dump d:\123.exe
    功能:dump文件至指定位置;

###修改程序

  • r 修改寄存器
    格式:r [erx] [value]
    示例:r eax 12345678
    功能:修改指定寄存器的值;
    仅供修改eax,ecx,edx,ebx;

  • eip 修改eip
    格式:eip [address]
    示例:eip 000a1050
    功能:修改eip为指定地址,
    下一行命令从所改位置处运行;

  • ao 修改OPCode
    格式:ao [address] [OPCode]
    示例:ao 000a1050 12 34 56 78
    功能:修改反汇编窗口中可见的OPCode指令;
    地址应为反汇编窗口中的地址;
    指令不超过该位置原有指令长度;

  • ai 修改汇编指令
    格式:ai [address] [Instruction]
    示例:ai 000a1050 nop
    功能:修改反汇编窗口中可见的汇编指令;
    地址应为反汇编窗口中的地址;

###断点设置

  • bp 普通断点
    格式:bp [address]
    示例:bp 000a1005
    功能:在指定地址处设置int3普通断点

  • bm 内存断点
    格式:bm [address] [type]
    示例:bm 000a1005 a
    示例:bm 000a1005 w
    功能:在指定地址处设置内存断点,类型可选访问(a)或写入(w);

  • bh 硬件断点
    格式:bh [address] [type] [length]
    示例:bh 000a1005 a b
    示例:bh 000a1005 w d
    功能:在指定地址处设置硬件断点,
    类型可选访问(a)或写入(w)或执行(e);
    长度可选字节(b),字(w),双字(d);
    执行断点只支持字节;

  • bi 条件断点
    格式:bi [address] [value]
    示例:bi eax 10
    示例:bi 000a1005 12345678
    功能:在指定地址处设置条件断点,符合条件断下,不符合条件则略过;
    地址可选寄存器(eax,ecx),或内存地址;
    值需输入十六进制数;

  • ap API断点
    格式:ap [FunName]
    示例:ap MessageBoxW
    功能:在指定地址处设置API断点;函数名称正确下断点,否则返回错误;
    API名称区分大小写;

#调试原理

吐槽:
这编辑器居然没有自动保存草稿功能吗????
保存还会出错啊啊啊啊啊???
出错还直接崩溃关闭!!
白忙活了半天。。。。

  • 异常分发流程
    异常分发流程

  • 调试器交互流程
    调试器建立调试事件,主动产生异常,
    根据异常分发机制,来实现调试程序
    调试器交互流程

##断点原理

  • 软件断点
    保存指定地址原有字节;
    替换为0xCC(int 3指令),
    CPU运行到这里产生异常断下,
    再恢复原有字节;

  • 硬件断点
    设置调试寄存器,
    断点地址写入DR0~DR3寄存器,
    断点类型写入DR7寄存器的RW0~RW3中,
    断点有效标志写入DR7寄存器L0~L3中,
    断点长度写入DR7寄存器的LEN0~LEN3中,
    硬件执行断点只能为单字节;
    硬件读写短的为2、4时地址需要对齐;

  • 内存断点
    更改指定地址所在内存分页的访问页属性,
    出发异常后,恢复页属性,
    执行单步到断点地址处;

  • 条件断点
    指定地址位置写入软件断点,
    断下后再根据条件判断是否继续;
    不符合条件则略过;

  • API断点
    通过调试符号服务器获取API地址,
    在地址位置下断;

  • 单步断点
    修改CPU标志寄存器的TF标志位,
    置为1即可实现单步断点;

  • 单步步过
    判断当前指令是否为call或rep重复指令,

是的话在下一条指令位置下软件断点,
运行程序,断到下一条指令位置;

否则执行单步断点

项目设计

项目架构

反汇编使用BeaEngine引擎;
汇编使用XEDParse引擎,
程序运行需要XEDParse.dll文件;
需要管理员权限;

获取context信息,显示寄存器信息,
根据寄存器信息,读取远程内存,
实现反汇编信息显示,
内存信息显示,堆栈信息显示,

遍历目标模块,显示模块信息

dump文件,
根据PE信息,
读取相应区段,
再写入到文件;

项目难点,
界面与工作线程分离,
不能产生冲突,
通过enent事件同步,
工作线程完成任务发送消息,
界面再刷新;

符号有点麻烦,
也可能环境的问题,
本机符号信息显示不太完整;

相关参考:
《一个调试器的实现》系列
http://www.cnblogs.com/zplutor/archive/2011/03/20/1989783.html

#End

猜你喜欢

转载自blog.csdn.net/D_K_01/article/details/80756355