编辑
2025-09-05
记录知识
0

目录

安装pwndbg
示例代码
基本调试
寄存器
代码段反汇编
源码
栈布局
栈帧布局
打印上下文
打印内存
更友好的查看内存
搜索内存
打印got和plt
调试arena
查看堆
查看bins
查看mapping
解析内存地址
更多命令

使用gdb久了就可以发现,有一些功能例如查看堆栈布局等直接使用gdb不是很方便,但是操作系统的核心问题通常又是在内存管理上,例如打印一个双向链表,单使用gdb并不是很方便的处理这个事情,那么有没有在gdb之上,能够更易用的工具,从而调试一些核心的操作系统上的问题呢,实际上是有的,那就是pwndbg,通过它能够更方便的排查系统核心问题。

安装pwndbg

直接克隆仓库,然后安装即可

git clone https://github.com/pwndbg/pwndbg.git pip3 install poetry ./setup.sh

如果不希望重编译,那么直接下载预编译二进制即可,根据最新的release build下载。

https://github.com/pwndbg/pwndbg/releases/download/2025.05.30/pwndbg_2025.05.30_arm64-portable.tar.xz

安装成功之后,可以看到其通过gdbinit默认加载了一个python文件,如下

root@kylin:~# cat .gdbinit source /root/pwndbg/gdbinit.py

示例代码

为了能够演示pwndbg相比于gdb的优势,提前先准备一个代码malloc.c如下

#include <stdlib.h> #include <string.h> int main() { void *p = malloc(100*sizeof(char)); memset(p, 0x55, 100*sizeof(char)); memcpy(p + 100*sizeof(char), "kylin", strlen("kylin")+1); free(p); }

此时编译后即可gdb调试它

基本调试

当代码断点时,pwndbg会把所有信息提供给我,如下

───────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]──────────────────────────────────────────────────────────────────────────────────────────── X0 0x412304 ◂— 0x2006e696c796b /* 'kylin' */ X1 0x400780 ◂— ldpsw x11, x30, [x11, #-0xa0] /* 'kylin' */ X2 6 X3 0x412304 ◂— 0x2006e696c796b /* 'kylin' */ X4 0x400786 ◂— madd w0, w0, w1, w0 X5 0x41230a ◂— 2 X6 0x696c796b X7 0x6e696c X8 0x38 X9 0x7ff7fadac0 (main_arena+96) —▸ 0x412300 ◂— 'UUUUkylin' X10 0 X11 0x28 X12 0x7ff7e43e50 ◂— udf #0 X13 0 X14 0 X15 0x70 X16 0x7ff7ec4a10 (__memcpy_generic) ◂— prfm pldl1keep, [x1] /* ' ' */ X17 0x411000 (memcpy@got.plt) —▸ 0x7ff7ec4a10 (__memcpy_generic) ◂— prfm pldl1keep, [x1] /* ' ' */ X18 0 X19 0x4006d0 (__libc_csu_init) ◂— stp x29, x30, [sp, #-0x40]! X20 0 X21 0x400570 (_start) ◂— mov x29, #0 X22 0 X23 0 X24 0 X25 0 X26 0 X27 0 X28 0 X29 0x7ffffff2b0 —▸ 0x7ffffff2d0 ◂— 0 SP 0x7ffffff2b0 —▸ 0x7ffffff2d0 ◂— 0 LR 0x4006bc (main+64) ◂— ldr x0, [sp, #0x18] PC 0x4006bc (main+64) ◂— ldr x0, [sp, #0x18] ────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM / aarch64 / set emulate on ]──────────────────────────────────────────────────────────────────────────────────────────────────── ► 0x4006bc <main+64> ldr x0, [sp, #0x18] X0, [0x7ffffff2c8] => 0x4122a0 ◂— 'UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU...' 0x4006c0 <main+68> bl #free@plt <free@plt> 0x4006c4 <main+72> mov w0, #0 W0 => 0 0x4006c8 <main+76> ldp x29, x30, [sp], #0x20 0x4006cc <main+80> ret 0x4006d0 <__libc_csu_init> stp x29, x30, [sp, #-0x40]! 0x4006d4 <__libc_csu_init+4> mov x29, sp 0x4006d8 <__libc_csu_init+8> stp x19, x20, [sp, #0x10] 0x4006dc <__libc_csu_init+12> adrp x20, #0x410000 X20 => 0x410000 ◂— 0x10102464c457f 0x4006e0 <__libc_csu_init+16> add x20, x20, #0xe00 0x4006e4 <__libc_csu_init+20> stp x21, x22, [sp, #0x20] ──────────────────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]────────────────────────────────────────────────────────────────────────────────────────────────────────────── In file: /root/malloc.c:9 4 int main() 5 { 6 void *p = malloc(100*sizeof(char)); 7 memset(p, 0x55, 100*sizeof(char)); 8 memcpy(p + 100*sizeof(char), "kylin", strlen("kylin")+1); ► 9 free(p); 10 } ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 00:0000│ x29 sp 0x7ffffff2b0 —▸ 0x7ffffff2d0 ◂— 0 01:0008│ 0x7ffffff2b8 —▸ 0x7ff7e60d90 (__libc_start_main+232) ◂— bl #0x7ff7e764b0 02:0010│ 0x7ffffff2c0 —▸ 0x4006d0 (__libc_csu_init) ◂— stp x29, x30, [sp, #-0x40]! 03:0018│ 0x7ffffff2c8 —▸ 0x4122a0 ◂— 'UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUkylin' 04:0020│ 0x7ffffff2d0 ◂— 0 05:0028│ 0x7ffffff2d8 —▸ 0x4005bc (_start+76) ◂— bl #0x400550 06:0030│ 0x7ffffff2e0 ◂— 0 07:0038│ 0x7ffffff2e8 ◂— 0 ────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]──────────────────────────────────────────────────────────────────────────────────────────────────────────────── ► 0 0x4006bc main+64 1 0x7ff7e60d90 __libc_start_main+232 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

这里包含如下几个部分

寄存器

第一部分就是寄存器的值,因为所有的trace都是第一时间拿到当前寄存器,pwndbg在寄存器的基础之上提供了更进一步的简化,例如

  1. 解析内存的值 0x412304 ◂— 0x2006e696c796b /* 'kylin' */
  2. 自动解析符号 0x7ff7ffd668 (_rtld_global_ro)
  3. 自动解析字符 0x7ff7fe5b28 ◂— '/lib/aarch64-linux-gnu/'
  4. 自动反汇编指令 0x4006d0 (__libc_csu_init) ◂— stp x29, x30, [sp, #-0x40]!
  5. 自动解析链表 X29 0x7fffffdf80 —▸ 0x7fffffdfb0 —▸ 0x7fffffe040 —▸ 0x7fffffe450 —▸ 0x7fffffe470 ◂— ...
  6. 自动计算plt 0x411000 (memcpy@got.plt) —▸ 0x7ff7ec4a10 (__memcpy_generic) ◂— prfm pldl1keep, [x1] /* ' ' */

这比我们gdb下自行计算来说方便很多

代码段反汇编

第二部分就是断点对应代码的反汇编,与gdb的diss不一样的是,它会在关键地方提供注释,例如

  1. 自动注释计算寄存器的值 ldr x0, [sp, #0x18] X0, [0x7ffffff2c8] => 0x4122a0 ◂— 'UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU...'
  2. 自动注释状态寄存器的值 cmp x20, x0 0x7ff7fffed0 - 0x0 CPSR => 0x20000000 [ n z C v q pan il d a i f el:0 sp ]
  3. 自动注释函数跳转位置 bl #free@plt <free@plt>
  4. 自动注释LR寄存器的值 ret <0x7ff7fd2f64>
  5. 自动注释SP寄存器链表 mov sp, x29 SP => 0x7fffffdfb0 —▸ 0x7fffffe040 —▸ 0x7fffffe450 —▸ 0x7fffffe470 ◂— ...
  6. 自动注释通用寄存器的值 mov w0, w28 W0 => 3
  7. 自动注释adrp页面的值 adrp x20, #0x410000 X20 => 0x410000 ◂— 0x10102464c457f

源码

如gdb能够找到源码,则直接打印源码内容

In file: /root/malloc.c:9 4 int main() 5 { 6 void *p = malloc(100*sizeof(char)); 7 memset(p, 0x55, 100*sizeof(char)); 8 memcpy(p + 100*sizeof(char), "kylin", strlen("kylin")+1); ► 9 free(p); 10 }

栈布局

第三部分就是当前函数的栈布局,同样的,给你足够详细的注释,如下

00:0000│ x29 sp 0x7ffffff2b0 —▸ 0x7ffffff2d0 ◂— 0 01:0008│ 0x7ffffff2b8 —▸ 0x7ff7e60d90 (__libc_start_main+232) ◂— bl #0x7ff7e764b0 02:0010│ 0x7ffffff2c0 —▸ 0x4006d0 (__libc_csu_init) ◂— stp x29, x30, [sp, #-0x40]! 03:0018│ 0x7ffffff2c8 —▸ 0x4122a0 ◂— 'UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUkylin' 04:0020│ 0x7ffffff2d0 ◂— 0 05:0028│ 0x7ffffff2d8 —▸ 0x4005bc (_start+76) ◂— bl #0x400550 06:0030│ 0x7ffffff2e0 ◂— 0 07:0038│ 0x7ffffff2e8 ◂— 0

栈帧布局

除了当前栈布局,还把代码栈帧直接打印出来,如下

► 0 0x4006bc main+64 1 0x7ff7e60d90 __libc_start_main+232

打印上下文

根据上面信息,默认情况下断点时会打印基本信息,而在调试过程中,也可以随时打印上下文,例如修改某些值之后,可以一股脑的把所有信息都打印,如下

pwndbg> context

打印内存

利用hexdump,可以直接查看malloc的内存内容,无需dump,或者x来计算

pwndbg> hexdump p +0000 0x4122a0 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 │UUUUUUUU│UUUUUUUU│ ... ↓ skipped 2 identical lines (32 bytes) +0030 0x4122d0 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 │UUUUUUUU│UUUUUUUU│

更友好的查看内存

在代码中,我故意在p后面追加了kylin,可以看到hexdump的p是带边界的,而telescope是直接往后打印的,如下

pwndbg> telescope p 00:0000│ 0x4122a0 ◂— 'UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUkylin' ... ↓ 7 skipped

搜索内存

如果在gdb中搜索,必须将其dump出来查找,但是pwndbg可以直接用search搜索你想要的东西,我对p标记了kylin,可以直接搜索如下

pwndbg> search kylin Searching for value: 'kylin' malloc 0x400780 ldpsw x11, x30, [x11, #-0xa0] /* 'kylin' */ malloc 0x410780 0x6e696c796b /* 'kylin' */ [heap] 0x412304 0x2006e696c796b /* 'kylin' */ libc-2.31.so 0x7ff7f665aa ldpsw x11, x30, [x11, #-0xa0] warning: Unable to access 16000 bytes of target memory at 0x7ff7fa1d04, halting search. [vdso] 0x7ff7ffc94d ldpsw x11, x30, [x11, #-0xa0] /* 'kylin1~20.04) 10.3.0' */

打印got和plt

这两块的值在gdb中需要自行计算,而pwndbg帮你直接默认计算好了,如下

pwndbg> got State of the GOT of /root/malloc: GOT protection: Partial RELRO | Found 7 GOT entries passing the filter [0x411000] memcpy@GLIBC_2.17 -> 0x7ff7ec4a10 (__memcpy_generic) ◂— prfm pldl1keep, [x1] /* ' ' */ [0x411008] malloc@GLIBC_2.17 -> 0x7ff7eb9130 (malloc) ◂— adrp x2, #0x7ff7fac000 [0x411010] __libc_start_main@GLIBC_2.17 -> 0x7ff7e60ca8 (__libc_start_main) ◂— stp x29, x30, [sp, #-0x150]! [0x411018] memset@GLIBC_2.17 -> 0x7ff7ec59c0 (__memset_generic) ◂— dup v0.16b, w1 [0x411020] __gmon_start__ -> 0x4004e0 ◂— stp x16, x30, [sp, #-0x10]! [0x411028] abort@GLIBC_2.17 -> 0x4004e0 ◂— stp x16, x30, [sp, #-0x10]! [0x411030] free@GLIBC_2.17 -> 0x4004e0 ◂— stp x16, x30, [sp, #-0x10]! pwndbg> plt Section .plt 0x4004e0-0x400570: 0x400500: memcpy@plt 0x400510: malloc@plt 0x400520: __libc_start_main@plt 0x400530: memset@plt 0x400540: __gmon_start__@plt 0x400550: abort@plt 0x400560: free@plt

调试arena

pwndbg为了方便调试内存管理,可以直接查看arena的结构信息,如下

pwndbg> arena Arena for thread 1 is located at: 0x7ff7fada60 { mutex = 0, flags = 0, have_fastchunks = 0, fastbinsY = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, top = 0x412300, last_remainder = 0x0, bins = {0x7ff7fadac0 <main_arena+96>, 0x7ff7fadac0 <main_arena+96>, 0x7ff7fadad0 <main_arena+112>, 0x7ff7fadad0 <main_arena+112>, 0x7ff7fadae0 <main_arena+128>, 0x7ff7fadae0 <main_arena+128>, 0x7ff7fadaf0 <main_arena+144>, 0x7ff7fadaf0 <main_arena+144>, 0x7ff7fadb00 <main_arena+160>, 0x7ff7fadb00 <main_arena+160>, 0x7ff7fadb10 <main_arena+176>, 0x7ff7fadb10 <main_arena+176>, 0x7ff7fadb20 <main_arena+192>, 0x7ff7fadb20 <main_arena+192>, 0x7ff7fadb30 <main_arena+208>, 0x7ff7fadb30 <main_arena+208>, 0x7ff7fadb40 <main_arena+224>, 0x7ff7fadb40 <main_arena+224>, 0x7ff7fadb50 <main_arena+240>, 0x7ff7fadb50 <main_arena+240>, 0x7ff7fadb60 <main_arena+256>, 0x7ff7fadb60 <main_arena+256>, 0x7ff7fadb70 <main_arena+272>, 0x7ff7fadb70 <main_arena+272>, 0x7ff7fadb80 <main_arena+288>, 0x7ff7fadb80 <main_arena+288>, 0x7ff7fadb90 <main_arena+304>, 0x7ff7fadb90 <main_arena+304>, 0x7ff7fadba0 <main_arena+320>, 0x7ff7fadba0 <main_arena+320>, 0x7ff7fadbb0 <main_arena+336>, 0x7ff7fadbb0 <main_arena+336>, 0x7ff7fadbc0 <main_arena+352>, 0x7ff7fadbc0 <main_arena+352>, 0x7ff7fadbd0 <main_arena+368>, 0x7ff7fadbd0 <main_arena+368>, 0x7ff7fadbe0 <main_arena+384>, 0x7ff7fadbe0 <main_arena+384>, 0x7ff7fadbf0 <main_arena+400>, 0x7ff7fadbf0 <main_arena+400>, 0x7ff7fadc00 <main_arena+416>, 0x7ff7fadc00 <main_arena+416>, 0x7ff7fadc10 <main_arena+432>, 0x7ff7fadc10 <main_arena+432>, 0x7ff7fadc20 <main_arena+448>, 0x7ff7fadc20 <main_arena+448>, 0x7ff7fadc30 <main_arena+464>, 0x7ff7fadc30 <main_arena+464>, 0x7ff7fadc40 <main_arena+480>, 0x7ff7fadc40 <main_arena+480>, 0x7ff7fadc50 <main_arena+496>, 0x7ff7fadc50 <main_arena+496>, 0x7ff7fadc60 <main_arena+512>, 0x7ff7fadc60 <main_arena+512>, 0x7ff7fadc70 <main_arena+528>, 0x7ff7fadc70 <main_arena+528>, 0x7ff7fadc80 <main_arena+544>, 0x7ff7fadc80 <main_arena+544>, 0x7ff7fadc90 <main_arena+560>, 0x7ff7fadc90 <main_arena+560>, 0x7ff7fadca0 <main_arena+576>, 0x7ff7fadca0 <main_arena+576>, 0x7ff7fadcb0 <main_arena+592>, 0x7ff7fadcb0 <main_arena+592>, 0x7ff7fadcc0 <main_arena+608>, 0x7ff7fadcc0 <main_arena+608>, 0x7ff7fadcd0 <main_arena+624>, 0x7ff7fadcd0 <main_arena+624>, 0x7ff7fadce0 <main_arena+640>, 0x7ff7fadce0 <main_arena+640>, 0x7ff7fadcf0 <main_arena+656>, 0x7ff7fadcf0 <main_arena+656>, 0x7ff7fadd00 <main_arena+672>, 0x7ff7fadd00 <main_arena+672>, 0x7ff7fadd10 <main_arena+688>, 0x7ff7fadd10 <main_arena+688>, 0x7ff7fadd20 <main_arena+704>, 0x7ff7fadd20 <main_arena+704>, 0x7ff7fadd30 <main_arena+720>, 0x7ff7fadd30 <main_arena+720>, 0x7ff7fadd40 <main_arena+736>, 0x7ff7fadd40 <main_arena+736>, 0x7ff7fadd50 <main_arena+752>, 0x7ff7fadd50 <main_arena+752>, 0x7ff7fadd60 <main_arena+768>, 0x7ff7fadd60 <main_arena+768>, 0x7ff7fadd70 <main_arena+784>, 0x7ff7fadd70 <main_arena+784>, 0x7ff7fadd80 <main_arena+800>, 0x7ff7fadd80 <main_arena+800>, 0x7ff7fadd90 <main_arena+816>, 0x7ff7fadd90 <main_arena+816>, 0x7ff7fadda0 <main_arena+832>, 0x7ff7fadda0 <main_arena+832>, 0x7ff7faddb0 <main_arena+848>, 0x7ff7faddb0 <main_arena+848>, 0x7ff7faddc0 <main_arena+864>, 0x7ff7faddc0 <main_arena+864>, 0x7ff7faddd0 <main_arena+880>, 0x7ff7faddd0 <main_arena+880>, 0x7ff7fadde0 <main_arena+896>, 0x7ff7fadde0 <main_arena+896>, 0x7ff7faddf0 <main_arena+912>, 0x7ff7faddf0 <main_arena+912>, 0x7ff7fade00 <main_arena+928>, 0x7ff7fade00 <main_arena+928>, 0x7ff7fade10 <main_arena+944>, 0x7ff7fade10 <main_arena+944>, 0x7ff7fade20 <main_arena+960>, 0x7ff7fade20 <main_arena+960>, 0x7ff7fade30 <main_arena+976>, 0x7ff7fade30 <main_arena+976>, 0x7ff7fade40 <main_arena+992>, 0x7ff7fade40 <main_arena+992>, 0x7ff7fade50 <main_arena+1008>, 0x7ff7fade50 <main_arena+1008>, 0x7ff7fade60 <main_arena+1024>, 0x7ff7fade60 <main_arena+1024>, 0x7ff7fade70 <main_arena+1040>, 0x7ff7fade70 <main_arena+1040>, 0x7ff7fade80 <main_arena+1056>, 0x7ff7fade80 <main_arena+1056>, 0x7ff7fade90 <main_arena+1072>, 0x7ff7fade90 <main_arena+1072>, 0x7ff7fadea0 <main_arena+1088>, 0x7ff7fadea0 <main_arena+1088>, 0x7ff7fadeb0 <main_arena+1104>, 0x7ff7fadeb0 <main_arena+1104>, 0x7ff7fadec0 <main_arena+1120>, 0x7ff7fadec0 <main_arena+1120>, 0x7ff7faded0 <main_arena+1136>, 0x7ff7faded0 <main_arena+1136>, 0x7ff7fadee0 <main_arena+1152>, 0x7ff7fadee0 <main_arena+1152>, 0x7ff7fadef0 <main_arena+1168>, 0x7ff7fadef0 <main_arena+1168>, 0x7ff7fadf00 <main_arena+1184>, 0x7ff7fadf00 <main_arena+1184>, 0x7ff7fadf10 <main_arena+1200>, 0x7ff7fadf10 <main_arena+1200>, 0x7ff7fadf20 <main_arena+1216>, 0x7ff7fadf20 <main_arena+1216>, 0x7ff7fadf30 <main_arena+1232>, 0x7ff7fadf30 <main_arena+1232>, 0x7ff7fadf40 <main_arena+1248>, 0x7ff7fadf40 <main_arena+1248>, 0x7ff7fadf50 <main_arena+1264>, 0x7ff7fadf50 <main_arena+1264>, 0x7ff7fadf60 <main_arena+1280>, 0x7ff7fadf60 <main_arena+1280>, 0x7ff7fadf70 <main_arena+1296>, 0x7ff7fadf70 <main_arena+1296>, 0x7ff7fadf80 <main_arena+1312>, 0x7ff7fadf80 <main_arena+1312>, 0x7ff7fadf90 <main_arena+1328>, 0x7ff7fadf90 <main_arena+1328>, 0x7ff7fadfa0 <main_arena+1344>, 0x7ff7fadfa0 <main_arena+1344>, 0x7ff7fadfb0 <main_arena+1360>, 0x7ff7fadfb0 <main_arena+1360>, 0x7ff7fadfc0 <main_arena+1376>, 0x7ff7fadfc0 <main_arena+1376>, 0x7ff7fadfd0 <main_arena+1392>, 0x7ff7fadfd0 <main_arena+1392>, 0x7ff7fadfe0 <main_arena+1408>, 0x7ff7fadfe0 <main_arena+1408>, 0x7ff7fadff0 <main_arena+1424>, 0x7ff7fadff0 <main_arena+1424>, 0x7ff7fae000 <main_arena+1440>, 0x7ff7fae000 <main_arena+1440>, 0x7ff7fae010 <main_arena+1456>, 0x7ff7fae010 <main_arena+1456>, 0x7ff7fae020 <main_arena+1472>, 0x7ff7fae020 <main_arena+1472>, 0x7ff7fae030 <main_arena+1488>, 0x7ff7fae030 <main_arena+1488>, 0x7ff7fae040 <main_arena+1504>, 0x7ff7fae040 <main_arena+1504>, 0x7ff7fae050 <main_arena+1520>, 0x7ff7fae050 <main_arena+1520>, 0x7ff7fae060 <main_arena+1536>, 0x7ff7fae060 <main_arena+1536>, 0x7ff7fae070 <main_arena+1552>, 0x7ff7fae070 <main_arena+1552>, 0x7ff7fae080 <main_arena+1568>, 0x7ff7fae080 <main_arena+1568>, 0x7ff7fae090 <main_arena+1584>, 0x7ff7fae090 <main_arena+1584>, 0x7ff7fae0a0 <main_arena+1600>, 0x7ff7fae0a0 <main_arena+1600>, 0x7ff7fae0b0 <main_arena+1616>, 0x7ff7fae0b0 <main_arena+1616>, 0x7ff7fae0c0 <main_arena+1632>, 0x7ff7fae0c0 <main_arena+1632>, 0x7ff7fae0d0 <main_arena+1648>, 0x7ff7fae0d0 <main_arena+1648>, 0x7ff7fae0e0 <main_arena+1664>, 0x7ff7fae0e0 <main_arena+1664>, 0x7ff7fae0f0 <main_arena+1680>, 0x7ff7fae0f0 <main_arena+1680>...}, binmap = {0, 0, 0, 0}, next = 0x7ff7fada60 <main_arena>, next_free = 0x0, attached_threads = 1, system_mem = 135168, max_system_mem = 135168 }

查看堆

既然arena能查看,那么程序的堆更能够查看,如下

pwndbg> heap Allocated chunk | PREV_INUSE Addr: 0x412000 Size: 0x290 (with flag bits: 0x291) Allocated chunk | PREV_INUSE Addr: 0x412290 Size: 0x70 (with flag bits: 0x71) Top chunk | IS_MMAPED | NON_MAIN_ARENA Addr: 0x412300 Size: 0x20068 (with flag bits: 0x2006e)

查看bins

既然堆内查看,同样的malloc内部的bins也能查看

pwndbg> bins cache tcachebins empty fastbins 0x20: 0x4132d0 —▸ 0x414578 —▸ 0x4145b8 ◂— 0x31 /* '1' */ 0x30: 0x413938 ◂— 0x411 0x40: 0x4145e8 ◂— 0x1fa11 0x50: 0x651 0x60: 0x414098 —▸ 0x4140d8 ◂— 0x31 /* '1' */ 0x70: 0x4142a8 —▸ 0x4142e8 ◂— 0x31 /* '1' */ 0x80: 0x414578 —▸ 0x4145b8 ◂— 0x31 /* '1' */ 0x90: 0x414578 —▸ 0x4145b8 ◂— 0x31 /* '1' */ 0xa0: 0x414368 —▸ 0x4143a8 ◂— 0x31 /* '1' */ 0xb0: 0x414368 —▸ 0x4143a8 ◂— 0x31 /* '1' */ unsortedbin all [corrupted] FD: 0x413e88 —▸ 0x413ec8 ◂— 0x31 /* '1' */ BK: 0x4144b8 —▸ 0x414498 ◂— 0x4c320000dd80 smallbins 0x20 [corrupted] FD: 0x414398 —▸ 0x4143d8 ◂— 0x31 /* '1' */ BK: 0x414398 —▸ 0x414378 ◂— 0x24ff000076c5 0x30 [corrupted] FD: 0x413330 —▸ 0x413340 —▸ 0x413eb8 —▸ 0x413ef8 ◂— 0x31 /* '1' */ BK: 0x413330 —▸ 0x413340 —▸ 0x413eb8 —▸ 0x413e98 ◂— 0x989b00002650 /* 'P&' */

查看mapping

同样的,gdb的mappings也有了更友好的优化,如下

pwndbg> vmmap LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA Start End Perm Size Offset File 0x400000 0x401000 r-xp 1000 0 /root/malloc 0x410000 0x411000 r--p 1000 0 /root/malloc 0x411000 0x412000 rw-p 1000 1000 /root/malloc 0x412000 0x433000 rw-p 21000 0 [heap] 0x7ff7e40000 0x7ff7f9a000 r-xp 15a000 0 /usr/lib/aarch64-linux-gnu/libc-2.31.so 0x7ff7f9a000 0x7ff7fa9000 ---p f000 15a000 /usr/lib/aarch64-linux-gnu/libc-2.31.so 0x7ff7fa9000 0x7ff7fad000 r--p 4000 159000 /usr/lib/aarch64-linux-gnu/libc-2.31.so 0x7ff7fad000 0x7ff7faf000 rw-p 2000 15d000 /usr/lib/aarch64-linux-gnu/libc-2.31.so 0x7ff7faf000 0x7ff7fb2000 rw-p 3000 0 [anon_7ff7faf] 0x7ff7fcc000 0x7ff7fed000 r-xp 21000 0 /usr/lib/aarch64-linux-gnu/ld-2.31.so 0x7ff7ff8000 0x7ff7ffa000 rw-p 2000 0 [anon_7ff7ff8] 0x7ff7ffa000 0x7ff7ffc000 r--p 2000 0 [vvar] 0x7ff7ffc000 0x7ff7ffd000 r-xp 1000 0 [vdso] 0x7ff7ffd000 0x7ff7ffe000 r--p 1000 21000 /usr/lib/aarch64-linux-gnu/ld-2.31.so 0x7ff7ffe000 0x7ff8000000 rw-p 2000 22000 /usr/lib/aarch64-linux-gnu/ld-2.31.so 0x7ffffdf000 0x8000000000 rw-p 21000 0 [stack]

解析内存地址

通过xinfo可以解析内存存放的信息,如下

pwndbg> xinfo p Extended information for virtual address 0x4122a0: Containing mapping: 0x412000 0x433000 rw-p 21000 0 [heap] Offset information: Mapped Area 0x4122a0 = 0x412000 + 0x2a0

更多命令

pwndbg非常强大,不过我经常是在调试内存时使用,更多关心的是内存的应用,所以上述命令只和内存相关。

这些命令已经完全满足我的需求了,更多用法可以参考

https://pwndbg.re/pwndbg/latest/commands/