Skip to content
Snippets Groups Projects
Commit d06241b4 authored by Jason Hiser's avatar Jason Hiser :tractor:
Browse files

mips?!

parent 10400dc7
No related branches found
No related tags found
No related merge requests found
#ifndef ARCHMIPS32_HPP
#define ARCHMIPS32_HPP
class ZiprArchitectureHelperMIPS32_t : public ZiprArchitectureHelperBase_t
{
public:
ZiprArchitectureHelperMIPS32_t(Zipr_SDK::Zipr_t* p_zipr_obj) : ZiprArchitectureHelperBase_t(p_zipr_obj)
{
}
virtual IRDB_SDK::Instruction_t* createNewJumpInstruction(IRDB_SDK::FileIR_t *p_firp, IRDB_SDK::Instruction_t* p_existing) override
{
// bytes = 0b00000000 0b00000000 0b00000000 0b00010000
// jump always with 26bit offset
const auto bits =string("\x10\x00\x00\x000",4);
auto ret=IRDB_SDK::addNewDataBits(p_firp, p_existing, bits);
const auto d=IRDB_SDK::DecodedInstruction_t::factory(ret);
assert(d->valid());
return ret;
}
virtual IRDB_SDK::Instruction_t* createNewHaltInstruction(IRDB_SDK::FileIR_t *p_firp, IRDB_SDK::Instruction_t* p_existing) override
{
// 0b00000000 0b00000000 0b00000000 0b00110100
// teq $0, $0, 0 --> trap always (as $0 is always 0)
const auto bits = string("\x00\x00\x00\x34",4);
auto ret = IRDB_SDK::addNewDataBits(p_firp, p_existing, bits);
const auto d = IRDB_SDK::DecodedInstruction_t::factory(ret);
assert(d->valid());
return ret;
}
};
#endif
/***************************************************************************
* Copyright (c) 2014 Zephyr Software LLC. All rights reserved.
*
* This software is furnished under a license and/or other restrictive
* terms and may be used and copied only in accordance with such terms
* and the inclusion of the above copyright notice. This software or
* any other copies thereof may not be provided or otherwise made
* available to any other person without the express written consent
* of an authorized representative of Zephyr Software LCC. Title to,
* ownership of, and all rights in the software is retained by
* Zephyr Software LCC.
*
* Zephyr Software LLC. Proprietary Information
*
* Unless otherwise specified, the information contained in this
* directory, following this legend, and/or referenced herein is
* Zephyr Software LLC. (Zephyr) Proprietary Information.
*
* CONTACT
*
* For technical assistance, contact Zephyr Software LCC. at:
*
*
* Zephyr Software, LLC
* 2040 Tremont Rd
* Charlottesville, VA 22911
*
* E-mail: jwd@zephyr-software.com
**************************************************************************/
#ifndef PATCHER_MIPS32
#define PATCHER_MIPS32
class ZiprPatcherMIPS32_t : public ZiprPatcherBase_t
{
// data
zipr::ZiprImpl_t* m_parent;
IRDB_SDK::FileIR_t* m_firp;
Zipr_SDK::MemorySpace_t &memory_space;
std::map<RangeAddress_t, RangeAddress_t> redirect_map;
public:
ZiprPatcherMIPS32_t(Zipr_SDK::Zipr_t* p_parent);
void ApplyNopToPatch(RangeAddress_t addr) override;
void ApplyPatch(RangeAddress_t from_addr, RangeAddress_t to_addr) override;
void PatchJump(RangeAddress_t at_addr, RangeAddress_t to_addr) override;
void PatchCall(RangeAddress_t at_addr, RangeAddress_t to_addr) override;
void CallToNop(RangeAddress_t at_addr) override;
};
#endif
#ifndef ZIPR_PINNER_MIPS32
#define ZIPR_PINNER_MIPS32
class ZiprPinnerMIPS32_t : public ZiprPinnerBase_t
{
public:
ZiprPinnerMIPS32_t(Zipr_SDK::Zipr_t* p_parent);
virtual void doPinning() override;
private:
zipr::ZiprImpl_t* m_parent;
IRDB_SDK::FileIR_t* m_firp;
Zipr_SDK::MemorySpace_t &memory_space;
Zipr_SDK::DollopManager_t &m_dollop_mgr;
Zipr_SDK::PlacementQueue_t &placement_queue;
};
#endif
#ifndef SIZERMIPS32_HPP
#define SIZERMIPS32_HPP
class ZiprSizerMIPS32_t : public ZiprSizerBase_t
{
private:
RangeAddress_t TBZPlopDollopEntryWithTarget (Zipr_SDK::DollopEntry_t *entry, RangeAddress_t override_place, RangeAddress_t override_target) const;
RangeAddress_t DefaultPlopDollopEntryWithTarget(Zipr_SDK::DollopEntry_t *entry, RangeAddress_t override_place, RangeAddress_t override_target) const;
public:
ZiprSizerMIPS32_t(Zipr_SDK::Zipr_t* p_zipr_obj);
size_t DetermineInsnSize(IRDB_SDK::Instruction_t*, bool account_for_jump = true) const override;
virtual RangeAddress_t PlopDollopEntryWithTarget(Zipr_SDK::DollopEntry_t *entry, RangeAddress_t override_place, RangeAddress_t override_target) const override;
};
#endif
......@@ -28,16 +28,19 @@ files= '''
arch_base.cpp
pinner_arm64.cpp
pinner_arm32.cpp
pinner_mips32.cpp
pinner_base.cpp
pinner_x86.cpp
patcher_arm64.cpp
patcher_arm32.cpp
patcher_mips32.cpp
patcher_base.cpp
patcher_x86.cpp
sizer_base.cpp
sizer_x86.cpp
sizer_arm64.cpp
sizer_arm32.cpp
sizer_mips32.cpp
range.cpp
'''
......
......@@ -7,6 +7,7 @@ namespace zipr
#include <arch/arch_x86.hpp>
#include <arch/arch_arm64.hpp>
#include <arch/arch_arm32.hpp>
#include <arch/arch_mips32.hpp>
}
#include <memory>
......@@ -25,10 +26,11 @@ ZiprArchitectureHelperBase_t::ZiprArchitectureHelperBase_t(Zipr_SDK::Zipr_t* p_z
unique_ptr<ZiprArchitectureHelperBase_t> ZiprArchitectureHelperBase_t::factory(Zipr_SDK::Zipr_t* p_zipr_obj)
{
auto l_firp=p_zipr_obj->getFileIR();
auto ret= l_firp->getArchitecture()->getMachineType() == admtX86_64 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperX86_t (p_zipr_obj) :
l_firp->getArchitecture()->getMachineType() == admtI386 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperX86_t (p_zipr_obj) :
l_firp->getArchitecture()->getMachineType() == admtAarch64 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperARM64_t(p_zipr_obj) :
l_firp->getArchitecture()->getMachineType() == admtArm32 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperARM32_t(p_zipr_obj) :
auto ret= l_firp->getArchitecture()->getMachineType() == admtX86_64 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperX86_t (p_zipr_obj) :
l_firp->getArchitecture()->getMachineType() == admtI386 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperX86_t (p_zipr_obj) :
l_firp->getArchitecture()->getMachineType() == admtAarch64 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperARM64_t(p_zipr_obj) :
l_firp->getArchitecture()->getMachineType() == admtArm32 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperARM32_t(p_zipr_obj) :
l_firp->getArchitecture()->getMachineType() == admtMips32 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperMIPS32_t(p_zipr_obj) :
throw domain_error("Cannot init architecture");
return unique_ptr<ZiprArchitectureHelperBase_t>(ret);
......
......@@ -13,6 +13,7 @@
#include <string> // std::string, std::to_string
#include <fstream>
#include <elf.h>
#include <endian.h>
#include "elfio/elfio.hpp"
#include "elfio/elfio_dump.hpp"
......@@ -22,6 +23,609 @@ using namespace std;
using namespace zipr;
using namespace ELFIO;
template<class T_Elf_Ehdr, class T_Elf_Shdr>
static inline void host_to_shdr(const T_Elf_Ehdr& ehdr, T_Elf_Shdr& shdr)
{
#if 0
struct Elf64_Shdr
{
Elf64_Word sh_name
Elf64_Word sh_type
Elf64_Xword sh_flags
Elf64_Addr sh_addr
Elf64_Off sh_offset
Elf64_Xword sh_size
Elf64_Word sh_link
Elf64_Word sh_info
Elf64_Xword sh_addralign
Elf64_Xword sh_entsize
}
steruct Elf32_Shdr
{
Elf32_Word sh_name
Elf32_Word sh_type
Elf32_Word sh_flags
Elf32_Addr sh_addr
Elf32_Off sh_offset
Elf32_Word sh_size
Elf32_Word sh_link
Elf32_Word sh_info
Elf32_Word sh_addralign
Elf32_Word sh_entsize
}
#endif
if(ehdr.e_ident[5]==1) // little endian elf file
{
shdr.sh_name = htole32(shdr.sh_name);
shdr.sh_type = htole32(shdr.sh_type);
shdr.sh_link = htole32(shdr.sh_link);
shdr.sh_info = htole32(shdr.sh_info);
if(sizeof(ehdr.e_entry)==4) // 32-bit header
{
shdr.sh_flags = htole32(shdr.sh_flags);
shdr.sh_size = htole32(shdr.sh_size);
shdr.sh_addr = htole32(shdr.sh_addr);
shdr.sh_offset = htole32(shdr.sh_offset);
shdr.sh_addralign = htole32(shdr.sh_addralign);
shdr.sh_entsize = htole32(shdr.sh_entsize);
}
else if(sizeof(ehdr.e_entry)==8) // 64-bit header
{
shdr.sh_flags = htole64(shdr.sh_flags);
shdr.sh_size = htole64(shdr.sh_size);
shdr.sh_addr = htole64(shdr.sh_addr);
shdr.sh_offset = htole64(shdr.sh_offset);
shdr.sh_addralign = htole64(shdr.sh_addralign);
shdr.sh_entsize = htole64(shdr.sh_entsize);
}
else
{
assert(0);
}
}
else if(ehdr.e_ident[5]==2) // big endian elf file
{
shdr.sh_name = htobe32(shdr.sh_name);
shdr.sh_type = htobe32(shdr.sh_type);
shdr.sh_link = htobe32(shdr.sh_link);
shdr.sh_info = htobe32(shdr.sh_info);
if(sizeof(ehdr.e_entry)==4) // 32-bit header
{
shdr.sh_flags = htobe32(shdr.sh_flags);
shdr.sh_size = htobe32(shdr.sh_size);
shdr.sh_addr = htobe32(shdr.sh_addr);
shdr.sh_offset = htobe32(shdr.sh_offset);
shdr.sh_addralign = htobe32(shdr.sh_addralign);
shdr.sh_entsize = htobe32(shdr.sh_entsize);
}
else if(sizeof(ehdr.e_entry)==8) // 64-bit header
{
shdr.sh_flags = htobe64(shdr.sh_flags);
shdr.sh_size = htobe64(shdr.sh_size);
shdr.sh_addr = htobe64(shdr.sh_addr);
shdr.sh_offset = htobe64(shdr.sh_offset);
shdr.sh_addralign = htobe64(shdr.sh_addralign);
shdr.sh_entsize = htobe64(shdr.sh_entsize);
}
else
{
assert(0);
}
}
else
{
assert(0);
}
}
template<class T_Elf_Ehdr, class T_Elf_Shdr>
static inline void shdr_to_host(const T_Elf_Ehdr& ehdr, T_Elf_Shdr& shdr)
{
#if 0
struct Elf64_Shdr
{
Elf64_Word sh_name
Elf64_Word sh_type
Elf64_Xword sh_flags
Elf64_Addr sh_addr
Elf64_Off sh_offset
Elf64_Xword sh_size
Elf64_Word sh_link
Elf64_Word sh_info
Elf64_Xword sh_addralign
Elf64_Xword sh_entsize
}
steruct Elf32_Shdr
{
Elf32_Word sh_name
Elf32_Word sh_type
Elf32_Word sh_flags
Elf32_Addr sh_addr
Elf32_Off sh_offset
Elf32_Word sh_size
Elf32_Word sh_link
Elf32_Word sh_info
Elf32_Word sh_addralign
Elf32_Word sh_entsize
}
#endif
if(ehdr.e_ident[5]==1) // little endian elf file
{
shdr.sh_name = le32toh(shdr.sh_name);
shdr.sh_type = le32toh(shdr.sh_type);
shdr.sh_link = le32toh(shdr.sh_link);
shdr.sh_info = le32toh(shdr.sh_info);
if(sizeof(ehdr.e_entry)==4) // 32-bit header
{
shdr.sh_flags = le32toh(shdr.sh_flags);
shdr.sh_size = le32toh(shdr.sh_size);
shdr.sh_addr = le32toh(shdr.sh_addr);
shdr.sh_offset = le32toh(shdr.sh_offset);
shdr.sh_addralign = le32toh(shdr.sh_addralign);
shdr.sh_entsize = le32toh(shdr.sh_entsize);
}
else if(sizeof(ehdr.e_entry)==8) // 64-bit header
{
shdr.sh_flags = le64toh(shdr.sh_flags);
shdr.sh_size = le64toh(shdr.sh_size);
shdr.sh_addr = le64toh(shdr.sh_addr);
shdr.sh_offset = le64toh(shdr.sh_offset);
shdr.sh_addralign = le64toh(shdr.sh_addralign);
shdr.sh_entsize = le64toh(shdr.sh_entsize);
}
else
{
assert(0);
}
}
else if(ehdr.e_ident[5]==2) // big endian elf file
{
shdr.sh_name = be32toh(shdr.sh_name);
shdr.sh_type = be32toh(shdr.sh_type);
shdr.sh_link = be32toh(shdr.sh_link);
shdr.sh_info = be32toh(shdr.sh_info);
if(sizeof(ehdr.e_entry)==4) // 32-bit header
{
shdr.sh_flags = be32toh(shdr.sh_flags);
shdr.sh_size = be32toh(shdr.sh_size);
shdr.sh_addr = be32toh(shdr.sh_addr);
shdr.sh_offset = be32toh(shdr.sh_offset);
shdr.sh_addralign = be32toh(shdr.sh_addralign);
shdr.sh_entsize = be32toh(shdr.sh_entsize);
}
else if(sizeof(ehdr.e_entry)==8) // 64-bit header
{
shdr.sh_flags = be64toh(shdr.sh_flags);
shdr.sh_size = be64toh(shdr.sh_size);
shdr.sh_addr = be64toh(shdr.sh_addr);
shdr.sh_offset = be64toh(shdr.sh_offset);
shdr.sh_addralign = be64toh(shdr.sh_addralign);
shdr.sh_entsize = be64toh(shdr.sh_entsize);
}
else
{
assert(0);
}
}
else
{
assert(0);
}
}
template<class T_Elf_Ehdr, class T_Elf_Phdr>
static inline void phdr_to_host(const T_Elf_Ehdr& ehdr, T_Elf_Phdr& phdr)
{
#if 0
64-bit:
struct {
Elf64_Word p_type; size=4
Elf64_Word p_flags; size=4
Elf64_Off p_offset; size=8
Elf64_Addr p_vaddr; size=8
Elf64_Addr p_paddr; size=8
Elf64_Xword p_filesz; size=8
Elf64_Xword p_memsz; size=8
Elf64_Xword p_align; size=8
}
32-bit:
struct {
Elf32_Word p_type; 4
Elf32_Off p_offset; 4
Elf32_Addr p_vaddr; 4
Elf32_Addr p_paddr; 4
Elf32_Word p_filesz; 4
Elf32_Word p_memsz; 4
Elf32_Word p_flags; 4
Elf32_Word p_align; 4
}
#endif
if(ehdr.e_ident[5]==1) // little endian elf file
{
phdr.p_flags = le32toh(phdr.p_flags);
if(sizeof(ehdr.e_entry)==4) // 32-bit header
{
phdr.p_offset = le32toh(phdr.p_offset);
phdr.p_vaddr = le32toh(phdr.p_vaddr);
phdr.p_paddr = le32toh(phdr.p_paddr);
phdr.p_filesz = le32toh(phdr.p_filesz);
phdr.p_memsz = le32toh(phdr.p_memsz);
phdr.p_align = le32toh(phdr.p_align);
}
else if(sizeof(ehdr.e_entry)==8) // 64-bit header
{
phdr.p_offset = le64toh(phdr.p_offset);
phdr.p_vaddr = le64toh(phdr.p_vaddr);
phdr.p_paddr = le64toh(phdr.p_paddr);
phdr.p_filesz = le64toh(phdr.p_filesz);
phdr.p_memsz = le64toh(phdr.p_memsz);
phdr.p_align = le64toh(phdr.p_align);
}
else
{
assert(0);
}
}
else if(ehdr.e_ident[5]==2) // big endian elf file
{
phdr.p_type = be32toh(phdr.p_type);
phdr.p_flags = be32toh(phdr.p_flags);
if(sizeof(ehdr.e_entry)==4) // 32-bit header
{
phdr.p_offset = be32toh(phdr.p_offset);
phdr.p_vaddr = be32toh(phdr.p_vaddr);
phdr.p_paddr = be32toh(phdr.p_paddr);
phdr.p_filesz = be32toh(phdr.p_filesz);
phdr.p_memsz = be32toh(phdr.p_memsz);
phdr.p_align = be32toh(phdr.p_align);
}
else if(sizeof(ehdr.e_entry)==8) // 64-bit header
{
phdr.p_offset = be64toh(phdr.p_offset);
phdr.p_vaddr = be64toh(phdr.p_vaddr);
phdr.p_paddr = be64toh(phdr.p_paddr);
phdr.p_filesz = be64toh(phdr.p_filesz);
phdr.p_memsz = be64toh(phdr.p_memsz);
phdr.p_align = be64toh(phdr.p_align);
}
else
{
assert(0);
}
}
else
{
assert(0);
}
}
template<class T_Elf_Ehdr, class T_Elf_Phdr>
static inline void host_to_phdr(const T_Elf_Ehdr& ehdr, T_Elf_Phdr& phdr)
{
#if 0
64-bit:
struct {
Elf64_Word p_type; size=4
Elf64_Word p_flags; size=4
Elf64_Off p_offset; size=8
Elf64_Addr p_vaddr; size=8
Elf64_Addr p_paddr; size=8
Elf64_Xword p_filesz; size=8
Elf64_Xword p_memsz; size=8
Elf64_Xword p_align; size=8
}
32-bit:
struct {
Elf32_Word p_type; 4
Elf32_Off p_offset; 4
Elf32_Addr p_vaddr; 4
Elf32_Addr p_paddr; 4
Elf32_Word p_filesz; 4
Elf32_Word p_memsz; 4
Elf32_Word p_flags; 4
Elf32_Word p_align; 4
}
#endif
if(ehdr.e_ident[5]==1) // little endian elf file
{
phdr.p_flags = htole32(phdr.p_flags);
if(sizeof(ehdr.e_entry)==4) // 32-bit header
{
phdr.p_offset = htole32(phdr.p_offset);
phdr.p_vaddr = htole32(phdr.p_vaddr);
phdr.p_paddr = htole32(phdr.p_paddr);
phdr.p_filesz = htole32(phdr.p_filesz);
phdr.p_memsz = htole32(phdr.p_memsz);
phdr.p_align = htole32(phdr.p_align);
}
else if(sizeof(ehdr.e_entry)==8) // 64-bit header
{
phdr.p_offset = htole64(phdr.p_offset);
phdr.p_vaddr = htole64(phdr.p_vaddr);
phdr.p_paddr = htole64(phdr.p_paddr);
phdr.p_filesz = htole64(phdr.p_filesz);
phdr.p_memsz = htole64(phdr.p_memsz);
phdr.p_align = htole64(phdr.p_align);
}
else
{
assert(0);
}
}
else if(ehdr.e_ident[5]==2) // big endian elf file
{
phdr.p_type = htobe32(phdr.p_type);
phdr.p_flags = htobe32(phdr.p_flags);
if(sizeof(ehdr.e_entry)==4) // 32-bit header
{
phdr.p_offset = htobe32(phdr.p_offset);
phdr.p_vaddr = htobe32(phdr.p_vaddr);
phdr.p_paddr = htobe32(phdr.p_paddr);
phdr.p_filesz = htobe32(phdr.p_filesz);
phdr.p_memsz = htobe32(phdr.p_memsz);
phdr.p_align = htobe32(phdr.p_align);
}
else if(sizeof(ehdr.e_entry)==8) // 64-bit header
{
phdr.p_offset = htobe64(phdr.p_offset);
phdr.p_vaddr = htobe64(phdr.p_vaddr);
phdr.p_paddr = htobe64(phdr.p_paddr);
phdr.p_filesz = htobe64(phdr.p_filesz);
phdr.p_memsz = htobe64(phdr.p_memsz);
phdr.p_align = htobe64(phdr.p_align);
}
else
{
assert(0);
}
}
else
{
assert(0);
}
}
template<class T_Elf_Ehdr>
static inline void ehdr_to_host(T_Elf_Ehdr& ehdr)
{
#if 0
struct Elf32_Ehdr {
unsigned char e_ident[16];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
}
struct Elf64_Ehdr {
unsigned char e_ident[16];
Elf64_Half e_type;
Elf64_Half e_machine;
Elf64_Word e_version;
Elf64_Addr e_entry;
Elf64_Off e_phoff;
Elf64_Off e_shoff;
Elf64_Word e_flags;
Elf64_Half e_ehsize;
Elf64_Half e_phentsize;
Elf64_Half e_phnum;
Elf64_Half e_shentsize;
Elf64_Half e_shnum;
Elf64_Half e_shstrndx;
}
#endif
if(ehdr.e_ident[5]==1) // little endian elf file
{
ehdr.e_type = le16toh(ehdr.e_type);
ehdr.e_machine = le16toh(ehdr.e_machine);
ehdr.e_version = le32toh(ehdr.e_version);
ehdr.e_flags = le32toh(ehdr.e_flags);
ehdr.e_ehsize = le16toh(ehdr.e_ehsize);
ehdr.e_phentsize = le16toh(ehdr.e_phentsize);
ehdr.e_phnum = le16toh(ehdr.e_phnum);
ehdr.e_shentsize = le16toh(ehdr.e_shentsize);
ehdr.e_shnum = le16toh(ehdr.e_shnum);
ehdr.e_shstrndx = le16toh(ehdr.e_shstrndx);
if(sizeof(ehdr.e_entry)==4) // 32-bit header
{
ehdr.e_entry = le32toh(ehdr.e_entry);
ehdr.e_phoff = le32toh(ehdr.e_phoff);
ehdr.e_shoff = le32toh(ehdr.e_shoff);
}
else if(sizeof(ehdr.e_entry)==8) // 64-bit header
{
ehdr.e_entry = le64toh(ehdr.e_entry);
ehdr.e_phoff = le64toh(ehdr.e_phoff);
ehdr.e_shoff = le64toh(ehdr.e_shoff);
}
else
{
assert(0);
}
}
else if(ehdr.e_ident[5]==2) // big endian elf file
{
ehdr.e_type = be16toh(ehdr.e_type);
ehdr.e_machine = be16toh(ehdr.e_machine);
ehdr.e_version = be32toh(ehdr.e_version);
ehdr.e_flags = be16toh(ehdr.e_flags);
ehdr.e_ehsize = be32toh(ehdr.e_ehsize);
ehdr.e_phentsize = be16toh(ehdr.e_phentsize);
ehdr.e_phnum = be16toh(ehdr.e_phnum);
ehdr.e_shentsize = be16toh(ehdr.e_shentsize);
ehdr.e_shnum = be16toh(ehdr.e_shnum);
ehdr.e_shstrndx = be16toh(ehdr.e_shstrndx);
if(sizeof(ehdr.e_entry)==4) //32-bit header
{
ehdr.e_entry = be32toh(ehdr.e_entry);
ehdr.e_phoff = be32toh(ehdr.e_phoff);
ehdr.e_shoff = be32toh(ehdr.e_shoff);
}
else if(sizeof(ehdr.e_entry)==8) // 64-bit header
{
ehdr.e_entry = be64toh(ehdr.e_entry);
ehdr.e_phoff = be64toh(ehdr.e_phoff);
ehdr.e_shoff = be64toh(ehdr.e_shoff);
}
else
{
assert(0);
}
}
else
{
assert(0);
}
}
template<class T_Elf_Ehdr>
static inline void host_to_ehdr(T_Elf_Ehdr& ehdr)
{
#if 0
struct Elf32_Ehdr {
unsigned char e_ident[16];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
}
struct Elf64_Ehdr {
unsigned char e_ident[16];
Elf64_Half e_type;
Elf64_Half e_machine;
Elf64_Word e_version;
Elf64_Addr e_entry;
Elf64_Off e_phoff;
Elf64_Off e_shoff;
Elf64_Word e_flags;
Elf64_Half e_ehsize;
Elf64_Half e_phentsize;
Elf64_Half e_phnum;
Elf64_Half e_shentsize;
Elf64_Half e_shnum;
Elf64_Half e_shstrndx;
}
#endif
if(ehdr.e_ident[5]==1) // little endian elf file
{
ehdr.e_type = htole16(ehdr.e_type);
ehdr.e_machine = htole16(ehdr.e_machine);
ehdr.e_version = htole32(ehdr.e_version);
ehdr.e_flags = htole32(ehdr.e_flags);
ehdr.e_ehsize = htole16(ehdr.e_ehsize);
ehdr.e_phentsize = htole16(ehdr.e_phentsize);
ehdr.e_phnum = htole16(ehdr.e_phnum);
ehdr.e_shentsize = htole16(ehdr.e_shentsize);
ehdr.e_shnum = htole16(ehdr.e_shnum);
ehdr.e_shstrndx = htole16(ehdr.e_shstrndx);
if(sizeof(ehdr.e_entry)==4) // 32-bit header
{
ehdr.e_entry = htole32(ehdr.e_entry);
ehdr.e_phoff = htole32(ehdr.e_phoff);
ehdr.e_shoff = htole32(ehdr.e_shoff);
}
else if(sizeof(ehdr.e_entry)==8) // 64-bit header
{
ehdr.e_entry = htole64(ehdr.e_entry);
ehdr.e_phoff = htole64(ehdr.e_phoff);
ehdr.e_shoff = htole64(ehdr.e_shoff);
}
else
{
assert(0);
}
}
else if(ehdr.e_ident[5]==2) // big endian elf file
{
ehdr.e_type = htobe16(ehdr.e_type);
ehdr.e_machine = htobe16(ehdr.e_machine);
ehdr.e_version = htobe32(ehdr.e_version);
ehdr.e_flags = htobe32(ehdr.e_flags);
ehdr.e_ehsize = htobe16(ehdr.e_ehsize);
ehdr.e_phentsize = htobe16(ehdr.e_phentsize);
ehdr.e_phnum = htobe16(ehdr.e_phnum);
ehdr.e_shentsize = htobe16(ehdr.e_shentsize);
ehdr.e_shnum = htobe16(ehdr.e_shnum);
ehdr.e_shstrndx = htobe16(ehdr.e_shstrndx);
if(sizeof(ehdr.e_entry)==4) //32-bit header
{
ehdr.e_entry = htobe32(ehdr.e_entry);
ehdr.e_phoff = htobe32(ehdr.e_phoff);
ehdr.e_shoff = htobe32(ehdr.e_shoff);
}
else if(sizeof(ehdr.e_entry)==8) // 64-bit header
{
ehdr.e_entry = htobe64(ehdr.e_entry);
ehdr.e_phoff = htobe64(ehdr.e_phoff);
ehdr.e_shoff = htobe64(ehdr.e_shoff);
}
else
{
assert(0);
}
}
else
{
assert(0);
}
}
static inline uintptr_t page_round_down(uintptr_t x)
{
......@@ -240,6 +844,7 @@ void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr, T_Elf_Shdr, T_Elf_Sym, T_El
fseek(fin,0,SEEK_SET);
auto res=fread(&ehdr,sizeof(ehdr), 1, fin);
assert(res==1);
ehdr_to_host(ehdr);
};
template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn>
......@@ -251,6 +856,7 @@ void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr, T_Elf_Sym, T_Elf
{
auto res=fread(&phdrs[i], sizeof(phdrs[i]), 1, fin);
assert(res==1);
phdr_to_host(ehdr,phdrs[i]);
}
};
......@@ -808,12 +1414,21 @@ filesz before we start writing out the elf. See "trim_last_seg_filesz"
// write the header.
fseek(fout,0,SEEK_SET);
fwrite(&new_ehdr, sizeof(new_ehdr), 1, fout);
auto new_ehdr_endian_correct = new_ehdr;
host_to_ehdr(new_ehdr_endian_correct);
fwrite(&new_ehdr_endian_correct, sizeof(new_ehdr), 1, fout);
// write the phdrs, which may be part of a segment written above.
std::cout<<"Writing segment headers at "<<std::hex<<new_ehdr.e_phoff
<<", size="<<new_phdrs.size()*sizeof(new_phdrs[0])<<std::endl;
cout << "Writing segment headers at " << hex << new_ehdr.e_phoff << ", size=" << new_phdrs.size()*sizeof(new_phdrs[0]) << endl;
fseek(fout,new_ehdr.e_phoff,SEEK_SET);
fwrite(new_phdrs.data(), sizeof(new_phdrs[0]), new_phdrs.size(), fout);
// doesn't account for endian issues
// fwrite(new_phdrs.data(), sizeof(new_phdrs[0]), new_phdrs.size(), fout);
for(auto phdr : new_phdrs)
{
host_to_phdr(ehdr,phdr);
fwrite(&phdr, sizeof(new_phdrs[0]), 1, fout);
}
}
template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn>
......@@ -1001,7 +1616,14 @@ void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr,T_Elf_Sym, T_Elf_
long shdr_file_pos=ftell(fout);
cout<<"Writing section headers at filepos="<<hex<<shdr_file_pos<<endl;
fwrite(shdrs.data(), sizeof(T_Elf_Shdr), shdrs.size(), fout);
// doesn't account for endianness
// fwrite(shdrs.data(), sizeof(T_Elf_Shdr), shdrs.size(), fout);
for(auto shdr : shdrs)
{
host_to_shdr(ehdr,shdr);
fwrite(&shdrs, sizeof(T_Elf_Shdr), 1, fout);
}
new_ehdr.e_shentsize=sizeof(T_Elf_Shdr);
new_ehdr.e_shnum=shdrs.size();
......@@ -1010,7 +1632,9 @@ void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr,T_Elf_Sym, T_Elf_
// rewrite the file header so that sections are listed.
fseek(fout,0,SEEK_SET);
fwrite(&new_ehdr, sizeof(new_ehdr),1,fout);
auto endian_ehdr = new_ehdr;
host_to_ehdr(endian_ehdr);
fwrite(&endian_ehdr, sizeof(new_ehdr),1,fout);
}
// explicit instantation of methods for 32- and 64-bit classes.
......
......@@ -32,6 +32,7 @@
namespace zipr
{
#include "patcher/patcher_mips32.hpp"
#include "patcher/patcher_arm32.hpp"
#include "patcher/patcher_arm64.hpp"
#include "patcher/patcher_x86.hpp"
......@@ -58,10 +59,11 @@ using namespace zipr;
unique_ptr<ZiprPatcherBase_t> ZiprPatcherBase_t::factory(Zipr_SDK::Zipr_t* p_parent)
{
auto l_firp=p_parent->getFileIR();
auto ret= l_firp->getArchitecture()->getMachineType() == admtX86_64 ? (ZiprPatcherBase_t*)new ZiprPatcherX86_t (p_parent) :
l_firp->getArchitecture()->getMachineType() == admtI386 ? (ZiprPatcherBase_t*)new ZiprPatcherX86_t (p_parent) :
l_firp->getArchitecture()->getMachineType() == admtAarch64 ? (ZiprPatcherBase_t*)new ZiprPatcherARM64_t(p_parent) :
l_firp->getArchitecture()->getMachineType() == admtArm32 ? (ZiprPatcherBase_t*)new ZiprPatcherARM32_t(p_parent) :
auto ret= l_firp->getArchitecture()->getMachineType() == admtX86_64 ? (ZiprPatcherBase_t*)new ZiprPatcherX86_t (p_parent) :
l_firp->getArchitecture()->getMachineType() == admtI386 ? (ZiprPatcherBase_t*)new ZiprPatcherX86_t (p_parent) :
l_firp->getArchitecture()->getMachineType() == admtAarch64 ? (ZiprPatcherBase_t*)new ZiprPatcherARM64_t(p_parent) :
l_firp->getArchitecture()->getMachineType() == admtArm32 ? (ZiprPatcherBase_t*)new ZiprPatcherARM32_t(p_parent) :
l_firp->getArchitecture()->getMachineType() == admtMips32 ? (ZiprPatcherBase_t*)new ZiprPatcherMIPS32_t(p_parent) :
throw domain_error("Cannot init architecture");
return unique_ptr<ZiprPatcherBase_t>(ret);
......
/***************************************************************************
* Copyright (c) 2014 Zephyr Software LLC. All rights reserved.
*
* This software is furnished under a license and/or other restrictive
* terms and may be used and copied only in accordance with such terms
* and the inclusion of the above copyright notice. This software or
* any other copies thereof may not be provided or otherwise made
* available to any other person without the express written consent
* of an authorized representative of Zephyr Software LCC. Title to,
* ownership of, and all rights in the software is retained by
* Zephyr Software LCC.
*
* Zephyr Software LLC. Proprietary Information
*
* Unless otherwise specified, the information contained in this
* directory, following this legend, and/or referenced herein is
* Zephyr Software LLC. (Zephyr) Proprietary Information.
*
* CONTACT
*
* For technical assistance, contact Zephyr Software LCC. at:
*
*
* Zephyr Software, LLC
* 2040 Tremont Rd
* Charlottesville, VA 22911
*
* E-mail: jwd@zephyr-software.com
**************************************************************************/
#include <zipr_all.h>
namespace zipr
{
#include "patcher/patcher_mips32.hpp"
}
#include <irdb-core>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <map>
#include <assert.h>
#include <sys/mman.h>
#include <ctype.h>
#include <iostream> // std::cout
#include <string> // std::string, std::to_string
#include <fstream>
#define ALLOF(a) begin(a),end(a)
using namespace IRDB_SDK;
using namespace std;
using namespace zipr;
ZiprPatcherMIPS32_t::ZiprPatcherMIPS32_t(Zipr_SDK::Zipr_t* p_parent) :
m_parent(dynamic_cast<zipr::ZiprImpl_t*>(p_parent)), // upcast to ZiprImpl
m_firp(p_parent->getFileIR()),
memory_space(*p_parent->getMemorySpace())
{
}
void ZiprPatcherMIPS32_t::ApplyNopToPatch(RangeAddress_t addr)
{ assert(0); }
void ZiprPatcherMIPS32_t::ApplyPatch(RangeAddress_t from_addr, RangeAddress_t to_addr)
{
const auto first_byte = (uint8_t)memory_space[from_addr+0];
const auto new_offset = (int32_t)((to_addr) - (from_addr+8)) >> 2;
// A Branch in binary is: op= 000010 imm26=0000 00000000 00000000 00000000
// it includes a 26-bit immediate, which is +/- 128mb, which should be a good enough "jump anywhere"
// for now.
const auto mask6 = (0b111111);
const auto is_uncond_branch = ((first_byte >> 2) & mask6) == (0b000010); // jump branch
if(is_uncond_branch)
{
cout<<"Applying uncond branch patch from "<<hex<<from_addr<<" to "<<to_addr<<endl;
const auto non_imm_bits = 32U-26U; // 32 bits - imm26
// assert there's no overflow.
assert((int64_t)(new_offset << non_imm_bits) == ((int64_t)new_offset) << non_imm_bits);
// or in opcode for first byte. set remaining bytes.
const auto mask26 = ((1<<26)-1);
const auto trimmed_offset = new_offset & mask26;
memory_space[from_addr+3] = (trimmed_offset>> 0)&0xff;
memory_space[from_addr+2] = (trimmed_offset>> 8)&0xff;
memory_space[from_addr+1] = (trimmed_offset>>16)&0xff;
memory_space[from_addr+0] |= (trimmed_offset>>24)&0x02;
}
else
{
cout<<"Applying cond branch patch from "<<hex<<from_addr<<" to "<<to_addr<<endl;
const auto non_imm_bits = 32U-24U; // 32 bits - imm24
// assert there's no overflow.
assert((int64_t)(new_offset << non_imm_bits) == ((int64_t)new_offset) << non_imm_bits);
// or in opcode for first byte. set remaining bytes.
const auto mask24 = ((1<<24)-1);
const auto trimmed_offset = new_offset & mask24;
memory_space[from_addr+3] = (trimmed_offset>> 0)&0xff;
memory_space[from_addr+2] = (trimmed_offset>> 8)&0xff;
memory_space[from_addr+1] = (trimmed_offset>>16)&0xff;
memory_space[from_addr+0] |= (trimmed_offset>>24)&0x02;
}
}
void ZiprPatcherMIPS32_t::PatchJump(RangeAddress_t at_addr, RangeAddress_t to_addr)
{
return this->ApplyPatch(at_addr,to_addr);
}
void ZiprPatcherMIPS32_t::PatchCall(RangeAddress_t at_addr, RangeAddress_t to_addr)
{
assert(0);
}
void ZiprPatcherMIPS32_t::CallToNop(RangeAddress_t at_addr)
{
assert(0);
}
......@@ -3,8 +3,9 @@
namespace zipr
{
#include <pinner/pinner_x86.hpp>
#include <pinner/pinner_arm32.hpp>
#include <pinner/pinner_arm64.hpp>
#include <pinner/pinner_arm32.hpp>
#include <pinner/pinner_mips32.hpp>
}
#include <memory>
......@@ -14,10 +15,11 @@ using namespace zipr;
unique_ptr<ZiprPinnerBase_t> ZiprPinnerBase_t::factory(Zipr_SDK::Zipr_t *p_parent)
{
auto ret= p_parent->getFileIR()->getArchitecture()->getMachineType() == admtX86_64 ? (ZiprPinnerBase_t*)new ZiprPinnerX86_t (p_parent) :
p_parent->getFileIR()->getArchitecture()->getMachineType() == admtI386 ? (ZiprPinnerBase_t*)new ZiprPinnerX86_t (p_parent) :
p_parent->getFileIR()->getArchitecture()->getMachineType() == admtAarch64 ? (ZiprPinnerBase_t*)new ZiprPinnerARM64_t(p_parent) :
p_parent->getFileIR()->getArchitecture()->getMachineType() == admtArm32 ? (ZiprPinnerBase_t*)new ZiprPinnerARM32_t(p_parent) :
auto ret= p_parent->getFileIR()->getArchitecture()->getMachineType() == admtX86_64 ? (ZiprPinnerBase_t*)new ZiprPinnerX86_t (p_parent) :
p_parent->getFileIR()->getArchitecture()->getMachineType() == admtI386 ? (ZiprPinnerBase_t*)new ZiprPinnerX86_t (p_parent) :
p_parent->getFileIR()->getArchitecture()->getMachineType() == admtAarch64 ? (ZiprPinnerBase_t*)new ZiprPinnerARM64_t(p_parent) :
p_parent->getFileIR()->getArchitecture()->getMachineType() == admtArm32 ? (ZiprPinnerBase_t*)new ZiprPinnerARM32_t(p_parent) :
p_parent->getFileIR()->getArchitecture()->getMachineType() == admtMips32 ? (ZiprPinnerBase_t*)new ZiprPinnerMIPS32_t(p_parent) :
throw domain_error("Cannot init architecture");
return unique_ptr<ZiprPinnerBase_t>(ret);
......
#include <zipr_all.h>
namespace zipr
{
#include <pinner/pinner_mips32.hpp>
}
#include <memory>
using namespace std;
using namespace IRDB_SDK;
using namespace zipr;
ZiprPinnerMIPS32_t::ZiprPinnerMIPS32_t(Zipr_SDK::Zipr_t* p_parent) :
m_parent(dynamic_cast<zipr::ZiprImpl_t*>(p_parent)), // upcast to ZiprImpl
m_firp(p_parent->getFileIR()),
memory_space(*m_parent->getMemorySpace()),
m_dollop_mgr(*p_parent->getDollopManager()),
placement_queue(*p_parent->getPlacementQueue())
{
}
void ZiprPinnerMIPS32_t::doPinning()
{
// deal with unpinned IBTs by putting them in the placement queue.
for(auto &insn : m_firp->getInstructions())
{
if(insn->getIndirectBranchTargetAddress()==nullptr)
continue;
if(insn->getIndirectBranchTargetAddress()->getVirtualOffset()==0)
{
// Unpinned IBT. Create dollop and add it to placement
// queue straight away--there are no pinning considerations.
auto newDoll=m_dollop_mgr.addNewDollops(insn);
placement_queue.insert({newDoll, 0});
continue;
}
auto ibta_addr=(RangeAddress_t)insn-> getIndirectBranchTargetAddress()-> getVirtualOffset();
// put unconditional branch with 24-bit offset in memory
// 1110 1010 0000 0000 0000 0000 0000 0000
uint8_t bytes[]={'\x18','\x00','\x00','\x00'};
for(auto i=0U;i<sizeof(bytes);i++)
{
const auto ibta_byte_addr = ibta_addr+i;
if(memory_space.find(ibta_byte_addr) != memory_space.end() )
{
cout << "Byte is marked as both code and data at: " << hex << ibta_byte_addr << endl;
exit(10);
}
memory_space[ibta_byte_addr]=bytes[i];
memory_space.splitFreeRange(ibta_byte_addr);
}
// insert a patch to patch the branch later.
const auto patch=Patch_t(ibta_addr, UnresolvedType_t::UncondJump_rel26);
const auto uu=UnresolvedUnpinned_t(insn);
m_parent->AddPatch(uu,patch);
}
}
......@@ -7,6 +7,7 @@ namespace zipr
#include <sizer/sizer_x86.hpp>
#include <sizer/sizer_arm64.hpp>
#include <sizer/sizer_arm32.hpp>
#include <sizer/sizer_mips32.hpp>
}
#include <memory>
......@@ -18,10 +19,11 @@ using namespace zipr;
unique_ptr<ZiprSizerBase_t> ZiprSizerBase_t::factory(Zipr_SDK::Zipr_t* p_zipr_obj)
{
auto l_firp=p_zipr_obj->getFileIR();
auto ret= l_firp->getArchitecture()->getMachineType() == admtX86_64 ? (ZiprSizerBase_t*)new ZiprSizerX86_t (p_zipr_obj) :
l_firp->getArchitecture()->getMachineType() == admtI386 ? (ZiprSizerBase_t*)new ZiprSizerX86_t (p_zipr_obj) :
l_firp->getArchitecture()->getMachineType() == admtAarch64 ? (ZiprSizerBase_t*)new ZiprSizerARM64_t(p_zipr_obj) :
l_firp->getArchitecture()->getMachineType() == admtArm32 ? (ZiprSizerBase_t*)new ZiprSizerARM32_t(p_zipr_obj) :
auto ret= l_firp->getArchitecture()->getMachineType() == admtX86_64 ? (ZiprSizerBase_t*)new ZiprSizerX86_t (p_zipr_obj) :
l_firp->getArchitecture()->getMachineType() == admtI386 ? (ZiprSizerBase_t*)new ZiprSizerX86_t (p_zipr_obj) :
l_firp->getArchitecture()->getMachineType() == admtAarch64 ? (ZiprSizerBase_t*)new ZiprSizerARM64_t(p_zipr_obj) :
l_firp->getArchitecture()->getMachineType() == admtArm32 ? (ZiprSizerBase_t*)new ZiprSizerARM32_t(p_zipr_obj) :
l_firp->getArchitecture()->getMachineType() == admtMips32 ? (ZiprSizerBase_t*)new ZiprSizerMIPS32_t(p_zipr_obj) :
throw domain_error("Cannot init architecture");
return unique_ptr<ZiprSizerBase_t>(ret);
......
#include <zipr_all.h>
namespace zipr
{
#include <sizer/sizer_mips32.hpp>
}
using namespace zipr ;
using namespace IRDB_SDK;
ZiprSizerMIPS32_t::ZiprSizerMIPS32_t(Zipr_SDK::Zipr_t* p_zipr_obj) : ZiprSizerBase_t(p_zipr_obj,4,4,4,4,4)
{
}
size_t ZiprSizerMIPS32_t::DetermineInsnSize(Instruction_t* insn, bool account_for_jump) const
{
// need 4 bytes for insn, plus 4 bytes for a jump
const auto size = 4u;
const auto jmp_size = account_for_jump ? 4 : 0;
return size + jmp_size;
}
RangeAddress_t ZiprSizerMIPS32_t::PlopDollopEntryWithTarget(
Zipr_SDK::DollopEntry_t *entry,
RangeAddress_t override_place,
RangeAddress_t override_target) const
{
const auto addr = (override_place == 0) ? entry->getPlace() : override_place;
const auto target_addr = (override_target == 0) ? entry->getTargetDollop()->getPlace() : override_target;
const auto insn = entry->getInstruction();
// plop instruction an d make it target the right address.
memory_space.PlopBytes(addr, insn->getDataBits().c_str(), 4);
m_zipr_obj.GetPatcher()->ApplyPatch(addr, target_addr);
return addr+4;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment