You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
codm/ligma/ligma-bypass/hooks/got_hook.h

46 lines
1.7 KiB

#include <elf.h>
#include <cstdint>
#include <dlfcn.h>
#include <map>
#include <android/log.h>
#define LOGI(...) ((void)__android_log_print(4, "ligma", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(5, "ligma", __VA_ARGS__))
namespace ligma
{
namespace hook
{
//
// TODO this doesnt work yet, needs to be debugged!
//
inline void* got_hook(elf32_hdr* module_base, const std::pair<const char*, const char*>& module_info, void* new_ptr)
{
if (!module_base || !module_info.first || !module_info.second || !new_ptr)
return {};
const auto orig_module_base = dlopen(module_info.first, RTLD_NOW);
const auto orig_ptr = dlsym(orig_module_base, module_info.second);
const auto shstrtab_header_offset = module_base->e_shoff + module_base->e_shstrndx * sizeof(elf32_shdr);
const auto shstr_header = reinterpret_cast<elf32_shdr*>(reinterpret_cast<std::uintptr_t>(module_base) + shstrtab_header_offset);
const auto shstr_section = reinterpret_cast<const char*>(module_base) + shstr_header->sh_offset;
auto section_header = reinterpret_cast<elf32_shdr*>(reinterpret_cast<std::uintptr_t>(module_base) + module_base->e_shoff);
for (auto idx = 0u; idx < module_base->e_shnum; ++idx)
{
if (strcmp(shstr_section + section_header->sh_name, ".got"))
{
for (auto section_value = reinterpret_cast<std::uintptr_t>(module_base) + section_header->sh_offset;
section_value < reinterpret_cast<std::uintptr_t>(module_base) + section_header->sh_size; section_value += 0x8)
if (*reinterpret_cast<void**>(section_value) == orig_ptr)
*reinterpret_cast<void**>(section_value) = new_ptr;
break;
}
section_header++;
}
return orig_ptr;
}
}
}