URL: https://www.opennet.ru/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 10292
[ Назад ]

Исходное сообщение
"Попытка реализовать собственный exec в userspace"

Отправлено Павел Отредиез , 02-Янв-20 20:36 
Я га OpenBSD 6.6 64-bit
Есть простая программка hello:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
//    printf("%d\n", argc);
//    printf("Hello world!\n");
      return argc;
}

$ objdump -x hello | grep main
0000000000005680 g     F .text  0000000000000010 main


Надо вызвать ее из другой программы используя ручные методы:

#include <stdlib.h>
#include <stdio.h>
#include <err.h>
#include <errno.h>
#include <sys/mman.h>
#include "defines.h"
#include <fcntl.h>

void * RAM;

int main(int argc, char **argv)
{
    int i = open("disk/hello", O_RDWR);

    if (i == -1)
        errc(errno, errno, "Unable to open file\n");

    RAM = mmap(0, MEMORY_NPAGE * MEM_PAGE_SIZE,
    PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, i, 0);
    if (RAM == MAP_FAILED) errc(errno, errno, "Unable to map memory\n");

    printf("fd an allocated addres %d %lx\n", i, (long int)RAM);

    // _Jv_RegisterClasses symbol

    long unsigned int * _Jv_RegisterClasses =  RAM;

    *_Jv_RegisterClasses = (long unsigned int) RAM;


    int (*System)(int, char**) = RAM + 0x5680; //Symbol "T main"

    int j = System(10, argv);

    printf("Hello return %d\n", j);

    if (munmap(RAM, MEMORY_NPAGE * MEM_PAGE_SIZE) == -1)
        errc(errno, errno, "Unable to umap memory\n");


    return 0;
}

Родительская программа mmap'ит исполняемый файл и легко найти в дочерней int main и вызвать. Пока в int main не обращаются к данным, а содержатся только команды, все естественно выполняется. Как увидеть дочерней программе её сегмент данных. Что означает единственный символ в статическом hello "_Jv_Register_Classes".

Спасибо за любую помощь.


Содержание

Сообщения в этом обсуждении
"Попытка реализовать собственный exec в userspace"
Отправлено Павел Отредиез , 02-Янв-20 20:44 
Результат выполнения дочерней программы без printf (обращения к сегменту данных)

fd an allocated addres 3 77f9ad30000
Hello return 10

То есть вызывается именно int main();

"Попытка реализовать собственный exec в userspace"
Отправлено Павел Отредиез , 02-Янв-20 20:59 
Проще, как добиться чтобы дочерняя напечатала Hello world!?


"Попытка реализовать собственный exec в userspace"
Отправлено ACCA , 02-Янв-20 22:36 
> Проще, как добиться чтобы дочерняя напечатала Hello world!?

Раскомментировать //    printf("Hello world!\n"); ?

Серьёзнее - mmap штука хорошая, но неплохо бы ещё и сегмент стека заиметь.
Да и STDIN с STDOUT как-то передать.

У линухов есть готовый мануал http://www.stratigery.com/userlandexec.html

Для чертей в общих словах тоже объясняют - https://www.netbsd.org/docs/internals/en/chap-processes.html


"Попытка реализовать собственный exec в userspace"
Отправлено Павел Отредиез , 03-Янв-20 11:48 
>> Проще, как добиться чтобы дочерняя напечатала Hello world!?
> Раскомментировать //    printf("Hello world!\n"); ?
> Серьёзнее - mmap штука хорошая, но неплохо бы ещё и сегмент стека
> заиметь.
> Да и STDIN с STDOUT как-то передать.
> У линухов есть готовый мануал http://www.stratigery.com/userlandexec.html
> Для чертей в общих словах тоже объясняют - https://www.netbsd.org/docs/internals/en/chap-processes.html

Большое спасибо за ссылки.



"Попытка реализовать собственный exec в userspace"
Отправлено Аноним , 05-Янв-20 03:52 
> Родительская программа mmap'ит исполняемый файл и легко найти в дочерней int main
> и вызвать. Пока в int main не обращаются к данным, а
> содержатся только команды, все естественно выполняется. Как увидеть дочерней программе
> её сегмент данных.

В OpenBSD последних версий по умолчанию используется PIE, это отчасти жизнь должно упрощать: read-only константы могут жить внутри свободно релоцируемого сегмента кода, и проблемы нет.

Но могут и не жить, плюс Но если я правильно понимаю задачу, вам нужно выполнить работу ld.so и ручками настроить таблицу смещений, да ещё и регистр процессора в нужное (не помню, кто там на amd64 зарезервирован под PIC) значение выставить.

Ну и это, вы сначала используйте PROT_READ|PROT_WRITE, а потом меняйте на PROT_READ|PROT_EXEC. Ну или придётся собирать с флагом компоновщика -z wxneeded, и запускать на ФС с wxallowed. Но лучше всё-таки по-человечески написать код. ;)


"Попытка реализовать собственный exec в userspace"
Отправлено Павел Отредиез , 06-Янв-20 12:42 
>[оверквотинг удален]
> В OpenBSD последних версий по умолчанию используется PIE, это отчасти жизнь должно
> упрощать: read-only константы могут жить внутри свободно релоцируемого сегмента кода,
> и проблемы нет.
> Но могут и не жить, плюс Но если я правильно понимаю задачу,
> вам нужно выполнить работу ld.so и ручками настроить таблицу смещений, да
> ещё и регистр процессора в нужное (не помню, кто там на
> amd64 зарезервирован под PIC) значение выставить.
> Ну и это, вы сначала используйте PROT_READ|PROT_WRITE, а потом меняйте на PROT_READ|PROT_EXEC.
> Ну или придётся собирать с флагом компоновщика -z wxneeded, и запускать
> на ФС с wxallowed. Но лучше всё-таки по-человечески написать код. ;)

Спасибо. Сейчас курю elf.h.



"Попытка реализовать собственный exec в userspace"
Отправлено Павел Отредиез , 24-Янв-20 17:59 
>[оверквотинг удален]
> В OpenBSD последних версий по умолчанию используется PIE, это отчасти жизнь должно
> упрощать: read-only константы могут жить внутри свободно релоцируемого сегмента кода,
> и проблемы нет.
> Но могут и не жить, плюс Но если я правильно понимаю задачу,
> вам нужно выполнить работу ld.so и ручками настроить таблицу смещений, да
> ещё и регистр процессора в нужное (не помню, кто там на
> amd64 зарезервирован под PIC) значение выставить.
> Ну и это, вы сначала используйте PROT_READ|PROT_WRITE, а потом меняйте на PROT_READ|PROT_EXEC.
> Ну или придётся собирать с флагом компоновщика -z wxneeded, и запускать
> на ФС с wxallowed. Но лучше всё-таки по-человечески написать код. ;)

Спасибо за наводки. Вопрос раскурен и реализован. Ответ - надо выполнить все relocations elf файла. При этом формируется и BSS область для программы.