OneShell

I fight for a brighter tomorrow

0%

FirmAE:如何实现debug功能

调试功能简介

FirmAE相比FirmAdyne增加了一个新的启动选项,-d,可以为仿真系统开启一个调试功能,使用者可以连接到仿真系统中,开启shell、指令命令、启动gdbserver调试进程等等。通过阅读代码,调试功能的本质就是将一个自启动脚本塞入到固件文件系统中,仿真系统启动后使用nc和telnetd等待宿主机连接,其中的gdbserver、tcpdump、file transfer都是在宿主机连接上仿真系统后,发送命令到仿真系统执行的方式启动的。
这个功能还是非常人性化的。在真实设备上或许还可以通过硬件接口连接到bootloader获取shell来开启调试,FirmAE的调试模式可以极大帮助使用者对成功仿真的系统进行调试。

run.sh:启动脚本

首先,如果是在启动脚本中使用了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
elif [ ${OPTION} = "debug" ]; then
# ================================
# run debug mode.
# ================================
if ($PING_RESULT); then
echo -e "[\033[32m+\033[0m] Run debug!"
IP=`cat ${WORK_DIR}/ip`
./scratch/$IID/run_debug.sh &
check_network ${IP} true

sleep 10
./debug.py ${IID}

sync
kill $(ps aux | grep `get_qemu ${ARCH}` | awk '{print $2}') 2> /dev/null | true
sleep 2
else
echo -e "[\033[31m-\033[0m] Network unreachable"
fi

会在对应的固件目录(以$IID标识)中,后台运行run_debug.sh,等运行完毕后,使用debug.py去连接到仿真的系统中。

run_debug.sh:仿真系统中监听

run_debug.sh的主要作用就是将如下的脚本写入到仿真系统中,并在启动仿真后,执行如下的脚本。

1
2
3
4
5
echo "#!/firmadyne/sh" > ${WORK_DIR}/image/firmadyne/debug.sh
if (echo ${RUN_MODE} | grep -q "debug"); then
echo "while (true); do /firmadyne/busybox nc -lp 31337 -e /firmadyne/sh; done &" >> ${WORK_DIR}/image/firmadyne/debug.sh
echo "/firmadyne/busybox telnetd -p 31338 -l /firmadyne/sh" >> ${WORK_DIR}/image/firmadyne/debug.sh
fi

在run_debug.sh中,会在仿真系统的/firmadyne目录生成debug.sh,debug.sh即运行在仿真系统中。在debug.sh中,会使用nc去监听端口31337,并使用telnetd开启telnet到31338端口

debug.py:宿主机连接

在宿主机上是通过debug.py来显示调试界面,根据用户的输入来选择功能。代码比较简单,只有一个类firmae_helper:

  • connect方法:连接到仿真系统nc开启的端口31337
  • send和sendrecv:连接成功后,发送命令到仿真系统执行
  • initalize_telnet:发送命令到仿真系统执行,初始化telnet
  • connect_socat和connect_shell:分别通过nc和telnet连接到仿真系统中
  • tcpdump、file_transfer、run_gdbserver:通过发送命令的方式启动对应功能