pwntools 读取程序输出的同时也记录在日志文件中
在使用 pwntools 的 pwnlib.tubes.process 模块时,遇到的问题是,既想要用 recvuntil() 在脚本中读取到程序的 stdout 输出,又想在终端 PTY 上同时看到程序的输入。
一般这是把程序 pipe 到 tee 来解决的,但得起个 shell 还得处理 buffer 的问题。
要么就只使用 recvline(),每次收到数据后自行转写文件。
或者直接开启 debug 日记级别,不过默认的输出格式和程序直接在终端上输出的样子大相径庭。
最后想了个简单的注入方式:
def tee(process, logfile='/tmp/challenge.log'):
orig_send_raw = process.send_raw
orig_recv_raw = process.recv_raw
log_file = open(logfile, 'wb')
def send_raw(data):
log_file.write(data)
log_file.flush()
return orig_send_raw(data)
def recv_raw(numb):
data = orig_recv_raw(numb) or b'' # orig may return str('')
log_file.write(data)
log_file.flush()
return data
process.send_raw = send_raw
process.recv_raw = recv_raw
context.terminal = ['tmux', 'splitw', '-v']
run_in_new_terminal('tail -s 0.1 -f ' + logfile, kill_at_exit=False)
p = process('/challenge/run')
tee(p, '/tmp/challenge.log')把 process 类真正处理输入输出的 send_raw & recv_raw 封装起来。
纵向分屏避免 tail 窗口关闭后因终端宽度变更,终端上已有文字产生错位。
Pyright 将 while True 循环退出后的变量推断为 Never 类型
在最近的编程时发现 VSCode / Zed 基于的 pyright 静态类型检查工具,对 while True 中带有条件 break 的变量赋值,类型推断上存在不足。
a = b''
while True:
if a and a:
break
a += b'0'
a.decode() # <- 此处 a 被推断为 Never 类型,方法无法识别a = b''
while 1:
if a and a:
break
a += b'0'
a.decode() # <- 此处 a 被推断为 bytes 类型,方法也正确解析并高亮在编辑器里有很明显的高亮提示差异。使用 while 1 替代 while True 能让方法正确识别。或者保持 while True,用 if a 直白判断。
查了一圈最接近的算是这些,而且官方不认为是 bug,也不会修复。
- Pylance while loop bug ? · 议题 #1364 · microsoft/pylance-release
- Type checking fails on get return if using while 1 · 议题 #4426 · microsoft/pylance-release
JetBrains 家的 IDE 倒是没这问题,毕竟另起炉灶实现的。