LINUX.ORG.RU

mmap && PROT_EXEC


0

0

задача: есть две программы. допустим, что одна из них печатает "hello workd!", назовём её hw, цель фторой программы - exec_hw - размапить кл-во памяти равное размеру бинарника hw и скопировать контекст данного бинарника в размапленную область, далее сделать jump на размапленный адрес. в теории после такого джампа должна выполнится программа hw, если при вызове ф-ии mmap был передан флаг PROT_EXEC, на практике же я получаю sigfault(сигнал SIGSEGV).

NOTE: задача не имеет никакой практической подоплёки. её единственная цель - удовлетворение моего любопытства, так что не нужно предлагать мне убить себя об стену, завести девушку, использовать lisp, what ever else...

код:

int main(void)
{
...
void *code_ref; /* start address of mapped file */
int fd; /* our hw binary file descriptor */
char buf[DEF_BUF_SIZE]; /* DEF_BUF_SIZE = 512 */
size_t ex_size, wr_size, cur_msize = 0;

ex_size = get_ex_file_size(); /* just get file size using stat() */

if((code_ref = mmap(code_ref, ex_size, PROT_EXEC | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0)) == NULL)
error("can't mmap hw!");
if((fd = open(EX_FILE_NAME, O_RDONLY)) < 0) /* EX_FILE_NAME = "./hw" */
error("can't open executable file!");

/* copy data from hw to maped memory */
while((wr_size = read(fd, buf, DEF_BUF_SIZE)) > 0) {
memmove(code_ref + cur_msize, buf, wr_size);
cur_msize += wr_size;
memset(buf, '\0', wr_size);
}

if(wr_size < 0)
error("can't read from executable file!\n");

close(fd);
__asm__("jmp *%0" : : "m" (code_ref)); /* jumping indeed */

...

exit(EXIT_SUCCESS);
}

может быть кто-нибудь знает в чём проблемма?


естественно знает. ты хочешь сделать что-то вроде execve from memory.

Хинт: что находется в самом нулевом слове заголовка ELF файла (куды ты делаешь джамп)?

йуная@кошычга

anonymous
()
Ответ на: комментарий от anonymous

> Хинт: что находется в самом нулевом слове заголовка ELF файла (куды ты делаешь джамп)?

хм, в смысле? это банальный стандартный elf заголовок executable файлов в линухах. или я должен каким-то образом править секции? если да, то каким?

10x

asgard
() автор топика
Ответ на: комментарий от asgard

начнем с того что ты должен проделать большую часть работы ядра (do_execve in Linux case) :). Мало того в общем случае таким способом нельзя запустить произвольный ELF бинарник.

В самом упрощенном варианте (бинарник при этом статически слинкованный и PIC) ты должен 1) распарсить ELF заголовок файла - отмапив каждый PT_LOAD сегмент куды он просит 2) подготовить стек и создать в нем минималльный контекст (просто argc/argv/envp) 3) передать управление на точку входа (а отнюдь не на первое слово в заголовке :))

если конечно это файл не ELF, а что-то вроде CP/M-овского .COM - то ты можешь запустить его сделав jmp на первый байт Но перед этим все равно нужно подготовить стек :)

йуная@кошычга

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.