Skip to content

Instantly share code, notes, and snippets.

@atejeda
Forked from x-projs/mkexeloadable.c
Created June 10, 2020 22:22
Show Gist options
  • Select an option

  • Save atejeda/3d6ca5fba255bfa5731f92e591ceec42 to your computer and use it in GitHub Desktop.

Select an option

Save atejeda/3d6ca5fba255bfa5731f92e591ceec42 to your computer and use it in GitHub Desktop.
Make the executable file can be loaded by dlopen() after glibc>=2.30.
/* There is a behavior change in glibc>=2.30. dlopen() will fail if the file is position independent executable.
This tool will clean up the PIE flag in the file to bypass the dlopen() check.
*/
#include <stdio.h>
#include <string.h>
#include <elf.h>
#define EXEC(x, err_msg) \
if (!(x)) { \
perror(err_msg); \
err = -1; \
goto ex; \
}
int main(int argc, char* argv[]) {
int err = 0;
if (argc != 2) {
printf("Usage: mkexeloadable <executable-elf64-file>\n");
return -1;
}
FILE* fp = fopen(argv[1], "r+b");
EXEC(fp != NULL, "Can't open file");
// Read elf header.
Elf64_Ehdr elf_header;
EXEC(fread(&elf_header, sizeof(elf_header), 1, fp) == 1, "Read elf64_ehdr failed");
// Is it a elf64 file?
EXEC(strncmp((char*)elf_header.e_ident, "\177ELF\002", 5) == 0, "It is not a valid elf64 file");
// Find out dynamic section
Elf64_Shdr section_header;
Elf64_Dyn dyn;
EXEC(fseek(fp, elf_header.e_shoff, SEEK_SET) == 0, "Seek file failed");
for (int i = 0; i < elf_header.e_shnum; ++i) {
EXEC(fread(&section_header, elf_header.e_shentsize, 1, fp) == 1, "Read section header failed");
if (section_header.sh_type == SHT_DYNAMIC) {
EXEC(fseek(fp, section_header.sh_offset, SEEK_SET) == 0, "Seek file failed");
while (1) {
EXEC(fread(&dyn, sizeof(Elf64_Dyn), 1, fp) == 1, "Read section entry failed");
EXEC(dyn.d_tag != 0, "Can't find flags_1");
if (dyn.d_tag == 0x6ffffffb) {
// Clear PIE flag.
dyn.d_un.d_val &= ~DF_1_PIE;
EXEC(fseek(fp, -sizeof(Elf64_Dyn), SEEK_CUR) == 0, "Seek flags_1 failed");
EXEC(fwrite(&dyn, sizeof(Elf64_Dyn), 1, fp) == 1, "Write back flags_1 failed");
// Success!
goto ex;
}
}
}
}
// Can't find required flags, something might be wrong.
EXEC(0, "Can't find required flags");
ex:
if (fp) {
fclose(fp);
}
return err;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment