前提
參考文章mips64調(diào)試環(huán)境搭建 這里做個(gè)記錄
如果用的是linux虛擬機(jī),那么內(nèi)存一定要設(shè)置3G以上,否則會(huì)經(jīng)常報(bào)錯(cuò)
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,有很多默認(rèn)設(shè)置。通過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,選擇具體的編譯參數(shù),例如安裝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開始編譯。當(dāng)然在配置package的時(shí)候,也可以加入其它選項(xiàng)進(jìn)行編譯。
3. 等待make結(jié)果:
等待幾十分鐘后,在路徑/buildroot/output/images/即可以看到。
rootfs.ext2 start-qemu.sh vmlinux
修改start-qemu.sh內(nèi)容如下所示:
#!/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是我自己添加的,預(yù)先在本地Ubuntu上修改了兩個(gè)文件,增加網(wǎng)橋設(shè)置。/etc/network/interfaces設(shè)置本地網(wǎng)卡:
$ 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
之后啟動(dòng)start-qemu.sh腳本,:
$ sudo ./start-qemu.sh

這樣qemu虛擬機(jī)啟動(dòng)后,root登錄進(jìn)去能夠直接和外界互聯(lián)網(wǎng)連通。
環(huán)境驗(yàn)證
編譯MIPS64 調(diào)試環(huán)境的目的是完成2020年強(qiáng)網(wǎng)杯題目mipsgame的環(huán)境搭建,由于程序包含PIE和NX,若用用戶態(tài)仿真qemu-mips64并沒有使棧隨機(jī)化,gdb調(diào)試的時(shí)候也不能用crtl+c暫停程序。
1. qemu虛擬機(jī)下載文件
在本地程序路徑下,用python -m SimpleHTTPServer開啟簡單的http客戶端。
之后,在虛擬機(jī)用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 *給程序以執(zhí)行權(quán)限。若直接運(yùn)行會(huì)報(bào)Permission denied
2. 運(yùn)行調(diào)試
首先將動(dòng)態(tài)鏈接庫指定到libc ld所在路徑export LD_LIBRARY_PATH=/root/lib。
之后執(zhí)行
ncat -vc "gdbserver 0.0.0.0:5555 ./httpd" -kl 0.0.0.0 3333
這樣我們在qemu外面就可以直接用nc連接3333端口,qemu就會(huì)啟動(dòng)gdbserver 命令,在qemu外面用gdb-multiarch調(diào)試,gdb-multiarch ./httpd進(jìn)入gdb后target remote ip:5555就可以愉快調(diào)試了。

運(yùn)行兩次可以看到每次棧排布地址都不一樣:


一點(diǎn)兒心得
- buildroot編譯若是虛擬機(jī),內(nèi)存至少3個(gè)G,而且由于網(wǎng)絡(luò)關(guān)系buildroot下載依賴包的時(shí)候特別慢,速度只有幾kb/s,最后是在vultr租了個(gè)vps編譯好后傳到本地使用的。
- buildroot除了編譯mips64以外,安裝同樣的方法也可以編譯arm64、MIPS32等仿真調(diào)試環(huán)境,為其他ctf比賽做準(zhǔn)備。