resolving relocate function and patching them (successfully done one :D)

This commit is contained in:
georgemoralis 2023-07-11 18:50:29 +03:00
parent 42dc535638
commit 81906c271a
4 changed files with 137 additions and 59 deletions

View File

@ -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,8 +498,7 @@ 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;
@ -511,12 +511,11 @@ static void relocate(u32 idx, elf_relocation* rel, Module* m, bool isJmpRel)
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);
} }
@ -524,41 +523,53 @@ static void relocate(u32 idx, elf_relocation* rel, Module* m, bool isJmpRel)
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;
switch (sym_type) SymbolRecord symrec{};
{ 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: default: LOG_INFO_IF(debug_loader, "unknown symbol type {}\n", sym_type);
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"); LOG_INFO_IF(debug_loader, "symbol visilibity !=0\n");
} }
switch (sym_bind) switch (sym_bind) {
{
case STB_GLOBAL: 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;
} }
rel_value = (rel_isResolved ? symbol_vitrual_addr + addend : 0);
if (!rel_isResolved) {
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, "R_X86_64_64-R_X86_64_JUMP_SLOT sym_type {} bind STB_GLOBAL symbol : {:#010x}\n", sym_type, symbol);
break;
default:
LOG_INFO_IF(debug_loader, "UNK bind {}\n", sym_bind);
}
} }
break; break;
default: default: LOG_INFO_IF(debug_loader, "UNK bind {}\n", sym_bind);
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
}
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;