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