diff --git a/libIRDB/include/core/fileir.hpp b/libIRDB/include/core/fileir.hpp index d5c8b5f181f81c095f1bd17b93a9fb8173186d28..3f8e250b2439101df6dd225ac809714cb66288c2 100644 --- a/libIRDB/include/core/fileir.hpp +++ b/libIRDB/include/core/fileir.hpp @@ -37,7 +37,7 @@ class FileIR_t : public BaseObj_t void AssembleRegistry(); void RegisterAssembly(Instruction_t *instr, std::string assembly); void UnregisterAssembly(Instruction_t *instr); - std::string LookupAssembly(Instruction_t *instr); + std::string LookupAssembly(Instruction_t *instr); //Needed for inserting assembly before an instruction. //if orig is not registered, the function returns, otherwise @@ -46,7 +46,13 @@ class FileIR_t : public BaseObj_t //removes the mapping for orig->assembly from the map. void ChangeRegistryKey(Instruction_t* orig, Instruction_t* updated); + static int GetArchitectureBitWidth(); + void SetArchitecture(); + private: + + static ArchitectureDescription_t *archdesc; + #define ASM_REG_MAX_SIZE 500000 typedef std::map<Instruction_t*,std::string> registry_type; diff --git a/libIRDB/include/libIRDB-core.hpp b/libIRDB/include/libIRDB-core.hpp index 05064f88cc9d610cdfa6ef5bec70a54d9f433300..2cbded135a4702257660d7e92d1634a92a0caadb 100644 --- a/libIRDB/include/libIRDB-core.hpp +++ b/libIRDB/include/libIRDB-core.hpp @@ -26,6 +26,7 @@ class Instruction_t; // forward decl for many classes #include <core/file.hpp> #include <core/function.hpp> #include <core/variantid.hpp> +#include <core/archdesc.hpp> #include <core/fileir.hpp> #include <core/pqxxdb.hpp> diff --git a/libIRDB/src/core/fileir.cpp b/libIRDB/src/core/fileir.cpp index 523d6a97f006a6b523046ca8f9f25ca7efb0d56a..9535dcdef7bcdf4c1aaf1253e7b2bb33600b0941 100644 --- a/libIRDB/src/core/fileir.cpp +++ b/libIRDB/src/core/fileir.cpp @@ -4,6 +4,7 @@ #include <cstdlib> #include <map> #include <fstream> +#include <elf.h> using namespace libIRDB; using namespace std; @@ -40,7 +41,10 @@ FileIR_t::FileIR_t(const VariantID_t &newprogid, File_t* fid) : BaseObj_t(NULL) fileptr=fid; if(progid.IsRegistered()) + { ReadFromDB(); + SetArchitecture(); + } } @@ -142,10 +146,7 @@ void FileIR_t::AssembleRegistry() DISASM disasm; memset(&disasm, 0, sizeof(DISASM)); - if(sizeof(void*)==8) - disasm.Archi=64; - else - disasm.Archi=32; + disasm.Archi=GetArchitectureBitWidth(); ifstream binreader; unsigned int filesize; @@ -528,3 +529,51 @@ std::string Relocation_t::WriteToDB(File_t* fid, Instruction_t* myinsn) string("'") + to_string(GetDoipID()) + string("') ; ") ; return q; } + +int FileIR_t::GetArchitectureBitWidth() +{ + return archdesc->GetBitWidth(); +} + +void FileIR_t::SetArchitecture() +{ + + /* the first 16 bytes of an ELF file define the magic number and ELF Class. */ + unsigned char e_ident[16]; + + DBinterface_t* myinter=BaseObj_t::GetInterface(); + pqxxDB_t *mypqxxintr=dynamic_cast<pqxxDB_t*>(myinter); + + int elfoid=GetFile()->GetELFOID(); + pqxx::largeobjectaccess loa(mypqxxintr->GetTransaction(), elfoid, PGSTD::ios::in); + + + loa.cread((char*)&e_ident, sizeof(e_ident)); + + if((e_ident[EI_MAG0]!=ELFMAG0) || + (e_ident[EI_MAG1]!=ELFMAG1) || + (e_ident[EI_MAG2]!=ELFMAG2) || + (e_ident[EI_MAG3]!=ELFMAG3)) + { + cerr << "ELF magic number wrong: is this an ELF file? " <<endl; + exit(-1); + } + + archdesc=new ArchitectureDescription_t; + + switch(e_ident[4]) + { + case ELFCLASS32: + archdesc->SetBitWidth(32); + break; + case ELFCLASS64: + archdesc->SetBitWidth(64); + break; + case ELFCLASSNONE: + default: + cerr << "Unknown ELF class " <<endl; + exit(-1); + } +} + +ArchitectureDescription_t* FileIR_t::archdesc=NULL; diff --git a/libIRDB/src/core/generate_spri.cpp b/libIRDB/src/core/generate_spri.cpp index 31fca4df55a78fc620f5e650bbbfec43881bd7a4..b4d0949652d9d96552ff14cd1296858dbb685c4e 100644 --- a/libIRDB/src/core/generate_spri.cpp +++ b/libIRDB/src/core/generate_spri.cpp @@ -386,10 +386,7 @@ static string emit_spri_instruction(FileIR_t* fileIRp, Instruction_t *newinsn, o memset(&disasm, 0, sizeof(DISASM)); disasm.Options = NasmSyntax + PrefixedNumeral + ShowSegmentRegs; - if(sizeof(void*)==8) - disasm.Archi = 64; - else - disasm.Archi = 32; + disasm.Archi = fileIRp->GetArchitectureBitWidth(); disasm.EIP = (UIntPtr)newinsn->GetDataBits().c_str(); disasm.VirtualAddr = old_insn ? old_insn->GetAddress()->GetVirtualOffset() : 0; @@ -666,10 +663,7 @@ static void emit_spri_rule(FileIR_t* fileIRp, Instruction_t* newinsn, ostream& f { DISASM disasm; disasm.Options = NasmSyntax + PrefixedNumeral + ShowSegmentRegs; - if(sizeof(void*)==8) - disasm.Archi = 64; - else - disasm.Archi = 32; + disasm.Archi = fileIRp->GetArchitectureBitWidth(); disasm.EIP = (UIntPtr)newinsn->GetDataBits().c_str(); disasm.VirtualAddr = old_insn ? old_insn->GetAddress()->GetVirtualOffset() : 0; diff --git a/libIRDB/src/core/instruction.cpp b/libIRDB/src/core/instruction.cpp index 7065b652956c17f6444baf3cf7847f97309033a1..8389160099ca92d7dfae5b4f5b9ca3a00eaa802e 100644 --- a/libIRDB/src/core/instruction.cpp +++ b/libIRDB/src/core/instruction.cpp @@ -51,11 +51,7 @@ int Instruction_t::Disassemble(DISASM &disasm){ memset(&disasm, 0, sizeof(DISASM)); disasm.Options = NasmSyntax + PrefixedNumeral; - if(sizeof(void*)==8) - disasm.Archi = 64; - else - disasm.Archi = 32; - + disasm.Archi = FileIR_t::GetArchitectureBitWidth(); disasm.EIP = (UIntPtr) GetDataBits().c_str(); disasm.VirtualAddr = GetAddress()->GetVirtualOffset(); int instr_len = Disasm(&disasm); diff --git a/libIRDB/test/fill_in_cfg.cpp b/libIRDB/test/fill_in_cfg.cpp index f234afe281e4a17ecf3954ef811c976676026cf6..8321c580a7aa334f973e62e0e3c99ed1d5882796 100644 --- a/libIRDB/test/fill_in_cfg.cpp +++ b/libIRDB/test/fill_in_cfg.cpp @@ -278,7 +278,7 @@ void add_new_instructions(FileIR_t *firp) memset(&disasm, 0, sizeof(DISASM)); disasm.Options = NasmSyntax + PrefixedNumeral; - disasm.Archi = sizeof(void*)*8; // 32 or 64 + disasm.Archi = firp->GetArchitectureBitWidth(); disasm.EIP = (UIntPtr) &data[offset_into_section]; disasm.VirtualAddr = missed_address; int instr_len = Disasm(&disasm); @@ -373,13 +373,6 @@ void fill_in_cfg(FileIR_t *firp) DISASM disasm; memset(&disasm, 0, sizeof(DISASM)); -#if 0 - disasm.Options = NasmSyntax + PrefixedNumeral; - disasm.Archi = 32; - disasm.EIP = (UIntPtr) insn->GetDataBits().c_str(); - disasm.VirtualAddr = insn->GetAddress()->GetVirtualOffset(); - int instr_len = Disasm(&disasm); -#endif int instr_len = insn->Disassemble(disasm); assert(instr_len==insn->GetDataBits().size()); diff --git a/libIRDB/test/fill_in_indtargs.cpp b/libIRDB/test/fill_in_indtargs.cpp index 81821808bf3e1cdba45b24bc8056b41af88c3693..83370ce0d592970bd21949a77f4e812f541e418e 100644 --- a/libIRDB/test/fill_in_indtargs.cpp +++ b/libIRDB/test/fill_in_indtargs.cpp @@ -100,10 +100,20 @@ void possible_target(int p) } } -void handle_argument(ARGTYPE *arg) +void handle_argument(ARGTYPE *arg, Instruction_t* insn) { - if( arg->ArgType == MEMORY_TYPE ) - possible_target(arg->Memory.Displacement); + if( (arg->ArgType&MEMORY_TYPE) == MEMORY_TYPE ) + { + if((arg->ArgType&RELATIVE_)==RELATIVE_) + { + assert(insn); + assert(insn->GetAddress()); + possible_target(arg->Memory.Displacement+insn->GetAddress()->GetVirtualOffset()+ + insn->GetDataBits().length()); + } + else + possible_target(arg->Memory.Displacement); + } } void mark_targets(FileIR_t *firp) @@ -156,9 +166,9 @@ void get_instruction_targets(FileIR_t *firp) /* otherwise, any immediate is a possible branch target */ possible_target(disasm.Instruction.Immediat); - handle_argument(&disasm.Argument1); - handle_argument(&disasm.Argument2); - handle_argument(&disasm.Argument3); + handle_argument(&disasm.Argument1, insn); + handle_argument(&disasm.Argument2, insn); + handle_argument(&disasm.Argument3, insn); } }