官网:https://www.qemu.org/
文档:
- https://www.qemu.org/documentation/
Wiki:
-
https://wiki.qemu.org/Main_Page
-
https://wiki.qemu.org/Documentation
1. QEMU
可以用apt的搜索命令看看有哪些可下载项:
$ apt search qemu-
可以列出很多, 一般需要的是qemu-system和qemu-user.
先只下载个静态应用版本的:
sudo apt-get install qemu-user-static
然后, qemu-arm和qemu-mips等模拟器就都有了.
本文只测试user模式, system模式应该还需要工具集等:
sudo apt-get install qemu-system qemu-utils
binfmt
一定要安装qemu-binfmt:
sudo apt install qemu-binfmt # 好像已经不用单独下载了
sudo mkdir /etc/qemu-binfmt
非静态编译时, 它可以找到正确的加载器, 等一会就能体会到它的用处了。
2. 编译测试
可以先安装好多指令集gdb:
sudo apt install gdb-multiarch
然后下载交叉编译工具,也可以编译buildroot获取交叉编译工具。
mips
搜索一下:
$ apt search gcc-mips
gcc-mips-linux-gnu # 大端
gcc-mips64-linux-gnuabi64 # 64位大端
gcc-mips64el-linux-gnuabi64 # 64位小端
gcc-mipsel-linux-gnu # 小端
$ apt search libc6-mips # 依赖库
$ apt search binutils-mips
下载对应的gcc以及其它相关库:
# 至少要下载gcc
sudo apt install gcc-mips-linux-gnu
# 需要安装一些库才能调试
sudo apt install emdebian-archive-keyring
sudo apt install linux-libc-dev-mips-cross
sudo apt install libc6-mips-cross libc6-dev-mips-cross
sudo apt install binutils-mips-linux-gnu
编一个代码试试:
// test.c
#include <stdio.h>
int main(void) {
printf("hello\n");
return 0;
}
编译结果:
$ mips-linux-gnu-gcc -static test.c -o test
$ file test
test: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=dc504f1926145fd24415a1415568e608eb3c16f1, not stripped
$ ldd test
not a dynamic executable
$ ./test
hello
$ mips-linux-gnu-readelf -h ./test
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: MIPS R3000
Version: 0x1
Entry point address: 0x400590
Start of program headers: 52 (bytes into file)
Start of section headers: 8776 (bytes into file)
Flags: 0x70001007, noreorder, pic, cpic, o32, mips32r2
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 11
Size of section headers: 40 (bytes)
Number of section headers: 38
Section header string table index: 37
如果是linux,就需要g++库:
$ sudo apt install g++-mips-linux-gnu
$ mips-linux-gnu-g++ -static test.cpp -o test
$ ./test
hello
也可以用qemu运行:
$ qemu-mips ./test
hello
如果没有-static, 直接运行就会找不到链接库,需要指定lib路径:
$ mips-linux-gnu-gcc test.c -o test
$ ldd test
not a dynamic executable
$ ./test
/lib/ld.so.1: No such file or directory
$ qemu-mips -L /usr/mips-linux-gnu/ ./test
hello
但更方便的做法是使用qemu-binfmt:
$ sudo ln -s /usr/mips-linux-gnu/ /etc/qemu-binfmt/mips
$ ./test
hello
ARM
ARM的gcc就比较多了:
$ sudo apt install gcc-arm-
gcc-arm-linux-gnueabi gcc-arm-linux-gnueabihf gcc-arm-none-eabi gcc-arm-none-eabi-source
ABI:二进制应用程序接口
EABI:嵌入式ABI
一般用GNU EABI版本:
sudo apt install gcc-arm-linux-gnueabi
sudo ln -s /usr/arm-linux-gnueabi /etc/qemu-binfmt/arm
3. 调试
GDB调试
用qemu启动调试gdbserver:
$ qemu-mips-static -g 1234 ./test
也可以用各个架构编译好的gdbserver:
- https://github.com/e3pem/embedded-toolkit
- https://github.com/rapid7/embedded-tools/tree/master/binaries/gdbserver
Gdb-multiarch连接:
$ gdb-multiarch ./test
gef> set architecture mips
The target architecture is assumed to be mips
gef> set endian big
gef> target remote localhost:1234
可以写成脚本setarch.gdb:
set architecture mips
set endian big
target remote localhost:1234
每次开启gdb后执行source setarch.gdb
。
不过用了一会,gef和pwndbg插件看起来都有bug, 都会报No registers
错误,可能还是需要对应版本的gdb。
IDA远程调试
linux端需要允许一个端口号:
sudo ufw allow 1234
监听端口,挂起刚刚编译好的test可执行文件:
sudo qemu-mips -g 1234 ./test
把test拖进ida,调试起选择远程GDB,Process Options设置好linux端的路径,linux的ip以及端口,attach to process,即可调试。
4. 脚本整合
sudo apt-get install qemu-user-static
sudo mkdir /etc/qemu-binfmt
sudo apt install gcc-mips-linux-gnu -y
sudo ln -s /usr/mips-linux-gnu/ /etc/qemu-binfmt/mips
sudo apt install gcc-mipsel-linux-gnu -y
sudo ln -s /usr/mipsel-linux-gnu/ /etc/qemu-binfmt/mipsel