Не удается выполнить системный вызов execve

Я новичок, поэтому могу быть неаккуратным с выражениями. Мне нужно сделать системный вызов "execve" на C с ассемблером. Я не использую никакие библиотеки. Часть, которая не работает,

char *nul=(char *)0;
char *argv[] = { "/bin/date", nul };
char *envp[] = { nul };
long ret;
asm volatile ("int $0x80" : "=a" (ret) : "a" (11), "b" (argv[0]), "c" (argv), "d" (envp));
//"a" (11) ... 11 correspondes to execve

Я компилирую код (и не получаю ни ошибок, ни предупреждений) с

gcc -m32 -nostdlib -nostdinc -static -O2 sysc.c -o sysc

Когда я пытаюсь запустить программу, я вижу это сообщение:

A NULL argv[0] was passed through an exec system call.
Aborted

person reasonable_assumption    schedule 29.04.2014    source источник
comment
Вы пытались передать &argv через ecx?   -  person ccKep    schedule 30.04.2014
comment
Почему вам нужно использовать ассемблер для вызова функции C из программы C? (Я не говорю, что нет никакой возможной причины, но знание вашей цели может помочь ответить на вопрос.)   -  person Keith Thompson    schedule 30.04.2014
comment
c также должно быть argv[0]. Указатели на массивы невероятно редки и бесполезны в C; обычно вы всегда работаете с указателем на первый элемент.   -  person Kerrek SB    schedule 30.04.2014
comment
@ccKep Я сделал, не помогает.   -  person reasonable_assumption    schedule 30.04.2014
comment
@KerrekSB нет, тоже не работает   -  person reasonable_assumption    schedule 30.04.2014
comment
@RomanSushkov: Это не должно было помочь, просто исправить типы в вашем вызове :-)   -  person Kerrek SB    schedule 30.04.2014
comment
Возможный дубликат Почему системный вызов execve может запускать /bin/sh без аргументов argv, но не /bin/ls?   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 17.02.2017
comment
Прежде чем закрыть как дубликат, может ли кто-нибудь подтвердить (1) ASM не влияет на проблему; и (2) /bin/date подпадает под действие coreutil и демонстрирует то же поведение, что и /bin/ls.   -  person jww    schedule 20.02.2017


Ответы (2)


Если вы посмотрите на сгенерированный код, вы увидите, что компилятор оптимизировал инициализацию argv и envp в предположении, что ваш ассемблерный блок не обращается к ним (поскольку вы только объявляете, что вам нужны сами указатели).

Решение: добавьте заглушку "memory", чтобы сообщить компилятору, что вы можете читать или записывать любую память.

person Jester    schedule 29.04.2014

Аргументы семейства функций exec() немного странные.

В частности, arg0 и arg1 примерно одинаковы:

char *args [] = {"./path/to/program", "arg1", "arg2", NULL};

int rc = execve (args[0], args, envp);
person wallyk    schedule 29.04.2014