resolving relocate function and patching them (successfully done one :D)
This commit is contained in:
parent
42dc535638
commit
81906c271a
|
@ -70,6 +70,7 @@ static std::string encodeId(u64 nVal)
|
||||||
Module* Linker::LoadModule(const std::string& elf_name)
|
Module* Linker::LoadModule(const std::string& elf_name)
|
||||||
{
|
{
|
||||||
auto* m = new Module;
|
auto* m = new Module;
|
||||||
|
m->linker = this;
|
||||||
m->elf = new Elf;
|
m->elf = new Elf;
|
||||||
m->elf->Open(elf_name);//load elf
|
m->elf->Open(elf_name);//load elf
|
||||||
|
|
||||||
|
@ -497,68 +498,78 @@ void Linker::LoadSymbols(Module* m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void relocate(u32 idx, elf_relocation* rel, Module* m, bool isJmpRel)
|
static void relocate(u32 idx, elf_relocation* rel, Module* m, bool isJmpRel) {
|
||||||
{
|
auto type = rel->GetType();
|
||||||
auto type = rel->GetType();
|
auto symbol = rel->GetSymbol();
|
||||||
auto symbol = rel->GetSymbol();
|
auto addend = rel->rel_addend;
|
||||||
auto addend = rel->rel_addend;
|
auto* symbolsTlb = m->dynamic_info->symbol_table;
|
||||||
auto* symbolsTlb = m->dynamic_info->symbol_table;
|
auto* namesTlb = m->dynamic_info->str_table;
|
||||||
auto* namesTlb = m->dynamic_info->str_table;
|
|
||||||
|
|
||||||
u64 rel_value = 0;
|
u64 rel_value = 0;
|
||||||
u64 rel_base_virtual_addr = m->base_virtual_addr;
|
u64 rel_base_virtual_addr = m->base_virtual_addr;
|
||||||
u64 rel_virtual_addr = m->base_virtual_addr + rel->rel_offset;
|
u64 rel_virtual_addr = m->base_virtual_addr + rel->rel_offset;
|
||||||
bool rel_isResolved = false;
|
bool rel_isResolved = false;
|
||||||
u08 rel_sym_type = 0;
|
u08 rel_sym_type = 0;
|
||||||
std::string rel_name;
|
std::string rel_name;
|
||||||
u08 rel_bind_type = -1;//-1 means it didn't resolve
|
u08 rel_bind_type = -1; //-1 means it didn't resolve
|
||||||
|
|
||||||
switch (type)
|
switch (type) {
|
||||||
{
|
case R_X86_64_RELATIVE:
|
||||||
case R_X86_64_RELATIVE:
|
if (symbol != 0) // should be always zero
|
||||||
if (symbol != 0)//should be always zero
|
{
|
||||||
{
|
LOG_INFO_IF(debug_loader, "R_X86_64_RELATIVE symbol not zero = {:#010x}\n", type, symbol);
|
||||||
LOG_INFO_IF(debug_loader, "R_X86_64_RELATIVE symbol not zero = {:#010x}\n", type, symbol);
|
}
|
||||||
}
|
rel_value = rel_base_virtual_addr + addend;
|
||||||
rel_value = rel_base_virtual_addr + addend;
|
rel_isResolved = true;
|
||||||
rel_isResolved = true;
|
break;
|
||||||
break;
|
case R_X86_64_64:
|
||||||
case R_X86_64_64:
|
case R_X86_64_JUMP_SLOT: // similar but addend is not take into account
|
||||||
case R_X86_64_JUMP_SLOT://similar but addend is not take into account
|
{
|
||||||
{
|
auto sym = symbolsTlb[symbol];
|
||||||
auto sym = symbolsTlb[symbol];
|
auto sym_bind = sym.GetBind();
|
||||||
auto sym_bind = sym.GetBind();
|
auto sym_type = sym.GetType();
|
||||||
auto sym_type = sym.GetType();
|
auto sym_visibility = sym.GetVisibility();
|
||||||
auto sym_visibility = sym.GetVisibility();
|
u64 symbol_vitrual_addr = 0;
|
||||||
u64 symbol_vitrual_addr = 0;
|
SymbolRecord symrec{};
|
||||||
switch (sym_type)
|
switch (sym_type) {
|
||||||
{
|
case STT_FUN: rel_sym_type = 2; break;
|
||||||
case STT_FUN: rel_sym_type = 2; break;
|
case STT_OBJECT: rel_sym_type = 1; break;
|
||||||
case STT_OBJECT: rel_sym_type = 1; break;
|
default: LOG_INFO_IF(debug_loader, "unknown symbol type {}\n", sym_type);
|
||||||
default:
|
}
|
||||||
LOG_INFO_IF(debug_loader, "unknown symbol type {}\n",sym_type);
|
if (sym_visibility != 0) // should be zero log if else
|
||||||
}
|
{
|
||||||
if (sym_visibility != 0)//should be zero log if else
|
LOG_INFO_IF(debug_loader, "symbol visilibity !=0\n");
|
||||||
{
|
}
|
||||||
LOG_INFO_IF(debug_loader, "symbol visilibity !=0");
|
switch (sym_bind) {
|
||||||
}
|
case STB_GLOBAL:
|
||||||
switch (sym_bind)
|
|
||||||
{
|
|
||||||
case STB_GLOBAL:
|
|
||||||
rel_bind_type = STB_GLOBAL;
|
rel_bind_type = STB_GLOBAL;
|
||||||
rel_name = namesTlb + sym.st_name;
|
rel_name = namesTlb + sym.st_name;
|
||||||
|
m->linker->Resolve(rel_name, rel_sym_type, m, &symrec);
|
||||||
|
symbol_vitrual_addr = symrec.virtual_address;
|
||||||
|
rel_isResolved = (symbol_vitrual_addr != 0);
|
||||||
|
|
||||||
|
rel_name = symrec.name;
|
||||||
if (type == R_X86_64_JUMP_SLOT) {
|
if (type == R_X86_64_JUMP_SLOT) {
|
||||||
addend = 0;
|
addend = 0;
|
||||||
}
|
}
|
||||||
LOG_INFO_IF(debug_loader, "R_X86_64_64-R_X86_64_JUMP_SLOT sym_type {} bind STB_GLOBAL symbol : {:#010x}\n", sym_type, symbol);
|
rel_value = (rel_isResolved ? symbol_vitrual_addr + addend : 0);
|
||||||
break;
|
if (!rel_isResolved) {
|
||||||
default:
|
LOG_INFO_IF(debug_loader, "R_X86_64_64-R_X86_64_JUMP_SLOT sym_type {} bind STB_GLOBAL symbol : {:#010x}\n", sym_type, symbol);
|
||||||
LOG_INFO_IF(debug_loader, "UNK bind {}\n", sym_bind);
|
}
|
||||||
}
|
break;
|
||||||
}
|
default: LOG_INFO_IF(debug_loader, "UNK bind {}\n", sym_bind);
|
||||||
break;
|
}
|
||||||
default:
|
|
||||||
LOG_INFO_IF(debug_loader, "UNK type {:#010x} rel symbol : {:#010x}\n", type, symbol);
|
} break;
|
||||||
|
default: LOG_INFO_IF(debug_loader, "UNK type {:#010x} rel symbol : {:#010x}\n", type, symbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rel_isResolved) {
|
||||||
|
Memory::VirtualMemory::memory_patch(rel_virtual_addr, rel_value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_INFO_IF(debug_loader, "function not patched!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,3 +586,46 @@ void Linker::Relocate(Module* m)
|
||||||
relocate(idx, rel, m, true);
|
relocate(idx, rel, m, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Linker::Resolve(const std::string& name, int Symtype, Module* m, SymbolRecord* return_info) {
|
||||||
|
auto ids = StringUtil::split(name, '#');
|
||||||
|
|
||||||
|
if (ids.size() == 3) // symbols are 3 parts name , library , module
|
||||||
|
{
|
||||||
|
const auto* library = FindLibrary(*m, ids.at(1));
|
||||||
|
const auto* module = FindModule(*m, ids.at(2));
|
||||||
|
|
||||||
|
if (library != nullptr && module != nullptr) {
|
||||||
|
SymbolRes sr{};
|
||||||
|
sr.name = ids.at(0);
|
||||||
|
sr.library = library->name;
|
||||||
|
sr.library_version = library->version;
|
||||||
|
sr.module = module->name;
|
||||||
|
sr.module_version_major = module->version_major;
|
||||||
|
sr.module_version_minor = module->version_minor;
|
||||||
|
sr.type = Symtype;
|
||||||
|
|
||||||
|
const SymbolRecord* rec = nullptr;
|
||||||
|
|
||||||
|
if (m_HLEsymbols != nullptr) {
|
||||||
|
rec = m_HLEsymbols->FindSymbol(sr);
|
||||||
|
}
|
||||||
|
if (rec != nullptr) {
|
||||||
|
*return_info = *rec;
|
||||||
|
} else {
|
||||||
|
return_info->virtual_address = 0;
|
||||||
|
return_info->name = "Unresolved!!!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
__debugbreak();//den tha prepei na ftasoume edo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
__debugbreak();//oute edo mallon
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
#include "Loader/SymbolsResolver.h"
|
#include "Loader/SymbolsResolver.h"
|
||||||
|
|
||||||
struct DynamicModuleInfo;
|
struct DynamicModuleInfo;
|
||||||
|
class Linker;
|
||||||
|
|
||||||
/*this struct keeps neccesary info about loaded modules.Main executeable is included too as well*/
|
/*this struct keeps neccesary info about loaded modules.Main executeable is included too as well*/
|
||||||
struct Module
|
struct Module
|
||||||
|
@ -13,6 +14,8 @@ struct Module
|
||||||
u64 aligned_base_size = 0;
|
u64 aligned_base_size = 0;
|
||||||
u64 base_virtual_addr = 0; //base virtual address
|
u64 base_virtual_addr = 0; //base virtual address
|
||||||
|
|
||||||
|
Linker* linker = nullptr;
|
||||||
|
|
||||||
void* m_dynamic = nullptr;
|
void* m_dynamic = nullptr;
|
||||||
void* m_dynamic_data = nullptr;
|
void* m_dynamic_data = nullptr;
|
||||||
DynamicModuleInfo* dynamic_info = nullptr;
|
DynamicModuleInfo* dynamic_info = nullptr;
|
||||||
|
@ -111,6 +114,7 @@ public:
|
||||||
void LoadSymbols(Module* m);
|
void LoadSymbols(Module* m);
|
||||||
SymbolsResolver* getHLESymbols() { return m_HLEsymbols; }
|
SymbolsResolver* getHLESymbols() { return m_HLEsymbols; }
|
||||||
void Relocate(Module* m);
|
void Relocate(Module* m);
|
||||||
|
void Resolve(const std::string& name, int Symtype, Module* m, SymbolRecord* return_info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const ModuleInfo* FindModule(const Module& m, const std::string& id);
|
const ModuleInfo* FindModule(const Module& m, const std::string& id);
|
||||||
|
|
|
@ -5,9 +5,26 @@
|
||||||
void SymbolsResolver::AddSymbol(const SymbolRes& s, u64 virtual_addr)
|
void SymbolsResolver::AddSymbol(const SymbolRes& s, u64 virtual_addr)
|
||||||
{
|
{
|
||||||
SymbolRecord r{};
|
SymbolRecord r{};
|
||||||
char str[256];
|
r.name = GenerateName(s);
|
||||||
sprintf(str, "%s (%s)[%s_v%d][%s_v%d.%d]", s.name.c_str(),s.nidName.c_str(), s.library.c_str(), s.library_version, s.module.c_str(),s.module_version_major, s.module_version_minor);
|
|
||||||
r.name = std::string(str);
|
|
||||||
r.virtual_address = virtual_addr;
|
r.virtual_address = virtual_addr;
|
||||||
m_symbols.push_back(r);
|
m_symbols.push_back(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string SymbolsResolver::GenerateName(const SymbolRes& s) {
|
||||||
|
char str[256];
|
||||||
|
sprintf(str, "%s lib[%s_v%d]mod[%s_v%d.%d]", s.name.c_str(),s.library.c_str(), s.library_version, s.module.c_str(),
|
||||||
|
s.module_version_major, s.module_version_minor);
|
||||||
|
return std::string(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SymbolRecord* SymbolsResolver::FindSymbol(const SymbolRes& s) const {
|
||||||
|
std::string name = GenerateName(s);
|
||||||
|
int index = 0;
|
||||||
|
for (auto symbol : m_symbols) {
|
||||||
|
if (symbol.name.compare(name) == 0) {
|
||||||
|
return &m_symbols.at(index);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
|
@ -31,6 +31,9 @@ public:
|
||||||
virtual ~SymbolsResolver() = default;
|
virtual ~SymbolsResolver() = default;
|
||||||
|
|
||||||
void AddSymbol(const SymbolRes& s, u64 virtual_addr);
|
void AddSymbol(const SymbolRes& s, u64 virtual_addr);
|
||||||
|
const SymbolRecord* FindSymbol(const SymbolRes& s) const;
|
||||||
|
|
||||||
|
static std::string GenerateName(const SymbolRes& s);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<SymbolRecord> m_symbols;
|
std::vector<SymbolRecord> m_symbols;
|
||||||
|
|
Loading…
Reference in New Issue