From 25bd705deb4de71bdf298cc568e7144b4bdf5be7 Mon Sep 17 00:00:00 2001 From: an7s <an7s@git.zephyr-software.com> Date: Thu, 23 Jul 2015 20:12:09 +0000 Subject: [PATCH] Windows support for meds2pdb NB: database schema changed: virtual_address_offset are now 64bit Former-commit-id: 8a965317cc568b9d662a93d57b72c26117be56b8 --- libEXEIO/include/exeio.h | 5 ++-- libEXEIO/include/exeio_pe.h | 10 ++++--- libIRDB/include/core/address.hpp | 4 ++- libIRDB/include/core/baseobj.hpp | 3 ++- libIRDB/include/core/basetypes.hpp | 4 +-- libIRDB/include/utils.hpp | 21 ++++++++++++++- libIRDB/src/core/fileir.cpp | 9 +++++-- tools/meds2pdb/SConscript | 1 + tools/meds2pdb/meds2pdb.cpp | 1 - xform/SConscript | 1 + xform/elfreader.cpp | 17 +++++++++--- xform/elfreader.h | 18 +++++++------ xform/instruction_descriptor.cpp | 10 ------- xform/rewriter.cpp | 43 +++++++----------------------- 14 files changed, 79 insertions(+), 68 deletions(-) diff --git a/libEXEIO/include/exeio.h b/libEXEIO/include/exeio.h index 09c5e011d..2da0c8707 100644 --- a/libEXEIO/include/exeio.h +++ b/libEXEIO/include/exeio.h @@ -14,8 +14,7 @@ namespace EXEIO typedef enum { ELF64, ELF32, PE32, PE64 } execlass_t; - typedef int virtual_offset_t; - + typedef uintptr_t virtual_offset_t; // create type to match elfio @@ -76,7 +75,7 @@ namespace EXEIO exeio_t(char* filename) { Init(); load(filename); } ~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/libEXEIO/include/exeio_pe.h b/libEXEIO/include/exeio_pe.h index 60eacb39c..cc496d6ec 100644 --- a/libEXEIO/include/exeio_pe.h +++ b/libEXEIO/include/exeio_pe.h @@ -17,7 +17,7 @@ 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); } + exeio_pe_section_t(const pe_bliss::section *the_s, const pe_bliss::pe_base *the_b) : s(the_s),b(the_b) { assert(s); assert(b);} bool isLoadable() const { return s->readable(); } bool isExecutable() const { return s->executable(); } @@ -25,11 +25,15 @@ namespace EXEIO 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(); } + EXEIO::virtual_offset_t get_address() const { + EXEIO::virtual_offset_t base = b->get_image_base_64(); + return base + s->get_virtual_address(); + } bool mightContainStrings() const { assert(0); } private: const pe_bliss::section *s; + const pe_bliss::pe_base *b; }; class exeio_pe_backend_t : public exeio_backend_t @@ -72,7 +76,7 @@ namespace EXEIO it != pe_sections->end(); ++it) { const pe_bliss::section& s = *it; - main->sections.add_section(new EXEIO::exeio_pe_section_t(&s)); + main->sections.add_section(new EXEIO::exeio_pe_section_t(&s,e)); } diff --git a/libIRDB/include/core/address.hpp b/libIRDB/include/core/address.hpp index dd267e9aa..7495975ef 100644 --- a/libIRDB/include/core/address.hpp +++ b/libIRDB/include/core/address.hpp @@ -18,10 +18,12 @@ * */ +#include <stdint.h> + // // An address in a variant. // -typedef int virtual_offset_t; +typedef uintptr_t virtual_offset_t; class AddressID_t : public BaseObj_t { public: diff --git a/libIRDB/include/core/baseobj.hpp b/libIRDB/include/core/baseobj.hpp index b3d78a64c..06a2feb94 100644 --- a/libIRDB/include/core/baseobj.hpp +++ b/libIRDB/include/core/baseobj.hpp @@ -19,8 +19,9 @@ */ +#include <stdint.h> -typedef int virtual_offset_t; +typedef uintptr_t virtual_offset_t; typedef int db_id_t; diff --git a/libIRDB/include/core/basetypes.hpp b/libIRDB/include/core/basetypes.hpp index aacca91c6..c458d202f 100644 --- a/libIRDB/include/core/basetypes.hpp +++ b/libIRDB/include/core/basetypes.hpp @@ -18,8 +18,8 @@ * */ +#include <stdint.h> - -typedef int virtual_offset_t; +typedef uintptr_t virtual_offset_t; typedef int db_id_t; typedef int schema_version_t; diff --git a/libIRDB/include/utils.hpp b/libIRDB/include/utils.hpp index 2e507fe5c..5a36002c0 100644 --- a/libIRDB/include/utils.hpp +++ b/libIRDB/include/utils.hpp @@ -19,12 +19,17 @@ */ - +#ifndef _IRDB_UTIL_ +#define _IRDB_UTIL_ #include <sstream> #include <map> #include <algorithm> #include <set> +#include <string> +#include <iostream> +#include <sstream> +#include <stdint.h> template <class T> inline std::string to_string (const T& t) @@ -74,3 +79,17 @@ inline S const& find_map_object( const std::map< T , S > &a_map, const T& key) return (*it).second; } + +typedef uintptr_t virtual_offset_t; + +template<class T> T strtoint(std::string s) +{ + std::stringstream str(s); + T off; + + str >> off; + + return off; +} + +#endif diff --git a/libIRDB/src/core/fileir.cpp b/libIRDB/src/core/fileir.cpp index d19411fdb..9aa6b9864 100644 --- a/libIRDB/src/core/fileir.cpp +++ b/libIRDB/src/core/fileir.cpp @@ -54,6 +54,11 @@ static void UpdateEntryPoints(std::map<db_id_t,Instruction_t*> &insnMap) } +virtual_offset_t strtovo(std::string s) +{ + return strtoint<virtual_offset_t>(s); +} + // Create a Variant from the database FileIR_t::FileIR_t(const VariantID_t &newprogid, File_t* fid) : BaseObj_t(NULL) { @@ -322,13 +327,13 @@ std::map<db_id_t,AddressID_t*> FileIR_t::ReadAddrsFromDB { // address_id integer PRIMARY KEY, // file_id integer REFERENCES file_info, -// vaddress_offset text, +// vaddress_offset bigint, // doip_id integer DEFAULT -1 db_id_t aid=atoi(dbintr->GetResultColumn("address_id").c_str()); db_id_t file_id=atoi(dbintr->GetResultColumn("file_id").c_str()); - int vaddr=atoi(dbintr->GetResultColumn("vaddress_offset").c_str()); + virtual_offset_t vaddr=strtovo(dbintr->GetResultColumn("vaddress_offset")); db_id_t doipid=atoi(dbintr->GetResultColumn("doip_id").c_str()); AddressID_t *newaddr=new AddressID_t(aid,file_id,vaddr); diff --git a/tools/meds2pdb/SConscript b/tools/meds2pdb/SConscript index fe81af7fa..db4b58d99 100644 --- a/tools/meds2pdb/SConscript +++ b/tools/meds2pdb/SConscript @@ -9,6 +9,7 @@ myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) cpppath=''' $SECURITY_TRANSFORMS_HOME/include $SECURITY_TRANSFORMS_HOME/xform + $SECURITY_TRANSFORMS_HOME/libEXEIO/include $SECURITY_TRANSFORMS_HOME/libIRDB/include $SECURITY_TRANSFORMS_HOME/libMEDSannotation/include $SECURITY_TRANSFORMS_HOME/beaengine/include diff --git a/tools/meds2pdb/meds2pdb.cpp b/tools/meds2pdb/meds2pdb.cpp index 3aac5bd90..f23b51208 100644 --- a/tools/meds2pdb/meds2pdb.cpp +++ b/tools/meds2pdb/meds2pdb.cpp @@ -115,7 +115,6 @@ void insert_instructions(int fileID, vector<wahoo::Instruction*> instructions, v int address_id = next_address_id++; - // insert into address table if (j != i) query += ","; query += "("; diff --git a/xform/SConscript b/xform/SConscript index 0bff1d594..a6558a57d 100644 --- a/xform/SConscript +++ b/xform/SConscript @@ -22,6 +22,7 @@ files= ''' ''' cpppath=''' $SECURITY_TRANSFORMS_HOME/beaengine/include/ + $SECURITY_TRANSFORMS_HOME/libEXEIO/include/ $SECURITY_TRANSFORMS_HOME/include/ ''' diff --git a/xform/elfreader.cpp b/xform/elfreader.cpp index 7db6b76aa..e5fac16a6 100644 --- a/xform/elfreader.cpp +++ b/xform/elfreader.cpp @@ -22,20 +22,30 @@ #include <string.h> #include "targ-config.h" +#include <stdio.h> + +/* #include "elfio/elfio.hpp" #include "elfio/elfio_dump.hpp" +*/ #include "elfreader.h" using namespace std; -using namespace ELFIO; +//using namespace ELFIO; +using namespace EXEIO; ElfReader::ElfReader(char *p_elfFile) { - m_reader=new elfio; -// ELFIO::GetInstance()->CreateELFI( &m_reader ); +// m_reader=new elfio; + m_reader=new EXEIO::exeio(p_elfFile); + assert(m_reader); + + EXEIO::dump::header(cout, *m_reader); + EXEIO::dump::section_headers(cout, *m_reader); // Initialize it +/* bool ok = m_reader->load( p_elfFile ); if ( ! ok ) { std::cerr << "Can't open file" << std::endl; @@ -64,6 +74,7 @@ ElfReader::ElfReader(char *p_elfFile) } std::cout << std::endl; +*/ } ElfReader::~ElfReader() diff --git a/xform/elfreader.h b/xform/elfreader.h index bcf58b179..23ae15bd4 100644 --- a/xform/elfreader.h +++ b/xform/elfreader.h @@ -2,7 +2,8 @@ #define _elfreader_H_ #include <vector> -#include "elfio/elfio.hpp" +// #include "elfio/elfio.hpp" +#include "exeio.h" #include "targ-config.h" #include <assert.h> @@ -21,15 +22,16 @@ class ElfReader bool read(app_iaddr_t p_pc, unsigned p_numBytes, char* p_buf); char* getInstructionBuffer(app_iaddr_t p_pc); - bool isElf64() { assert(m_reader); return m_reader->get_class()==ELFCLASS64; } - - - - + bool isElf32() { assert(m_reader); return m_reader->get_class()==EXEIO::ELF32; } + bool isElf64() { assert(m_reader); return m_reader->get_class()==EXEIO::ELF64; } + bool isPe32() { assert(m_reader); return m_reader->get_class()==EXEIO::PE32; } + bool isPe64() { assert(m_reader); return m_reader->get_class()==EXEIO::PE64; } private: - ELFIO::elfio* m_reader; - std::vector < const ELFIO::section* > m_sections; +// ELFIO::elfio* m_reader; + EXEIO::exeio* m_reader; + +// std::vector < const ELFIO::section* > m_sections; }; diff --git a/xform/instruction_descriptor.cpp b/xform/instruction_descriptor.cpp index 9704848cd..36164b1be 100644 --- a/xform/instruction_descriptor.cpp +++ b/xform/instruction_descriptor.cpp @@ -18,7 +18,6 @@ * */ -#include <string.h> #include "instruction_descriptor.h" #include "function_descriptor.h" @@ -35,7 +34,6 @@ wahoo::Instruction::Instruction() m_stackRef = false; m_varStackRef = false; m_isVisited = false; -// m_data[0] = '\0'; m_data = NULL; } @@ -50,7 +48,6 @@ wahoo::Instruction::Instruction(app_iaddr_t p_address, int p_size, Function* p_f m_allocSite = false; m_deallocSite = false; m_stackRef = false; - // m_data[0] = '\0'; m_data = NULL; } @@ -86,10 +83,3 @@ void wahoo::Instruction::markVarStackRef() { m_varStackRef = true; } - -/* -void wahoo::Instruction::setData(void *data, int len) -{ - memcpy(m_data, data, len); -} -*/ diff --git a/xform/rewriter.cpp b/xform/rewriter.cpp index d06c56562..a7ed292b4 100644 --- a/xform/rewriter.cpp +++ b/xform/rewriter.cpp @@ -109,7 +109,7 @@ void Rewriter::readAnnotationFile(char p_filename[]) else annot_type=size_type_u.type; -// fprintf(stderr,"main loop: addr 0x%x scope: %s\n", addr, scope); +// fprintf(stderr,"main loop: addr 0x%p scope: %s\n", addr, scope); /* if the size > 0, then this is a declaration of a variable */ if(strcmp(type,"FUNC")==0) @@ -230,7 +230,7 @@ void Rewriter::readAnnotationFile(char p_filename[]) } else if(strcmp(type,"INSTR")==0) { -//fprintf(stderr, "At 0x%x, handling %s -- scope:%s\n", addr, type, scope); +//fprintf(stderr, "INSTR: At %p, handling %s -- scope:%s\n", addr, type, scope); /* optimizing annotation about not needing heavyweight metadata update */ /* ignore for now */ @@ -667,11 +667,11 @@ void Rewriter::readElfFile(char p_filename[]) objdump=strdup("objdump"); sprintf(buf, "%s -d --prefix-addresses %s | grep \"^[0-9]\"", objdump, p_filename); FILE* pin=popen(buf, "r"); - int addr; + app_iaddr_t addr; assert(pin); - fscanf(pin, "%x", &addr); + fscanf(pin, "%p", &addr); fgets(buf,sizeof(buf),pin); do { @@ -697,6 +697,8 @@ void Rewriter::dissassemble() vector<wahoo::Instruction*> instructions=getAllInstructions(); + fprintf(stderr, "Rewriter::disassemble(): number of instructions: %d\n", instructions.size()); + for (int j = 0; j < instructions.size(); ++j) { wahoo::Instruction *instr = instructions[j]; @@ -707,11 +709,13 @@ void Rewriter::dissassemble() disasm.Options = NasmSyntax + PrefixedNumeral; - if(getElfReader()->isElf64()) + if(getElfReader()->isElf64() || getElfReader()->isPe64()) disasm.Archi = 64; + else disasm.Archi = 32; + disasm.EIP = (UIntPtr) getElfReader()->getInstructionBuffer(instr->getAddress()); disasm.VirtualAddr = instr->getAddress(); @@ -729,7 +733,7 @@ void Rewriter::dissassemble() } else { - cerr<<"BeaEngine has decided that instrution at "<<hex + cerr<<"BeaEngine has decided that instruction at "<<hex <<instr->getAddress()<<dec<<" is bogus."<<endl; /* bogus intruction, remove it */ m_instructions[instr->getAddress()]=NULL; @@ -873,33 +877,6 @@ map<wahoo::Function*, double> Rewriter::getFunctionCoverage(char *p_instructionF visitedInstructions.insert((app_iaddr_t) address); } -/* - - FILE *fp = fopen(p_instructionFile, "r"); - if (!fp) { - cerr << "File containing instructions visited not found:" << p_instructionFile << endl; - return coverage; - } - - cerr<<"func cover checkpoint2"<<endl; - - set<app_iaddr_t> visitedInstructions; - - while (!feof(fp)) - { - int address = 0; - fscanf(fp, "%x\n", &address); - - cerr<<"address = "<<address<<endl; - - visitedInstructions.insert((app_iaddr_t) address); - } - - cerr<<"func cover checkpoint3"<<endl; - - fclose(fp); -*/ - vector<wahoo::Instruction*> allInstructions = getAllInstructions(); for (int i = 0; i < allInstructions.size(); ++i) -- GitLab