Skip to content
Advertisement

Execute binary file inside C code (No system())

I am trying to execute a binary executable file inside C code without using system since it has security and resource management issues.

The system used here is Debian Buster with kernel 5.4.0-2-amd64 and gcc 9.2.1.

I used the method in this question: execute binary machine code from C

which is to convert executable into hexadecimal code with xxd -i, but constantly get Segmentation fault.

The procedures I used are:

First attempt

executable.c:

#include <stdio.h>
int main(void)
{
    printf("Hello, World!n");
    return 0;
}

after compiling it with gcc -o executable executable.c

xxd -i executable will display binary file into hex

Then copy and paste the output to embedded.c

embedded.c:

#include <string.h>
#include <unistd.h>
#include <sys/mman.h>

const unsigned char[] executable = {
    0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01,
    ...
};

int main(void)
{
    void *buf = mmap(
        NULL, sizeof(executable), PROT_READ | PROT_WRITE | PROT_EXEC,
        MAP_PRIVATE | MAP_ANON, -1, 0);
    memcpy(buf, sizeof(executable);
    __builtin___clear_cache(buf, buf + sizeof(executable) - 1);

    int i = ((int (*) (void)buf)();
    return 0;
}

when compiled and run, the terminal displays Segmentation fault.

Second attempt

Another method I tried is by using ld which also displayed Segmentation fault:

embedded.c:

extern const char _binary_executable_start[];
extern const char _binary_executable_end[];

// And same as the previous code.

The code was compiled using:

gcc -c -o embedded.o embedded.c

ld -r -b binary -o executable.o executable

gcc -o embedded embedded.o executable.o

And failed.

Is there anything I missed or is it impossible to embed binary file into C code and run it?

Advertisement

Answer

The executable content you’re providing is an ELF executable, not raw machine code. On Linux, ELF is the container format that is used to contain executables and shared libraries, and it wraps the actual executable code and associated data, like strings and arrays, with a format that allows it to be loaded easily.

As a result, the code you’re trying to execute isn’t actually machine code, it’s ELF header data. Even if you extract the executable code out of the ELF, it generally still needs to be relocated by the dynamic linker, so it won’t easily be able to be executed directly.

Instead, consider putting the additional code into a shared library and executing it there. If you need to load the code dynamically, you can use the dlopen(3) function to load a shared library and dlsym(3) to find the function you want to execute, provided you link with -ldl.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement