前提
参考文章mips64调试环境搭建 这里做个记录
如果用的是linux虚拟机,那么内存一定要设置3G以上,否则会经常报错
buildroot编译
1.下载
在buildroot下载页面直接通过wget
下载到指定路径。
wget https://buildroot.org/downloads/buildroot-2020.11.3.tar.gz
之后解压缩并cd到该路径下:
tar -xvf ./buildroot-2020.11.3.tar.gz`
cd ./buildroot-2020.11.3.tar.gz`
2.config编译配置
在开始编译前,先安装好buildroot编译所需的依赖包:
apt install sed make binutils build-essential gcc g++ bash patch gzip bzip2 perl tar cpio unzip rsync file bc ncurses-dev
buildroot如其口号所说,Making Embedded Linux Easy,有很多默认设置。通过ls configs
可以查看:
$ ls configs
aarch64_efi_defconfig ci20_defconfig licheepi_zero_defconfig orangepi_rk3399_defconfig qemu_x86_defconfig
acmesystems_aria_g25_128mb_defconfig csky_gx6605s_defconfig linksprite_pcduino_defconfig orangepi_win_defconfig qemu_xtensa_lx60_defconfig
acmesystems_aria_g25_256mb_defconfig cubieboard2_defconfig microchip_sama5d27_wlsom1_ek_mmc_defconfig orangepi_zero_defconfig qemu_xtensa_lx60_nommu_defconfig
acmesystems_arietta_g25_128mb_defconfig engicam_imx6qdl_icore_defconfig microchip_sama5d27_wlsom1_ek_mmc_dev_defconfig orangepi_zero_plus2_defconfig raspberrypi0_defconfig
acmesystems_arietta_g25_256mb_defconfig engicam_imx6qdl_icore_qt5_defconfig minnowboard_max_defconfig orangepi_zero_plus_defconfig raspberrypi0w_defconfig
amarula_a64_relic_defconfig engicam_imx6qdl_icore_rqs_defconfig minnowboard_max-graphical_defconfig pandaboard_defconfig raspberrypi2_defconfig
amarula_vyasa_rk3288_defconfig engicam_imx6ul_geam_defconfig mx25pdk_defconfig pcengines_apu2_defconfig raspberrypi3_64_defconfig
andes_ae3xx_defconfig engicam_imx6ul_isiot_defconfig mx51evk_defconfig pc_x86_64_bios_defconfig raspberrypi3_defconfig
arcturus_ucls1012a_defconfig freescale_imx28evk_defconfig mx53loco_defconfig pc_x86_64_efi_defconfig raspberrypi3_qt5we_defconfig
arcturus_ucp1020_defconfig freescale_imx6dlsabreauto_defconfig mx6cubox_defconfig pine64_defconfig raspberrypi4_64_defconfig
armadeus_apf27_defconfig freescale_imx6dlsabresd_defconfig mx6sx_udoo_neo_defconfig pine64_sopine_defconfig raspberrypi4_defconfig
armadeus_apf28_defconfig freescale_imx6qsabreauto_defconfig mx6udoo_defconfig qemu_aarch64_virt_defconfig raspberrypi_defconfig
armadeus_apf51_defconfig freescale_imx6qsabresd_defconfig nanopc_t4_defconfig qemu_arm_versatile_defconfig riotboard_defconfig
arm_foundationv8_defconfig freescale_imx6sxsabresd_defconfig nanopi_m1_defconfig qemu_arm_versatile_nommu_defconfig rock_pi_4_defconfig
arm_juno_defconfig freescale_imx6ullevk_defconfig nanopi_m1_plus_defconfig qemu_arm_vexpress_defconfig rock_pi_n10_defconfig
asus_tinker_rk3288_defconfig freescale_imx7dsabresd_defconfig nanopi_m4_defconfig qemu_arm_vexpress_tz_defconfig rock_pi_n8_defconfig
at91sam9260eknf_defconfig freescale_imx8mmevk_defconfig nanopi_neo4_defconfig qemu_csky610_virt_defconfig rockpro64_defconfig
at91sam9g20dfc_defconfig freescale_imx8mnevk_defconfig nanopi_neo_defconfig qemu_csky807_virt_defconfig roc_pc_rk3399_defconfig
at91sam9g45m10ek_defconfig freescale_imx8mqevk_defconfig nanopi_r1_defconfig qemu_csky810_virt_defconfig roseapplepi_defconfig
at91sam9rlek_defconfig freescale_imx8qmmek_defconfig nexbox_a95x_defconfig qemu_csky860_virt_defconfig s6lx9_microboard_defconfig
at91sam9x5ek_defconfig freescale_imx8qxpmek_defconfig nitrogen6sx_defconfig qemu_m68k_mcf5208_defconfig sheevaplug_defconfig
at91sam9x5ek_dev_defconfig freescale_p1025twr_defconfig nitrogen6x_defconfig qemu_m68k_q800_defconfig snps_aarch64_vdk_defconfig
at91sam9x5ek_mmc_defconfig freescale_t1040d4rdb_defconfig nitrogen7_defconfig qemu_microblazebe_mmu_defconfig snps_arc700_axs101_defconfig
at91sam9x5ek_mmc_dev_defconfig freescale_t2080_qds_rdb_defconfig nitrogen8m_defconfig qemu_microblazeel_mmu_defconfig snps_archs38_axs103_defconfig
atmel_sama5d27_som1_ek_mmc_dev_defconfig friendlyarm_nanopi_a64_defconfig nitrogen8mm_defconfig qemu_mips32r2el_malta_defconfig snps_archs38_haps_defconfig
atmel_sama5d2_xplained_mmc_defconfig friendlyarm_nanopi_neo2_defconfig nitrogen8mn_defconfig qemu_mips32r2_malta_defconfig snps_archs38_hsdk_defconfig
atmel_sama5d2_xplained_mmc_dev_defconfig friendlyarm_nanopi_neo_plus2_defconfig odroidc2_defconfig qemu_mips32r6el_malta_defconfig snps_archs38_vdk_defconfig
atmel_sama5d3xek_defconfig galileo_defconfig odroidxu4_defconfig qemu_mips32r6_malta_defconfig socrates_cyclone5_defconfig
atmel_sama5d3_xplained_defconfig globalscale_espressobin_defconfig olimex_a10_olinuxino_lime_defconfig qemu_mips64el_malta_defconfig solidrun_clearfog_defconfig
atmel_sama5d3_xplained_dev_defconfig grinn_chiliboard_defconfig olimex_a13_olinuxino_defconfig qemu_mips64_malta_defconfig solidrun_clearfog_gt_8k_defconfig
atmel_sama5d3_xplained_mmc_defconfig grinn_liteboard_defconfig olimex_a20_olinuxino_lime2_defconfig qemu_mips64r6el_malta_defconfig solidrun_macchiatobin_defconfig
atmel_sama5d3_xplained_mmc_dev_defconfig hifive_unleashed_defconfig olimex_a20_olinuxino_lime_defconfig qemu_mips64r6_malta_defconfig stm32f429_disco_defconfig
atmel_sama5d4_xplained_defconfig imx23evk_defconfig olimex_a20_olinuxino_micro_defconfig qemu_nios2_10m50_defconfig stm32f469_disco_defconfig
atmel_sama5d4_xplained_dev_defconfig imx6-sabreauto_defconfig olimex_a33_olinuxino_defconfig qemu_or1k_defconfig stm32mp157a_dk1_defconfig
atmel_sama5d4_xplained_mmc_defconfig imx6-sabresd_defconfig olimex_a64_olinuxino_defconfig qemu_ppc64_e5500_defconfig stm32mp157c_dk2_defconfig
atmel_sama5d4_xplained_mmc_dev_defconfig imx6-sabresd_qt5_defconfig olimex_imx233_olinuxino_defconfig qemu_ppc64le_pseries_defconfig toradex_apalis_imx6_defconfig
bananapi_m1_defconfig imx6slevk_defconfig olpc_xo175_defconfig qemu_ppc64_pseries_defconfig ts4900_defconfig
bananapi_m2_plus_defconfig imx6sx-sdb_defconfig olpc_xo1_defconfig qemu_ppc_g3beige_defconfig ts5500_defconfig
bananapi_m2_ultra_defconfig imx6ulevk_defconfig openblocks_a6_defconfig qemu_ppc_mac99_defconfig ts7680_defconfig
bananapi_m2_zero_defconfig imx6ullevk_defconfig orangepi_lite2_defconfig qemu_ppc_mpc8544ds_defconfig wandboard_defconfig
bananapi_m64_defconfig imx6ulpico_defconfig orangepi_lite_defconfig qemu_ppc_virtex_ml507_defconfig warp7_defconfig
bananapro_defconfig imx7dpico_defconfig orangepi_one_defconfig qemu_riscv32_virt_defconfig warpboard_defconfig
beagleboardx15_defconfig imx7d-sdb_defconfig orangepi_one_plus_defconfig qemu_riscv64_virt_defconfig zynq_microzed_defconfig
beagleboneai_defconfig imx8mmpico_defconfig orangepi_pc2_defconfig qemu_s390x_defconfig zynqmp_zcu106_defconfig
beaglebone_defconfig imx8mpico_defconfig orangepi_pc_defconfig qemu_sh4eb_r2d_defconfig zynq_qmtech_defconfig
beaglebone_qt5_defconfig imx8mqevk_defconfig orangepi_pc_plus_defconfig qemu_sh4_r2d_defconfig zynq_zc706_defconfig
beelink_gs1_defconfig kontron_smarc_sal28_defconfig orangepi_plus_defconfig qemu_sparc64_sun4u_defconfig zynq_zed_defconfig
chromebook_elm_defconfig lafrite_defconfig orangepi_prime_defconfig qemu_sparc_ss10_defconfig
chromebook_snow_defconfig lego_ev3_defconfig orangepi_r1_defconfig qemu_x86_64_defconfig
用这些config可以生成qemu用的vmlinux还有rootfs,这里我们的目的是生成mips64为的qemu镜像,键入命令
make qemu_mips64_malta_defconfig
接着敲入make menuconfig
,选择具体的编译参数,例如安装nmap等
Toolchain 这样选:
Target Package注意勾选
Show packages that are also provided by busybox
在
Debugging, profiling and benchmark
中勾选dt
和starce
、gdb
在
> Target packages > Networking applications
中选中netcat
nmap
ncat
openssh
之后save退出,敲入
make
开始编译。当然在配置package的时候,也可以加入其它选项进行编译。
3. 等待make结果:
等待几十分钟后,在路径/buildroot/output/images/
即可以看到。
rootfs.ext2 start-qemu.sh vmlinux
修改start-qemu.sh内容如下所示:
#!/bin/sh
IMAGE_DIR="${0%/*}/"
if [ "${1}" = "serial-only" ]; then
EXTRA_ARGS='-nographic'
else
EXTRA_ARGS='-serial stdio'
fi
export PATH="/home/ruan/buildroot-2020.05.1/output/host/bin:${PATH}"
exec qemu-system-mips64 -M malta -m 1024 -kernel ${IMAGE_DIR}/vmlinux -drive file=${IMAGE_DIR}/rootfs.ext2,format=raw -append "rootwait root=/dev/hda" ${EXTRA_ARGS} -net nic,macaddr=00:16:3e:00:00:01 -net tap
其中-net nic,macaddr=00:16:3e:00:00:01 -net tap
是我自己添加的,预先在本地Ubuntu上修改了两个文件,增加网桥设置。/etc/network/interfaces
设置本地网卡:
$ cat /etc/network/interfaces
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback
auto ens33
iface ens33 inet manual
up iconfig ens33 0.0.0.0 up
auto br0
iface br0 inet dhcp
bridge_ports ens33
bridge_maxwait 0
修改/etc/qemu-ifup
:
cat /etc/qemu-ifup
#! /bin/sh
echo "Executing /etc/qemu-ifup"
echo "Bringing $1 for bridged mode ..."
sudo /sbin/ifconfig $1 0.0.0.0 promisc up
echo "Adding $1 to br0..."
sudo /sbin/brctl addif br0 $1
sleep 3
之后启动start-qemu.sh
脚本,:
$ sudo ./start-qemu.sh
这样qemu虚拟机启动后,root登录进去能够直接和外界互联网连通。
环境验证
编译MIPS64 调试环境的目的是完成2020年强网杯题目mipsgame的环境搭建,由于程序包含PIE和NX,若用用户态仿真qemu-mips64
并没有使栈随机化,gdb调试的时候也不能用crtl+c
暂停程序。
1. qemu虚拟机下载文件
在本地程序路径下,用python -m SimpleHTTPServer
开启简单的http客户端。
之后,在虚拟机用wget将程序下载到本地:
# wget 192.168.94.134:8000/httpd
Connecting to 192.168.94.134:8000 (192.168.94.134:8000)
saving to 'httpd'
httpd 100% |********************************| 87512 0:00:00 ETA
'httpd' saved
同理,将ld和libc文件也下载到本地。并且chmod +x *
给程序以执行权限。若直接运行会报Permission denied
2. 运行调试
首先将动态链接库指定到libc ld所在路径export LD_LIBRARY_PATH=/root/lib
。
之后执行
ncat -vc "gdbserver 0.0.0.0:5555 ./httpd" -kl 0.0.0.0 3333
这样我们在qemu外面就可以直接用nc连接3333端口,qemu就会启动gdbserver 命令,在qemu外面用gdb-multiarch调试,gdb-multiarch ./httpd
进入gdb后target remote ip:5555
就可以愉快调试了。
运行两次可以看到每次栈排布地址都不一样:
一点儿心得
- buildroot编译若是虚拟机,内存至少3个G,而且由于网络关系buildroot下载依赖包的时候特别慢,速度只有几kb/s,最后是在vultr租了个vps编译好后传到本地使用的。
- buildroot除了编译mips64以外,安装同样的方法也可以编译arm64、MIPS32等仿真调试环境,为其他ctf比赛做准备。