-
Notifications
You must be signed in to change notification settings - Fork 0
/
elffile.c
59 lines (53 loc) · 1.64 KB
/
elffile.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <elf.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "elffile.h"
elffile_t *elffile_open(char *path){
int fd = open(path, 0);
struct stat stat;
fstat(fd, &stat);
elffile_t *ef = malloc(sizeof(elffile_t));
ef->size = stat.st_size;
ef->buffer = malloc(ef->size);
read(fd, ef->buffer, ef->size);
close(fd);
ef->hdr = (void *)ef->buffer;
ef->phdrs = (void *)&ef->buffer[ef->hdr->e_phoff];
return ef;
}
char *elffile_locate(elffile_t *ef, uintptr_t address){
for(int i = 0; i < ef->hdr->e_phnum; i++){
if(ef->phdrs[i].p_type == PT_LOAD){
if(ef->phdrs[i].p_vaddr <= address &&
address < ef->phdrs[i].p_vaddr + ef->phdrs[i].p_filesz){
size_t offset = ef->phdrs[i].p_offset + (address - ef->phdrs[i].p_vaddr);
return &ef->buffer[offset];
}
}
}
return NULL;
}
void elffile_memcpy(elffile_t *ef, uintptr_t address, char *from, size_t size){
char *buffer = elffile_locate(ef, address);
memcpy(buffer, from, size);
}
void elffile_write(elffile_t *ef, char *path){
uint32_t max_offset = 0xffffffff;
for(int i = 0; i < ef->hdr->e_phnum; i++){
if(ef->phdrs[i].p_type == PT_LOAD){
max_offset = ef->phdrs[i].p_offset + ef->phdrs[i].p_filesz;
}
}
ef->size = max_offset;
ef->hdr->e_shnum = 0;
ef->hdr->e_shoff = 0;
ef->hdr->e_shstrndx = 0;
int fd = open("tmp", O_CREAT | O_TRUNC | O_RDWR, 0777);
write(fd, ef->buffer, ef->size);
rename("tmp", path);
}