From 08de37f245e3544522406f988a683a3388e6afe0 Mon Sep 17 00:00:00 2001 From: Kasper Date: Wed, 23 Apr 2025 09:35:17 +0300 Subject: [PATCH] drafting the got/plt changes --- src/moduler/moduler.c | 96 ++++++++++++++++++++++++++++++++++++++++--- src/symbols.h | 2 + 2 files changed, 93 insertions(+), 5 deletions(-) diff --git a/src/moduler/moduler.c b/src/moduler/moduler.c index 80a7436..a0dbc7f 100644 --- a/src/moduler/moduler.c +++ b/src/moduler/moduler.c @@ -9,6 +9,7 @@ #include "types.h" #include +#include #include #include #include @@ -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; } diff --git a/src/symbols.h b/src/symbols.h index 1d308e6..93c0484 100644 --- a/src/symbols.h +++ b/src/symbols.h @@ -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;