diff --git a/libIRDB/test/fill_in_indtargs.cpp b/libIRDB/test/fill_in_indtargs.cpp index 28ff48a8a4816f184a41a785f12298d5b6fcb792..648f8cf31b6c2a4cba3033888ff4f48b616061c0 100644 --- a/libIRDB/test/fill_in_indtargs.cpp +++ b/libIRDB/test/fill_in_indtargs.cpp @@ -43,8 +43,6 @@ using namespace libIRDB; using namespace std; using namespace EXEIO; -#define HELLNODE_ID 0 -#define INDIRECT_CALLS_ID 1 int next_icfs_set_id = 2; ICFS_t* hellnode_tgts = NULL; @@ -248,6 +246,11 @@ void mark_jmptables(FileIR_t *firp) Instruction_t* instr = it->first; set<Instruction_t*> instruction_targets = it->second; + // ignore if instr already marked complete. + // FIXME: assert that fill_in_indtarg analysis matches already complete analysis. + if(instr->GetIBTargets() && instr->GetIBTargets()->IsComplete()) + continue; + assert(instruction_targets.size() > 0); ICFS_t* new_icfs = new ICFS_t(next_icfs_set_id++, true); @@ -1421,11 +1424,25 @@ void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, DISASM d jmptables[IJ] = ibtargets; } +template <class T> T MAX(T a, T b) +{ + return a>b ? a : b; +} + void icfs_init(FileIR_t* firp) { + + assert(firp); - hellnode_tgts = new ICFS_t(HELLNODE_ID, false); - indirect_calls = new ICFS_t(INDIRECT_CALLS_ID, false); + db_id_t max_id=0; + for(ICFSSet_t::iterator it=firp->GetAllICFS().begin(); it!=firp->GetAllICFS().end(); ++it) + { + max_id=MAX<db_id_t>(max_id, (*it)->GetBaseID()); + } + next_icfs_set_id = max_id+1; + cerr<<"Found max ICFS id=="<<max_id<<endl; + hellnode_tgts = new ICFS_t(next_icfs_set_id++, false); + indirect_calls = new ICFS_t(next_icfs_set_id++, false); firp->GetAllICFS().insert(hellnode_tgts); firp->GetAllICFS().insert(indirect_calls); } @@ -1433,13 +1450,13 @@ void icfs_init(FileIR_t* firp) void icfs_set_indirect_calls(FileIR_t* const firp, ICFS_t* const targets) { assert(firp && targets); - for( - FunctionSet_t::const_iterator it=firp->GetFunctions().begin(); - it!=firp->GetFunctions().end(); - ++it - ) - { - Function_t *func=*it; + for( + FunctionSet_t::const_iterator it=firp->GetFunctions().begin(); + it!=firp->GetFunctions().end(); + ++it + ) + { + Function_t *func=*it; if(!func->GetEntryPoint()) continue; targets->insert(func->GetEntryPoint()); @@ -1472,6 +1489,10 @@ void check_for_ret(FileIR_t* const firp, Instruction_t* const insn) if(strstr(d.Instruction.Mnemonic, "ret")==NULL) return; + // already analysed by ida. + if(insn->GetIBTargets() && insn->GetIBTargets()->IsComplete()) + return; + insn->SetIBTargets(hellnode_tgts); } @@ -1487,11 +1508,17 @@ void check_for_indirect_jmp(FileIR_t* const firp, Instruction_t* const insn) if(d.Argument1.ArgType®ISTER_TYPE) { + // already analysed by ida. + if(insn->GetIBTargets() && insn->GetIBTargets()->IsComplete()) + return; insn->SetIBTargets(hellnode_tgts); } else if(d.Argument1.ArgType&MEMORY_TYPE && (!d.Argument1.ArgType&RELATIVE_)) { + // already analysed by ida. + if(insn->GetIBTargets() && insn->GetIBTargets()->IsComplete()) + return; insn->SetIBTargets(hellnode_tgts); } } @@ -1509,6 +1536,10 @@ void check_for_indirect_call(FileIR_t* const firp, Instruction_t* const insn) if(d.Argument1.ArgType&CONSTANT_TYPE) return; + // already analysed by ida. + if(insn->GetIBTargets() && insn->GetIBTargets()->IsComplete()) + return; + insn->SetIBTargets(indirect_calls); } diff --git a/tools/meds2pdb/meds2pdb.cpp b/tools/meds2pdb/meds2pdb.cpp index bed63cfbd406a9ce00546fb84faffcdf9feaee90..e12b6098972ba0fbede16079e497b16042a11481 100644 --- a/tools/meds2pdb/meds2pdb.cpp +++ b/tools/meds2pdb/meds2pdb.cpp @@ -41,6 +41,8 @@ string functionTable; string addressTable; string instructionTable; string typesTable; +string icfsTable; +string icfsMapTable; static const int STRIDE = 50; @@ -56,6 +58,7 @@ inline std::string my_to_string (const T& t) int next_address_id=0; map<app_iaddr_t,int> address_to_instructionid_map; +map<wahoo::Instruction*,int> instruction_to_addressid_map; // extract the file id from the md5 hash and the program name int get_file_id(char *progName, char *md5hash) @@ -81,8 +84,63 @@ int get_file_id(char *progName, char *md5hash) } +void insert_icfs(int fileID, const vector<wahoo::Instruction*>& instructions) +{ + using namespace wahoo; + + connection conn; + work txn(conn); + txn.exec("SET client_encoding='LATIN1';"); + + int next_icfs_id=0; + + for (int i = 0; i < instructions.size(); i ++) + { + wahoo::Instruction *instruction = instructions[i]; + assert(instruction); + + const std::set<Instruction*> &ibts=instruction->getIBTs(); + + if(ibts.size()==0) + continue; + cerr<<"Found fromIB=="<<instruction->getAddress()<<endl; + + string query = "INSERT INTO " + icfsTable; + query += " (icfs_id,is_complete) VALUES "; + query += "("; + query += txn.quote(next_icfs_id) + ","; + query += txn.quote(1); + query += ")"; + + string query2 = "INSERT INTO " + icfsMapTable; + query2 += " (icfs_id,address_id) VALUES "; + + for(set<Instruction*>::iterator it=ibts.begin(); it!=ibts.end(); it++) + { + cerr<<"Found toIBT=="<<(*it)->getAddress()<<endl; + if(it!=ibts.begin()) + query2+=","; + int target_address_id=instruction_to_addressid_map[*it]; + query2 += "("; + query2 += txn.quote(next_icfs_id) + ","; + query2 += txn.quote(target_address_id); + query2 += ")"; + + } + + query+=";"; + query2+=";"; + txn.exec(query+query2); + next_icfs_id++; + } + cerr<<"Finished inserting ICFS into IR."<<endl; + txn.commit(); + +} + + // insert addresses & instructions into DB -void insert_instructions(int fileID, vector<wahoo::Instruction*> instructions, vector<wahoo::Function*> functions) +void insert_instructions(int fileID, const vector<wahoo::Instruction*> &instructions, const vector<wahoo::Function*> &functions) { cerr << "Inserting instructions in the DB"<<endl; connection conn; @@ -115,6 +173,7 @@ void insert_instructions(int fileID, vector<wahoo::Instruction*> instructions, v address_to_instructionid_map[addr]=j; int address_id = next_address_id++; + instruction_to_addressid_map[instruction]=address_id; // insert into address table if (j != i) query += ","; @@ -329,7 +388,7 @@ void populate_predefined_types() txn.commit(); } -void update_function_prototype(vector<wahoo::Function*> functions, char* annotFile) +void update_function_prototype(const vector<wahoo::Function*> &functions, char* annotFile) { populate_predefined_types(); @@ -456,9 +515,9 @@ void update_function_prototype(vector<wahoo::Function*> functions, char* annotFi int main(int argc, char **argv) { - if (argc != 10) + if (argc != 12) { - cerr << "usage: " << argv[0] << " <annotations file> <info annotation file> <file id> <func tab name> <insn tab name> <addr tab name> <types tab name> <elf file> <STARSxref file>" << endl; + cerr << "usage: " << argv[0] << " <annotations file> <info annotation file> <file id> <func tab name> <insn tab name> <addr tab name> <types tab name> <icfs table name> <icfs map table name> <elf file> <STARSxref file>" << endl; return 1; } @@ -469,22 +528,30 @@ int main(int argc, char **argv) char *myInstructionTable=argv[5]; char *myAddressTable=argv[6]; char *myTypesTable=argv[7]; - char *elfFile=argv[8]; - char *starsXrefFile=argv[9]; + char *myicfsTable=argv[8]; + char *myicfsMapTable=argv[9]; + char *elfFile=argv[10]; + char *starsXrefFile=argv[11]; cout<<"Annotation file: "<< annotFile<<endl; cout<<"Info annotation file: "<< infoAnnotFile<<endl; cout<<"File ID: "<< fid<<endl; - cout<<"FTN:: "<< myFunctionTable<<endl; + cout<<"FTN: "<< myFunctionTable<<endl; cout<<"ITN: "<< myInstructionTable<<endl; cout<<"ATN: "<< myAddressTable<<endl; cout<<"TYP: "<< myTypesTable<<endl; + cout<<"ICFSTab: "<< myicfsTable<<endl; + cout<<"ICFSMapTab: "<< myicfsMapTable<<endl; + cout<<"elfFile: "<< elfFile<<endl; + cout<<"xrefFile: "<< starsXrefFile<<endl; // set global vars for importing. functionTable=myFunctionTable; addressTable=myAddressTable; instructionTable=myInstructionTable; typesTable=myTypesTable; + icfsTable=myicfsTable; + icfsMapTable=myicfsMapTable; Rewriter *rewriter = new Rewriter(elfFile, annotFile, starsXrefFile); @@ -504,6 +571,7 @@ int main(int argc, char **argv) insert_functions(fileID, functions); insert_instructions(fileID, instructions, functions); update_functions(fileID, functions); + insert_icfs(fileID, instructions); // add function prototype information to the IRDB update_function_prototype(functions, infoAnnotFile); diff --git a/xform/instruction_descriptor.h b/xform/instruction_descriptor.h index e09c6bfd7705f4bab2b9402c48feef8c9aa7e9b1..420332a4f631f82f4f4afc95ff19f751f07dfc57 100644 --- a/xform/instruction_descriptor.h +++ b/xform/instruction_descriptor.h @@ -2,6 +2,7 @@ #define _instruction_h_ #include <string> +#include <set> #include "targ-config.h" @@ -46,6 +47,10 @@ class Instruction { void setVisited() { m_isVisited = true; } bool isVisited() const { return m_isVisited; } + // include Indirect branch targets for insructions. + void addIBT(Instruction* insn) { ibts.insert(insn); } + const std::set<Instruction*>& getIBTs() { return ibts; } + private: app_iaddr_t m_address; app_iaddr_t m_ibt_address; @@ -61,6 +66,9 @@ class Instruction { bool m_varStackRef; bool m_isVisited; + + std::set<Instruction*> ibts; + }; } diff --git a/xform/rewriter.cpp b/xform/rewriter.cpp index 7c7a45db44137ee222cdb1227f9992030e135483..6e80e709c2535532d10ae41a9f9625adee439d39 100644 --- a/xform/rewriter.cpp +++ b/xform/rewriter.cpp @@ -652,16 +652,20 @@ void Rewriter::readXrefsFile(char p_filename[]) do { - + addr=0; fscanf(fin, "%p %d\n", (void**)&addr, &size_type_u.size); if(feof(fin)) // deal with blank lines at the EOF break; fscanf(fin, "%s%s", type,scope); + if(feof(fin)) // deal with blank lines at the EOF + break; assert(strcmp(type,"INSTR")==0); assert(strcmp(scope,"XREF")==0); - fscanf(fin, "%s%s%s", ibt,fromib,dest); + fscanf(fin, "%s%s", ibt,fromib); + if(feof(fin)) // deal with blank lines at the EOF + break; assert(strcmp(ibt,"IBT")==0); assert(strcmp(fromib,"FROMIB")==0 || strcmp(fromib,"FROMDATA")==0 || strcmp(fromib,"FROMUNKNOWN")==0); @@ -672,11 +676,29 @@ void Rewriter::readXrefsFile(char p_filename[]) { // cout<<"Setting IBT for addr "<<std::hex<<addr<<std::dec<<endl; instr->setIBTAddress(addr); + if(strcmp(fromib,"FROMIB")==0) + { + // get the from point into memory. + app_iaddr_t from_addr = 0; + fscanf(fin, "%p\n", (void**)&from_addr); + if(feof(fin)) // deal with blank lines at the EOF + break; + + // find that instruction + wahoo::Instruction *from_instr = addr_to_insn_map[from_addr]; + assert(from_instr); + + // record in the IR listing. + from_instr->addIBT(instr); + } } else { - cerr<<"Warning, instruction at "<<std::hex<<addr<<std::dec<<" not in db?"<<endl; + cerr<<"Error: instruction at "<<std::hex<<addr<<std::dec<<" not in db?"<<endl; + // assert(0); } + + char remainder[2000]; fgets(remainder, sizeof(remainder), fin); diff --git a/xform/rewriter.h b/xform/rewriter.h index 417c2950117b819f6860419aa48df71331f364a8..c035835215fa86a001a66380de4dcd5f89a35584 100644 --- a/xform/rewriter.h +++ b/xform/rewriter.h @@ -1,4 +1,5 @@ #include <map> +#include <set> #include "targ-config.h" #include "elfio/elfio.hpp" #include "elfio/elfio_dump.hpp" @@ -6,6 +7,7 @@ #include "elfreader.h" #include "function_descriptor.h" + using namespace std; class Rewriter