drafting the got/plt changes
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#include "types.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <elf.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <gelf.h>
|
||||
@@ -138,8 +139,9 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HiloadResult moduler_apply_module_patch(const char *module_name, const char *patch_name,
|
||||
struct sc_array_memreg *memregs) {
|
||||
static HiloadResult
|
||||
moduler_apply_module_patch(const char *module_name, const char *patch_name,
|
||||
struct sc_array_memreg *memregs) {
|
||||
|
||||
MemoryRegionSpan patch_memory = memory_get_module_span(memregs, patch_name);
|
||||
void *patch_base = (void *)patch_memory.region_start;
|
||||
@@ -157,13 +159,97 @@ static HiloadResult moduler_apply_module_patch(const char *module_name, const ch
|
||||
void *module_base = (void *)module_memory.region_start;
|
||||
size_t module_size = module_memory.region_end - module_memory.region_start;
|
||||
|
||||
ElfW(Rela) *rela = NULL;
|
||||
ElfW(Sym) *symtab = NULL;
|
||||
char *strtab = NULL;
|
||||
size_t rela_size = 0;
|
||||
|
||||
Elf *elf = NULL;
|
||||
GElf_Phdr *dyn_sct = hi_elf_find_dynamic_segment(module_base, module_size, &elf);
|
||||
(void)dyn_sct;
|
||||
// TODO: cont
|
||||
ElfW(Dyn) *dyn_sct =
|
||||
hi_elf_find_dynamic_segment(module_base, module_size, &elf);
|
||||
for (ElfW(Dyn) *d = dyn_sct; d->d_tag != DT_NULL; d++) {
|
||||
switch (d->d_tag) {
|
||||
case DT_JMPREL:
|
||||
rela = (ElfW(Rela) *)d->d_un.d_ptr;
|
||||
break;
|
||||
case DT_PLTRELSZ:
|
||||
rela_size = d->d_un.d_val;
|
||||
break;
|
||||
case DT_SYMTAB:
|
||||
symtab = (ElfW(Sym)*)d->d_un.d_ptr;
|
||||
break;
|
||||
case DT_STRTAB:
|
||||
strtab = (char *)d->d_un.d_ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust relative pointers by adding the module base address
|
||||
if (rela && ((void *)rela < module_base ||
|
||||
(void *)rela >= (void *)((char *)module_base + module_size))) {
|
||||
rela = (ElfW(Rela) *)((char *)module_base + (uintptr_t)rela);
|
||||
}
|
||||
|
||||
if (symtab &&
|
||||
((void *)symtab < module_base ||
|
||||
(void *)symtab >= (void *)((char *)module_base + module_size))) {
|
||||
symtab = (ElfW(Sym) *)((char *)module_base + (uintptr_t)symtab);
|
||||
}
|
||||
|
||||
if (strtab &&
|
||||
((void *)strtab < module_base ||
|
||||
(void *)strtab >= (void *)((char *)module_base + module_size))) {
|
||||
strtab = (char *)module_base + (uintptr_t)strtab;
|
||||
}
|
||||
|
||||
if (!rela || !symtab || !strtab || rela_size == 0) {
|
||||
log_error("Missing required dynamic information\n");
|
||||
elf_end(elf);
|
||||
return HILOAD_FAIL;
|
||||
}
|
||||
|
||||
|
||||
// Process relocations to find GOT entries
|
||||
int found_count = 0;
|
||||
size_t rela_count = rela_size / sizeof(ElfW(Rela));
|
||||
|
||||
printf("Processing %zu relocations\n", rela_count);
|
||||
|
||||
size_t num_symbols = 0;
|
||||
for (size_t i = 0; i < rela_count; i++) {
|
||||
ElfW(Rela)* r = &rela[i];
|
||||
int sym_idx = ElfW(R_SYM)(r->r_info);
|
||||
int rel_type = ElfW(R_TYPE)(r->r_info);
|
||||
|
||||
// We're only interested in JMP_SLOT relocations (GOT entries for functions)
|
||||
if (rel_type != R_X86_64_JUMP_SLOT && rel_type != R_386_JMP_SLOT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ElfW(Sym)* sym = &symtab[sym_idx];
|
||||
char* name = strtab + sym->st_name;
|
||||
|
||||
/* // Calculate the GOT entry address */
|
||||
/* void** got_entry = (void**)((char*)module_base + r->r_offset); */
|
||||
|
||||
/* // Check if this is a symbol we want to patch */
|
||||
/* for (int j = 0; j < num_symbols; j++) { */
|
||||
/* if (strcmp(symbols[j].name, name) == 0) { */
|
||||
/* symbols[j].got_entry = got_entry; */
|
||||
/* symbols[j].orig_addr = *got_entry; // Save the original function pointer */
|
||||
|
||||
/* printf("Found GOT entry for '%s' at %p (points to %p)\n", */
|
||||
/* name, got_entry, *got_entry); */
|
||||
|
||||
/* found_count++; */
|
||||
/* break; */
|
||||
/* } */
|
||||
/* } */
|
||||
}
|
||||
|
||||
symbol_term_symbols(&symbols);
|
||||
|
||||
elf_end(elf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ typedef struct HiSymbol {
|
||||
HiSymbolBind binding;
|
||||
HiSymbolType type;
|
||||
void *address;
|
||||
void **got_entry;
|
||||
void *orig_address;
|
||||
} HiSymbol;
|
||||
sc_array_def(HiSymbol, sym);
|
||||
typedef struct sc_array_sym HiSymbols;
|
||||
|
||||
Reference in New Issue
Block a user