因为我对交叉调试和交叉编译不熟悉,所以我需要一些帮助,因为我感到很困惑。我有一个MIPS精灵文件[myelf] [1]。您会在下面看到file myelf的输出:

myelf: ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, BuildID[sha1]=0xc89c3571514c7ec1afc74a189a9c2d24e276ec4c, with unknown capability 0xf41 = 0x756e6700, with unknown capability 0x70100 = 0x1040000  stripped


我只想运行和调试程序。所以我不需要交叉编译器吧?由于我没有MIPS硬件(我具有INTEL微处理器),因此我需要一个仿真器。我选择使用QEMU。根据此站点,我下载了以下内核映像和initrds:

debian_squeeze_mips_standard.qcow2

vmlinux-2.6.32-5-4kc-malta


然后我以32位(因为elf信息)运行了指定的命令MIPS系统。

qemu-system-mips -M malta -kernel vmlinux-2.6.32-5-4kc-malta -hda debian_squeeze_mips_standard.qcow2 -append "root=/dev/sda1 console=tty0"


到目前为止,我已经将仿真器运行在一个shell中,并且命令uname -a给了我: />
模拟器上只有非常基本的命令/工具。我已经读过gdb可以从x86_64主机上的远程目标(这里是MIPS仿真器)上调试。老实说,我不知道我现在应该做什么。我首先尝试在qemu模拟器上安装gdb本身。当我运行gdb时,我的精灵可以看到gdb被自动配置为mips-linux-gnu。

Linux debian-mips 2.6.32-5-4kc-malta #1 Tue Sep 24 00:02:22 UTC 2013 mips GNU/Linux


信息文件为我提供了正确的信息(我已使用IDA拆解了elf,以便可以确认)。



root@debian-mips:~# gdb myelf 
GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "mips-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/myelf...(no debugging symbols found)...done.


我等待了大约10分钟,没有任何反应。 (通常程序应该打印一个字符串“ Usage:./myelf password”,因为我没有提供任何参数)。
然后我尝试在模拟器上使用gdbserver,并在主机上尝试为mipsel处理器配置gdb,但是它不起作用。我很困惑。如果有人可以告诉我我的过程中有什么问题,或者有人尝试运行myelf文件,我会知道他是怎么做的,以便能够在不同的计算机上运行任何程序。

,谢谢美好的一天!

#1 楼

准备冒险吧!

您需要一些东西来完成任务!让我们从头开始。

QEMU和GDB

QEMU是用于各种体系结构的仿真器。通常,它用于模拟整个PC(即运行虚拟机)。但是,对于调试单个程序,这不是必需的。在Linux上,可以使用QEMU用户空间仿真。

$ sudo apt-get install qemu qemu-user qemu-user-static


此外,默认情况下为Ubuntu和类似操作系统安装的GDB对其他信息一无所知。建筑。幸运的是,有一个gdb-multiarch软件包可以使用!采用。对于二进制文件,没有这样的标准。为了填补这个空白,可以使用#!包查看文件的类型,并自动调用正确的解释器。在我们的例子中,它将看到您正在尝试运行一个低端的MIPS(binfmt)二进制文件并调用mipsel

$ sudo apt-get install gdb-multiarch


运行静态链接的二进制文件

对于静态链接的MIPSEL二进制文件,通常只需要这样做。但是,您链接到的那个依赖于外部库。如果它是静态链接的,则可以立即运行。您可以创建一个示例二进制文件来演示此操作:

$ sudo apt-get install 'binfmt*'




由于所选的二进制文件是动态链接的,因此需要安装库如qemu-mipsellibc.so适用的架构。我们还需要告诉ld.so在哪里可以找到它们。

Ubuntu为ARM和AArch64提供了跨体系结构的软件包。例如:

$ echo 'int main() {puts("Hello world!");}' > hello.c
$ mipsel-linux-gnu-gcc -xc -static -o mipsel-test hello.c
$ file mipsel-test
a.out: ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, for GNU/Linux 2.6.18, BuildID[sha1]=2556cc80429de1ab3116278ac10832d72bd7ebab, not stripped
$ ./mipsel-test
Hello world!


Ubuntu(如果版本低于Ubuntu 16.04 / Xenial)

Ubuntu 14.04,不提供MIPS软件包。幸运的是,Debian(基于Ubuntu)确实提供了软件包,并且这些软件包与Ubuntu兼容。不幸的是,Debian不支持低字节序的MIPS(mipsel)。再次幸运的是,作为不同的Debian衍生产品,Embedded Debian(emdebian)确实提供了这些软件包。

您可以使用以下命令将这两个存储库都添加到Ubuntu或其他基于Debian的发行版中。如果您仅使用ARM或AArch64,则无需执行此操作。

$ sudo apt-get install libc6-armhf-armel-cross


清理

完成后安装软件包(见下文)时,强烈建议删除我们之前创建的文件binfmt。尽管Emdebian软件包兼容,但emdebian.list确实很奇怪,可以选择使用apt软件包而不是您的发行版应该使用的软件包。如果以后需要安装更多软件包,可以再次添加。

$ sudo apt-get install debian-keyring
$ sudo apt-get install debian-archive-keyring
$ sudo apt-get install emdebian-archive-keyring
$ sudo tee /etc/apt/sources.list.d/emdebian.list << EOF
deb http://mirrors.mit.edu/debian squeeze main
deb http://www.emdebian.org/debian squeeze main
EOF
$ sudo apt-get update


安装库

现在我们可以安装软件包了!该软件包包含运行您选择的二进制文件所需的所有Debian库,

$ sudo rm /etc/apt/sources.list.d/emdebian.list
$ sudo apt-get update


如果要构建上述示例的程序,则需要交叉编译器。

$ sudo apt-get install libc6-mipsel-cross      # For MIPS-EL
$ sudo apt-get install libc6-armhf-armel-cross # For ARM


最后,我们需要告诉mipsel二进制binfmt的库所在的位置。

$ sudo apt-get install gcc-4.4-mipsel-linux-gnu # For MIPS-EL on Ubuntu 14.04
$ sudo apt-get install gcc-mipsel-linux-gnu     # For MIPS-EL on Ubuntu 16.04
$ sudo apt-get install gcc-arm-linux-gnueabihf  # For ARM


现在您可以在系统上运行二进制文件了!!

$ sudo mkdir /etc/qemu-binfmt
$ sudo ln -s /usr/mipsel-linux-gnu /etc/qemu-binfmt/mipsel # MIPSEL
$ sudo ln -s /usr/arm-linux-gnueabihf /etc/qemu-binfmt/arm # ARM


调试

这是全部,对吧?

strace

最快的方法是能够在二进制文件上运行mipsel。您可以使用以下方法执行此操作:从运行二进制文件以及从strace开始,您应该已经看到该二进制文件尝试对其自身调用strace。这是ptrace的局限之一,是不支持qemu-user。如果二进制文件需要自我跟踪,则需要构建完整的QEMU系统映像。我通常使用这里提供的那些。运行QEMU超出了此答案的范围,但是我链接到的页面具有有用的命令行。

您可以轻松地从二进制文件中删除ptrace调用(它是反调试的东西),并且它运行良好。但是,我认为这是crackme的一部分:P。

$ ./myelf
Usage: ./crackme password


QEMU GDB Stub

为了使用GDB调试二进制文件,您需要启动ptrace,以便它公开GDB存根,并从GDB连接。

请注意,由于您在qemu-mips内部运行,因此某些命令无法正常运行。特别是,qemu-user不起作用。您可能要看一下我的pwndbg项目,该项目可以解决其中一些限制。

评论


你好!首先感谢您如此完整的答案!我通过以下方式安装binfmt:sudo apt-get install binfmt-support。删除了交叉编译器,因此我没有测试静态链接的Binaries。然后执行每个步骤,但是当我想告诉binfmt哪里有库。用于mipsel二进制文件。我意识到我没有/ etc / qemu-binfmt /文件夹。我只有/ etc / qemu和target-x86_64.conf文件。所以我创建了/ etc / qemu-binfmt / mipsel目录。但是,当我尝试运行./myelf时,得到了:/lib/ld.so.1:没有丢失的此类文件或目录,问题出在链接上吗?还是binfmt?

–creuchmeuch
15年5月19日在7:34



抱歉,我想澄清一遍,在创建/ etc / qemu-binfmt / mipsel目录后,我已经执行以下命令:sudo ln -s / usr / mipsel-linux-gnu / etc / qemu-binfmt / mipsel 。在此先感谢您,我将测试静态链接的二进制文件,等待您的回答。

–creuchmeuch
2015年5月19日在7:46

即使我无法解决上述问题。由于qemu-mipsel -g 12345 -L / usr / mipsel-linux-gnu ./myelf&,我成功运行了myelf。但是我有一个警告:无法找到动态链接器断点功能。 GDB将无法调试共享库初始化程序,也无法跟踪显式加载的动态代码。逐步进入程序,我发现通过将elf文件与IDA分解来比较指令,从而发现了不同的指令。无论如何,感谢您的帮助。

–creuchmeuch
15年5月19日在14:43

默认情况下,/ etc / qemu-binfmt目录不存在。我为此添加了一条评论。

–扎克(Jach)步枪
15年5月30日在22:57

@ZachRiggle当我尝试使用上述步骤在Ubuntu 14.04上安装gcc-4.4-mipsel-linux-gnu时,出现依赖项cpp-4.4-mipsel-linux-gnu的错误。当我尝试安装cpp-4.4-mipsel-linux-gnu时,它具有对lipgmp3c2的依赖,而该依赖在Ubuntu仓库中不可用。如何在Ubuntu 14.04上为MIPS安装交叉编译工具链?谢谢。

–霓虹灯
17年6月22日在10:16

#2 楼

您可以尝试使用radare2工具通过以下行连接远程gdbserver:

r2 -a mips gdb://[address]


#3 楼

qemu-system-mips带有Buildroot的完整系统仿真

此方法可以仿真整个MIPS CPU,并且可以克服以下用户域仿真中提到的限制:https://reverseengineering.stackexchange.com/a/8917/12321

此脚本可完全自动化您可以自动执行的所有操作:https://github.com/cirosantilli/linux-kernel-module-cheat/tree/1d197f35ee177c6ab3e6a2f518292b8dc4e53431#gdbserver

Buildroot下载并编译我们的整个目标文件系统,不包括gdbserver以及主机QEMU和gdb。下面介绍的主要步骤。

现在剩下的“唯一”内容是:


交叉编译/以正确的版本安装所有库可执行文件。 stdlib已经被交叉编译,但是您仍然会遇到版本不匹配的问题...
确保动态加载程序配置正确。 TODO:Buildroot支持自定义它,还是可以在可执行文件本身上对其进行修补?

,以确保您能够运行该可执行文件。

但是请注意,这些步骤userland方法也需要。

我的脚本完成的主要步骤是:



在Buildroot配置上启用gdbserver

BR2_DEBUG_3=y
BR2_ENABLE_DEBUG=y
BR2_OPTIMIZE_0=y
BR2_PACKAGE_GDB=y
BR2_PTHREAD_DEBUG=y


在Buildroot配置上使用BR2_ROOTFS_OVERLAY将可执行文件放置在文件系统中。

通过命令行将主机端口转发到QEMU目标选项(此处4545545455):

-net user,hostfwd=tcp::45455-:45455



在目标上启动gdbserver

gdbserver :45455 myexec



从主机启动交叉编译的GDB,并将其指向交叉编译的可执行文件和转发的端口:

buildroot/output/host/usr/bin/mips64-linux-gdb \
  -ex 'target remote localhost:45455' \
  -ex 'tb main' \
  -ex 'c' \
  buildroot/output/build/mypackage-1.0.0/myexec



最低工作用户模式示例

作为完整系统的一种更快捷,更肮脏的替代方法,您可以摆脱用户模式的约束,具体方法如下:https://stackoverflow.com/questions/20590155/how-to-single-step-arm-assembly-in-gdb -on-qemu / 51310791#51310791

#4 楼

我只想添加关于qemu-userptrace的快速收据。


在主机上启动qemu-binfmt服务以注册qemu用户二进制文件。
使用buildah创建amd64容器。 br />在此amd64容器中安装最新的qemu,内核将使用它们代替主机。
在amd64容器中构建一些工具链。
使用常规strace来跟踪您的二进制文件。例如:



buildah copy 2f64fe2cdbfd /tmp/readdir32.c /tmp/
buildah run --cap-add=CAP_SYS_PTRACE 2f64fe2cdbfd -- sh -c "mips-unknown-linux-gnu-gcc /tmp/readdir32.c -o /tmp/readdir32 && LD_PRELOAD='/usr/mips-unknown-linux-gnu/lib/libc.so.6' strace -v /tmp/readdir32"



write(1,“ errno 89函数未实现” ...


完美的作品。

完整的示例在这里。请注意-测试图像尚未完成,我仍在与mips作战。