I'm trying to use libelf to edit some things in ELF binaries, but so far I'm unable to even write the binary out without corrupting it. This sample:
#include <libelf.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <assert.h>
#include <gelf.h>
int main() {
elf_version(EV_CURRENT);
int fd = open("elftest", O_RDWR, 0);
assert(fd >= 0);
Elf *elf = elf_begin(fd, ELF_C_RDWR, NULL);
assert(elf != NULL);
assert(elf_kind(elf) == ELF_K_ELF);
assert(elf_update(elf, ELF_C_WRITE) != -1);
elf_end(elf);
close(fd);
}
which should just read in elftest and write it back out unchanged instead converts a working C hello world into a program that segfaults immediately (according to gdb, even before main is called).
The first discrepancy I noticed with readelf -h was that it moved the start of section headers back somewhat, and also reports that
readelf: Warning: the .dynamic section is not contained within the dynamic segment
What is causing libelf to alter the executable even when nothing is actually changed?