Встроенная сборка GCC в виде двоичного массива - PullRequest
0 голосов
/ 26 июня 2018

Есть ли способ в GCC представить встроенный __asm__ как char[] массив? Я хочу что-то вроде:

void my_func();

char my_code[] = {
    __asm__("callq %0" :: "r" (my_func))
};

Позже my_code будет использоваться как исправление во время выполнения, т.е.

void another_function();
mprotect(another_function, getpagesize(), PROT_WRITE | PROT_READ | PROT_EXEC);
memcpy(another_function + offset, my_code, sizeof(my_code));

Есть идеи?

1 Ответ

0 голосов
/ 26 июня 2018

Вы можете просто определить функцию, скомпилировать ее, а затем получить ее исходный машинный код?

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>

void my_func(void) {}

extern void my_code(void);
extern void my_code_end(void);

__attribute__((__used__)) static void _my_code(void) {
        asm volatile(
                ".globl my_code\n"
                "my_code:\n"
                "  callq *%0\n"
                "  nop\n"
                "  ret\n"
                ".globl my_code_end\n"
                "my_code_end:\n"
                :: "r" (my_func)
        );
}

int main() {
        size_t my_code_len = (uintptr_t)my_code_end - (uintptr_t)my_code;
        const unsigned char *arr = (const char*)my_code;
        printf("my_code[%zu]=", my_code_len);
        for (size_t i = 0; i < my_code_len; ++i) {
                printf("%02x", arr[i]);
        }
        printf("\n");
        return 0;
}

Пример вывода:

my_code[4]=ffd090c3

Мы можем проверить, что все в порядке с вывода сборки:

$ objdump -D ./a.out
...
0000000000000727 <my_code>:
 727:   ff d0                   callq  *%rax
 729:   90                      nop
 72a:   c3                      retq   
...
...