Long story short, I have an array of integers that represents the .text section of an ELF binary with one function. I want to execute this function. I have run this command prior to trying to execute the command:
mprotect(function, sHeader.sh_size, PROT_EXEC | PROT_READ | PROT_WRITE);
thinking that it might resolve permission issues, but it still segfaults when i try to run it:
int (*fp)(int, int) = (int (*)(int, int))getFunc("t.o");
int a = 2;
int b = 3;
cout << fp(a, b) << "\n";
but it still segfaults when i try to run it:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000603010 in ?? ()
is there anything I missed?
objdump of the function i’m trying to execute:
0000000000000000 <mult>:
mult():
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 89 7d fc mov %edi,-0x4(%rbp)
7: 89 75 f8 mov %esi,-0x8(%rbp)
a: 8b 45 fc mov -0x4(%rbp),%eax
d: 0f af 45 f8 imul -0x8(%rbp),%eax
11: 5d pop %rbp
12: c3 retq
An ELF object file contains relocation information, and very probably its
.textsection contains code to be relocated, so that code won’t run as is. Use theobjdumpandreadelfcommands to explore it. If you really want to load it the way you do, you should process the relocation information, which is complex, processor specific, and tedious. If you really want to spend weeks doing this, study the x86-64 ABI. But usingdlopenof a.sothendlsymis much simpler (becausedlopenis doing the relocation after havingmmap-ed segments fromt.so), see below.The x86-64 ABI used to be on http://x86-64.org/documentation/abi.pdf but that site don’t work today
What is
getFunc? How do you do relocation inside yourt.o? Why can’t you have at.soshared object (e.g. compiled withgcc -Wall -fPIC -O -shared t.c -o t.so) then load it using dlopen(3) anddlsym(3)e.g.Once the
fpreturned and no call stack frames exist using any function int.soyou candlclose(dlh);which wouldmunmapthe segments fromt.so. You could avoid callingdlclose(that would usually make an insignificant leak of process address space; see the file/proc/1234/mapsfor process of pid 1234), especially if you don’tdlopena big lot of shared objects.If the
t.soplugin calls functions from your main program, you want that main program to be linked with the-rdynamicoption toldorgccIf
t.sohas been compiled from some C++ source, it should declarebecause of name mangling done by
g++My manydl.c program shows that you can do many hundreds of thousands of
dlopen-s in a Linux process. It works by generating “random” C code, compiling it into some.so, anddlopen-ing that.sofile, then repeating that many times.If you don’t want the burden of compiling a
.cor.cccode into a.soplugin, you could consider in-memory just-in-time code generation using LLVM, asmjit, libjit, GNU lightning etc…