diff --git a/libEXEIO/include/exeio.h b/libEXEIO/include/exeio.h index 7b103b4803b7bbbd9cf0d66d9b7c053427662214..6681d9b699abd5c0bc0012c7559561772240a060 100644 --- a/libEXEIO/include/exeio.h +++ b/libEXEIO/include/exeio.h @@ -79,7 +79,7 @@ namespace EXEIO exeio_t(char* filename) { Init(); load(filename); } virtual ~exeio_t() { delete backend; } - virtual void load(std::string filename) { load((char*)filename.c_str()); } + virtual void load(std::string filename) { load((char*)filename.c_str()); } // load the file virtual void load(char* fn); diff --git a/libIRDB/src/core/fileir.cpp b/libIRDB/src/core/fileir.cpp index 1b75c18323f4d4074aa6fc8281f3f724fc1d39d9..46a43d8de41d5b61054581f9379ee879f6a85181 100644 --- a/libIRDB/src/core/fileir.cpp +++ b/libIRDB/src/core/fileir.cpp @@ -1272,7 +1272,7 @@ void FileIR_t::SplitScoop( before->SetStart(before_start); before->SetEnd(before_end); before->setRawPerms(tosplit->getRawPerms()); - before->GetContents().resize(before_end->GetVirtualOffset() - before_start->GetVirtualOffset()); + before->GetContents().resize(before_end->GetVirtualOffset() - before_start->GetVirtualOffset()+1); // copy bytes for(virtual_offset_t i=before_start->GetVirtualOffset() ; i< before_end->GetVirtualOffset(); i++) @@ -1298,7 +1298,7 @@ void FileIR_t::SplitScoop( containing->SetStart(containing_start); containing->SetEnd(containing_end); containing->setRawPerms(tosplit->getRawPerms()); - containing->GetContents().resize(containing_end->GetVirtualOffset() - containing_start->GetVirtualOffset()); + containing->GetContents().resize(containing_end->GetVirtualOffset() - containing_start->GetVirtualOffset()+1); // copy bytes for(virtual_offset_t i=containing_start->GetVirtualOffset() ; i< containing_end->GetVirtualOffset(); i++) containing->GetContents()[i-containing_start->GetVirtualOffset()] = tosplit->GetContents()[i-tosplit->GetStart()->GetVirtualOffset()]; @@ -1324,7 +1324,7 @@ void FileIR_t::SplitScoop( after->SetStart(after_start); after->SetEnd(after_end); after->setRawPerms(tosplit->getRawPerms()); - after->GetContents().resize(after_end->GetVirtualOffset() - after_start->GetVirtualOffset()); + after->GetContents().resize(after_end->GetVirtualOffset() - after_start->GetVirtualOffset()+1); // copy bytes for(virtual_offset_t i=after_start->GetVirtualOffset() ; i < after_end->GetVirtualOffset(); i++) after->GetContents()[i-after_start->GetVirtualOffset()] = tosplit->GetContents()[i-tosplit->GetStart()->GetVirtualOffset()]; diff --git a/libIRDB/test/fill_in_cfg.cpp b/libIRDB/test/fill_in_cfg.cpp index 27b031eab80c38d3efa249dcf3c5132f58dbe54b..0c099399de8df090f6c17fdbf3708bd60780f6b3 100644 --- a/libIRDB/test/fill_in_cfg.cpp +++ b/libIRDB/test/fill_in_cfg.cpp @@ -31,12 +31,16 @@ #include <ctype.h> #include <exeio.h> +#include "elfio/elfio.hpp" +#include "elfio/elfio_dump.hpp" + #include "beaengine/BeaEngine.h" int odd_target_count=0; int bad_target_count=0; int bad_fallthrough_count=0; +EXEIO::exeio *elfiop=NULL; using namespace libIRDB; using namespace std; @@ -217,7 +221,6 @@ static File_t* find_file(FileIR_t* firp, db_id_t fileid) } -EXEIO::exeio *elfiop=NULL; void add_new_instructions(FileIR_t *firp) { @@ -423,6 +426,47 @@ void fill_in_cfg(FileIR_t *firp) } +static bool is_in_relro_segment(const int secndx) +{ + ELFIO::elfio *real_elfiop = reinterpret_cast<ELFIO::elfio*>(elfiop->get_elfio()); + if(!real_elfiop) + return false; + + int segnum = real_elfiop->segments.size(); + int segndx=0; + + virtual_offset_t sec_start=(virtual_offset_t)(elfiop->sections[secndx]->get_address()); + virtual_offset_t sec_end=(virtual_offset_t)(elfiop->sections[secndx]->get_address() + elfiop->sections[segndx]->get_size() - 1 ); + + /* look through each section */ + for (int segndx=1; segndx<segnum; segndx++) + { + ELFIO::Elf_Word type=real_elfiop->segments[segndx]->get_type(); +#ifndef PT_GNU_RELRO +#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ +#endif + + if(type==PT_GNU_RELRO) + { + virtual_offset_t seg_start=(virtual_offset_t)(real_elfiop->segments[segndx]->get_virtual_address()); + virtual_offset_t seg_end=(virtual_offset_t)(real_elfiop->segments[segndx]->get_virtual_address() + real_elfiop->segments[segndx]->get_memory_size() - 1 ); + + // check if start lies within + if(seg_start <= sec_start && sec_start <= seg_end) + return true; + + // check if end lies within + if(seg_start <= sec_end && sec_end <= seg_end) + return true; + + // check if crosses + if(sec_start < seg_start && seg_end < sec_end) + return true; + } + } + + return false; +} void fill_in_scoops(FileIR_t *firp) { @@ -497,7 +541,8 @@ void fill_in_scoops(FileIR_t *firp) ( elfiop->sections[secndx]->isWriteable() << 1 ) | ( elfiop->sections[secndx]->isExecutable() << 0 ) ; - DataScoop_t *newscoop=new DataScoop_t(BaseObj_t::NOT_IN_DATABASE, name, startaddr, endaddr, NULL, permissions, false, the_contents); + 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); assert(newscoop); firp->GetDataScoops().insert(newscoop);