为什么当我使用 qemu 和 chroot 调试程序时缺少 system() 的某些输出



最近,我尝试用QEMU调试一个交叉编译的arm程序,但我遇到了一个问题。

这是代码,非常简单。

int main()  
{  
printf("aaan");
int  status;  
status = system("./bin/ls"); 
printf("Result of [system] = 0x%xn", status);
}

当我使用命令启动程序时

spy@spy-virtual-machine:/usr/arm-linux-gnueabihf$ ./qemu-arm-static -L ./ ./a.out 

输出为:

aaa
bin              include          lib              test.c           qemu-arm-static  a.out            qemu-arm         shell.sh
Result of [system] = 0x0

但是当我像这样使用 chroot 启动程序时:

spy@spy-virtual-machine:/usr/arm-linux-gnueabihf$ sudo chroot ./ ./qemu-arm-static -L ./ ./a.out

输出结果是:

aaa
Result of [system] = 0x7f00

显然,system("./bin/ls")没有按预期运行。

但是./bin/ls命令可以由chroot和QEMU运行:

spy@spy-virtual-machine:/usr/arm-linux-gnueabihf$ sudo chroot ./ ./qemu-arm-static -L ./ ./bin/ls
bin              include          lib              test.c           qemu-arm-static  a.out            qemu-arm         shell.sh

现在我完全糊涂了。任何人都可以给我一个提示,以及使用chroot命令时我可以做些什么来获得system函数的正确输出。

所有命令行输入和输出都可以在下图中找到: 命令行内容

来自 man 3 系统:

system(( 通过调用/bin/sh -c 来执行命令中指定的命令 命令

所以你需要在 chroot 内部有一个工作 shell,以便能够成功调用 system((。

当此程序在 qemu-arm-static 中运行时,会发生以下情况:system()会导致fork()后跟 shell 的exec()。当你在没有chroot的情况下运行它时,这是你的主机(x86(shell。然后,shell 调用fork(),后跟bin/ls(ARM( 的exec()。我的理解是,只有在主机上注册了 ARM ELF 的 binfmt 处理程序时,它才能成功。在这种情况下,注册的 qemu-arm 被加载并执行bin/ls.

当您在 chroot 中执行相同的操作时,无法访问主机外壳,因此system()会导致exec()调用bin/sh(ARM(。看起来您的 binfmt 处理程序在 chroot 中无法访问,因此加载bin/sh失败,并且错误状态从system()返回。

您可以在/proc/sys/fs/binfmt_misc 中检查已注册的 binfmt 处理程序

最新更新