记录gdb开源python扩展libheap的实际使用

copy需告知说明,转载需注明出处。

 

libheap使用的是python3开发的,但是我的gdb自带的使用的是python2,这种情况需要重新源码编译gdb 携带--with-python选项,./configure --with-python="/usr/bin/python3",但是因为某些原因,我这样操作很麻烦,所以我尝试用python2来进行调试。

可以看到,我已经可以使用libheap的部分功能

(gdb) heapls
getting heap base from proc
           ADDR             SIZE            STATUS
sbrk_base  0x104f000
chunk      0x104f000        0x20            (inuse)
chunk      0x104f020        0x240           (inuse)
chunk      0x104f260        0x240           (inuse)
chunk      0x104f4a0        0x20b60         [!] Could not read address 0x1070000
(F) FD 0x0 BK 0x0 [!] Could not read address 0x1070000
(LC)
[!] Could not read address 0x1070000
chunk      0x1070000        0x0             [!] Could not read address 0x1070000
[!] Could not read address 0x1070000
Python Exception <type 'exceptions.TypeError'> int() argument must be a string or a number, not 'NoneType':
(F) FD Error occurred in Python command: int() argument must be a string or a number, not 'NoneType'

现在调用基础的heap命令

(gdb) heap
[!] No arenas could be found at 0x7fae7992f780

  这段打印由heap.py控制

        # XXX: add arena address passing via arg (-a)
        if (len(arg) == 0) and (ar_ptr.next == 0):
            # struct malloc_state may be invalid size (wrong glibc version)
            print_error("No arenas could be found at {:#x}".format(
                        ar_ptr.address))
            return

我加了一些print进行调试

(gdb) heap
ar_ptr.address=140387340711808   # 我加的调试信息
main_arena.address=0x7fae7992f780 <main_arena>  # 我加的调试信息
arena_address=140387340711808   # 我加的调试信息
type(self.dbg)=<type 'instance'>  # 我加的调试信息
self.dbg=<libheap.pydbg.debugger.pydbg instance at 0x7f6e09a6bdd0># 我加的调试信息
[!] No arenas could be found at 0x7fae7992f780
(gdb) p &main_arena
$1 = (struct malloc_state *) 0x7fae7992f780 <main_arena>

明明是有arena的,但是却打印不出来,只能说明malloc_state这个类有问题

代码里经常有self.debugger这个属性,经调试,原型是gdb.frame

(gdb) python print(gdb.selected_frame().read_var("main_arena"))
struct malloc_state {
mutex            = 0x0
flags            = 0x0
fastbinsY        = {...}
top              = 0x104f4a0
last_remainder   = 0x0
bins             = {...}
binmap           = {...}
next             = 0x7fae6c000020
next_free        = 0x0
attached_threads = 0x1
system_mem       = 0x21000
max_system_mem   = 0x21000
(gdb) p main_arena
$1 = struct malloc_state {
mutex            = 0x0
flags            = 0x0
fastbinsY        = {...}
top              = 0x104f4a0
last_remainder   = 0x0
bins             = {...}
binmap           = {...}
next             = 0x7fae6c000020
next_free        = 0x0
attached_threads = 0x1
system_mem       = 0x21000
max_system_mem   = 0x21000
(gdb) python print(gdb.selected_frame().read_var("main_arena").next) Traceback (most recent call last): File "<string>", line 1, in <module> AttributeError: 'gdb.Value' object has no attribute 'next' Error while executing Python code. (gdb) p 0x7fae6c000020 $2 = 140387112976416 

随便试试

(gdb) set $a= (struct malloc_state*) 0x7fae6c000020
(gdb) p $a
$9 = (struct malloc_state *) 0x7fae6c000020
(gdb) p *$a
$10 = struct malloc_state {
mutex            = 0x0
flags            = 0x2
fastbinsY        = {...}
top              = 0x7fae6c0008d0
last_remainder   = 0x0
bins             = {...}
binmap           = {...}
next             = 0x7fae74000020
next_free        = 0x0
attached_threads = 0x1
system_mem       = 0x21000
max_system_mem   = 0x21000

(gdb) set $b = (struct malloc_state*)0x7fae74000020
(gdb) p *$b
$11 = struct malloc_state {
mutex            = 0x0
flags            = 0x2
fastbinsY        = {...}
top              = 0x7fae740008d0  
last_remainder   = 0x0
bins             = {...}
binmap           = {...}
next             = 0x7fae7992f780   # 这个值已经是一开始的main_arena的地址了
next_free        = 0x0
attached_threads = 0x1
system_mem       = 0x21000
max_system_mem   = 0x21000

小结:

1、next所指向的地址,一共有0x7fae7992f780,0x7fae6c000020,0x7fae74000020三个,正好是我代码中malloc的个数。

2、0x21000转换成10进制为135168

(gdb) heap
self.size=2200      # 我在malloc_state.py添加的打印
self.version=2.27   # 我在malloc_state.py添加的打印
[!] No arenas could be found at 0x7fae7992f780

 上面就看出问题了,版本是2.27,但是我的实际glibc版本是2.17,所以没有进行配置,修改libheap.cfg改为2.17,重新执行

(gdb) heap
Arena(s) found:
  arena @ 0x7fae7992f780
self.size=2184
self.version=2.17
  arena @ 0x7fae6c000020
self.size=2184
self.version=2.17
  arena @ 0x7fae74000020
self.size=2184
self.version=2.17

 哇咔咔,终于有阶段性进展了

(gdb) mstats
Malloc Stats

self.size=2184
self.version=2.17
Arena 0:
system bytes     = 135168
in use bytes     = 1152
self.size=2184
self.version=2.17
Arena 1:
system bytes     = 135168
in use bytes     = 2256
self.size=2184
self.version=2.17
Arena 2:
system bytes     = 135168
in use bytes     = 2256

Total (including mmap):
system bytes     = 405504
in use bytes     = 5664
max system bytes = 0
max mmap regions = 0
max mmap bytes   = 0

  

 

在heapls.py里发现也读取了thread_arena的内容,尝试在gdb中打印thread_arena

(gdb) p &thread_arena
No symbol "thread_arena" in current context.
(gdb) info threads
  Id   Target Id         Frame
  3    Thread 0x7fae79567700 (LWP 46) "lynalee" __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95
  2    Thread 0x7fae78d66700 (LWP 47) "lynalee" 0x00007fae796578dd in write () at ../sysdeps/unix/syscall-template.S:81
* 1    Thread 0x7fae79d6f740 (LWP 45) "lynalee" 0x00007fae7965787d in read () at ../sysdeps/unix/syscall-template.S:81

 发现没有这个symbol;所以考虑是不是没有调试线程的原因

(gdb) thread 2
[Switching to thread 2 (Thread 0x7fae78d66700 (LWP 47))]
#0  0x00007fae796578dd in write () at ../sysdeps/unix/syscall-template.S:81
81      T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
(gdb) p &thread_arena
No symbol "thread_arena" in current context.

依然没有thread_arena符号

 

参考:https://sourceware.org/gdb/onlinedocs/gdb/Python-API.html    # gdb的python扩展api文档

lynalee
调试信息
posted @ 2022-08-12 11:56  lynalee  阅读(122)  评论(0编辑  收藏  举报