Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
libtalloc — libtalloc is a python script for use with GDB that can be used to analyse the "trivial allocator" (talloc) | Kitploit
工具/GitHubGitHub/nccgroup/libtalloc
Memory ForensicsVulnerability AnalysisReverse EngineeringDebuggersBinary Analysis
GitHubnccgroup/libtalloc

libtalloc

libtalloc is a python script for use with GDB that can be used to analyse the "trivial allocator" (talloc)

查看仓库
17511年前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

libtalloc

libtalloc 是一个用于 GDB 的 python 脚本,可用于分析“平凡分配器”(talloc)。关于 talloc 的介绍可以在这里找到:

https://talloc.samba.org/talloc/doc/html/index.html

libtalloc 的灵感来自其他用于分析堆的 gdb python 脚本,例如 unmask_jemalloc 和 libheap。一些基本功能与这些项目相同。

https://github.com/cloudburst/libheap

https://github.com/argp/unmask_jemalloc

请注意,我不是 python 专家,代码质量也反映了这一点。如果你看到让你反感的地方,随时欢迎发送补丁或给我一些建议。所有反馈都受欢迎。

Testing

libtalloc 已在多种 talloc 2.x 版本上测试,并支持动态版本检测,以尝试克服各版本之间的结构差异。它已在 32 位和 64 位上测试,但并非详尽无遗,所以如果它时不时出问题,请不要感到惊讶。

它已在 x86 和 x64 上进行了一定程度的测试:

  • 2.0.7
  • 2.0.8
  • 2.1.0
  • 2.1.1

如果你在另一个版本上测试过它,请告诉我它是否有效,或是什么出了问题,我会尽力相应地更新它和/或文档。

Installation

该脚本只需要一个相对较新的、带 python 支持的 GDB 版本。

一些 LTS 发行版(如 Ubuntu 12.04)仍在使用带 python 2.7 的 GDB,而较新的版本(如 14.04)使用 python 3.0。我试图让这个脚本同时适用于两者,所以你只需要:

root@kitploit:~
(gdb) source libtalloc.py

Usage

大部分功能都是仿照 unmask_jemalloc 的方法实现的,即提供单独的命令而不是一组复杂的开关。

提供了一些专门设计用于模仿 talloc 库 C 函数的方法,以帮助那些已经熟悉该库、想尝试扩展 libtalloc 的人。

要查看完整的命令列表,你可以发出 tchelp 命令:

root@kitploit:~
(gdb) tchelp
[libtalloc] talloc commands for gdb
[libtalloc] tcchunk -v -x <addr>  : show chunk contents (-v for verbose, -x for data dump)
[libtalloc] tcvalidate -a <addr>  : validate chunk (-a for whole heap)
[libtalloc] tcsearch <addr>       : search heap for hex value or address
[libtalloc] tcwalk <func>         : walk whole heap calling func on every chunk
[libtalloc] tcreport <addr>       : give talloc_report_full() info on memory context
[libtalloc] tcdump -s <addr>      : dump chunks linked to memory context (-s for sorted by addr)
[libtalloc] tcparents <addr>      : show all parents of chunk
[libtalloc] tcchildren <addr>     : show all children of chunk
[libtalloc] tcinfo                : show information known about heap
[libtalloc] tcprobe               : try to collect information about talloc version
[libtalloc] tchelp                : this help message

Dynamic Version Probing

最重要的命令之一是 tcprobe。需要运行它来确定实际安装的 talloc 版本。不同版本的结构布局可能差异很大,因此为了让大多数函数正常工作,必须知道版本。

如果命令有效,它应该告诉你检测到的版本:

root@kitploit:~
(gdb) tcprobe
Version: 2.1.1 
File: /usr/lib/libtalloc.so.2.1.1

Meta information

tcinfo 命令旨在显示尽可能多的关于堆的收集信息,例如来自 tcprobe 的信息、null_context 结构(如果找到)等。目前它只显示版本以及 null_context 是否已设置。null_context 是大多数遍历实际层次结构的函数所必需的,为了找到它,大多数其他功能(如 tchunk 等)会尝试自动查找它。

在 tcprobe 运行之后、tchunk 实际使用之前:

(gdb) tcinfo [libtalloc] null_context not yet found yet [libtalloc] Version: 2.0.7 [libtalloc] File: /usr/lib/i386-linux-gnu/libtalloc.so.2.0.7

然后分析一个块之后,像这样:

(gdb) tcchunk 0xb94a52b0 WARNING: 0xb94a52b0 not a talloc_chunk. Assuming ptr to chunk data 0xb94a5280 sz:0x0000003c, flags:...., name:struct tevent_context

你可以事后使用 tcinfo 确认它已被找到。

(gdb) tcinfo [libtalloc] null_context: 0xb94a5028 [libtalloc] Version: 2.0.7 [libtalloc] File: /usr/lib/i386-linux-gnu/libtalloc.so.2.0.7

现在 null_context 已设置,你可以运行其他通常会抱怨它未设置的命令,比如 tcsearch 命令。

Chunk analysis

tcchunk 可以为你提供块的摘要、每个字段的更详细输出,或关于每个周围块的极其详细的信息。

注意:关于 tcchunk 有一个重点需要说明,它在内部使用 tc_chunk() 方法,该方法尝试纠正传入块地址时出现的错误。具体来说,如果你传入的是块数据本身的地址,当它没有找到预期的 talloc magic 时,它会在内存中稍早的位置寻找合法的块头。在损坏的情况下这可能会给你带来困扰,所以除非你只是做粗略分析,否则一定要确保传入明确的地址。

摘要输出:

root@kitploit:~
(gdb) tcchunk 0x80a13c88
0x80a13c88 sz:0x00000020, flags:..p., name:struct netr_ServerPasswordSet

以下是摘要输出中块的图例:

root@kitploit:~
p - Member of a pool (POOLMEM flag)
P - Chunk is a pool (POOL flag)
F - Chunk is free (FREE flag)
L - Chunk is looped (LOOP flag)

详细输出:

root@kitploit:~
(gdb) tcchunk -v 0x80a13c88
struct talloc_chunk @ 0x80a13c88 {
next         = 0x0
prev         = 0x80a140c8
parent       = 0x0
child        = 0x80a14088
refs         = 0x0
destructor   = 0x0
name         = 0x807d9f2f (struct netr_ServerPasswordSet)
size         = 0x20
flags        = 0xe8150c78 (POOLMEM)
limit        = 0x0
pool         = 0x80a13248

Validation

talloc 块包含一些可用于验证其是否正常的 magic 值。tcvalidate 命令将分析一个块,以确保块 magic 符合预期。此外,它还会分析所有其他指针成员,以确保它们确实落在内存范围内(由 gdb 所知)、大小是否有效等。

root@kitploit:~
(gdb) tcvalidate 0x80a13c88
Chunk header is valid

我们将使用一个内置方法来修改一个值,以展示它如何失败:

root@kitploit:~
(gdb) python set_destructor(tc_chunk(0x80a13c88), 0x41414141)
(gdb) tcchunk -v 0x80a13c88
struct talloc_chunk @ 0x80a13c88 {
next         = 0x0
prev         = 0x80a140c8
parent       = 0x0
child        = 0x80a14088
refs         = 0x0
destructor   = 0x41414141
name         = 0x807d9f2f (struct netr_ServerPasswordSet)
size         = 0x20
flags        = 0xe8150c78 (POOLMEM)
limit        = 0x0
pool         = 0x80a13248
(gdb) tcvalidate 0x80a13c88
Chunk header is invalid:
0x80a13c88: Chunk has bad destructor pointer 0x41414141

Finding parents

tcparents 可用于查看所提供块的所有父节点:

root@kitploit:~
(gdb) tcparents 0x80a13c88
0x809f8300: null_context
  0x80a08660: TALLOC_CTX *
    0x809f8370: talloc_new: ../lib/util/talloc_stack.c:147
      0x809fb680: talloc_new: ../lib/util/talloc_stack.c:147
        0x80a13258: UNNAMED
          0x80a13c58: talloc_new: ../lib/util/talloc_stack.c:147
            0x80a13c88: struct netr_ServerPasswordSet

Finding children

tchildren 可用于查看所提供块的所有子节点(以及孙节点等):

root@kitploit:~
(gdb) tcchildren 0x80a13c88
0x80a14088: struct netr_Authenticator
0x80a14048: librpc/gen_ndr/ndr_netlogon.c:10964
0x80a14008: librpc/gen_ndr/ndr_netlogon.c:10958
0x80a13fc8: librpc/gen_ndr/ndr_netlogon.c:10951
0x80a13f88: lib/charcnv.c:506
0x80a13ec8: lib/charcnv.c:506
0x80a13d48: librpc/gen_ndr/ndr_netlogon.c:10913
  0x80a13e08: 
0x80a13cd8: struct ndr_pull
  0x80a13f48: struct ndr_token_list
  0x80a13f08: struct ndr_token_list
  0x80a13e88: struct ndr_token_list
  0x80a13e48: struct ndr_token_list
  0x80a13dc8: struct ndr_token_list
  0x80a13d88: struct ndr_token_list

Pool analysis

talloc 有池块的概念。它们基本上是常规的 talloc 块,但用于分配新块,而不是回退到系统的底层 malloc() 实现。池块的头部根据所用版本略有不同,有时使用填充,有时使用前缀/后缀头部。

tcpool 可用于分析池块头部,类似于 tcchunk:

root@kitploit:~
# First we find a pool to analyze
(gdb) tcchunk -v 0x80a13c88
struct talloc_chunk @ 0x80a13c88 {
next         = 0x0
prev         = 0x80a140c8
parent       = 0x0
child        = 0x80a14088
refs         = 0x0
destructor   = 0x0
name         = 0x807d9f2f (struct netr_ServerPasswordSet)
size         = 0x20
flags        = 0xe8150c78 (POOLMEM)
limit        = 0x0
pool         = 0x80a13248

(gdb) tcpool -v 0x80a13248
struct talloc_pool_hdr @ 0x80a13248 {
end          = 0x80a14108
object_count = 0x19
poolsize     = 0x2000
struct talloc_chunk @ 0x80a13258 {
next         = 0x0
prev         = 0x0
parent       = 0x809fb680
child        = 0x80a13c58
refs         = 0x0
destructor   = 0x80429aa0
name         = 0x0 (UNNAMED)
size         = 0x0
flags        = 0xe8150c74 (POOL)
limit        = 0x0
pool         = 0x0

在上面的例子中,该池带有一个前缀的 talloc_pool_hdr,如图所示。可以将 -l 选项传给 tcpool,以列出池内所有已分配的块:

root@kitploit:~
(gdb) tcpool -l 0x80a13248
Pool summary -- objects: 0x19, total size: 0x2000, space left: 0x1180, next free: 0x80a14108
0x80a13258 sz:0x00000000, flags:.P.., name:UNNAMED
0x80a13288 sz:0x000007a3, flags:..p., name:char
0x80a13a68 sz:0x0000005c, flags:..p., name:struct smb_request
0x80a13af8 sz:0x00000008, flags:..p., name:struct pipe_write_andx_state
0x80a13b38 sz:0x00000038, flags:..p., name:struct tevent_req
0x80a13ba8 sz:0x00000028, flags:..p., name:struct tevent_immediate
0x80a13c08 sz:0x00000014, flags:..p., name:struct np_write_state
0x80a13c58 sz:0x00000000, flags:..p., name:talloc_new: ../lib/util/talloc_stack.c:147
0x80a13c88 sz:0x00000020, flags:..p., name:struct netr_ServerPasswordSet
0x80a13cd8 sz:0x00000038, flags:..p., name:struct ndr_pull
0x80a13d48 sz:0x00000001, flags:..p., name:librpc/gen_ndr/ndr_netlogon.c:10913
0x80a13d88 sz:0x00000010, flags:..p., name:struct ndr_token_list
0x80a13dc8 sz:0x00000010, flags:..p., name:struct ndr_token_list
0x80a13e08 sz:0x00000001, flags:..p., name:
0x80a13e48 sz:0x00000010, flags:..p., name:struct ndr_token_list
0x80a13e88 sz:0x00000010, flags:..p., name:struct ndr_token_list
0x80a13ec8 sz:0x00000008, flags:..p., name:lib/charcnv.c:506
0x80a13f08 sz:0x00000010, flags:..p., name:struct ndr_token_list
0x80a13f48 sz:0x00000010, flags:..p., name:struct ndr_token_list
0x80a13f88 sz:0x00000008, flags:..p., name:lib/charcnv.c:506
0x80a13fc8 sz:0x0000000c, flags:..p., name:librpc/gen_ndr/ndr_netlogon.c:10951
0x80a14008 sz:0x00000010, flags:..p., name:librpc/gen_ndr/ndr_netlogon.c:10958
0x80a14048 sz:0x0000000c, flags:..p., name:librpc/gen_ndr/ndr_netlogon.c:10964
0x80a14088 sz:0x0000000c, flags:..p., name:struct netr_Authenticator
0x80a140c8 sz:0x0000000b, flags:..p., name:/etc/samba

注意上面输出中的 P 标志,最顶部的块是池块,它持有下面所有的块。

Heap dumping

tcdump 可用于转储整棵树中的所有块。默认情况下按层次顺序显示,但可以使用 -s 选项按地址对输出进行排序。

root@kitploit:~
(gdb) tcdump -a 0x809f8300
0x809f8300 sz:0x00000000, flags:...., name:null_context
0x80a0b3f8 sz:0x0000000c, flags:...., name:struct handle_list
0x809ff178 sz:0x00000014, flags:...., name:struct security_token
0x80a089e8 sz:0x00000198, flags:...., name:lib/util_nttoken.c:50
0x80a07268 sz:0x00000188, flags:...., name:connection_struct
0x80a08bc8 sz:0x00000020, flags:...., name:struct fd_handle
0x80a00c30 sz:0x000000f0, flags:...., name:struct files_struct
0x80a083b8 sz:0x00000008, flags:...., name:struct fake_file_handle
0x80a08c20 sz:0x0000009c, flags:...., name:struct pipes_struct
0x80a07900 sz:0x00000760, flags:...., name:uint8_t
0x80a07428 sz:0x000000c0, flags:...., name:struct auth_serversupplied_info
0x80a06390 sz:0x00000001, flags:...., name:
0x80a06350 sz:0x00000007, flags:...., name:nobody
0x80a06158 sz:0x000000cc, flags:...., name:struct netr_SamInfo3
0x80a062d8 sz:0x00000044, flags:...., name:struct dom_sid
[SNIP]

tcreport 是一个类似于 tcdump 的命令,但它稍微美化了输出,旨在模仿 talloc 库本身提供的 talloc_report_full() 调试函数。

root@kitploit:~
(gdb) tcreport 0x80a0b3f8 -a
Full talloc report on 'null_context' (total 558651 bytes in 446 blocks)
    struct handle_list             contains     12 bytes in   1 blocks (ref 67) 0x80a0b3f8
    struct security_token          contains    428 bytes in   2 blocks (ref 66) 0x809ff178
        lib/util_nttoken.c:50          contains    408 bytes in   1 blocks (ref 0) 0x80a089e8
    connection_struct              contains 531071 bytes in  36 blocks (ref 65) 0x80a07268
        struct fd_handle               contains     32 bytes in   1 blocks (ref 4) 0x80a08bc8
        struct files_struct            contains 529681 bytes in  22 blocks (ref 3) 0x80a00c30
            struct fake_file_handle        contains 529308 bytes in  19 blocks (ref 1) 0x80a083b8
                struct pipes_struct            contains 529300 bytes in  18 blocks (ref 0) 0x80a08c20
                    uint8_t                        contains   1888 bytes in   1 blocks (ref 2) 0x80a07900
                    struct auth_serversupplied_info contains    934 bytes in  10 blocks (ref 1) 0x80a07428
                                                       contains      1 bytes in   1 blocks (ref 4) 0x80a06390
                        nobody                         contains      7 bytes in   1 blocks (ref 3) 0x80a06350
                        struct netr_SamInfo3           contains    290 bytes in   4 blocks (ref 2) 0x80a06158
[SNIP]

Searching

有两个搜索命令:tcsearch 和 tcfindaddr。

tcsearch 可用于查找包含所提供十六进制值的块。它从 null_context(如果已知)或从提供的起始块开始遍历整个树层次结构。

root@kitploit:~
(gdb) python set_destructor(tc_chunk(0x80a13c88), 0x41414141)
(gdb) tcsearch 0x41414141 0x809f8300
[libtalloc] 0x41414141 found in chunk at 0x80a1d218
[libtalloc] 0x41414141 found in chunk at 0x80a13c88
(gdb) tcchunk -v 0x80a1d218
struct talloc_chunk @ 0x80a1d218 {
next         = 0x80a00158
prev         = 0x809fb0c8
parent       = 0x0
child        = 0x0
refs         = 0x0
destructor   = 0x0
name         = 0x8071fcbd (uint8_t)
size         = 0x80050
flags        = 0xe8150c70 ()
limit        = 0x0
pool         = 0x0
(gdb) tcchunk -x 0x80a1d218
0x80a1d218 sz:0x00080050, flags:...., name:uint8_t
Chunk data (524368 bytes):
0x80a1d248:	0x41414141	0x00000000	0x00000000	0x00000000
0x80a1d258:	0x00000001	0x00000000	0x00000001	0x00020000
0x80a1d268:	0x00000001	0x00000000	0x00000001	0xaaaa0000
[SNIP]    
(gdb) tcchunk -v 0x80a13c88
struct talloc_chunk @ 0x80a13c88 {
next         = 0x0
prev         = 0x80a140c8
parent       = 0x0
child        = 0x80a14088
refs         = 0x0
destructor   = 0x41414141
name         = 0x807d9f2f (struct netr_ServerPasswordSet)
size         = 0x20
flags        = 0xe8150c78 (POOLMEM)
limit        = 0x0
pool         = 0x80a13248

tcfindaddr 可用于确定一个地址是否落在 talloc 树中某个块的边界内。假设你知道 0x80a1d3280 有一些你控制的数据,你想看看它是否落在一个块内。注意第二个地址是 null_context,但可以是任何能让我们找到堆顶的块。

root@kitploit:~
(gdb) tcfindaddr 0x80a1d328 0x809f8300
[libtalloc] address 0x80a1d328 falls within chunk @ 0x80a1d218 (size 0x80050)

Heap walking

部分树搜索使用了一个递归函数,我通过 tcwalk 命令将其暴露出来。它是一个辅助函数,让你指定一个 python 方法,该方法将对树中发现的每个块调用。

在下面的例子中,我们将在堆中的每个块上调用堆验证方法,看看是否有任何东西损坏。

root@kitploit:~
(gdb) tcwalk validate_chunk 
0x80a13c88: Chunk has bad destructor pointer 0x41414141

注意,如果 null_context 尚未设置,你必须传入一个块地址作为第二个参数。

Contact

由 Aaron Adams 编写

Email: aaron (dot) adams (at) nccgroup (dot) trust

Twitter: @fidgetingbits

下载工具