首页
社区
课程
招聘
[分享]自写自用的调试分析工具 udbg
2021-5-9 14:10 26459

[分享]自写自用的调试分析工具 udbg

2021-5-9 14:10
26459

自己利用业余时间写了很长时间了,核心功能使用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.exe
  • udbg -a notepad.exe (默认的调试引擎) 附加到 notepad.exe
  • udbg -A spy notepad.exe 通过spy调试引擎 创建并调试 notepad.exe
  • udbg -A spy -a notepad.exe 通过spy调试引擎 附加到 notepad.exe
  • udbg -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 0.1.0
metaworm
 
USAGE:
    udbg.exe [FLAGS] [OPTIONS] [--] [ARGS]
 
FLAGS:
    -a, --attach       Attach target
    -h, --help         Prints help information
    -W, --no-window    Dont show the main window
    -o, --open         Open the target, not attach
    -p, --pid          Target as pid
        --version      Prints version information
    -V, --verbose      Show the verbose info
    -w, --watch        Watch the executed lua script
 
OPTIONS:
    -A, --adaptor <adaptor>          Specify the adaptor [default: ]
    -r, --remote <address:port>      Connect to udbg server, with cui [env: UDBG_SERVER=]
        --cwd <directory>            Set CWD for target
    -e, --execute <lua path>         Execute lua script
    -c, --config <udbg config>...    Set the __config
 
ARGS:
    <target-path>    Create debug target
    <args>...        Shell Arguments to target

软件截图
图片描述

脚本自动执行

  1. 最直接的方法是通过命令行启动udbg -e test.lua --watch指定运行一个脚本并监控其改动,然后自动执行
  2. 可以在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                                        设置断点
    <address>       (string)              断点地址
    <vars...>       (optional string)     变量列表
 
    -n, --name        (optional string)   断点名称
    -c, --cond        (optional string)   中断条件
    -l, --log         (optional string)   日志表达式
    -f, --filter      (optional string)   日志条件
    -s, --statistics  (optional string)   统计表达式
    -t, --type        (optional bp_type)  断点类型(e|w|a)(1|2|4|8)
    --tid             (optional number)   命中线程
    --temp                                临时断点
    --symbol                              转换为符号
    --hex                                 十六进制显示
    --caller                              显示调用者
    -m, --module                          模块加载断点

如果需要了解bp命令的详细实现方式,参考script/udbg/command/bp.lua

自定义断点回调

通过脚本定制更复杂的断点处理逻辑

1
2
3
4
5
6
7
8
9
10
11
12
add_bp('kernel32!CreateFileW', function()
    local path = read_wstring(reg.rcx)
    log('[CreateFileW]', path)
    if path:find 'xxx' then
        -- 返回true表示这个断点会中断给用户处理
        return true
    end
    -- 在调用 CreateFileW 的返回点处设置断点
    add_bp(reg.rsp, function()
        log('[CreateFileW]', 'return', reg.rax)
    end, {temp = true, type = 'table'})
end)

堆栈回溯

除了堆栈视图,还可以使用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
function uevent.on.module_load(m)
    if m.base == PA 'xx.dll' then
        m:load_symbol [[D:\xx.pdb]]
    end
end

内存读写

  • 直接在内存视图中查看
    • 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
function uevent.on.exception(tid, code, first)
    if code == STATUS_CPP_EH_EXCEPTION then
        return 'run'
    end
    if reg.rip == 0 then
        return 'run'
    end
end

单步跟踪

在目标断下时,可以通过如下脚本来启动一个单步跟踪过程

1
2
3
4
5
6
7
8
9
-- 单步跟踪1000步并输出每一步的汇编语句
local count = 1000
local disasm = disasm
ui.continue('step', function()
    count = count - 1
    local pc = reg._pc
    log(hex(pc), disasm(pc).string)
    return count == 0
end)

配置脚本

  • 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.luaudbg/plugin/init.lua的是两个不同的lua虚拟机,前者是给客户端UI使用的,后者是给调试器核心使用的

  • autorun/目录下的lua脚本发生改动时,会被(调试器的lua虚拟机)自动执行

远程调试

  1. 启动udbg服务:将udbg-server.exe lua54.dll uspy.dll 三个文件拷到目标机器上,然后管理员权限运行udbg-server.exe
  2. 通过udbg -r 目标机器地址:端口连接到udbg服务进行调试,比如udbg -r 192.168.1.239:2333 C:\Windows\notepad.exe

[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

收藏
点赞11
打赏
分享
最新回复 (16)
雪    币: 219
活跃值: (88)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ulysseswu 2021-5-9 14:29
2
0
不明觉厉,支持一下
雪    币: 357
活跃值: (2593)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
KooJiSung 2021-5-9 14:32
3
0
牛叉
雪    币: 876
活跃值: (434)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mb_qmomcleg 2021-5-9 16:47
4
0
雪    币: 4097
活跃值: (2569)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
linghaien 2021-5-9 18:03
5
0

弄一些过反调试的东西进去,现在的调试器,好多都 过不了反调试

最后于 2021-5-9 18:04 被linghaien编辑 ,原因:
雪    币: 434
活跃值: (1670)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
metaworm 2021-5-9 18:12
6
0
linghaien 弄一些过反调试的东西进去,现在的调试器,好多都 过不了反调试
反调试这个需求可能比较小众,后面会考虑以插件的形式实现一些反调试功能
雪    币: 7184
活跃值: (3176)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
十年后 2021-5-9 21:02
7
0
牛叉,试用了下,界面很清爽,希望楼主能持续更新,期待增加新功能,还有问题目前仅有x86版本吗?
雪    币: 2863
活跃值: (1597)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
chixiaojie 2021-5-9 21:39
8
0
跟x64dbg比还是差了一大堆,不过很好了。
雪    币: 434
活跃值: (1670)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
metaworm 2021-5-9 22:01
9
0
十年后 牛叉,试用了下,界面很清爽,希望楼主能持续更新,期待增加新功能,还有问题目前仅有x86版本吗?
没有x86版本,暂时也不考虑提供x86版本,但是支持调试WOW64应用
雪    币: 7763
活跃值: (2226)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
option 2021-5-10 07:24
10
0
谢谢分享,下载试用
雪    币: 2769
活跃值: (1855)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wx_荣仔 2021-5-10 08:44
11
0
make一下。可能会有用到的时候呢 
雪    币: 22979
活跃值: (3327)
能力值: (RANK:648 )
在线值:
发帖
回帖
粉丝
KevinsBobo 8 2021-5-10 10:25
12
0
感谢分享!
雪    币: 1042
活跃值: (455)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Rookietp 2021-5-10 14:15
13
0
卧槽,牛X
雪    币: 1987
活跃值: (1501)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
basketwill 1 2021-5-12 12:00
14
0
rust真是个好东西,还能开发驱动
雪    币: 15
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
夏季爸爸 2021-6-2 21:15
15
0
不明觉厉,支持一下
雪    币: 4016
活跃值: (5833)
能力值: ( LV7,RANK:102 )
在线值:
发帖
回帖
粉丝
fjqisba 2021-6-2 21:49
16
0
这真是小母牛不下崽,牛逼坏了
雪    币: 3864
活跃值: (5488)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
badboyl 2 2021-8-5 10:23
17
0
fjqisba 这真是小母牛不下崽,牛逼坏了
你说话真是精辟坏了
游客
登录 | 注册 方可回帖
返回