最近,我尝试用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 处理程序