From 9da5b9e1b6d09c9226372697885a0d7fcb827890 Mon Sep 17 00:00:00 2001 From: jdh8d <jdh8d@git.zephyr-software.com> Date: Wed, 1 Jun 2016 03:05:55 +0000 Subject: [PATCH] Update to zipr to support relro scoops, and fix to move globals/SplitScoop to handle file size properly. Former-commit-id: bf907e0a2983b239b5bbee037394cdbc86a25f14 --- libEXEIO/include/exeio.h | 2 +- libIRDB/src/core/fileir.cpp | 6 ++--- libIRDB/test/fill_in_cfg.cpp | 49 ++++++++++++++++++++++++++++++++++-- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/libEXEIO/include/exeio.h b/libEXEIO/include/exeio.h index 7b103b480..6681d9b69 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 1b75c1832..46a43d8de 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 27b031eab..0c099399d 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); -- GitLab