Skip to content

Commit 56982a1

Browse files
committed
new(trueblog): how to install pwndbg on termux
1 parent fb05475 commit 56982a1

File tree

5 files changed

+100
-0
lines changed

5 files changed

+100
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
---
2+
title: 在termux上运行pwndbg
3+
date: 2025/08/09 15:44:00
4+
updated: 2025/08/09 21:32:00
5+
tags:
6+
- non-ctf
7+
- tricks
8+
thumbnail: /assets/trueblog/termux_thumbnail.jpg
9+
excerpt: >-
10+
在开发过程中,调试器是绕不开的一环,如果使用gdb的话,pwndbg是必不可少的伴侣。
11+
平时大家主要在 PC 上使用 pwndbg,但偶尔只带了手机时,也需要在手机上做一些探索。
12+
借助termux,可以实现在手机上编译并调试,不过只有原版的gdb未免过于简陋,有没有办法将
13+
pwndbg搬到手机上呢?有的,兄弟...
14+
---
15+
16+
在开发过程中,调试器是绕不开的一环,如果使用gdb的话,pwndbg是必不可少的伴侣。
17+
平时大家主要在 PC 上使用 pwndbg,但偶尔只带了手机时,也需要在手机上做一些探索。
18+
借助termux,可以实现在手机上编译并调试,不过只有原版的gdb未免过于简陋,有没有办法将
19+
pwndbg搬到手机上呢?有的,兄弟,有的。
20+
21+
# 获取官方二进制包
22+
23+
打开[pwndbg的releases页](https://github.com/pwndbg/pwndbg/releases)
24+
里面已经有针对arm64的包了,可以使用curl等工具下载后解压。然而,
25+
直接解压后并不能直接运行:
26+
27+
<img src="/assets/trueblog/termux_fail.jpg" width="50%">
28+
29+
# 无法启动?
30+
31+
如果仔细看的话,会发现这个`pwndbg`是一个脚本,实际上会用ld去执行gdb。
32+
33+
```sh bin/pwndbg
34+
#!/bin/sh
35+
dir="$(cd -- "$(dirname "$(dirname "$(realpath "$0")")")" >/dev/null 2>&1 ; pwd -P)"
36+
export TERMINFO_DIRS=/etc/terminfo:/lib/terminfo:/usr/share/terminfo:/run/current-system/sw/share/terminfo:$dir/share/terminfo
37+
export PYTHONNOUSERSITE=1
38+
export PYTHONHOME="$dir"
39+
export PYTHONPATH=""
40+
export PATH="$dir/bin/:$PATH"
41+
42+
exec "$dir/lib/ld-linux-aarch64.so.1" "$dir/exe/gdb" --quiet --early-init-eval-command="set auto-load safe-path /" --command=$dir/exe/gdbinit.py "$@"
43+
```
44+
45+
继续检查lib路径,其中都是glibc一类的打包时的库,如果链接`libc.so``libc.so.6`的话,
46+
就会显示缺少了符号。对啊,lib中就没有`libc.so`这个文件,它一般是安卓程序的依赖。
47+
检查`LD_PRELOAD`,发现确实提前加载了一个`libtermux-exec-ld-preload.so`
48+
那就把`LD_PRELOAD` unset掉试试?这样就不会引入安卓的依赖了。然而,又出错了:
49+
50+
<img src="/assets/trueblog/termux_invalsys.jpg" width="50%">
51+
52+
什么?这次直接报 *invalid syscall* 了?难道是有seccomp?我这么猜测,并用`seccomp-tools`
53+
扫描了各种进程的seccomp filter(有root权限),结果都没有发现。这究竟是怎么回事?
54+
55+
我去求助pwndbg群友(discord),既不能设置`LD_PRELOAD`,又不能unset之,该如何是好?
56+
*@cypis* 检查了audit日志,并最终发现pwndbg调用了`set_robust_list`系统调用,
57+
并被seccomp杀了。他发现,`proot`[处理这些安卓上不能用的syscall](https://github.com/termux/proot/blob/master/src/tracee/seccomp.c)
58+
因此使用`proot`启动就可以了。
59+
60+
{% note green fa-heart %}
61+
感谢 *@cypis* 帮我找到问题所在,并找到解决方案!
62+
{% endnote %}
63+
64+
# 写一个wrapper
65+
66+
基于以上考虑,只需要在`unset LD_PRELOAD`后,使用`proot`运行就可以了
67+
68+
```sh $PREFIX/bin/pwndbg
69+
#!/bin/sh
70+
unset LD_PRELOAD
71+
exec proot $PREFIX/../home/pwndbg/bin/pwndbg "$@"
72+
```
73+
74+
然后在命令行里直接调用就可以启动了。
75+
76+
<img src="/assets/trueblog/termux_success.jpg" width="50%">
77+
78+
# 题外话
79+
80+
为了查看程序的沙箱,我尝试把[ceccomp](https://github.com/dbgbgtf1/Ceccomp)
81+
移植到termux上,一开始有问题,后面一一解决了,现在只要`LD_FLAGS`加一个`-largp`就可以了。
82+
83+
一般来说检查程序已经应用的沙箱是需要`CAP_SYS_ADMIN`特权的,结果普通用户也可以正常检查,
84+
我以为是给普通用户返回空结果了呢,结果root用户也检查不出来,最后看安卓内核源码发现,
85+
根本没机会返回,内核直接拒绝了...
86+
87+
```c common/include/linux/seccomp.h
88+
static inline long seccomp_get_filter(struct task_struct *task,
89+
unsigned long n, void __user *data)
90+
{
91+
return -EINVAL;
92+
}
93+
```
94+
95+
# 参考
96+
97+
1. [Releases - pwndbg/pwndbg](https://github.com/pwndbg/pwndbg/releases)
98+
2. [proot/src/tracee/seccomp.c at master](https://github.com/termux/proot/blob/master/src/tracee/seccomp.c)
99+
3. [dbgbgtf1/Ceccomp: A tool to resolve seccomp](https://github.com/dbgbgtf1/Ceccomp)
100+
4. [seccomp.h: Android Code Search](https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/include/linux/seccomp.h;l=94;drc=354893f20269ea62e322c7bc371f12e3fd606e53)
96.1 KB
Loading
89.4 KB
Loading
454 KB
Loading
185 KB
Loading

0 commit comments

Comments
 (0)