From fce7ecf7ef33d0b7fe9b2a9944338cb6b126bba5 Mon Sep 17 00:00:00 2001
From: jdh8d <jdh8d@git.zephyr-software.com>
Date: Sat, 11 Jul 2015 03:04:42 +0000
Subject: [PATCH] Former-commit-id: d22cc26ae510469b51f2564a95442e4c9f28ea3c

---
 .gitattributes              |   4 +
 libEXEIO/SConscript         |   1 +
 libEXEIO/include/exeio.h    |   2 +-
 libEXEIO/include/exeio_pe.h | 144 ++++++++++++++++++++++++++++++++++++
 libEXEIO/src/SConscript     |   2 +
 libEXEIO/src/exeio_src.cpp  |  21 +++++-
 libEXEIO/test/SConscript    |  37 +++++++++
 libEXEIO/test/SConstruct    |   6 ++
 libEXEIO/test/main.cpp      |  23 ++++++
 9 files changed, 238 insertions(+), 2 deletions(-)
 create mode 100644 libEXEIO/include/exeio_pe.h
 create mode 100644 libEXEIO/test/SConscript
 create mode 100644 libEXEIO/test/SConstruct
 create mode 100644 libEXEIO/test/main.cpp

diff --git a/.gitattributes b/.gitattributes
index 3b284ae74..cadaae1c5 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -188,9 +188,13 @@ libEXEIO/SConscript -text
 libEXEIO/SConstruct -text
 libEXEIO/include/exeio.h -text
 libEXEIO/include/exeio_elf.h -text
+libEXEIO/include/exeio_pe.h -text
 libEXEIO/src/SConscript -text
 libEXEIO/src/SConstruct -text
 libEXEIO/src/exeio_src.cpp -text
+libEXEIO/test/SConscript -text
+libEXEIO/test/SConstruct -text
+libEXEIO/test/main.cpp -text
 libIRDB/LICENSE.txt -text
 libIRDB/Makefile.in -text
 libIRDB/SConscript -text
diff --git a/libEXEIO/SConscript b/libEXEIO/SConscript
index 4440b8bb3..604584b90 100644
--- a/libEXEIO/SConscript
+++ b/libEXEIO/SConscript
@@ -3,3 +3,4 @@ import os
 Import('env')
 
 SConscript("src/SConscript")
+SConscript("test/SConscript")
diff --git a/libEXEIO/include/exeio.h b/libEXEIO/include/exeio.h
index 4537352e6..09c5e011d 100644
--- a/libEXEIO/include/exeio.h
+++ b/libEXEIO/include/exeio.h
@@ -12,7 +12,7 @@ namespace EXEIO
 {
 	class exeio_t; // forward decl
 
-	typedef enum { ELF64, ELF32 } execlass_t;
+	typedef enum { ELF64, ELF32, PE32, PE64 } execlass_t;
 
 	typedef int virtual_offset_t;
 
diff --git a/libEXEIO/include/exeio_pe.h b/libEXEIO/include/exeio_pe.h
new file mode 100644
index 000000000..60eacb39c
--- /dev/null
+++ b/libEXEIO/include/exeio_pe.h
@@ -0,0 +1,144 @@
+#ifndef EXEIO_PE_H
+#define EXEIO_PE_H
+
+#include <iostream>
+#include <vector>
+#include <assert.h>
+#include <fstream>
+#include <pe_bliss.h>
+
+
+class exeio_backend;
+class exeio_section;
+
+
+namespace EXEIO
+{
+	class exeio_pe_section_t : public exeio_section_t
+	{
+		public:
+			exeio_pe_section_t(const pe_bliss::section *the_s) : s(the_s) { assert(s); }
+
+			bool isLoadable() const { return s->readable(); }
+			bool isExecutable() const { return s->executable(); }
+			bool isBSS() const  { return s->empty(); }
+			const char* get_data() const  { return s->get_raw_data().c_str(); }
+			std::string get_name() const { return s->get_name(); }
+			int get_size() const  { return s->get_virtual_size(); }
+			EXEIO::virtual_offset_t get_address() const { return s->get_virtual_address(); }
+			bool mightContainStrings() const { assert(0); }
+
+		private:
+			const pe_bliss::section *s;
+	};
+
+	class exeio_pe_backend_t : public exeio_backend_t
+	{
+		public:
+			exeio_pe_backend_t() : e(NULL), main(NULL), pe_sections(NULL) {}
+			~exeio_pe_backend_t()
+			{
+				if(!main)
+					return;
+				// remove subclasses.
+				for(int i=0;i<main->sections.size(); ++i)
+				{
+					// copy each section into the main class' structure.
+					delete main->sections[i];
+				}
+
+				// remove the pe_bliss class.
+				delete e;
+			}
+			void load(exeio* the_main, char* filename)
+			{
+				main=the_main;
+
+				std::ifstream pe_file(filename, std::ios::in | std::ios::binary);
+        			if(!pe_file)
+        			{
+                			std::cerr << "Cannot open " << filename << std::endl;
+                			assert(0);
+					exit(1);
+        			}
+
+
+				e=new pe_bliss::pe_base(pe_bliss::pe_factory::create_pe(pe_file));
+				assert(e);
+
+				pe_sections=new pe_bliss::section_list(e->get_image_sections());
+
+                		for(pe_bliss::section_list::const_iterator it = pe_sections->begin(); 
+					it != pe_sections->end(); ++it)
+                		{
+                        		const pe_bliss::section& s = *it; 
+					main->sections.add_section(new EXEIO::exeio_pe_section_t(&s));
+				}
+
+	
+			}
+                        virtual void dump_header(std::ostream& stream) 
+			{
+				assert(e);
+
+                		std::cout << "EP : " <<std::hex<< e->get_ep() << std::endl;
+                		std::cout << "EP section name: " << e->section_from_rva(e->get_ep()).get_name() << std::endl;
+                		std::cout << "EP section data length: " << 
+					e->section_data_length_from_rva(e->get_ep()) << std::endl;
+
+                		if(e->has_imports())
+				{
+                        		std::cout << "Import section name: " << 
+						e->section_from_directory(pe_bliss::pe_win
+						::image_directory_entry_import).get_name() 
+						<< std::endl;
+				}
+			}
+                        virtual void dump_section_headers(std::ostream& stream) 
+			{
+				assert(e);
+                		for(pe_bliss::section_list::const_iterator it = pe_sections->begin(); 
+					it != pe_sections->end(); ++it)
+                		{
+                        		const pe_bliss::section& s = *it; //Секция
+                        		std::cout << "Section [" << s.get_name() << "]" << std::endl //Имя секции
+                                		<< "Characteristics: " << s.get_characteristics() << std::endl 
+                                		<< "Size of raw data: " << s.get_size_of_raw_data() << std::endl 
+                                		<< "Virtual address: " << s.get_virtual_address() << std::endl 
+                                		<< "Virtual size: " << s.get_virtual_size() << std::endl 
+                                		<< std::endl;
+                		}
+
+			}
+                        virtual execlass_t get_class() 
+			{
+				assert(e);
+        			if(e->get_pe_type() == pe_bliss::pe_type_32)
+					return PE32;
+        			if(e->get_pe_type() == pe_bliss::pe_type_64)
+					return PE64;
+				assert(0);
+			}
+
+			// get entry point of function.
+                        virtual virtual_offset_t get_entry()
+			{
+				assert(e);
+				return (virtual_offset_t)e->get_ep();
+			}
+
+
+                        virtual bool isDLL() { assert(0); }
+
+
+	
+		private:  
+			pe_bliss::pe_base* e;
+			pe_bliss::section_list* pe_sections;
+			EXEIO::exeio* main;
+	};
+	
+
+}
+
+#endif
diff --git a/libEXEIO/src/SConscript b/libEXEIO/src/SConscript
index 8e84e12f9..edc6d2869 100644
--- a/libEXEIO/src/SConscript
+++ b/libEXEIO/src/SConscript
@@ -14,9 +14,11 @@ cpppath='''
 	.
 	$SECURITY_TRANSFORMS_HOME/include/
 	$SECURITY_TRANSFORMS_HOME/libEXEIO/include
+	$SECURITY_TRANSFORMS_HOME/pebliss/trunk/pe_lib/
 	'''
 
 #myenv.Append(CCFLAGS="-Wp,-w -Wall")
+myenv.Append(CCFLAGS="-w")
 
 myenv=myenv.Clone(CPPPATH=Split(cpppath))
 lib=myenv.Library(libname, Split(files))
diff --git a/libEXEIO/src/exeio_src.cpp b/libEXEIO/src/exeio_src.cpp
index afecb4db3..fb59192a9 100644
--- a/libEXEIO/src/exeio_src.cpp
+++ b/libEXEIO/src/exeio_src.cpp
@@ -1,15 +1,34 @@
 
 
+#include <istream>
+#include <fstream>
 #include <exeio.h>
 #include <exeio_elf.h>
+#include <exeio_pe.h>
 
 
 using namespace EXEIO;
+using namespace pe_bliss;
 using namespace std;
 
 void exeio::load(char* filename)
 {
-	backend=new exeio_elf_backend_t();
+
+	ifstream instream(filename); 
+
+	if(!instream)
+		assert(0 && "Cannot open file");
+
+
+	// check for elf magic number
+	if( instream.get()=='E' && instream.get()=='L' && instream.get()=='F' )
+	{
+		backend=new exeio_elf_backend_t();
+	}
+	// we assume it's ELF or PE.
+	else
+		backend=new exeio_pe_backend_t();
+
 	backend->load(this, filename);
 
 }
diff --git a/libEXEIO/test/SConscript b/libEXEIO/test/SConscript
new file mode 100644
index 000000000..a8581a4c8
--- /dev/null
+++ b/libEXEIO/test/SConscript
@@ -0,0 +1,37 @@
+import os
+
+Import('env')
+myenv=env
+myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME'])
+
+
+libname="test"
+files=  '''
+	main.cpp
+	'''
+
+cpppath=''' 
+	.
+	$SECURITY_TRANSFORMS_HOME/include/
+	$SECURITY_TRANSFORMS_HOME/libEXEIO/include
+	$SECURITY_TRANSFORMS_HOME/libEXEIO/include
+	'''
+libpath=''' 
+	$SECURITY_TRANSFORMS_HOME/lib/
+	'''
+
+#myenv.Append(CCFLAGS="-Wp,-w -Wall")
+myenv.Append(CCFLAGS="-g")
+
+libs=   '''
+	EXEIO
+	PEBLISS
+	iconv
+	'''
+
+myenv=myenv.Clone(CPPPATH=Split(cpppath), LIBS=Split(libs), LIBPATH=Split(libpath))
+lib=myenv.Program(libname, Split(files))
+
+#install=myenv.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib)
+#Default(install)
+
diff --git a/libEXEIO/test/SConstruct b/libEXEIO/test/SConstruct
new file mode 100644
index 000000000..c0dd68a00
--- /dev/null
+++ b/libEXEIO/test/SConstruct
@@ -0,0 +1,6 @@
+
+
+
+env=Environment()
+Export('env')
+SConscript("SConscript")
diff --git a/libEXEIO/test/main.cpp b/libEXEIO/test/main.cpp
new file mode 100644
index 000000000..041d395f3
--- /dev/null
+++ b/libEXEIO/test/main.cpp
@@ -0,0 +1,23 @@
+#include <iostream>
+#include <exeio.h>
+
+using namespace std;
+using namespace EXEIO;
+
+
+int main(int argc, char* argv[])
+{
+	if(argc!=2)
+	{
+		cout<<"Usage: "<<argv[0]<<": <exe>"<<endl;
+	}
+
+	exeio *exep=new exeio;
+
+	exep->load(argv[1]);
+
+	EXEIO::dump::header(cout,*exep);
+	EXEIO::dump::section_headers(cout,*exep);
+
+	return 0;
+}
-- 
GitLab