elf64 実行可能ファイル foo を「手動で」ロードして開始し、そこから他の関数を呼び出せるようにしたいと考えています。それをメモリにロードし、それを実行するように命令ポインタを設定するにはどうすればよいですか。
foo は共有オブジェクト ライブラリではなく、SO であるかのようにエクスポートされた特定の関数を持つ実行可能ファイルです。
それで、いくつか質問があります:
- バイナリをメモリにロードして実行可能にする場所は? スタック?ヒープ?
- プログラムから foo のエントリ ポイントに変更する命令ポインタを設定するにはどうすればよいですか?
たとえば、次のものがありますが、セグメンテーション違反になります:
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <elf.h>
#define ELF_SIZE 10000
int main(int argc, char **argv)
{
FILE *fp;
void * entry_point ;
Elf64_Ehdr *elfHdr;
uint8_t *buffer = malloc(ELF_SIZE);
fp = fopen("./foo", "rb");
int read_size = fread(buffer, 1, ELF_SIZE, fp);
if (read_size == ELF_SIZE)
{
printf("loaded ELF onto heap
\n");
} else
{
printf("read failed: %d\n", read_size);
return 0;
}
printf("elf loaded at %x\n", buffer);
elfHdr = (Elf64_Ehdr*) buffer;
printf("entry point at %x\n", elfHdr->e_entry);
entry_point = elfHdr->e_entry + buffer;
printf("trying to jump to: %x\n", entry_point
);
int a;
__asm__ ("jmp %1;"
: "=r" (a)
: "r" (entry_point));
return 0;
}
通常の方法を使用して foo() を起動するのに system() やその他の標準 OS ツールを使用することは、さまざまな理由からオプションではありません。_start を呼び出して開始し、実行が開始されたら "foo_bar()" を呼び出せるようにする必要があります。dlopen/dlsym を使用してみましたが、共有ライブラリではなく実行可能ファイルであるため、機能しません。