定位了GET请求发包时的拼接点:




目标是定位到这段参数是在何时被存储进结构体的,由此,我就需要捕获这个结构体的内存被修改的时机。
在正常情况下,这可以通过dbg下硬件断点,通过watch监视来解决,不过qemu-user的gdb_stub并不支持这一功能,同时也出于需要组建局域网进一步验证的考量,我选择使用更为全能的qemu-system来解决问题,可以静态编译一个gdbserver实现监视。
手动配置网桥会比较麻烦,所以我使用了virt-manager工具来辅助组网。
该路由器基于Openwrt二次开发,先去官网下载一个适配qemu的通用内核:

通过dd和mkfs制作ext4文件,并通过mount -o loop,将该文件模拟成一个loop设备进行挂载,将解包的根目录复制进去:

下一步是配置虚拟机:


多余的外设统统删掉,只保留串口,控制台和网卡:

成功登入:

这里我在后面又补了一个串口便于操作,一开始是想通过ssh登录的,但openwrt实现ssh的组件是dropbear,同时这个路由器使用的组件比较老,在加密上有诸多版本匹配缺陷,最后还是选择了双串口。
串口是一个字符设备,用于进行常规的控制台通信,ttyAMA的一系列串口就主要服务于aarch64架构。
但事实上,如果仅仅只是通过手动添加硬件设备来增加串口是不够的,哪怕内核引导参数里同时写了console=ttyAMA0和console=ttyAMA1,但因为启动时只有一个控制台被启用,所以它拿到了/bin/sh,而另一个其实是空置的状态,所以需要人为地在启动脚本中mknod出新的字符设备,让它能通过open /dev/ttyAMA1这种方式来与接口通信,并通过sh 0</dev/ttyAMA1 /dev/ttyAMA1>1 2>&1来绑定交互式shell:

除此之外,我顺便在启动脚本里写了两条网络配置:
ip addr add 192.168.122.2/24 dev eth0 配置静态ip
ip route add default via 192.168.122.1 添加路由规则,让网络包顺利走网卡
在VMware,virt-manager这类虚拟机管理器中,一个NAT模式的虚拟局域网内的某个ip往往遵循这样的链路:
客户机自身 -> 虚拟交换机 -> 虚拟路由器(NAT)-> 宿主机网卡
其中,这个虚拟路由器其实算是一个网络接口,通过iptables/nft的的NAT转换规则模拟一台路由器,将数据包根据POSTROUTING规则执行地址转换,并发给物理网卡。

成功发包。
花了一些时间找gdbserver,用musl库的工具链编译,传进虚拟机:
