The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]



"Попытка реализовать собственный exec в userspace"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (C/C++)
Изначальное сообщение [ Отслеживать ]

"Попытка реализовать собственный exec в userspace"  +/
Сообщение от Павел Отредиезemail (?), 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".

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

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения [Сортировка по ответам | RSS]

1. Сообщение от Павел Отредиезemail (?), 02-Янв-20, 20:44   +/
Результат выполнения дочерней программы без printf (обращения к сегменту данных)

fd an allocated addres 3 77f9ad30000
Hello return 10

То есть вызывается именно int main();
Ответить | Правка | Наверх | Cообщить модератору
Ответы: #2

2. Сообщение от Павел Отредиезemail (?), 02-Янв-20, 20:59   +/
Проще, как добиться чтобы дочерняя напечатала Hello world!?

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #1 Ответы: #3

3. Сообщение от ACCA (ok), 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

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #2 Ответы: #4

4. Сообщение от Павел Отредиезemail (?), 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

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


Ответить | Правка | Наверх | Cообщить модератору
Родитель: #3

5. Сообщение от Аноним (5), 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. Но лучше всё-таки по-человечески написать код. ;)

Ответить | Правка | Наверх | Cообщить модератору
Ответы: #6, #7

6. Сообщение от Павел Отредиезemail (?), 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.


Ответить | Правка | Наверх | Cообщить модератору
Родитель: #5

7. Сообщение от Павел Отредиезemail (?), 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 область для программы.


Ответить | Правка | Наверх | Cообщить модератору
Родитель: #5


Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру