Почему некоторые выходные данные из system() отсутствуют, когда я отлаживаю программу с помощью qemu и chroot

Недавно я пытался отлаживать кросс-компилированную программу для рук с помощью QEMU, но столкнулся с проблемой.

Это код, очень простой.

int main()  
{  
    printf("aaa\n");
    int  status;  
    status = system("./bin/ls"); 
    printf("Result of [system] = 0x%x\n", 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

Теперь я в полном замешательстве. Может ли кто-нибудь дать мне подсказку по этому поводу, и что я могу сделать, чтобы получить правильный вывод функции system при использовании команды chroot.

Весь ввод и вывод командной строки можно найти на этом рисунке: Содержимое командной строки


person Light-Sec    schedule 19.06.2020    source источник


Ответы (1)


Из системы man 3:

system() выполняет команду, указанную в команде, вызывая команду /bin/sh -c

Поэтому вам нужна работающая оболочка внутри chroot, чтобы иметь возможность успешно вызывать system().

Когда эта программа работает в qemu-arm-static, происходит следующее: system() приводит к fork(), за которым следует exec() для оболочки. Когда вы запускаете его без chroot, это ваша хостовая (x86) оболочка. Затем оболочка вызывает fork(), а затем exec() для bin/ls (ARM). Насколько я понимаю, это может быть успешным, только если у вас есть обработчик binfmt для ARM ELF, зарегистрированный на вашем хосте. В этом случае зарегистрированный qemu-arm загружается и выполняет bin/ls.

Когда вы делаете то же самое в chroot, оболочка хоста недоступна, поэтому system() приводит к exec() вызову bin/sh (ARM). Похоже, ваш обработчик binfmt недоступен внутри chroot, и из-за этого происходит сбой загрузки bin/sh и возвращается статус ошибки из system().

Вы можете проверить зарегистрированные обработчики binfmt в файле /proc/sys/fs/binfmt_misc.

person jcmvbkbc    schedule 19.06.2020
comment
У нас уже есть оболочка в каталоге bin внутри chroot. Я могу запустить bin/sh из qemu, но моя программа по-прежнему не запускает system. Вывод командной строки здесь - person Light-Sec; 22.06.2020