diff --git a/libIRDB/include/core/fileir.hpp b/libIRDB/include/core/fileir.hpp index 4c77987f3c3eaf39248ef8b00996ee74f5db58c1..e0d699c36ee4b048153f6395e0361ac7e6f25fc2 100644 --- a/libIRDB/include/core/fileir.hpp +++ b/libIRDB/include/core/fileir.hpp @@ -1,3 +1,5 @@ + + // A variant of a problem, this // may be an original variant // (i.e., and unmodified Variant) or a modified variant. @@ -27,11 +29,21 @@ class FileIR_t : public BaseObj_t File_t* GetFile() { return fileptr; } + // Used for modifying a large number of instructions. AssembleRegistry + // assembles the assembly isntructions for each registered instruction + // and clears the registry. RegisterAssembly registers the instruction + // to be assembled later. + void AssembleRegistry(); + void RegisterAssembly(Instruction_t *instr, std::string assembly); + private: + typedef std::map<Instruction_t*,std::string> registry_type; + // a pointer to the original variants IR, NULL means not yet loaded. FileIR_t* orig_variant_ir_p; + registry_type assembly_registry; void ReadFromDB(); //accesses DB diff --git a/libIRDB/src/core/fileir.cpp b/libIRDB/src/core/fileir.cpp index 9fe0b90c91c298fc7530089a933b411f4dbe75b7..5cd584bb8dc18065b84b5a060c6d3834ba1bf8e5 100644 --- a/libIRDB/src/core/fileir.cpp +++ b/libIRDB/src/core/fileir.cpp @@ -3,6 +3,7 @@ #include <utils.hpp> #include <stdlib.h> #include <map> +#include <fstream> using namespace libIRDB; using namespace std; @@ -57,6 +58,95 @@ void FileIR_t::ReadFromDB() } +void FileIR_t::AssembleRegistry() +{ + if(assembly_registry.size() == 0) + return; + + const string assemblyFile = "tmp.asm"; + const string binaryOutputFile = "tmp.bin"; + + string command = "rm -f " + assemblyFile; + system(command.c_str()); + + ofstream asmFile; + asmFile.open(assemblyFile.c_str()); + if(!asmFile.is_open()) + assert(false); + + asmFile<<"BITS 32"<<endl; //TODO: probably should use a defined val + + //in case the map is some how updated again, the instructions are placed + //in a vector so the number and order of instructions are guaranteed + vector<Instruction_t*> instructions; + for(registry_type::iterator it = assembly_registry.begin(); + it != assembly_registry.end(); + it++ + ) + { + instructions.push_back(it->first); + asmFile<<it->second<<endl; + } + asmFile.close(); + + //after assembly, clear registry + assembly_registry.clear(); + + command = "nasm " + assemblyFile + " -o " + binaryOutputFile; + system(command.c_str()); + + DISASM disasm; + memset(&disasm, 0, sizeof(DISASM)); + + + ifstream binreader; + unsigned int filesize; + binreader.open(binaryOutputFile.c_str(),ifstream::in|ifstream::binary); + + if(!binreader.is_open()) + assert(false); + + binreader.seekg(0,ios::end); + filesize = binreader.tellg(); + binreader.seekg(0,ios::beg); + + unsigned char *binary_stream = new unsigned char[filesize]; + + binreader.read((char*)binary_stream,filesize); + binreader.close(); + + unsigned int instr_index = 0; + //for(unsigned int index=0; index < filesize; instr_index++) + unsigned int index = 0; + while(index < filesize) + { + disasm.EIP = (int) &binary_stream[index]; + int instr_len = Disasm(&disasm); + string rawBits; + rawBits.resize(instr_len); + for(int i=0;i<instr_len;i++,index++) + { + rawBits[i] = binary_stream[index]; + } + + //if this worked, all the instructions should have been covered + assert(instr_index < instructions.size()); + instructions[instr_index]->SetDataBits(rawBits); + + instr_index++; + } + + assert(instr_index == instructions.size()); + + delete [] binary_stream; + +} + +void FileIR_t::RegisterAssembly(Instruction_t *instr, string assembly) +{ + assembly_registry[instr] = assembly; +} + std::map<db_id_t,Function_t*> FileIR_t::ReadFuncsFromDB ( std::map<db_id_t,AddressID_t*> &addrMap @@ -254,10 +344,11 @@ void FileIR_t::ReadRelocsFromDB } - - void FileIR_t::WriteToDB() { + //Resolve (assemble) any instructions in the registry. + AssembleRegistry(); + /* assign each item a unique ID */ SetBaseIDS(); diff --git a/libIRDB/src/core/generate_spri.cpp b/libIRDB/src/core/generate_spri.cpp index a83d3b36e054d3cb3242592ee1805efe00a5ce9e..39eee64ea2853e33195d92122c52c745e9451f64 100644 --- a/libIRDB/src/core/generate_spri.cpp +++ b/libIRDB/src/core/generate_spri.cpp @@ -633,6 +633,9 @@ static void generate_unmoved_insn_targets_set(FileIR_t* fileIRp) void FileIR_t::GenerateSPRI(FileIR_t *orig_fileIRp, ostream &fout) { + //Resolve (assemble) any instructions in the registry. + AssembleRegistry(); + // give 'this' a name FileIR_t *fileIRp=this;