各前缀的具体用途

1. io.xxx:与目标程序的交互操作

io 是交互句柄的简写(全称 I/O,输入 / 输出),所有和目标程序的通信都通过它完成,核心方法:

常用方法 作用 示例
io.send() 发送数据到目标程序 io.send(b"AAAA")
io.sendline() 发送数据 + 换行(等价于 send (b”AAAA\n”)) io.sendline(b"cat flag")
io.recv() 接收目标程序输出(指定长度) io.recv(1024)
io.recvuntil() 接收直到匹配指定字符串 io.recvuntil(b"Password:")
io.interactive() 切换到交互模式(手动输入命令) io.interactive()
io.close() 关闭连接 / 进程 io.close()

2. p.xxx:数据类型转换(打包 / 解包)

p 是pack的简写,核心解决整数 ↔ 字节串的转换(PWN 中最常用的操作,比如构造溢出 payload、传递地址):

python

运行

1
2
3
4
5
6
7
8
# 示例:将0xdeadbeef(内存地址)转成小端序的4字节(x86架构默认)
payload = p(0xdeadbeef, 32) # 等价于 pack(0xdeadbeef, 32),32表示32位(4字节)
# 等价写法(更常见):
payload = p32(0xdeadbeef) # pwntools内置的快捷函数,p32=32位小端,p64=64位小端

# 反向:解包(bytes转整数)
data = io.recv(4)
addr = u32(data) # u32=unpack 32位小端

三、为什么要这样简写?

  1. 减少代码量:PWN 脚本需要频繁写交互 / 打包操作,io.send() 比 process_handle.send() 更简洁,p32() 比 pack(..., 32) 更高效;
  2. 语义清晰
    • io 一眼能识别是 “和目标程序的交互对象”;
    • p/u 一眼能识别是 “打包 / 解包操作”;
  3. 社区规范:pwntools 官方文档、CTF 题解都用这类简写,新人统一写法能快速看懂别人的代码。

四、常见变种(本质还是别名)

前缀 含义 示例
sh shell 交互句柄 sh = ssh("user", "ip")
libc libc 库对象 libc = ELF("./libc.so.6")
elf 目标程序 ELF 对象 elf = ELF("./vuln")

总结

io./p. 不是语法关键字,而是:

  • io = 目标程序的 “交互管道”(发 / 收数据);
  • p = 数据类型转换的 “工具函数”(整数↔字节);

核心目的是简化代码 + 明确语义,符合 CTF 快速写脚本的需求。只要逻辑对,换成process_handle.send()/pack(...)也能运行,但社区通用写法更易读、易维护。