From 18a775066cf323159707737f893753f79dac7303 Mon Sep 17 00:00:00 2001 From: an7s <an7s@git.zephyr-software.com> Date: Sat, 28 Mar 2015 23:58:37 +0000 Subject: [PATCH] Getting ibtargets into the IRDB map successfully Former-commit-id: 3860ac8105f05ed5c57b7f01771785b4479e13d6 --- libIRDB/src/core/Makefile | 2 +- libIRDB/src/core/fileir.cpp | 58 ++++-------- libIRDB/src/core/variantid.cpp | 4 +- libIRDB/test/fill_in_indtargs.cpp | 141 ++++++++++++++++++++---------- libIRDB/test/read_variantir.cpp | 21 ++++- 5 files changed, 136 insertions(+), 90 deletions(-) diff --git a/libIRDB/src/core/Makefile b/libIRDB/src/core/Makefile index 21680626f..6176ec9bb 100644 --- a/libIRDB/src/core/Makefile +++ b/libIRDB/src/core/Makefile @@ -2,7 +2,7 @@ LIB=../../lib/libIRDB-core.a -OBJS=baseobj.o type.o variantid.o pqxxdb.o dbinterface.o function.o fileir.o file.o instruction.o address.o generate_spri.o +OBJS=baseobj.o type.o variantid.o pqxxdb.o dbinterface.o function.o fileir.o file.o instruction.o address.o icfs.o generate_spri.o all: $(OBJS) diff --git a/libIRDB/src/core/fileir.cpp b/libIRDB/src/core/fileir.cpp index bbf9fe8c4..e8c88fcd0 100644 --- a/libIRDB/src/core/fileir.cpp +++ b/libIRDB/src/core/fileir.cpp @@ -595,11 +595,13 @@ void FileIR_t::WriteToDB() } dbintr->IssueQuery(q); -/* xxx - xxxq = string(""); - xxxq = ibtargets.WriteToDB(fileptr); -*/ - dbintr->IssueQuery(q); + for (ICFSSet_t::iterator it = GetAllICFS().begin(); it != GetAllICFS().end(); ++it) + { + ICFS_t* icfs = *it; + assert(icfs); + string q = icfs->WriteToDB(fileptr); + dbintr->IssueQuery(q); + } } @@ -913,6 +915,8 @@ void FileIR_t::ReadAllICFSFromDB(std::map<db_id_t,Instruction_t*> &addr2instMap, std::string q= "select * from " + fileptr->icfs_table_name + " ; "; dbintr->IssueQuery(q); +cout << "ReadAllICFSFromDB(): A: query: " << q << endl; + while(!dbintr->IsDone()) { db_id_t icfs_id = atoi(dbintr->GetResultColumn("icfs_id").c_str()); @@ -925,12 +929,16 @@ void FileIR_t::ReadAllICFSFromDB(std::map<db_id_t,Instruction_t*> &addr2instMap, isComplete = true; } +cout << "icfs_id: " << icfs_id << " complete: " << isComplete << endl; ICFS_t* icfs = new ICFS_t(icfs_id, isComplete); GetAllICFS().insert(icfs); icfsMap[icfs_id] = icfs; + dbintr->MoveToNextRow(); } +cout << "ReadAllICFSFromDB(): B" << endl; + ICFSSet_t all_icfs = GetAllICFS(); // for each set, populate its members @@ -942,6 +950,7 @@ void FileIR_t::ReadAllICFSFromDB(std::map<db_id_t,Instruction_t*> &addr2instMap, int icfsid = icfs->GetBaseID(); sprintf(query2,"select * from %s WHERE icfs_id = %d;", fileptr->icfs_map_table_name.c_str(), icfsid); dbintr->IssueQuery(query2); +cout << "ReadAllICFSFromDB(): icfsid: " << icfsid << " query: " << query2 << endl; while(!dbintr->IsDone()) { db_id_t address_id = atoi(dbintr->GetResultColumn("address_id").c_str()); @@ -952,9 +961,12 @@ void FileIR_t::ReadAllICFSFromDB(std::map<db_id_t,Instruction_t*> &addr2instMap, // these are allowed by the DB schema but we don't yet handle them // if we encounter an unresolved address, we should mark the ICFS // as unresolved + + dbintr->MoveToNextRow(); } } +cout << "ReadAllICFSFromDB(): C: size unresolved: " << unresolvedICFS.size() << endl; // backpatch all unresolved instruction -> ICFS std::map<Instruction_t*, db_id_t>::iterator uit; for (std::map<Instruction_t*, db_id_t>::iterator uit = unresolvedICFS.begin(); uit != unresolvedICFS.end(); ++uit) @@ -970,39 +982,3 @@ void FileIR_t::ReadAllICFSFromDB(std::map<db_id_t,Instruction_t*> &addr2instMap, unresolved->SetIBTargets(icfs); } } - -/* -void FileIR_t::ReadIBTargetsFromDB(std::map<db_id_t,Instruction_t*> &insnMap) -{ - std::string q= "select * from " + fileptr->ibtargets_table_name + " ; "; - - dbintr->IssueQuery(q); - - while(!dbintr->IsDone()) - { - // instruction_id | target_instruction_id - // target_instruction_id < 0 HELLNODE encoding (only one for now) - db_id_t instr_id = atoi(dbintr->GetResultColumn("instruction_id").c_str()); - db_id_t ibtarget_id = atoi(dbintr->GetResultColumn("target_instruction_id").c_str()); - - assert(instr_id >= 0); - - Instruction_t* instruction = insnMap[instr_id]; - assert(instruction); - - Instruction_t* ibtarget = NULL; - if (ibtarget_id >= 0) - { - ibtarget = insnMap[ibtarget_id]; - assert(ibtarget); - } - - if (ibtarget) - ibtargets.AddTarget(instruction, ibtarget); - else - ibtargets.AddHellnodeTarget(instruction, (ICFGHellnodeType)ibtarget_id); - - dbintr->MoveToNextRow(); - } -} -*/ diff --git a/libIRDB/src/core/variantid.cpp b/libIRDB/src/core/variantid.cpp index b37c7e2f5..dea26ea95 100644 --- a/libIRDB/src/core/variantid.cpp +++ b/libIRDB/src/core/variantid.cpp @@ -221,12 +221,12 @@ File_t* VariantID_t::CloneFile(File_t* fptr) dbintr->IssueQuery(q); q="drop table "; - q+=icfs; + q+=icfsmap; q+=" ; "; dbintr->IssueQuery(q); q="drop table "; - q+=icfsmap; + q+=icfs; q+=" ; "; dbintr->IssueQuery(q); diff --git a/libIRDB/test/fill_in_indtargs.cpp b/libIRDB/test/fill_in_indtargs.cpp index 75ca30c75..eca06275d 100644 --- a/libIRDB/test/fill_in_indtargs.cpp +++ b/libIRDB/test/fill_in_indtargs.cpp @@ -36,6 +36,16 @@ #include "beaengine/BeaEngine.h" #include "check_thunks.hpp" +using namespace libIRDB; +using namespace std; +using namespace ELFIO; + +#define HELLNODE_ID 0 +#define INDIRECT_JMPS_ID 1 +int next_icfs_set_id = 2; + +ICFS_t* hellnode_tgts = NULL; +ICFS_t* indirect_jmps = NULL; #define arch_ptr_bytes() (firp->GetArchitectureBitWidth()/8) @@ -43,10 +53,6 @@ int odd_target_count=0; int bad_target_count=0; int bad_fallthrough_count=0; -using namespace libIRDB; -using namespace std; -using namespace ELFIO; - bool is_possible_target(uintptr_t p, uintptr_t addr); set< pair <int,int> > bounds; @@ -68,8 +74,9 @@ void check_for_PIC_switch_table64(FileIR_t*, Instruction_t* insn, DISASM disasm, void check_for_nonPIC_switch_table(FileIR_t*, Instruction_t* insn, DISASM disasm, ELFIO::elfio* elfiop); void check_for_nonPIC_switch_table_pattern2(FileIR_t*, Instruction_t* insn, DISASM disasm, ELFIO::elfio* elfiop); -void check_for_indirect_jmps(FileIR_t* firp, Instruction_t* insn); -void check_for_indirect_calls(FileIR_t* firp, Instruction_t* insn); +void check_for_indirect_jmp(FileIR_t* const firp, Instruction_t* const insn); +void check_for_indirect_call(FileIR_t* const firp, Instruction_t* const insn); +void check_for_ret(FileIR_t* const firp, Instruction_t* const insn); void range(int start, int end) { @@ -226,17 +233,14 @@ void mark_jmptables(FileIR_t *firp) { Instruction_t* instr = it->first; set<Instruction_t*> instruction_targets = it->second; - for (set<Instruction_t*>::iterator j = instruction_targets.begin(); - j != instruction_targets.end(); - ++j) - { - Instruction_t *ibtarget = *j; - assert(instr && ibtarget); + assert(instruction_targets.size() > 0); - assert(0); // XXX wip -// firp->GetIBTargets().AddTarget(instr, ibtarget); - } + ICFS_t* new_icfs = new ICFS_t(next_icfs_set_id++, true); + *new_icfs = instruction_targets; + firp->GetAllICFS().insert(new_icfs); + + cout << "jmp table: size: " << new_icfs->size() << endl; } } @@ -291,10 +295,11 @@ void get_instruction_targets(FileIR_t *firp, ELFIO::elfio* elfiop, const set<int // assign hellnode type to indirect jmps that are not detected // to be switch tables if (jmptables.count(insn) == 0) - check_for_indirect_jmps(firp, insn); + check_for_indirect_jmp(firp, insn); // assign special hellnode type to indirect calls - check_for_indirect_calls(firp, insn); + check_for_indirect_call(firp, insn); + check_for_ret(firp, insn); /* other branches can't indicate an indirect branch target */ if(disasm.Instruction.BranchType) @@ -1019,8 +1024,61 @@ void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, DISASM d jmptables[IJ] = ibtargets; } +void icfs_init(FileIR_t* firp) +{ + assert(firp); + hellnode_tgts = new ICFS_t(HELLNODE_ID, false); + indirect_jmps = new ICFS_t(INDIRECT_JMPS_ID, false); + firp->GetAllICFS().insert(hellnode_tgts); + firp->GetAllICFS().insert(indirect_jmps); +} + +void icfs_set_indirect_jmps(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; + if(!func->GetEntryPoint()) + continue; + targets->insert(func->GetEntryPoint()); + } +} + +void icfs_set_hellnode_targets(FileIR_t* const firp, ICFS_t* const targets) +{ + assert(firp && targets); + for( + InstructionSet_t::const_iterator it=firp->GetInstructions().begin(); + it!=firp->GetInstructions().end(); ++it) + { + Instruction_t* insn=*it; + if(insn->GetIndirectBranchTargetAddress()) + { + targets->insert(insn); + } + } +} + -void check_for_indirect_jmps(FileIR_t* firp, Instruction_t* insn) +void check_for_ret(FileIR_t* const firp, Instruction_t* const insn) +{ + assert(firp && insn); + + DISASM d; + insn->Disassemble(d); + + if(strstr(d.Instruction.Mnemonic, "ret")==NULL) + return; + + insn->SetIBTargets(hellnode_tgts); +} + +void check_for_indirect_jmp(FileIR_t* const firp, Instruction_t* const insn) { assert(firp && insn); @@ -1033,14 +1091,10 @@ void check_for_indirect_jmps(FileIR_t* firp, Instruction_t* insn) if(d.Argument1.ArgType&CONSTANT_TYPE) return; - if (getenv("IB_VERBOSE")) - cout << insn->getDisassembly() << " is an indirect call, assign to DEFAULT HELNNODE" << endl; - - assert(0); -// firp->GetIBTargets().AddHellnodeTarget(insn, DEFAULT_ICFG_HELLNODE); + insn->SetIBTargets(hellnode_tgts); } -void check_for_indirect_calls(FileIR_t* firp, Instruction_t* insn) +void check_for_indirect_call(FileIR_t* const firp, Instruction_t* const insn) { assert(firp && insn); @@ -1053,11 +1107,7 @@ void check_for_indirect_calls(FileIR_t* firp, Instruction_t* insn) if(d.Argument1.ArgType&CONSTANT_TYPE) return; - if (getenv("IB_VERBOSE")) - cout << insn->getDisassembly() << " is an indirect call, assign to CALL HELNNODE" << endl; - -// firp->GetIBTargets().AddHellnodeTarget(insn, CALL_ICFG_HELLNODE); - assert(0); + insn->SetIBTargets(indirect_jmps); } @@ -1076,8 +1126,6 @@ void calc_preds(FileIR_t* firp) if(insn->GetFallthrough()); preds[insn->GetFallthrough()].insert(insn); } - - } @@ -1190,17 +1238,18 @@ void fill_in_indtargs(FileIR_t* firp, elfio* elfiop) mark_targets(firp); mark_jmptables(firp); + icfs_set_indirect_jmps(firp, indirect_jmps); + icfs_set_hellnode_targets(firp, hellnode_tgts); -/* -xxx XXX wip - if(getenv("IB_VERBOSE")!=NULL) + for(ICFSSet_t::const_iterator it=firp->GetAllICFS().begin(); + it != firp->GetAllICFS().end(); + ++it) { - cout << firp->GetIBTargets().toString() << endl; + ICFS_t *icfs = *it; + cout << dec << "icfs set id: " << icfs->GetBaseID() << " #ibtargets: " << icfs->size() << endl; } - */ } - main(int argc, char* argv[]) { @@ -1225,19 +1274,20 @@ main(int argc, char* argv[]) cout<<"New Variant, after reading registration, is: "<<*pidp << endl; - for(set<File_t*>::iterator it=pidp->GetFiles().begin(); - it!=pidp->GetFiles().end(); - ++it - ) - { - File_t* this_file=*it; - assert(this_file); + for(set<File_t*>::iterator it=pidp->GetFiles().begin(); + it!=pidp->GetFiles().end(); + ++it) + { + File_t* this_file=*it; + assert(this_file); cout<<"Analyzing file "<<this_file->GetURL()<<endl; // read the db firp=new FileIR_t(*pidp, this_file); + icfs_init(firp); + int elfoid=firp->GetFile()->GetELFOID(); pqxx::largeobject lo(elfoid); lo.to_file(pqxx_interface.GetTransaction(),"readeh_tmp_file.exe"); @@ -1256,7 +1306,10 @@ main(int argc, char* argv[]) // write the DB back and commit our changes firp->WriteToDB(); + delete firp; + delete indirect_jmps; + delete hellnode_tgts; } pqxx_interface.Commit(); diff --git a/libIRDB/test/read_variantir.cpp b/libIRDB/test/read_variantir.cpp index d2ff4c826..d01836c58 100644 --- a/libIRDB/test/read_variantir.cpp +++ b/libIRDB/test/read_variantir.cpp @@ -76,14 +76,31 @@ main(int argc, char* argv[]) ICFS_t::iterator ibtargets_it; - for (ibtargets_it = ibtargets->begin(); ibtargets_it != ibtargets->end(); ++ibtargets_it) + if (ibtargets->size() > 0) + cout<<" indirect branch targets: "; + + int count; + for (count = 0, ibtargets_it = ibtargets->begin(); ibtargets_it != ibtargets->end(); ++ibtargets_it, ++count) { Instruction_t* insn = *ibtargets_it; assert(insn); - cout<<" indirect branch target: " << std::hex << insn->GetAddress()->GetVirtualOffset() << dec << endl; + cout<< std::hex << insn->GetAddress()->GetVirtualOffset() << " "; + if (count >= 10) { + cout << "..."; + break; + } } + if (ibtargets->size() > 0) + cout << dec << endl; } + for(ICFSSet_t::const_iterator it=firp->GetAllICFS().begin(); + it != firp->GetAllICFS().end(); + ++it) + { + ICFS_t *icfs = *it; + cout << "icfs set id: " << icfs->GetBaseID() << " #ibtargets: " << icfs->size() << endl; + } delete firp; } delete pidp; -- GitLab