The OpenNET Project / Index page

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




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
Попытка реализовать собственный 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, !*! Павел Отредиез, 20:44 , 02-Янв-20 (1)
    Результат выполнения дочерней программы без printf (обращения к сегменту данных)

    fd an allocated addres 3 77f9ad30000
    Hello return 10

    То есть вызывается именно int main();
  • Попытка реализовать собственный exec в userspace, !*! Аноним, 03:52 , 05-Янв-20 (5)
    > Родительская программа 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, !*! Павел Отредиез, 12:42 , 06-Янв-20 (6)
      >[оверквотинг удален]
      > В OpenBSD последних версий по умолчанию используется PIE, это отчасти жизнь должно
      > упрощать: read-only константы могут жить внутри свободно релоцируемого сегмента кода,
      > и проблемы нет.
      > Но могут и не жить, плюс Но если я правильно понимаю задачу,
      > вам нужно выполнить работу ld.so и ручками настроить таблицу смещений, да
      > ещё и регистр процессора в нужное (не помню, кто там на
      > amd64 зарезервирован под PIC) значение выставить.
      > Ну и это, вы сначала используйте PROT_READ|PROT_WRITE, а потом меняйте на PROT_READ|PROT_EXEC.
      > Ну или придётся собирать с флагом компоновщика -z wxneeded, и запускать
      > на ФС с wxallowed. Но лучше всё-таки по-человечески написать код. ;)

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


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

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





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

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