自己利用业余时间写了很长时间了,核心功能使用rust开发,上层逻辑使用lua开发,不敢说比现有的调试器更好用,主要是方便我自己用来做一些自动化调试分析的事情
- 项目地址: https://gitee.com/udbg/udbg
- 文档地址: https://udbg.github.io/udbg/index.html
从release页面下载dist.zip解压到本地即可使用,路径中不要包含Unicode字符
要介绍的内容有点多,文档还在完善中...
设计理念
- 尽可能支持更多的调试/分析场景
- Windows:标准调试器
- Windows:VEH调试器
- 非侵入式调试、进程信息查看
- WinDbg 调试引擎:可用于分析dmp、内核调试
- [ ] ARK工具、内核信息查看
- [ ] 跨平台:支持linux、android
- 方便地编写扩展
- udbg本身使用lua编写了大部分上层逻辑
- 提供了大量lua接口,支持libffi
- 提供原生的Rust接口,编写高性能的扩展
- 界面/核心分离,可进行远程分析/调试
- CUI && GUI 双界面: CUI便于和其他第三方编辑器集成、GUI便于展示更多数据
- 功能抽象、分层,跨平台:既保留各平台的共性,降低学习成本,也允许差异化定制,实现平台特定的功能
启动调试器
主要是命令行启动
udbg
启动udbg,并显示主窗口,相当于在资源管理器中双击udbg.exe进行启动udbg -W
无窗口启动udbg,在命令行中调试udbg -e test.lua
启动udbg并执行 test.lua 脚本udbg -e test.lua --watch
监控 test.lua 脚本改动并自动执行udbg notepad.exe
(默认的调试引擎) 创建并调试 notepad.exeudbg -a notepad.exe
(默认的调试引擎) 附加到 notepad.exeudbg -A spy notepad.exe
通过spy调试引擎 创建并调试 notepad.exeudbg -A spy -a notepad.exe
通过spy调试引擎 附加到 notepad.exeudbg -r localhost:2333
连接到udbg-server,并启动,后面可跟上面所有的参数,参考 远程调试
完整的命令行语法如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
软件截图
脚本自动执行
- 最直接的方法是通过命令行启动
udbg -e test.lua --watch
指定运行一个脚本并监控其改动,然后自动执行 - 可以在udbg.exe所在目录下创建
config/autorun/
目录,autorun目录下的lua脚本发生改动时都会自动执行
断点
设置断点最简单的方法是在反汇编视图中,选择对应汇编语句,按F2
键
但如果想设置更复杂的断点需要使用bp
命令,列几个常用的断点设置示例
- 常规断点
bp CreateFileW
在 CreateFileW 函数处下断点 - 日志断点
bp CreateFileW wstr(reg[1])
在 CreateFileW 函数处下断点,并显示第一个参数- 其中
wstr(reg[1])
是一个lua表达式,表示需要记录的内容,reg[1]
表示当前架构下标准调用约定的第一个参数(x64下相当于reg.rcx
),可跟多个表达式比如bp CreateFileW wstr(reg[1]) reg.rdx
- 如果想过滤需要记录的日志,可加
-f
参数+lua表达式,比如bp CreateFileW wstr(reg[1]) -f v1:find'log.txt'
可以过滤带有log.txt的路径,其中v1表示CreateFileW后面的表达式列表里的第一个表达式的值
- 其中
- 条件断点
bp CreateFileW wstr(reg[1]) -c v1:find'log.txt'
当CreateFileW的第一个参数路径包含 log.txt 时断下 - 硬件断点
bp CreateFileW -t e1
临时(一次性)断点bp CreateFileW --temp
bp命令的完整帮助 bp -h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
如果需要了解bp命令的详细实现方式,参考script/udbg/command/bp.lua
自定义断点回调
通过脚本定制更复杂的断点处理逻辑
1 2 3 4 5 6 7 8 9 10 11 12 |
|
堆栈回溯
除了堆栈视图,还可以使用dp -r rsp
来查看堆栈;udbg目前未实现基于符号的堆栈回溯,dp -r
本质上是暴力搜索堆栈上的返回地址
模块符号
udbg自带的调试引擎支持加载pdb符号,可在配置文件中通过__config.symbol_cache = 'D:/Symbols
来指定pdb符号所在的目录,目录结构和windbg的符号缓存目录一致,可以在windbg里下载系统所需要的符号
udbg首先会根据dll/exe里的pdb路径去加载符号,如果没有的话再寻找dll所在目录下的同名pdb,如果也没有就会去符号缓存目录中加载
如果想给一个模块手动指定pdb路径,可以使用命令 load-symbol xx.dll D:\xx.pdb
也可以在配置文件中写脚本来自动加载
1 2 3 4 5 |
|
内存读写
- 直接在内存视图中查看
Ctrl+1
Ctrl+2
Ctrl+3
Ctrl+4
分别切换BYTE WORD DWORD QWORD显示Ctrl+F
切换float显示Ctrl+D
切换double显示Ctrl+G
可以输入地址表达式并跳转到对应地址
mem <address>
命令在内存视图中 跳转到对应的地址表达式mem ntdll.dll
mem [[0x403000]+0x10]
e
命令编辑内存- Lua函数
{read|write}_{u8|u16|u32|u64|ptr|float|double}
异常处理
相关配置
__config.ignore_all_exception = false
是否忽略所有异常
处理异常事件
可以通过脚本配置更复杂的异常处理
1 2 3 4 5 6 7 8 |
|
单步跟踪
在目标断下时,可以通过如下脚本来启动一个单步跟踪过程
1 2 3 4 5 6 7 8 9 |
|
配置脚本
- udbg所在目录下的
config
目录为配置目录,可以通过同步盘同步配置,软连接到config - config目录本身也会被加到lua的模块搜索路径里
-
config下的
client.lua
为第一个被执行的配置脚本,主要用于定制一些跟客户端UI相关的配置,配置脚本示例如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-
-
指定其他插件
/
配置路径
plugins
=
{
{path
=
[[D:\Plugin1]]},
{path
=
[[D:\Plugin2]]},
}
-
-
指定启动编辑器的命令
-
-
默认是 notepad
edit_cmd
=
'notepad.exe %1'
-
-
如果安装了vscode,建议改为 vscode
edit_cmd
=
'code %1'
-
-
远程地址映射
-
-
配置了此项可在命令行中用键名代替对应的地址端口
-
-
比如: udbg
-
r vmware C:\Windows\notepad.exe
remote_map
=
{
[
'local'
]
=
'127.0.0.1:2333'
,
local1
=
'127.0.0.1:2334'
,
local2
=
'127.0.0.1:2335'
,
vmware
=
'192.168.1.239:2333'
,
}
-
config下的
udbg/plugin/init.lua
会在调试器初始化时被执行,可以做一些跟调试器相关的配置,比如1
2
3
4
5
6
7
8
-
-
忽略初始断点(不中断给用户)
__config.ignore_initbp
=
true
-
-
初始断点事件触发时自动下断点
function uevent.on.init_bp()
if
udbg.target.path:find
'notepad'
then
ucmd
'bp kernel32!CreateFileW'
end
end
注意,执行
client.lua
和udbg/plugin/init.lua
的是两个不同的lua虚拟机,前者是给客户端UI使用的,后者是给调试器核心使用的 autorun/
目录下的lua脚本发生改动时,会被(调试器的lua虚拟机)自动执行
远程调试
- 启动udbg服务:将
udbg-server.exe
lua54.dll
uspy.dll
三个文件拷到目标机器上,然后管理员权限运行udbg-server.exe - 通过
udbg -r 目标机器地址:端口
连接到udbg服务进行调试,比如udbg -r 192.168.1.239:2333 C:\Windows\notepad.exe