LINUX.ORG.RU

Из c++ начать выполнять код с определенного адреса

 


1

2

Добрый вечер, подскажите как это сделать, есть у меня допустим на c++ код, в котором я например прочитал инструкции из бинаря. Как мне этот код исполнить? Если я например выделю буфер в сегменте данных то туда jmp я наверное из программы на c++ не сделаю, страница может быть помечена как RW. Код там не привязан к смещения, так что ничего не должно упасть, просто проделает несколько инструкции. И еще в каком сегменте памяти разместить этот буфер, где будет исполняться код? Написал немного сумбурно, подумал и если точнее есть машинные инструкции в файле, нужно во время работы программы их загрузать в адресное пространство процесса и там выполнить.



Последнее исправление: da17 (всего исправлений: 1)

Страницу надо смапить как исполняемую (man mmap, PROT_EXEC). Впрочем, если у тебя ядро 32-битное без PAE и/или старый проц то можно это не делать т.к. там этот флаг не проверяется.

Собственно вызов кода так:

typedef void (*void_func)(void);

....
   ((void_func)0x12345678)();

Сделает CALL 0x12345678

А тебе точно именно jmp нужен? Зачем? Может CALL сойдёт или даже лучше?

JMP можно сделать либо встроенным ассемблером, либо в gcc есть расширение - goto на указатель (но я им не пользовался никогда).

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 4)
Ответ на: комментарий от firkax

Ага, спасибо, кажется это то что мне нужно. CALL тоже подойдет, а можете по коду подскать, void_func это указатель на ф-ию которая принимает void и возвращает указать на void? А потом я делаю вызов ф-ии?

da17
() автор топика
Последнее исправление: da17 (всего исправлений: 1)
Ответ на: комментарий от da17

Да, именно так (точнее нет, возвращает она не указатель на void а сам void, не заметил сначала). Собственно можно и другие прототипы функций использовать, тогда в твой асм код будут передаваться аргументы или забираться из него возвращаемое значение в соответствии с тем как это принято в Си.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 2)

Ну вот тебе пример на коленке.

f.c:

int f(int i) {
  return i + 100500;
}

main.c:

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

typedef int (* _f_int)(int i);

void main(void) {
    int fd;
    struct stat sb;
    _f_int f;

   fd = open("./f.bin", O_RDONLY);
   fstat(fd, &sb);

   f = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0);

   printf("f: %i\n", f(42));
}

Makefile:

all:
	gcc -c f.c
	objcopy -S -O binary --only-section='.text' f.o f.bin
	gcc main.c -o main.bin

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

void_func это указатель на ф-ию которая принимает void и возвращает указать на void?

Указатель на функцию которая ничего не принимает и ничего не возвращает.

anonymous
()