diff --git a/.gitattributes b/.gitattributes index 4407c0d715f46148763da236124244c3f78caeb9..36b39ffeb9793664a4b72c3dc72278de5c72ea8b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -240,7 +240,6 @@ libIRDB/src/cfg/SConscript -text libIRDB/src/cfg/SConstruct -text libIRDB/src/cfg/callgraph.cpp -text libIRDB/src/cfg/domgraph.cpp -text -libIRDB/src/core/Makefile -text libIRDB/src/core/SConscript -text libIRDB/src/core/SConstruct -text libIRDB/src/core/address.cpp -text diff --git a/libIRDB/include/core/fileir.hpp b/libIRDB/include/core/fileir.hpp index ecf8ea3f20dc6f1c580012e938139c05eac0e6d2..31b6ad37f1459c2ac04e78982e54c5c5c8c40361 100644 --- a/libIRDB/include/core/fileir.hpp +++ b/libIRDB/include/core/fileir.hpp @@ -69,6 +69,7 @@ class FileIR_t : public BaseObj_t void GenerateSPRI(FileIR_t *orig_varirp, std::ostream &fout, bool with_ilr=false); void SetBaseIDS(); + db_id_t GetMaxBaseID(); File_t* GetFile() const { return fileptr; } diff --git a/libIRDB/src/core/Makefile b/libIRDB/src/core/Makefile deleted file mode 100644 index 8ab0b7f628a261ab2d5af0e0868e568c46ca1f98..0000000000000000000000000000000000000000 --- a/libIRDB/src/core/Makefile +++ /dev/null @@ -1,16 +0,0 @@ - -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 icfs.o generate_spri.o - -all: $(OBJS) - -$(OBJS): ../../include/core/*.hpp *.hpp ../../include/*.hpp - -clean: - rm -f $(OBJS) - -.cpp.o: - $(CXX) -fPIC -g -c -I. -I../../include -I../../../beaengine/include $< - ar rc $(LIB) $@ diff --git a/libIRDB/src/core/fileir.cpp b/libIRDB/src/core/fileir.cpp index 23f15847c4454d3f6ce80c3ea352ce86cadfc221..4cbeeb409319f9ff383cccf05c2f55f6dc3a5451 100644 --- a/libIRDB/src/core/fileir.cpp +++ b/libIRDB/src/core/fileir.cpp @@ -854,7 +854,7 @@ void FileIR_t::WriteToDB() } -void FileIR_t::SetBaseIDS() +db_id_t FileIR_t::GetMaxBaseID() { #define MAX(a,b) (((a)>(b)) ? (a) : (b)) @@ -879,9 +879,14 @@ void FileIR_t::SetBaseIDS() for(auto i=eh_css.begin(); i!=eh_css.end(); ++i) j=MAX(j,(*i)->GetBaseID()); + return j+1; // easy to off-by-one this so we do it for a user just in case. +} + +void FileIR_t::SetBaseIDS() +{ + auto j=GetMaxBaseID(); /* increment past the max ID so we don't duplicate */ j++; - /* for anything that's not yet in the DB, assign an ID to it */ for(auto i=funcs.begin(); i!=funcs.end(); ++i) if((*i)->GetBaseID()==NOT_IN_DATABASE) @@ -1515,24 +1520,38 @@ void FileIR_t::SplitScoop( return; } - bool needs_before = addr!=tosplit->GetStart()->GetVirtualOffset(); - bool needs_after = addr+size-1 != tosplit->GetEnd()->GetVirtualOffset(); + const auto max=GetMaxBaseID(); + const auto multiple=1000; + + // round to nearest multiple + const auto rounded_max = ((max + multiple/2) / multiple) * multiple; + + auto id=rounded_max + multiple; // and skip forward so we're passed the highest. + + assert(id>=max); + + const bool needs_before = addr!=tosplit->GetStart()->GetVirtualOffset(); + const bool needs_after = addr+size-1 != tosplit->GetEnd()->GetVirtualOffset(); if(needs_before) { // setup before - AddressID_t* before_start=NULL; + // const AddressID_t* before_start=NULL; - before_start=new AddressID_t; + const auto before_start=new AddressID_t; + before_start->SetBaseID(id++); before_start->SetFileID(tosplit->GetStart()->GetFileID()); before_start->SetVirtualOffset(tosplit->GetStart()->GetVirtualOffset()); - AddressID_t* before_end=new AddressID_t; + // const AddressID_t* before_end=new AddressID_t; + const auto before_end=new AddressID_t; + before_end->SetBaseID(id++); before_end->SetFileID(tosplit->GetStart()->GetFileID()); before_end->SetVirtualOffset(addr-1); before=new DataScoop_t; + before->SetBaseID(id++); before->SetName(tosplit->GetName()+"3"); before->SetStart(before_start); before->SetEnd(before_end); @@ -1550,15 +1569,20 @@ void FileIR_t::SplitScoop( } // setup containing - AddressID_t* containing_start=new AddressID_t; + // AddressID_t* containing_start=new AddressID_t; + const auto containing_start=new AddressID_t; + containing_start->SetBaseID(id++); containing_start->SetFileID(tosplit->GetStart()->GetFileID()); containing_start->SetVirtualOffset(addr); - AddressID_t* containing_end=new AddressID_t; + //AddressID_t* containing_end=new AddressID_t; + const auto containing_end=new AddressID_t; + containing_end->SetBaseID(id++); containing_end->SetFileID(tosplit->GetStart()->GetFileID()); containing_end->SetVirtualOffset(addr+size-1); containing=new DataScoop_t; + containing->SetBaseID(id++); containing->SetName(tosplit->GetName()+"3"); containing->SetStart(containing_start); containing->SetEnd(containing_end); @@ -1576,15 +1600,20 @@ void FileIR_t::SplitScoop( if(needs_after) { // setup after - AddressID_t* after_start=new AddressID_t; + // AddressID_t* after_start=new AddressID_t; + const auto after_start=new AddressID_t; + after_start->SetBaseID(id++); after_start->SetFileID(tosplit->GetStart()->GetFileID()); after_start->SetVirtualOffset(addr+size); - AddressID_t* after_end=new AddressID_t; + // AddressID_t* after_end=new AddressID_t; + const auto after_end=new AddressID_t; + after_end->SetBaseID(id++); after_end->SetFileID(tosplit->GetStart()->GetFileID()); after_end->SetVirtualOffset(tosplit->GetEnd()->GetVirtualOffset()); after=new DataScoop_t; + after->SetBaseID(id++); after->SetName(tosplit->GetName()+"3"); after->SetStart(after_start); after->SetEnd(after_end); diff --git a/libIRDB/test/fill_in_cfg.cpp b/libIRDB/test/fill_in_cfg.cpp index a78efb90ccce7367c0993e335ccefc40eb48c20a..d27abadc1468a1a93bd1c5fac40bbbe3f2f5d5db 100644 --- a/libIRDB/test/fill_in_cfg.cpp +++ b/libIRDB/test/fill_in_cfg.cpp @@ -468,8 +468,10 @@ static bool is_in_relro_segment(const int secndx) void fill_in_scoops(FileIR_t *firp) { - int secnum = elfiop->sections.size(); - int secndx=0; + + auto max_base_id=firp->GetMaxBaseID(); + auto secnum = elfiop->sections.size(); + auto secndx=0; /* look through each section */ for (secndx=1; secndx<secnum; secndx++) @@ -540,7 +542,7 @@ void fill_in_scoops(FileIR_t *firp) ( elfiop->sections[secndx]->isExecutable() << 0 ) ; bool is_relro=is_in_relro_segment(secndx); - DataScoop_t *newscoop=new DataScoop_t(BaseObj_t::NOT_IN_DATABASE, name, startaddr, endaddr, NULL, permissions, is_relro, the_contents); + DataScoop_t *newscoop=new DataScoop_t(max_base_id++, name, startaddr, endaddr, NULL, permissions, is_relro, the_contents); assert(newscoop); firp->GetDataScoops().insert(newscoop); diff --git a/tools/transforms/OffsetInference.cpp b/tools/transforms/OffsetInference.cpp index ef534fba2c1152b3c45987ec01bc8770804f30f5..eac562491b77e0b572ef0c18028627421ba36d28 100644 --- a/tools/transforms/OffsetInference.cpp +++ b/tools/transforms/OffsetInference.cpp @@ -32,6 +32,21 @@ using namespace std; using namespace libIRDB; +static Relocation_t* FindRelocation(Instruction_t* insn, string type) +{ + RelocationSet_t::iterator rit; + for( rit=insn->GetRelocations().begin(); rit!=insn->GetRelocations().end(); ++rit) + { + Relocation_t& reloc=*(*rit); + if(reloc.GetType()==type) + { + return &reloc; + } + } + return NULL; +} + + extern int get_saved_reg_size(); //TODO: Use cfg entry point only, then use func instructions, @@ -544,7 +559,14 @@ else if(regexec(&(pn_regex->regex_push_anything), disasm_str.c_str(), max, pmatch, 0)==0) { Instruction_t* ft=instr->GetFallthrough(); - if(ft && !ft->GetFallthrough() && + const auto reloc1=FindRelocation(instr,"32-bit"); + const auto reloc2=FindRelocation(instr,"push64"); + + if(reloc1!=NULL || reloc2!=NULL) + { + /* definite a push from a fixed calls */ + } + else if(ft && !ft->GetFallthrough() && (ft->GetTarget()==NULL || ft->GetTarget()->GetFunction()!=instr->GetFunction())) { /* probably a push/jmp converted by fix calls */ @@ -989,12 +1011,12 @@ else //if the size of aoi is the same as any other inference //assume they are the same (insert a null layout entry) if(pn_direct_offsets->GetRanges().size() != aoi_size) - direct[func] = new PNStackLayout(*pn_direct_offsets); + direct[func] = new PNStackLayout(*pn_direct_offsets, func); else direct[func] = NULL; if(pn_scaled_offsets->GetRanges().size() != aoi_size) - scaled[func] = new PNStackLayout(*pn_scaled_offsets); + scaled[func] = new PNStackLayout(*pn_scaled_offsets, func); else scaled[func] = NULL; @@ -1002,9 +1024,9 @@ else //AOI, I don't want to generate it to save time, but what if a function //has no coverage, so p1 is used, if I set it null here because the //layouts are the same, I wont have any modification for that function. - p1[func] = new PNStackLayout(*pn_p1_offsets); + p1[func] = new PNStackLayout(*pn_p1_offsets, func); - all_offsets[func] = new PNStackLayout(*pn_all_offsets); + all_offsets[func] = new PNStackLayout(*pn_all_offsets, func); if(!dealloc_flag) { diff --git a/tools/transforms/PNStackLayout.cpp b/tools/transforms/PNStackLayout.cpp index 6ea04b8360b7f327e80079d4de6e19d45a261f3e..047e660ad58d23d9a2737c3bf1a7d2ad2a2d11e4 100644 --- a/tools/transforms/PNStackLayout.cpp +++ b/tools/transforms/PNStackLayout.cpp @@ -105,7 +105,7 @@ unsigned int PNStackLayout::GetRandomPadding(unsigned int obj_size) //TODO: negative offsets? -PNStackLayout::PNStackLayout(StackLayout stack_layout) : stack_layout(stack_layout) +PNStackLayout::PNStackLayout(StackLayout stack_layout, libIRDB::Function_t* func) : stack_layout(stack_layout) { ALIGNMENT_BYTE_SIZE=libIRDB::FileIR_t::GetArchitectureBitWidth()/sizeof(int); //PNTransformDriver sets up the seed, I need a better way of handling this @@ -123,8 +123,11 @@ PNStackLayout::PNStackLayout(StackLayout stack_layout) : stack_layout(stack_layo mem_objects.push_back(pn_obj); } - base_id = 0; + assert(func); + base_id = func->GetBaseID(); entry_id = 0; + if(func->GetEntryPoint()!=NULL) + entry_id=func->GetEntryPoint()->GetBaseID(); } PNStackLayout::PNStackLayout(const PNStackLayout &stack_layout): stack_layout(stack_layout.stack_layout) diff --git a/tools/transforms/PNStackLayout.hpp b/tools/transforms/PNStackLayout.hpp index d6e28e826bfc3cf1f745eb0d2a2281c7c0fc61a3..a57ede07ef3c341d8ab5cfd9c26354ac8fbbfcfd 100644 --- a/tools/transforms/PNStackLayout.hpp +++ b/tools/transforms/PNStackLayout.hpp @@ -28,6 +28,7 @@ #include <assert.h> #include "globals.h" #include "canary.h" +#include <libIRDB-core.hpp> //NOTE: padding adds a value between max and min, plus the frame size //I believe this was done to protect against a very large buffer @@ -65,14 +66,14 @@ protected: unsigned int altered_alloc_size; std::vector<canary> canaries; - int base_id; - int entry_id; + libIRDB::db_id_t base_id; + libIRDB::db_id_t entry_id; virtual void AddCanaryPadding(); public: - PNStackLayout(StackLayout stack_layout); + PNStackLayout(StackLayout stack_layout, libIRDB::Function_t* func); PNStackLayout(const PNStackLayout &stack_layout); virtual ~PNStackLayout(); diff --git a/tools/transforms/PNTransformDriver.cpp b/tools/transforms/PNTransformDriver.cpp index d93081cb8fde1026ec8fe76176c9ae8a78a44072..f77b36a30f926159ddcb4d17611bb2c477631c30 100644 --- a/tools/transforms/PNTransformDriver.cpp +++ b/tools/transforms/PNTransformDriver.cpp @@ -2271,8 +2271,8 @@ bool PNTransformDriver::Canary_Rewrite(PNStackLayout *orig_layout, Function_t *f orig_layout->SetCanaries(canaries); - orig_layout->SetBaseID(func->GetBaseID()); - orig_layout->SetEntryID(func->GetEntryPoint()->GetBaseID()); +// orig_layout->SetBaseID(func->GetBaseID()); +// orig_layout->SetEntryID(func->GetEntryPoint()->GetBaseID()); EhUpdater_t eh_update(orig_virp, func, layout); if(!eh_update.execute()) @@ -2307,6 +2307,7 @@ bool PNTransformDriver::Sans_Canary_Rewrite(PNStackLayout *layout, Function_t *f if(!Instruction_Rewrite(layout,instr,&cfg)) return false; } + EhUpdater_t eh_update(orig_virp, func, layout); if(!eh_update.execute()) return false; diff --git a/tools/transforms/PNTransformDriver.hpp b/tools/transforms/PNTransformDriver.hpp index acc41b3648008661a7c3d9cdfc8b20ffaf418db6..d707bffbb687c5087fce8b4921418be230d5bd59 100644 --- a/tools/transforms/PNTransformDriver.hpp +++ b/tools/transforms/PNTransformDriver.hpp @@ -31,6 +31,7 @@ #include "Rewrite_Utility.hpp" #include <libIRDB-cfg.hpp> #include "canary.h" +#include <libIRDB-core.hpp> //TODO: I should use the types defined by beaengine diff --git a/tools/transforms/PrecedenceBoundaryInference.cpp b/tools/transforms/PrecedenceBoundaryInference.cpp index 9f495ddb2580f5d9e49951908cbc47de73b1be9f..b9ca0c30e53c4d910e0c77214418a18923aebcf2 100644 --- a/tools/transforms/PrecedenceBoundaryInference.cpp +++ b/tools/transforms/PrecedenceBoundaryInference.cpp @@ -192,7 +192,7 @@ PNStackLayout* PrecedenceBoundaryInference::GetPNStackLayout(libIRDB::Function_t //and I have removed, as of this version, this inference from P1 // revised_playout.SetCanarySafe(false); - return new PNStackLayout(revised_playout); + return new PNStackLayout(revised_playout, func); } //I don't know why I marked these as not canary safe originally, I think this was @@ -201,7 +201,7 @@ PNStackLayout* PrecedenceBoundaryInference::GetPNStackLayout(libIRDB::Function_t //and I have removed, as of this version, this inference from P1 // precedence_layout.SetCanarySafe(false); - return new PNStackLayout(precedence_layout); + return new PNStackLayout(precedence_layout, func); } string PrecedenceBoundaryInference::GetInferenceName() const