Skip to content

Instantly share code, notes, and snippets.

@fwsGonzo
Created September 27, 2020 10:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fwsGonzo/e3dbcd9097953e7e113fd3f3ada04316 to your computer and use it in GitHub Desktop.
Save fwsGonzo/e3dbcd9097953e7e113fd3f3ada04316 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <elf.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#define ELF_EHDR Elf64_Ehdr
#define ELF_PHDR Elf64_Phdr
/* Change the permissions on a segment */
int main(int argc, char *argv[])
{
char *sInFile;
unsigned long ulPerm = 0;
int iSegNo, iInFd, i;
char *pcFileAddr;
struct stat tStatBuf;
off_t tMapSize;
ELF_EHDR *ptElfHdr;
ELF_PHDR *ptElfPHdr;
char sElfMagic[] = "\x7f" "ELF";
if (argc != 4) {
fprintf(stderr,
"Usage: %s <file> <segment no> <segment permissions (e.g rwx)>\n",
argv[0]);
exit(1);
}
i = 0;
while (argv[3][i]) {
switch(argv[3][i]) {
case 'x':
ulPerm |= PF_X; break;
case 'r':
ulPerm |= PF_R; break;
case 'w':
ulPerm |= PF_W; break;
}
i++;
}
sInFile = argv[1];
iSegNo = atoi(argv[2]);
if (-1 == (iInFd = open(sInFile, O_RDWR))) {
fprintf(stderr, "Could not open %s, %d %s\n", sInFile, errno, strerror(errno));
exit(-1);
}
if (fstat(iInFd, &tStatBuf)) {
fprintf(stderr, "Could not stat %s, %d %s\n", sInFile, errno, strerror(errno));
exit(-1);
}
tMapSize = tStatBuf.st_size;
if (!(pcFileAddr = mmap(0, tMapSize, PROT_READ | PROT_WRITE, MAP_SHARED, iInFd, 0))) { fprintf(stderr, "Could not mmap %s, %d %s\n", sInFile, errno, strerror(errno));
exit(-1);
}
printf("File %s mapped at %p for %lu bytes\n", sInFile, pcFileAddr, tMapSize);
ptElfHdr = (ELF_EHDR *) pcFileAddr;
if (memcmp(&(ptElfHdr->e_ident), sElfMagic, sizeof(sElfMagic) - 1)) {
fprintf(stderr, "File %s does not appear to be an ELF file\n", sInFile);
exit(-1);
}
/* Does this file have the segment they requested? */
if ((iSegNo < 0) || (iSegNo >= ptElfHdr->e_phnum)) {
printf("Segment %d does not exist in the executable\n", iSegNo);
exit(-1);
}
/* Get the segment header for the specified segment */
ptElfPHdr = (ELF_PHDR *) ((char *) pcFileAddr + ptElfHdr->e_phoff +
(ptElfHdr->e_phentsize * iSegNo));
/* Set the permissions as specified */
ptElfPHdr->p_flags = ulPerm;
munmap(pcFileAddr, tMapSize);
close(iInFd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment