diff --git a/libIRDB/include/core/reloc.hpp b/libIRDB/include/core/reloc.hpp index 91b6149b65c2c03a1e1924c272316799c724106f..cae7cb3627f0294ede97a1b737e207cd320b7864 100644 --- a/libIRDB/include/core/reloc.hpp +++ b/libIRDB/include/core/reloc.hpp @@ -32,7 +32,7 @@ class Relocation_t : public BaseObj_t Relocation_t(db_id_t reloc_id) : BaseObj_t(NULL) { assert(0);} // read from DB void WriteToDB() { assert(0); } // writes to DB ID is not -1. - std::string WriteToDB(File_t* fid, Instruction_t* insn); // writes to DB, ID is not -1. + std::string WriteToDB(File_t* fid, BaseObj_t* insn); // writes to DB, ID is not -1. void SetOffset(int off) { offset=off;} int GetOffset() { return offset; } diff --git a/libIRDB/src/core/fileir.cpp b/libIRDB/src/core/fileir.cpp index c623be425b2bc0f8ec092bcb87eef1f9d27db195..8e7c3860feae1a92b06d775a6c18af913240f884 100644 --- a/libIRDB/src/core/fileir.cpp +++ b/libIRDB/src/core/fileir.cpp @@ -478,7 +478,7 @@ void FileIR_t::ReadRelocsFromDB db_id_t wrt_id=atoi(dbintr->GetResultColumn("wrt_id").c_str()); - BaseObj_t* wrt_obj=objMap[wrt_id]; + BaseObj_t* wrt_obj=objMap[wrt_id]; // might be null. Relocation_t *reloc=new Relocation_t(reloc_id,reloc_offset,reloc_type,wrt_obj); assert(objMap[instruction_id]!=NULL); @@ -634,7 +634,15 @@ void FileIR_t::WriteToDB() DataScoop_t* scoop = *it; assert(scoop); string q = scoop->WriteToDB(fileptr,j); + + const std::set<Relocation_t*> &the_relocs = scoop->GetRelocations(); + for(set<Relocation_t*>::const_iterator rit=the_relocs.begin(); rit!=the_relocs.end(); ++rit) + { + Relocation_t* reloc=*rit; + q+=reloc->WriteToDB(fileptr,scoop); + } dbintr->IssueQuery(q); + } } @@ -687,16 +695,18 @@ void FileIR_t::SetBaseIDS() (*i)->SetBaseID(j++); } -std::string Relocation_t::WriteToDB(File_t* fid, Instruction_t* myinsn) +std::string Relocation_t::WriteToDB(File_t* fid, BaseObj_t* myinsn) { string q; + db_id_t wrt_id=wrt_obj ? wrt_obj->GetBaseID() : BaseObj_t::NOT_IN_DATABASE; q ="insert into " + fid->relocs_table_name; - q+="(reloc_id,reloc_offset,reloc_type,instruction_id,doip_id) "+ + q+="(reloc_id,reloc_offset,reloc_type,instruction_id,wrt_id,doip_id) "+ string(" VALUES (") + string("'") + to_string(GetBaseID()) + string("', ") + string("'") + to_string(offset) + string("', ") + string("'") + (type) + string("', ") + string("'") + to_string(myinsn->GetBaseID()) + string("', ") + + string("'") + to_string(wrt_id) + string("', ") + string("'") + to_string(GetDoipID()) + string("') ; ") ; return q; } diff --git a/libIRDB/src/core/scoop.cpp b/libIRDB/src/core/scoop.cpp index 878a52aece683696772b2fde2ff6dce163dc8c18..31f3a50173dabdf527547134ddec7fdcda7c2c8b 100644 --- a/libIRDB/src/core/scoop.cpp +++ b/libIRDB/src/core/scoop.cpp @@ -1,5 +1,8 @@ #include "all.hpp" #include <utils.hpp> +#include <sstream> +#include <iomanip> + using namespace std; using namespace libIRDB; @@ -21,14 +24,21 @@ string DataScoop_t::WriteToDB(File_t *fid, db_id_t newid) db_id_t type_id=(GetType() ? GetType()->GetBaseID() : BaseObj_t::NOT_IN_DATABASE); + ostringstream hex_data; + hex_data << setfill('0') << hex;; + for (size_t i = 0; i < contents.length(); ++i) + hex_data << setw(2) << (int)(contents[i]&0xff); + + string q=string("insert into ")+fid->scoop_table_name + - string(" (scoop_id, name, type_id, start_address_id, end_address_id, permissions) ")+ + string(" (scoop_id, name, type_id, start_address_id, end_address_id, data, permissions) ")+ string(" VALUES (") + string("'") + to_string(GetBaseID()) + string("', ") + string("'") + GetName() + string("', ") + string("'") + to_string(type_id) + string("', ") + string("'") + to_string(GetStart()->GetBaseID()) + string("', ") + string("'") + to_string(GetEnd()->GetBaseID()) + string("', ") + + string("decode('") + hex_data.str() + string("', 'hex'), ") + string("'") + to_string(permissions) + string("'); ") ; return q; diff --git a/libIRDB/test/fill_in_indtargs.cpp b/libIRDB/test/fill_in_indtargs.cpp index 98be6f7be6823708a4b3f79ff0f7d5ec01c625b7..dc587376e93495b0affde6820a73e766738fa31b 100644 --- a/libIRDB/test/fill_in_indtargs.cpp +++ b/libIRDB/test/fill_in_indtargs.cpp @@ -1019,7 +1019,9 @@ DN: 0x4824XX: .long 0x4824e0-LN case REG13: base_reg="r13"; break; case REG14: base_reg="r14"; break; case REG15: base_reg="r15"; break; - default: assert(0); + default: + // no base register; + return; } string lea_string="lea "; lea_string+=base_reg; @@ -1883,6 +1885,64 @@ cout<<"using jmp hell node for "<<hex<<insn->GetAddress()->GetVirtualOffset()<<e } +void unpin_init_array(FileIR_t *firp) +{ + for( + DataScoopSet_t::iterator it=firp->GetDataScoops().begin(); + it!=firp->GetDataScoops().end(); + ++it + ) + { + // 4 or 8 + int ptrsize=firp->GetArchitectureBitWidth()/8; + + DataScoop_t* scoop=*it; + const char *scoop_contents=scoop->GetContents().c_str(); + if(scoop->GetName()==".init_array") + { + for(int i=0; i+ptrsize <= scoop->GetSize() ; i+=ptrsize) + { + virtual_offset_t vo; + if(ptrsize==4) + /* get int, 4 bytes */ + vo=(virtual_offset_t)*(int*)&scoop_contents[i]; + else if(ptrsize==8) + /* get long long, 8 bytes */ + vo=(virtual_offset_t)*(long long*)&scoop_contents[i]; + else + assert(0); + + + Instruction_t* insn=lookupInstruction(firp,vo); + + + cout<<"Unpinning entry at offset "<<dec<<i<<endl; + // these asserts are probably overkill, but want them for sanity checking for now. + assert(insn); + assert(targets.find(vo)!=targets.end()); + assert(targets[vo].areOnlyTheseSet( + ibt_provenance_t::ibtp_initarray | ibt_provenance_t::ibtp_stars_data)); + // when/if they fail, convert to if and guard the reloc creation. + + Relocation_t* nr=new Relocation_t(); + assert(nr); + nr->SetType("init_array_entry"); + nr->SetOffset(i); + nr->SetWRT(insn); + + // add reloc to IR. + firp->GetRelocations().insert(nr); + scoop->GetRelocations().insert(nr); + } + } + } +} + +void unpin_well_analyzed_ibts(FileIR_t *firp) +{ + unpin_init_array(firp); +} + /* @@ -1951,6 +2011,9 @@ void fill_in_indtargs(FileIR_t* firp, exeio* elfiop, std::list<virtual_offset_t> // try to setup an ICFS for every IB. setup_icfs(firp); + + + unpin_well_analyzed_ibts(firp); } diff --git a/libIRDB/test/fill_in_indtargs.hpp b/libIRDB/test/fill_in_indtargs.hpp index 7fea34de9e19ac18fa66a77f7c8e764542b0edcb..1f14c2760b2d9b07dbc66418eb1cf5d8572bd7ea 100644 --- a/libIRDB/test/fill_in_indtargs.hpp +++ b/libIRDB/test/fill_in_indtargs.hpp @@ -95,12 +95,15 @@ class ibt_provenance_t static const provtype_t ibtp_unknown=1<<28; // completely unknown static const provtype_t ibtp_got=1<<29; // got is 0 init'd, shouldn't see this one. - void add(provtype_t t) { value |=t; } - void add(ibt_provenance_t t) { value |=t.value; } - bool isFullySet(provtype_t t) { return (value&t) == t; } - bool isFullySet(ibt_provenance_t t) { return (value&t.value) == t.value; } - bool isPartiallySet(provtype_t t) { return (value&t) != 0; } - bool isPartiallySet(ibt_provenance_t t) { return (value&t.value) != 0; } + void add(const provtype_t t) { value |=t; } + void add(const ibt_provenance_t t) { value |=t.value; } + bool isFullySet(const provtype_t t) const { return (value&t) == t; } + bool isFullySet(const ibt_provenance_t t) const { return (value&t.value) == t.value; } + bool isPartiallySet(const provtype_t t) const { return (value&t) != 0; } + bool isPartiallySet(const ibt_provenance_t t) const { return (value&t.value) != 0; } + + bool areOnlyTheseSet(const provtype_t t) const { return (value&~t) == 0; } + bool areOnlyTheseSet(const ibt_provenance_t t) const { return (value&~t.value) == 0; } private: