Qemu是使用最广泛的跨平台仿真软件,可以模拟运行二进制文件和系统固件。因为某东路由是mips小端格式,因此我们使用mipsel进行仿真。
QEMU主要有两种仿真方式:
- 用户模式仿真:允许一个(Linux)进程执行在不同架构的CPU上,该模式下,QEMU 可以作为进程级虚拟机。
- 系统模式仿真:允许仿真完整的系统,包括处理器和配套的外设,该模式下,QEMU 也可以作为系统虚拟机。
安装qemu
1 2 3 4 5 6
| sudo apt-get install qemu sudo apt-get install qemu-user-static sudo apt-get install qemu-system sudo apt-get install uml-utilities sudo apt-get install bridge-utils sudo apt-get install qemu-user-static qemu-system-mips
|
用户模式下仿真
首先将qemu-mipsel-static拷贝到固件解包的系统目录下
1 2
| cd squashfs-root cp $(which qemu-mipsel-static) ./
|
执行二进制程序
1
| sudo chroot . ./qemu-mipsel-static sbin/ifconfig
|
系统模式下仿真
下载文件
首先我们需要从debian官网下载kernel和image,我使用vmlinux-2.6.32-5-4kc-malta和debian_squeeze_mipsel_standard.qcow2。当然也可以使用自己的kernel和imgage,后面模拟固件启动时会用到。
配置网络
1 2 3 4 5
| sudo brctl addbr Virbr0 sudo ifconfig Virbr0 192.168.244.133/24 up sudo tunctl -t tap0 sudo ifconfig tap0 192.168.244.134/24 up sudo brctl addif Virbr0 tap0
|
启动虚拟环境
1 2
| sudo qemu-system-mipsel -M malta -kernel vmlinux-2.6.32-5-4kc-malta -hda debian_squeeze_mipsel_standard.qcow2 \ -append "root=/dev/sda1 console=tty0" -net nic -net tap,ifname=tap0,script=no,downscript=no -nographic -s
|
系统启动后输入root/root登录至文件系统。
配置虚拟机IP
1
| ifconfig eth0 192.168.244.132/24
|
上传固件文件系统
1
| scp -r ./squashfs-root root@192.168.244.132:/root/
|
运行固件服务
1
| chroot squashfs-root /bin/sh
|
但是由于某些原因我运行一直出错,后来索性不再尝试,改为使用另外一个工具firmware-analysis-toolkit。
FAT
FAT可以直接提取固件的image然后模拟固件运行。
下载安装工具
1 2 3
| git clone https://github.com/attify/firmware-analysis-toolkit.git cd firmware-analysis-toolkit ./setup.sh
|
由于国内网络的原因,建议搭梯子。
启动固件
首先修改fat.config文件,将自己用户的密码添加进去,因为fat最终也是通过qemu模拟固件运行的,需要使用sudo权限。
运行FAT
实际运行中FAT会由于环境或者参数的原因生成的img有问题,导致系统无法启动,所以我手动运行的解包命令
1 2
| cd firmadyne/sources/extractor/ ./extract.sh xxx.bin ../../images
|
并对fat.py做了一定的修改。最终生成的启动命令如下:
1 2 3 4 5 6
| sudo qemu-system-mipsel -m 256 -M malta -kernel firmadyne/binaries//vmlinux.mipsel \ -drive if=ide,format=raw,file=firmadyne/scratch//1//image.raw \ -append "root=/dev/sda1 console=ttyS0 nandsim.parts=64,64,64,64,64,64,64,64,64,64 rdinit=/firmadyne/preInit.sh \ rw debug ignore_loglevel print-fatal-signals=1 user_debug=31 firmadyne.syscall=0" -nographic \ -netdev socket,id=net1,listen=:2001 -device e1000,netdev=net1 -netdev socket,id=net2,listen=:2002 \ -device e1000,netdev=net2 -netdev socket,id=net3,listen=:2003 -device e1000,netdev=net3
|
可以从上面启动命令中看到使用的image是FAT通过提取固件生成的。系统启动信息如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| Nov 2 04:23:31 (none) kern.info kernel: [ 0.120000] NET: Registered protocol family 2 Nov 2 04:23:31 (none) kern.info kernel: [ 0.120000] IP route cache hash table entries: 2048 (order: 1, 8192 bytes) Nov 2 04:23:31 (none) kern.info kernel: [ 0.120000] TCP established hash table entries: 8192 (order: 4, 65536 bytes) Nov 2 04:23:31 (none) kern.info kernel: [ 0.124000] TCP bind hash table entries: 8192 (order: 3, 32768 bytes) Nov 2 04:23:31 (none) kern.info kernel: [ 0.124000] TCP: Hash tables configured (established 8192 bind 8192) Nov 2 04:23:31 (none) kern.info kernel: [ 0.124000] TCP reno registered Nov 2 04:23:31 (none) kern.info kernel: [ 0.124000] UDP hash table entries: 256 (order: 0, 4096 bytes) Nov 2 04:23:31 (none) kern.info kernel: [ 0.124000] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes) Nov 2 04:23:31 (none) kern.info kernel: [ 0.124000] NET: Registered protocol family 1 Nov 2 04:23:31 (none) kern.debug kernel: [ 0.124000] PCI: CLS 0 bytes, default 64 Nov 2 04:23:31 (none) kern.info kernel: [ 0.184000] squashfs: version 4.0 (2009/01/31) Phillip Lougher Nov 2 04:23:31 (none) kern.info kernel: [ 0.184000] Registering unionfs 2.6 (for 2.6.39.4) Nov 2 04:23:31 (none) kern.info kernel: [ 0.184000] JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc. Nov 2 04:23:31 (none) kern.info kernel: [ 0.184000] ROMFS MTD (C) 2007 Red Hat, Inc. Nov 2 04:23:31 (none) kern.info kernel: [ 0.188000] msgmni has been set to 492 Nov 2 04:23:31 (none) kern.info kernel: [ 0.192000] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253) Nov 2 04:23:31 (none) kern.info kernel: [ 0.192000] io scheduler noop registered Nov 2 04:23:31 (none) kern.info kernel: [ 0.192000] io scheduler cfq registered (default) Nov 2 04:23:31 (none) daemon.notice procd: /etc/rc.d/S10boot: /etc/rc.common: line 37: vconfig: not found Nov 2 04:23:31 (none) kern.info kernel: [ 0.192000] firmadyne: devfs: 1, execute: 1, procfs: 1, syscall: 0 Nov 2 04:23:31 (none) kern.warn kernel: [ 0.192000] firmadyne: Cannot register character device: watchdog, 0xa, 0x82! Nov 2 04:23:31 (none) kern.warn kernel: [ 0.192000] firmadyne: Cannot register character device: wdt, 0xfd, 0x0! Nov 2 04:23:31 (none) kern.warn kernel: [ 0.228000] PCI: Enabling device 0000:00:12.0 (0000 -> 0002) Nov 2 04:23:31 (none) kern.info kernel: [ 0.228000] cirrusfb 0000:00:12.0: Cirrus Logic chipset on PCI bus, RAM (4096 kB) at 0x10000000 Nov 2 04:23:31 (none) kern.info kernel: [ 0.448000] Console: switching to colour frame buffer device 80x30 Nov 2 04:23:31 (none) kern.info kernel: [ 0.460000] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled Nov 2 04:23:31 (none) kern.info kernel: [ 0.484000] serial8250.0: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A Nov 2 04:23:31 (none) kern.info kernel: [ 0.488000] console [ttyS0] enabled, bootconsole disabled Nov 2 04:23:31 (none) kern.info kernel: [ 0.508000] serial8250.0: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A Nov 2 04:23:31 (none) kern.info kernel: [ 0.532000] serial8250.0: ttyS2 at MMIO 0x1f000900 (irq = 18) is a 16550A Nov 2 04:23:31 (none) kern.info kernel: [ 0.536000] brd: module loaded Nov 2 04:23:31 (none) kern.info kernel: [ 0.536000] loop: module loaded Nov 2 04:23:31 (none) kern.debug kernel: [ 0.536000] ata_piix 0000:00:0a.1: version 2.13 power off the port 0 [ 14.960000] e1000: eth1 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX [ 14.996000] 8021q: adding VLAN 0 to HW filter on device eth1 [ 15.840000] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX [ 15.848000] ADDRCONF(NETDEV_UP): eth0: link is not ready [ 15.848000] 8021q: adding VLAN 0 to HW filter on device eth0 [ 15.852000] ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready btnd start_service start v6 bridge ########### ####start SFE#### ####enable SFE#### en:1 en:0 en:0 en:0 en:1 BusyBox v1.29.2 () built-in shell (ash)
----------------------------------------------------- JDCOS 2.3.4.r1307, r7258-5eb055306f ----------------------------------------------------- MAC: FFFFFFFFFFFF Product: NULL ROM: HR06 ----------------------------------------------------- root@HaiOS:/#
|