交叉编译实践

什么是交叉编译

在本架构的主机上编译出另一种架构的可执行文件。

为什么需要交叉编译?

可执行文件有确定的架构,如x86、MIPS、ARM等,这些可执行文件只能在对应架构的CPU上运行。一般而言,我们只需要编译出能够在自己主机架构上运行的程序。但是像路由器这些固件一般是MIPS、ARM架构的,我们要想在X64的电脑上调试这些文件,就需要用到交叉编译,常用的工具是BuildRoot。

实验目的

  • 学会使用Buildroot构建交叉编译工具链
  • 掌握LD_PRELOAD使用

实验内容

完成交叉编译工具链生成

制作MIPS32 小端的BuildRoot

img

img

img

img

编译完成:

img

img

MIPS32 大端

配置类似,这是编译结果:

img

img

完成静态编译Busybox工具

编译BusyBox MIPS小端

把BuildRoot的bin添加到环境变量中

img

设置交叉编译头

img

静态编译

img

img

img

测试:

img

大端

同理:

先把大端BuildBoot的bin添加到环境变量

img

重新解压一份busybox,重命名

img

img

-mipsel是刚才的小端busybox

修改交叉编译头

img

编译完成:

img

img

这个是动态编译的

设置为静态编译:

img

启动编译

img

编译成功

img

测试

img

编译libpcap

大端libpcap

官网查看编译教程

https://github.com/the-tcpdump-group/libpcap/blob/master/INSTALL.md

img

没有make menuconfig,需要在命令行中配置

img

我们需要配置的有:

img

这个是输出的目录,默认会放到/usr/bin/local之类的地方,会全局可用。我们会准备多个版本的libpcap,自然不能添加到全局。使用—prefix=/home/szl/lib指定输出目录

img

–host是一个目标三元组,用于描述交叉编译工具链的目标架构和环境。我们应该使用mips-linux-gnu

img

CC是编译器,我们的是mips-linux-gcc,这个已经是全局变量

CFALGS是头文件、优化级别、警告级别,我们只用于添加头文件

LDFLAGS指定了链接库和是否静态编译,我们添加链接库

遇到报错:

img

更详细的报错在config.log中

img

说是需要c99,但是添加了c99或gnu99都无法解决

参考:

https://lore.kernel.org/all/20210123164535.515E78151B@busybox.osuosl.org/T/

通过硬编码ac_cv_prog_cc_c99来避免wchar_t检查问题

img

img

然后make

img

这是因为之前留下了一些x86的libpcap文件

img

clean掉就可以

然后重新make,make install

去我们设置的prefix中查看

img

动态大端libpcap编译完成

编译静态的libpcap失败:

img

配置–static表示静态编译libpcap

然后make会报错:

img

即使添加-fPIC也不行

img

img

相同的报错,老师说动态的libpcap也可以,遂放弃编译静态libpcap

编译大端tcpdump

img

然后make,make install

img

img

测试tcpdump

img

失败

img

img

在普通环境和chroot中都失败了

参考:https://github.com/docker/for-mac/issues/6707

img

似乎qemu中的tcpdump会有问题

编译小端libpcap

img

先make clean一下

然后make, make install

img

img

编译mips小端tcpdump

img

img

和编译libpcap类似

小端tcpdump

img

然后make,make clean

img

静态MIPS小端的tcpdump编译完成

LD_PRELOAD劫持随机数生成

img

img

这里提取出来的suqashfs-root是空的

img

上面提示我们没有安装sasquatch,接下来安装这个

img

PPT中虽然给了对应的解决办法

img

这个deps.sh在binwalk下面,最终目的还是为了解决binwalk的安装问题。但我们之前的Binwalk是可以正常运行的,只是现在报错了。

我们可以找一下其他的解决办法:

https://github.com/devttys0/sasquatch/issues/48#issuecomment-1267506233

这个是采用了:https://github.com/devttys0/sasquatch/pull/47中的一个patch文件来进行补丁。

命令:

img

img

现在正常了:

img

img

需要采用32位小端MIPS

img

编译test.c

img

img

在squashfs-root中修改文件需要root权限,我们在外面把test和so编译好再拷到squashfs-root中

编译libnvram.so

img

完整的学号有13位,超过了%d的范围,我们只使用学号的后9位

img

-fPIC表示生成与位置无关的代码,创建共享库需要这个。

-shared:指示编译器生成共享库。

再把qemu-mipsel-static移过来

img

运行

img

劫持成功

命令解释:

chroot .把根目录改为了当前文件夹。我们要用到uClibc,这个文件在提取出来的/lib下面,如果不使用chroot的话会找不到uClibc

img

-E是qemu用来设置环境变量的,LD_PRELOAD是一个环境变量,用于在运行时加载指定的共享库。这样test在调用rand函数时就会调用libnvram.so中的rand函数,完成劫持。


交叉编译实践
https://asxjdb.github.io/2024/08/03/交叉编译实践/
作者
Asxjdb
发布于
2024年8月3日
许可协议