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