Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifying static byte array in a compiled ELF executable [closed]

Tags:

c

elf

I have a scenario where i wan't to provide a utility for my users to create a compressed self-extracting executable (similar to UPX but with other properties).

This is currently done by compressing an executable and then generating c source code containing a byte array containing the executable:

#include "exdata.c"

exdata.c:

const unsigned char compressedData[] = { 0x28,0xB5... }
const size_t uncompressedSize =  3697664;

The problem is that i want to be able to change this byte array without recompiling the program to enable my users to use the utility without require them to install a c compiler.

Can i use a "placeholder" byte array, find that value in the compiled binary and replace it with the real data? Or can i somehow add the data to a custom "segment" and just modify that?

Edit: I found a python library called lief that seem to be able to modify segment content but modifying a segment with more data than what’s already there seems very complicated as all other segments and addresses + offsets needs to be handled

like image 916
Richard Avatar asked Jul 13 '26 08:07

Richard


1 Answers

I think gcc and objcopy can solve a lot of your problem:

  • Put the default compressed image in its own section using gcc's __attribute__ extension

  • Make a file with the user's compressed image.

  • a user script runs objcopy to replace your section with the user's file

$ more replaceable_contents.c 
#include <stdio.h>

struct {
    unsigned char sz;
    const char data[];
} datablob __attribute__((section("COMPRESSEDDATA"))) = {12, "Hello World!"};

int global_counter = 0;


int main(int argc, const char* argv[]) {

    for (int i;i<argc;i++) {
        printf("printing %d characters: ", datablob.sz);
        printf("%.*s\n", datablob.sz, datablob.data);
    }
}

$ gcc replaceable_contents.c && ./a.out 2
printing 12 characters: Hello World!
printing 12 characters: Hello World!

$ more text.txt
2This is a test of the emergency compression system

$ objcopy --update-section COMPRESSEDDATA=text.txt a.out a2.out
objcopy: a2.out: section .bss lma 0x201020 adjusted to 0x201044

$ ./a2.out 2
printing 50 characters: This is a test of the emergency compression system
printing 50 characters: This is a test of the emergency compression system
like image 109
AShelly Avatar answered Jul 17 '26 15:07

AShelly