(capstone) feat: add capstone disassembler files

This commit is contained in:
Robin Thunig
2019-08-26 04:17:22 +02:00
parent ea6c1c031b
commit d04afaac54
17 changed files with 1283 additions and 1 deletions

View File

@ -12,6 +12,7 @@
#cmakedefine BUILD_ARM
#cmakedefine BUILD_LLVM_DISASSEMBLER
#cmakedefine BUILD_CAPSTONE_DISASSEMBLER
#define ARCH_TOOL_PREFIX "@ARCH_TOOL_PREFIX@"

View File

@ -81,12 +81,22 @@ endif(CONFIG_INJECTIONPOINT_HOPS)
add_library(fail-util ${SRCS})
add_dependencies(fail-util fail-comm)
target_link_libraries(fail-util fail-comm ${ADDITIONAL_LIBS} ${PROTOBUF_LIBRARY} ${Boost_LIBRARIES} ${LibIberty_LIBRARIES} ${ZLIB_LIBRARIES} ${LIBDWARF_LIBRARIES} ${LIBELF_LIBRARIES})
target_link_libraries(fail-util fail-comm fail-sal ${ADDITIONAL_LIBS} ${PROTOBUF_LIBRARY} ${Boost_LIBRARIES} ${LibIberty_LIBRARIES} ${ZLIB_LIBRARIES} ${LIBDWARF_LIBRARIES} ${LIBELF_LIBRARIES})
option(BUILD_CAPSTONE_DISASSEMBLER "Build the Capstone-based disassembler (Capstone 4.0.1 required, higher versions may not work)" OFF)
if (BUILD_CAPSTONE_DISASSEMBLER)
add_subdirectory(capstonedisassembler)
endif (BUILD_CAPSTONE_DISASSEMBLER)
option(BUILD_LLVM_DISASSEMBLER "Build the LLVM-based disassembler (LLVM 3.9, 4.0, 5.0 or 6.0 preferred, other versions may not work)" OFF)
if (BUILD_LLVM_DISASSEMBLER)
add_subdirectory(llvmdisassembler)
endif (BUILD_LLVM_DISASSEMBLER)
if (BUILD_CAPSTONE_DISASSEMBLER AND BUILD_LLVM_DISASSEMBLER)
message(FATAL_ERROR "BUILD_CAPSTONE_DISASSEMBLER and BUILD_LLVM_DISASSEMBLER can't be on at the same time!")
endif (BUILD_CAPSTONE_DISASSEMBLER AND BUILD_LLVM_DISASSEMBLER)
### Tests
add_executable(memorymap-test testing/memorymap-test.cc)
target_link_libraries(memorymap-test fail-util)

View File

@ -0,0 +1,26 @@
set(SRCS
CapstoneDisassembler.cpp
CapstoneDisassembler.hpp
CapstoneToFailBochs.cpp
CapstoneToFailBochs.hpp
CapstoneToFailGem5.hpp
CapstoneToFailGem5.cpp
CapstoneToFailTranslator.cpp
CapstoneToFailTranslator.hpp
)
include(FindCapstone)
add_library(fail-capstonedisassembler ${SRCS})
target_link_libraries(fail-capstonedisassembler ${CAPSTONE_LIBRARY})
include_directories(${CAPSTONE_INCLUDE_DIR})
### Tests
add_executable(capstoneDisTest testing/capstoneDisTest.cc)
target_link_libraries(capstoneDisTest fail-capstonedisassembler fail-sal)
add_test(NAME capstoneDisx86Test COMMAND capstoneDisTest ${CMAKE_CURRENT_SOURCE_DIR}/testing/x86 )
add_test(NAME capstoneDisx86_64Test COMMAND capstoneDisTest ${CMAKE_CURRENT_SOURCE_DIR}/testing/x86_64 )
add_test(NAME capstoneDisARMM3Test COMMAND capstoneDisTest ${CMAKE_CURRENT_SOURCE_DIR}/testing/armm3 )
add_test(NAME capstoneDisARM9Test COMMAND capstoneDisTest ${CMAKE_CURRENT_SOURCE_DIR}/testing/arm9 )

View File

@ -0,0 +1,281 @@
#include "CapstoneDisassembler.hpp"
using namespace fail;
CapstoneToFailTranslator *CapstoneDisassembler::getTranslator() {
if (ctofail == 0) {
switch (m_elf->m_machine) {
case EM_386:
case EM_X86_64:
ctofail = new CapstoneToFailBochs();
break;
case EM_ARM:
ctofail = new CapstoneToFailGem5();
break;
default:
std::cerr << "ArchType "
<< m_elf->m_machine
<< " not supported\n";
exit(1);
}
}
return ctofail;
}
std::map<uint64_t, uint64_t> CapstoneDisassembler::get_symtab_map(uint32_t sect_size) {
// Make a list of all the symbols in this section.
std::vector<std::pair<uint64_t, uint64_t> > symbols;
for (ElfReader::container_t::const_iterator it = m_elf->sym_begin(); it != m_elf->sym_end(); ++it) {
if (it->getSymbolType() != 2 /*SST_FUNC*/) {
continue;
}
symbols.push_back(std::make_pair(it->getAddress(), it->getSize()));
#if 0
std::cout << std::hex << it->getAddress() << "\t" << it->getSymbolType() << "\t" << it->getName().c_str() << "\t" << it->getSize() << std::endl;
#endif
}
// Sort the symbols by address, just in case they didn't come in that way.
std::sort(symbols.begin(), symbols.end());
std::map<uint64_t, uint64_t> symtab_map;
uint64_t start;
uint64_t end; // exclusive
for (unsigned si = 0, se = symbols.size(); si != se; ++si) {
start = symbols[si].first;
if (symbols[si].second == 0) {
// The end is either the size of the section or the beginning of the next symbol.
if (si == se - 1)
end = sect_size;
// Make sure this symbol takes up space.
else if (symbols[si + 1].first != start)
end = symbols[si + 1].first;
else
// This symbol has the same address as the next symbol. Skip it.
continue;
symbols[si].second = end - start;
}
symtab_map[symbols[si].first] = symbols[si].second;
}
#if 0
for (std::map<uint64_t, uint64_t>::iterator it=symtab_map.begin(); it!=symtab_map.end(); ++it)
std::cout << std::hex << it->first << " => " << it->second << std::endl;
#endif
return symtab_map;
}
int CapstoneDisassembler::disassemble_section(Elf_Data *data, Elf32_Shdr *shdr32, Elf64_Shdr *shdr64, std::map<uint64_t, uint64_t> symtab_map) {
#if 0
std::cout << std::dec << "bit: " << m_elf->m_elfclass << " 32: "<< ELFCLASS32 << " 64: " << ELFCLASS64 << " arch: " << m_elf->m_machine << " arm:" << EM_ARM << " x86: " << EM_386 << " x86_64: "<< EM_X86_64 << std::endl;
#endif
csh handle;
cs_insn *insn;
size_t count, j;
cs_regs regs_read, regs_write;
uint8_t read_count, write_count, i;
cs_opt_skipdata skipdata = {
.mnemonic = "db",
};
// Arm may not work, because thumb is a problem
if (m_elf->m_machine == EM_386) {
if (cs_open(CS_ARCH_X86, CS_MODE_32, &handle) != CS_ERR_OK)
return -1;
} else if(m_elf->m_machine == EM_X86_64) {
if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK)
return -1;
} else if (m_elf->m_machine == EM_ARM) {
if (m_elf->m_elfclass == ELFCLASS32) {
if (cs_open(CS_ARCH_ARM, CS_MODE_ARM, &handle) != CS_ERR_OK)
return -1;
} else {
if (cs_open(CS_ARCH_ARM64, CS_MODE_ARM, &handle) != CS_ERR_OK)
return -1;
}
}
cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON);
cs_option(handle, CS_OPT_SKIPDATA_SETUP, (size_t)&skipdata);
int global_count = 0;
for (std::map<uint64_t, uint64_t>::iterator it=symtab_map.begin(); it!=symtab_map.end(); ++it) {
if (m_elf->m_elfclass == ELFCLASS32) {
count = cs_disasm(handle,
(uint8_t *) ((uint64_t) data->d_buf + (uint64_t) it->first - (uint64_t) shdr32->sh_addr),
it->second, it->first, 0, &insn);
} else {
count = cs_disasm(handle,
(uint8_t *) ((uint64_t) data->d_buf + (uint64_t) it->first - (uint64_t) shdr64->sh_addr),
it->second, it->first, 0, &insn);
}
if (count > 0) {
for (j = 0; j < count; j++) {
unsigned int opcode = 0;
if (m_elf->m_machine == EM_386 || m_elf->m_machine == EM_X86_64) {
opcode = (insn[j].detail->x86.opcode[3] << 24) | (insn[j].detail->x86.opcode[2] << 16) |
(insn[j].detail->x86.opcode[1] << 8) | insn[j].detail->x86.opcode[0];
} else if (m_elf->m_machine == EM_ARM) {
// placeholder
opcode = 0;
}
// Print assembly
#if 0
printf("%s\t%s\n", insn[j].mnemonic, insn[j].op_str);
printf("Opcode: %x\t Adress: %lx\t Size: %d\n", opcode, insn[j].address, insn[j].size);
#endif
// Print all registers accessed by this instruction.
if (cs_regs_access(handle, &insn[j], regs_read, &read_count, regs_write, &write_count) == 0) {
Instr instr;
instr.opcode = opcode;
instr.length = insn[j].size;
instr.address = insn[j].address;
// FIXME could not find a functionality in capstone
instr.conditional_branch = false;
if (read_count > 0) {
// printf("\n\tRegisters read:");
for (i = 0; i < read_count; i++) {
instr.reg_uses.push_back(regs_read[i]);
// printf(" %s, %d |", cs_reg_name(handle, regs_read[i]), regs_read[i]);
}
// printf("\n");
}
if (write_count > 0) {
// printf("\n\tRegisters modified:");
for (i = 0; i < write_count; i++) {
instr.reg_defs.push_back(regs_write[i]);
// printf(" %s, %d |", cs_reg_name(handle, regs_write[i]), regs_write[i]);
}
// printf("\n");
}
(*instrs)[instr.address] = instr;
}
// printf("________________________________________________\n");
}
global_count += count;
cs_free(insn, count);
} else
std::cerr << "ERROR: Failed to disassemble given code!" << std::endl;
}
// printf("len_instr_map: %d\n", instrs->size());
cs_close(&handle);
// printf("%d instructions\n", global_count);
return 0;
}
void CapstoneDisassembler::disassemble() {
int fd; // File descriptor for the executable ELF file
char *section_name;
size_t shstrndx;
Elf *e; // ELF struct
Elf_Data *data = 0;
Elf_Scn *scn; // Section index struct
Elf32_Shdr *shdr32 = 0; // Section struct 32 Bit
Elf64_Shdr *shdr64 = 0; // Section struct 64 Bit
if (elf_version(EV_CURRENT) == EV_NONE)
std::cerr << "ELF library initialization failed" << std::endl;
if ((fd = open(m_elf->getFilename().c_str(), O_RDONLY, 0)) < 0)
std::cerr << "open " << m_elf->getFilename().c_str() << " failed" << std::endl;
if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL)
std::cerr << "elf_begin() failed" << std::endl;
if (elf_kind(e) != ELF_K_ELF) {
std::cerr << m_elf->getFilename().c_str() << " is not an Elf object" << std::endl;
}
if (elf_getshdrstrndx(e, &shstrndx) != 0)
std::cerr << "elf_getshdrstrndx() failed" << std::endl;
scn = NULL;
// Loop over all sections in the ELF object
while ((scn = elf_nextscn(e, scn)) != NULL) {
// Given an Elf Scn pointer, retrieve the associated section header
if (m_elf->m_elfclass == ELFCLASS32) {
if ((shdr32 = elf32_getshdr(scn)) == NULL)
std::cerr << "getshdr() failed" << std::endl;
// Retrieve the name of the section
if ((section_name = elf_strptr(e, shstrndx, shdr32->sh_name)) == NULL)
std::cerr << "elf_strptr() failed" << std::endl;
if (!strcmp(section_name, ".text")) {
if ((data = elf_rawdata(scn, data)) == NULL) {
std::cerr << "No section data available" << std::endl;
}
#if 0
printf("Section name: %s\n", section_name);
printf("sh_offset: %x\n", shdr32->sh_offset);
printf("sh_type: %x\n", shdr32->sh_type);
printf("sh_flags: %x\n", shdr32->sh_flags);
printf("sh_addr: %x\n", shdr32->sh_addr);
printf("sh_size: %x\n", shdr32->sh_size);
printf("sh_link: %x\n", shdr32->sh_link);
printf("sh_info: %x\n", shdr32->sh_info);
printf("sh_addralign: %x\n", shdr32->sh_addralign);
printf("sh_entsize: %x\n", shdr32->sh_entsize);
printf("data: %x\n", data);
printf("buf: %x\n", data->d_buf);
printf("size: %d\n", data->d_size);
#endif
break;
}
}
else {
if ((shdr64 = elf64_getshdr(scn)) == NULL)
std::cerr << "getshdr() failed" << std::endl;
// Retrieve the name of the section
if ((section_name = elf_strptr(e, shstrndx, shdr64->sh_name)) == NULL)
std::cerr << "elf_strptr() failed" << std::endl;
if (!strcmp(section_name, ".text")) {
if ((data = elf_rawdata(scn, data)) == NULL) {
std::cerr << "No section data availible" << std::endl;
}
#if 0
printf("Section name: %s\n", section_name);
printf("sh_offset: %lx\n", shdr64->sh_offset);
printf("sh_type: %lx\n", shdr64->sh_type);
printf("sh_flags: %lx\n", shdr64->sh_flags);
printf("sh_addr: %lx\n", shdr64->sh_addr);
printf("sh_size: %lx\n", shdr64->sh_size);
printf("sh_link: %lx\n", shdr64->sh_link);
printf("sh_info: %lx\n", shdr64->sh_info);
printf("sh_addralign: %lx\n", shdr64->sh_addralign);
printf("sh_entsize: %lx\n", shdr64->sh_entsize);
printf("data: %lx\n", data);
printf("buf: %lx\n", data->d_buf);
printf("size: %d\n", data->d_size);
#endif
break;
}
}
}
std::map<uint64_t, uint64_t> symtab_map;
if (m_elf->m_elfclass == ELFCLASS32) {
symtab_map = get_symtab_map(shdr32->sh_size);
} else if (m_elf->m_elfclass == ELFCLASS64) {
symtab_map = get_symtab_map(shdr64->sh_size);
}
disassemble_section(data, shdr32, shdr64, symtab_map);
elf_end(e);
close(fd);
}

View File

@ -0,0 +1,84 @@
#ifndef __CAPSTONEDISASSEMBLER_HPP__
#define __CAPSTONEDISASSEMBLER_HPP__
#include <iostream>
#include <vector>
#include <map>
#include <limits.h>
#include <memory> // unique_ptr
#include <algorithm>
#include <elf.h>
#include "CapstoneToFailTranslator.hpp"
#include "CapstoneToFailBochs.hpp"
#include "CapstoneToFailGem5.hpp"
#include <capstone/capstone.h>
#include <unistd.h>
#include <fcntl.h>
#include <libelf.h>
#include <fstream>
#include <string>
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <array>
#include <vector>
#include <sstream>
#include <map>
#include "util/ElfReader.hpp"
namespace fail {
class CapstoneDisassembler {
public:
typedef uint16_t register_t;
typedef unsigned int address_t;
struct Instr {
unsigned int opcode;
unsigned int address;
unsigned char length;
bool conditional_branch;
std::vector<register_t> reg_uses;
std::vector<register_t> reg_defs;
};
typedef std::map<address_t, Instr> InstrMap;
private:
std::unique_ptr<InstrMap> instrs;
fail::CapstoneToFailTranslator *ctofail;
fail::ElfReader *m_elf;
static bool error(std::error_code ec) {
if (!ec) return false;
std::cerr << "DIS error: " << ec.message() << ".\n";
return true;
}
public:
CapstoneDisassembler(fail::ElfReader *elf) : ctofail(0) {
this->m_elf = elf;
this->instrs.reset(new InstrMap());
}
~CapstoneDisassembler() { delete ctofail; };
InstrMap &getInstrMap() { return *instrs; };
fail::CapstoneToFailTranslator *getTranslator();
void disassemble();
private:
int disassemble_section(Elf_Data *data, Elf32_Shdr *shdr, Elf64_Shdr *shdr64, std::map<uint64_t, uint64_t> symtab_map);
std::map<uint64_t, uint64_t> get_symtab_map(uint32_t sect_size);
};
}
#endif // __CAPSTONEDISASSEMBLER_HPP__

View File

@ -0,0 +1,103 @@
#include <capstone/x86.h>
#include "CapstoneToFailBochs.hpp"
#include "sal/x86/X86Architecture.hpp"
using namespace fail;
CapstoneToFailBochs::CapstoneToFailBochs() {
capstone_to_fail_map[X86_REG_AH] = reginfo_t(RID_CAX, 8, 8);
capstone_to_fail_map[X86_REG_AL] = reginfo_t(RID_CAX, 8);
capstone_to_fail_map[X86_REG_AX] = reginfo_t(RID_CAX, 16);
capstone_to_fail_map[X86_REG_EAX] = reginfo_t(RID_CAX, 32);
capstone_to_fail_map[X86_REG_RAX] = reginfo_t(RID_CAX, 64);
capstone_to_fail_map[X86_REG_BH] = reginfo_t(RID_CBX, 8, 8);
capstone_to_fail_map[X86_REG_BL] = reginfo_t(RID_CBX, 8);
capstone_to_fail_map[X86_REG_BX] = reginfo_t(RID_CBX, 16);
capstone_to_fail_map[X86_REG_EBX] = reginfo_t(RID_CBX, 32);
capstone_to_fail_map[X86_REG_RBX] = reginfo_t(RID_CBX, 64);
capstone_to_fail_map[X86_REG_CH] = reginfo_t(RID_CCX, 8, 8);
capstone_to_fail_map[X86_REG_CL] = reginfo_t(RID_CCX, 8);
capstone_to_fail_map[X86_REG_CX] = reginfo_t(RID_CCX, 16);
capstone_to_fail_map[X86_REG_ECX] = reginfo_t(RID_CCX, 32);
capstone_to_fail_map[X86_REG_RCX] = reginfo_t(RID_CCX, 64);
capstone_to_fail_map[X86_REG_DH] = reginfo_t(RID_CDX, 8, 8);
capstone_to_fail_map[X86_REG_DL] = reginfo_t(RID_CDX, 8);
capstone_to_fail_map[X86_REG_DX] = reginfo_t(RID_CDX, 16);
capstone_to_fail_map[X86_REG_EDX] = reginfo_t(RID_CDX, 32);
capstone_to_fail_map[X86_REG_RDX] = reginfo_t(RID_CDX, 64);
capstone_to_fail_map[X86_REG_R8] = reginfo_t(RID_R8, 64);
capstone_to_fail_map[X86_REG_R8D] = reginfo_t(RID_R8, 32);
capstone_to_fail_map[X86_REG_R8W] = reginfo_t(RID_R8, 16);
capstone_to_fail_map[X86_REG_R8B] = reginfo_t(RID_R8, 8);
capstone_to_fail_map[X86_REG_R9] = reginfo_t(RID_R9, 64);
capstone_to_fail_map[X86_REG_R9D] = reginfo_t(RID_R9, 32);
capstone_to_fail_map[X86_REG_R9W] = reginfo_t(RID_R9, 16);
capstone_to_fail_map[X86_REG_R9B] = reginfo_t(RID_R9, 8);
capstone_to_fail_map[X86_REG_R10] = reginfo_t(RID_R10, 64);
capstone_to_fail_map[X86_REG_R10D] = reginfo_t(RID_R10, 32);
capstone_to_fail_map[X86_REG_R10W] = reginfo_t(RID_R10, 16);
capstone_to_fail_map[X86_REG_R10B] = reginfo_t(RID_R10, 8);
capstone_to_fail_map[X86_REG_R11] = reginfo_t(RID_R11, 64);
capstone_to_fail_map[X86_REG_R11D] = reginfo_t(RID_R11, 32);
capstone_to_fail_map[X86_REG_R11W] = reginfo_t(RID_R11, 16);
capstone_to_fail_map[X86_REG_R11B] = reginfo_t(RID_R11, 8);
capstone_to_fail_map[X86_REG_R12] = reginfo_t(RID_R12, 64);
capstone_to_fail_map[X86_REG_R12D] = reginfo_t(RID_R12, 32);
capstone_to_fail_map[X86_REG_R12W] = reginfo_t(RID_R12, 16);
capstone_to_fail_map[X86_REG_R12B] = reginfo_t(RID_R12, 8);
capstone_to_fail_map[X86_REG_R13] = reginfo_t(RID_R13, 64);
capstone_to_fail_map[X86_REG_R13D] = reginfo_t(RID_R13, 32);
capstone_to_fail_map[X86_REG_R13W] = reginfo_t(RID_R13, 16);
capstone_to_fail_map[X86_REG_R13B] = reginfo_t(RID_R13, 8);
capstone_to_fail_map[X86_REG_R14] = reginfo_t(RID_R14, 64);
capstone_to_fail_map[X86_REG_R14D] = reginfo_t(RID_R14, 32);
capstone_to_fail_map[X86_REG_R14W] = reginfo_t(RID_R14, 16);
capstone_to_fail_map[X86_REG_R14B] = reginfo_t(RID_R14, 8);
capstone_to_fail_map[X86_REG_R15] = reginfo_t(RID_R15, 64);
capstone_to_fail_map[X86_REG_R15D] = reginfo_t(RID_R15, 32);
capstone_to_fail_map[X86_REG_R15W] = reginfo_t(RID_R15, 16);
capstone_to_fail_map[X86_REG_R15B] = reginfo_t(RID_R15, 8);
capstone_to_fail_map[X86_REG_DIL] = reginfo_t(RID_CDI, 8);
capstone_to_fail_map[X86_REG_DI] = reginfo_t(RID_CDI, 16);
capstone_to_fail_map[X86_REG_EDI] = reginfo_t(RID_CDI, 32);
capstone_to_fail_map[X86_REG_RDI] = reginfo_t(RID_CDI, 64);
capstone_to_fail_map[X86_REG_BPL] = reginfo_t(RID_CBP, 8);
capstone_to_fail_map[X86_REG_BP] = reginfo_t(RID_CBP, 16);
capstone_to_fail_map[X86_REG_EBP] = reginfo_t(RID_CBP, 32);
capstone_to_fail_map[X86_REG_RBP] = reginfo_t(RID_CBP, 64);
capstone_to_fail_map[X86_REG_EFLAGS] = reginfo_t(RID_FLAGS, 64);
// RFLAGS doesn't exist in the x86.h of capstone, therefore X86_REG_EFLAGS is set to 64bit
// capstone_to_fail_map[RFLAGS] = reginfo_t(RID_FLAGS, 64);
capstone_to_fail_map[X86_REG_EIP] = reginfo_t(RID_PC, 32);
capstone_to_fail_map[X86_REG_RIP] = reginfo_t(RID_PC, 64);
capstone_to_fail_map[X86_REG_SIL] = reginfo_t(RID_CSI, 8);
capstone_to_fail_map[X86_REG_SI] = reginfo_t(RID_CSI, 16);
capstone_to_fail_map[X86_REG_ESI] = reginfo_t(RID_CSI, 32);
capstone_to_fail_map[X86_REG_RSI] = reginfo_t(RID_CSI, 64);
capstone_to_fail_map[X86_REG_SPL] = reginfo_t(RID_CSP, 8);
capstone_to_fail_map[X86_REG_SP] = reginfo_t(RID_CSP, 16);
capstone_to_fail_map[X86_REG_ESP] = reginfo_t(RID_CSP, 32);
capstone_to_fail_map[X86_REG_RSP] = reginfo_t(RID_CSP, 64);
capstone_to_fail_map[X86_REG_CR0] = reginfo_t(RID_CR0);
capstone_to_fail_map[X86_REG_CR2] = reginfo_t(RID_CR2);
capstone_to_fail_map[X86_REG_CR3] = reginfo_t(RID_CR3);
capstone_to_fail_map[X86_REG_CR4] = reginfo_t(RID_CR4);
capstone_to_fail_map[X86_REG_CS] = reginfo_t(RID_CS, 16);
capstone_to_fail_map[X86_REG_DS] = reginfo_t(RID_DS, 16);
capstone_to_fail_map[X86_REG_ES] = reginfo_t(RID_ES, 16);
capstone_to_fail_map[X86_REG_FS] = reginfo_t(RID_FS, 16);
capstone_to_fail_map[X86_REG_GS] = reginfo_t(RID_GS, 16);
capstone_to_fail_map[X86_REG_SS] = reginfo_t(RID_SS, 16);
}

View File

@ -0,0 +1,14 @@
#ifndef __CAPSTONETOFAILBOCHS_HPP_
#define __CAPSTONETOFAILBOCHS_HPP_
#include "CapstoneToFailTranslator.hpp"
namespace fail {
class CapstoneToFailBochs : public CapstoneToFailTranslator {
public:
CapstoneToFailBochs();
};
} // end of namespace
#endif

View File

@ -0,0 +1,24 @@
#include <capstone/arm.h>
#include "CapstoneToFailGem5.hpp"
#include "sal/arm/ArmArchitecture.hpp"
using namespace fail;
CapstoneToFailGem5::CapstoneToFailGem5() {
capstone_to_fail_map[ARM_REG_R0] = reginfo_t(RI_R0);
capstone_to_fail_map[ARM_REG_R1] = reginfo_t(RI_R1);
capstone_to_fail_map[ARM_REG_R2] = reginfo_t(RI_R2);
capstone_to_fail_map[ARM_REG_R3] = reginfo_t(RI_R3);
capstone_to_fail_map[ARM_REG_R4] = reginfo_t(RI_R4);
capstone_to_fail_map[ARM_REG_R5] = reginfo_t(RI_R5);
capstone_to_fail_map[ARM_REG_R6] = reginfo_t(RI_R6);
capstone_to_fail_map[ARM_REG_R7] = reginfo_t(RI_R7);
capstone_to_fail_map[ARM_REG_R8] = reginfo_t(RI_R8);
capstone_to_fail_map[ARM_REG_R9] = reginfo_t(RI_R9);
capstone_to_fail_map[ARM_REG_R10] = reginfo_t(RI_R10);
capstone_to_fail_map[ARM_REG_R11] = reginfo_t(RI_R11);
capstone_to_fail_map[ARM_REG_R12] = reginfo_t(RI_R12);
capstone_to_fail_map[ARM_REG_SP] = reginfo_t(RI_SP);
capstone_to_fail_map[ARM_REG_LR] = reginfo_t(RI_LR);
capstone_to_fail_map[ARM_REG_PC] = reginfo_t(RI_IP);
}

View File

@ -0,0 +1,14 @@
#ifndef __CAPSTONETOFAILGEM5_HPP_
#define __CAPSTONETOFAILGEM5_HPP_
#include "CapstoneToFailTranslator.hpp"
namespace fail {
class CapstoneToFailGem5 : public CapstoneToFailTranslator {
public:
CapstoneToFailGem5();
};
} // end of namespace
#endif // __CAPSTONETOFAILGEM5_HPP_

View File

@ -0,0 +1,50 @@
#include <algorithm>
#include "CapstoneToFailTranslator.hpp"
#include "sal/SALInst.hpp"
using namespace fail;
const CapstoneToFailTranslator::reginfo_t & CapstoneToFailTranslator::getFailRegisterInfo(unsigned int regid) {
ctof_map_t::iterator it = capstone_to_fail_map.find(regid);
if ( it != capstone_to_fail_map.end() ) {// found
return (*it).second;
} else { // not found
// std::cout << "Fail ID for Capstone Register id " << std::dec << regid << " not found :(" << std::endl;
// exit(EXIT_FAILURE);
return notfound;
}
}
regdata_t CapstoneToFailTranslator::getRegisterContent(ConcreteCPU& cpu, const reginfo_t &reginfo){
regdata_t result;
Register* reg = cpu.getRegister(reginfo.id);
result = cpu.getRegisterContent(reg);
result &= reginfo.mask;
result >>= reginfo.offset;
return result;
}
void CapstoneToFailTranslator::setRegisterContent(ConcreteCPU & cpu, const reginfo_t &reginfo, regdata_t value){
Register* reg = cpu.getRegister(reginfo.id);
regdata_t origval = cpu.getRegisterContent(reg); // Get register Value from fail
origval &= ~(reginfo.mask); // clear bits to write
value <<= reginfo.offset; // shift value to write up to position
value &= reginfo.mask; // mask out trailing and leading bits
value |= origval; // set bits to write
cpu.setRegisterContent( reg, value ); // write back register content
}
int CapstoneToFailTranslator::getMaxFailRegisterID()
{
auto max = std::max_element(capstone_to_fail_map.cbegin(), capstone_to_fail_map.cend(),
[] (const ctof_map_t::value_type& v1, const ctof_map_t::value_type& v2) {
return v1.second.id < v2.second.id;
});
return max->second.id;
}

View File

@ -0,0 +1,93 @@
#ifndef __CAPSTONETOFAILTRANSLATOR_HPP_
#define __CAPSTONETOFAILTRANSLATOR_HPP_
#include "sal/SALConfig.hpp"
#include "sal/ConcreteCPU.hpp"
#include <map>
namespace fail {
/**
* Translates Capstone disassembler ids
* to FAIL* SAL representations.
*/
class CapstoneToFailTranslator {
public:
/**
* Maps registers to/from linear addresses usable for def/use-pruning
* purposes and storage in the database. Takes care that the linear
* addresses of x86 subregisters (e.g., AX represents the lower 16 bits of
* EAX) overlap with their siblings.
*/
struct reginfo_t {
int id;
regwidth_t width;
regdata_t mask;
byte_t offset;
int toDataAddress() const {
// .. 5 4 | 3 2 1 0
// <reg> | <offset>
return (id << 4) | (offset / 8);
}
static reginfo_t fromDataAddress(int addr, int width) {
int id = addr >> 4;
byte_t offset = (addr & 0xf) * 8;
return reginfo_t(id, width * 8, offset);
}
reginfo_t(int id=-1, regwidth_t width = 32, byte_t offs = 0)
: id(id), width(width), mask((((regdata_t) 1 << width) - 1) << offs), offset(offs)
{
if (width >= sizeof(regdata_t) * 8) { // all ones, (1 << width) == 0!
mask = -1;
}
#if 0
std::cerr << "constructing reginfo_t: " << std::dec << id << " " << width << " " << ((int)offs) << std::hex << " 0x" << mask << std::endl;
#endif
}
};
protected:
CapstoneToFailTranslator(){};
typedef std::map<unsigned int, struct reginfo_t> ctof_map_t;
ctof_map_t capstone_to_fail_map;
public:
/**
* Translates a backend-specific register ID to a Fail register ID.
* @param regid A backend-specific register ID.
* @return A FAIL* register-info struct, or CapstonetoFailTranslator::notfound
* if no mapping was found.
*/
const reginfo_t & getFailRegisterInfo(unsigned int regid);
static regdata_t getRegisterContent(ConcreteCPU & cpu, const reginfo_t & reg);
static void setRegisterContent(ConcreteCPU & cpu, const reginfo_t &reg, regdata_t value);
regdata_t getRegisterContent(ConcreteCPU & cpu, unsigned int csid) {
return getRegisterContent(cpu, getFailRegisterInfo(csid));
}
void setRegisterContent(ConcreteCPU & cpu, unsigned int csid, regdata_t value) {
setRegisterContent(cpu, getFailRegisterInfo(csid), value);
}
/**
* Translates a backend-specific register ID to a Fail register ID.
* @param regid A backend-specific register ID.
* @return A FAIL* register ID. May do funny things if regid does not exist.
*/
int getFailRegisterID(unsigned int regid) { return this->getFailRegisterInfo(regid).id; };
int getMaxFailRegisterID();
fail::address_t getMaxDataAddress() { reginfo_t r(getMaxFailRegisterID() + 1); return r.toDataAddress() - 1; }
reginfo_t notfound;
// static CapstoneToFailTranslator* createFromBinary(const std::string elf_path);
};
} // end of namespace
#endif

Binary file not shown.

View File

@ -0,0 +1,281 @@
Triple: arm-unknown-unknown
Number of Registers: 278
0 - NOREG
1 - APSR
2 - CPSR
3 - D0
4 - D1
5 - D2
6 - D3
7 - D4
8 - D5
9 - D6
10 - D7
11 - D8
12 - D9
13 - D10
14 - D11
15 - D12
16 - D13
17 - D14
18 - D15
19 - D16
20 - D17
21 - D18
22 - D19
23 - D20
24 - D21
25 - D22
26 - D23
27 - D24
28 - D25
29 - D26
30 - D27
31 - D28
32 - D29
33 - D30
34 - D31
35 - FPEXC
36 - FPSCR
37 - FPSCR_NZCV
38 - FPSID
39 - ITSTATE
40 - LR
41 - MVFR0
42 - MVFR1
43 - PC
44 - Q0
45 - Q1
46 - Q2
47 - Q3
48 - Q4
49 - Q5
50 - Q6
51 - Q7
52 - Q8
53 - Q9
54 - Q10
55 - Q11
56 - Q12
57 - Q13
58 - Q14
59 - Q15
60 - R0
61 - R1
62 - R2
63 - R3
64 - R4
65 - R5
66 - R6
67 - R7
68 - R8
69 - R9
70 - R10
71 - R11
72 - R12
73 - S0
74 - S1
75 - S2
76 - S3
77 - S4
78 - S5
79 - S6
80 - S7
81 - S8
82 - S9
83 - S10
84 - S11
85 - S12
86 - S13
87 - S14
88 - S15
89 - S16
90 - S17
91 - S18
92 - S19
93 - S20
94 - S21
95 - S22
96 - S23
97 - S24
98 - S25
99 - S26
100 - S27
101 - S28
102 - S29
103 - S30
104 - S31
105 - SP
106 - SPSR
107 - D0_D2
108 - D1_D3
109 - D2_D4
110 - D3_D5
111 - D4_D6
112 - D5_D7
113 - D6_D8
114 - D7_D9
115 - D8_D10
116 - D9_D11
117 - D10_D12
118 - D11_D13
119 - D12_D14
120 - D13_D15
121 - D14_D16
122 - D15_D17
123 - D16_D18
124 - D17_D19
125 - D18_D20
126 - D19_D21
127 - D20_D22
128 - D21_D23
129 - D22_D24
130 - D23_D25
131 - D24_D26
132 - D25_D27
133 - D26_D28
134 - D27_D29
135 - D28_D30
136 - D29_D31
137 - Q0_Q1
138 - Q1_Q2
139 - Q2_Q3
140 - Q3_Q4
141 - Q4_Q5
142 - Q5_Q6
143 - Q6_Q7
144 - Q7_Q8
145 - Q8_Q9
146 - Q9_Q10
147 - Q10_Q11
148 - Q11_Q12
149 - Q12_Q13
150 - Q13_Q14
151 - Q14_Q15
152 - Q0_Q1_Q2_Q3
153 - Q1_Q2_Q3_Q4
154 - Q2_Q3_Q4_Q5
155 - Q3_Q4_Q5_Q6
156 - Q4_Q5_Q6_Q7
157 - Q5_Q6_Q7_Q8
158 - Q6_Q7_Q8_Q9
159 - Q7_Q8_Q9_Q10
160 - Q8_Q9_Q10_Q11
161 - Q9_Q10_Q11_Q12
162 - Q10_Q11_Q12_Q13
163 - Q11_Q12_Q13_Q14
164 - Q12_Q13_Q14_Q15
165 - D0_D1_D2
166 - D1_D2_D3
167 - D2_D3_D4
168 - D3_D4_D5
169 - D4_D5_D6
170 - D5_D6_D7
171 - D6_D7_D8
172 - D7_D8_D9
173 - D8_D9_D10
174 - D9_D10_D11
175 - D10_D11_D12
176 - D11_D12_D13
177 - D12_D13_D14
178 - D13_D14_D15
179 - D14_D15_D16
180 - D15_D16_D17
181 - D16_D17_D18
182 - D17_D18_D19
183 - D18_D19_D20
184 - D19_D20_D21
185 - D20_D21_D22
186 - D21_D22_D23
187 - D22_D23_D24
188 - D23_D24_D25
189 - D24_D25_D26
190 - D25_D26_D27
191 - D26_D27_D28
192 - D27_D28_D29
193 - D28_D29_D30
194 - D29_D30_D31
195 - D0_D2_D4
196 - D1_D3_D5
197 - D2_D4_D6
198 - D3_D5_D7
199 - D4_D6_D8
200 - D5_D7_D9
201 - D6_D8_D10
202 - D7_D9_D11
203 - D8_D10_D12
204 - D9_D11_D13
205 - D10_D12_D14
206 - D11_D13_D15
207 - D12_D14_D16
208 - D13_D15_D17
209 - D14_D16_D18
210 - D15_D17_D19
211 - D16_D18_D20
212 - D17_D19_D21
213 - D18_D20_D22
214 - D19_D21_D23
215 - D20_D22_D24
216 - D21_D23_D25
217 - D22_D24_D26
218 - D23_D25_D27
219 - D24_D26_D28
220 - D25_D27_D29
221 - D26_D28_D30
222 - D27_D29_D31
223 - D0_D2_D4_D6
224 - D1_D3_D5_D7
225 - D2_D4_D6_D8
226 - D3_D5_D7_D9
227 - D4_D6_D8_D10
228 - D5_D7_D9_D11
229 - D6_D8_D10_D12
230 - D7_D9_D11_D13
231 - D8_D10_D12_D14
232 - D9_D11_D13_D15
233 - D10_D12_D14_D16
234 - D11_D13_D15_D17
235 - D12_D14_D16_D18
236 - D13_D15_D17_D19
237 - D14_D16_D18_D20
238 - D15_D17_D19_D21
239 - D16_D18_D20_D22
240 - D17_D19_D21_D23
241 - D18_D20_D22_D24
242 - D19_D21_D23_D25
243 - D20_D22_D24_D26
244 - D21_D23_D25_D27
245 - D22_D24_D26_D28
246 - D23_D25_D27_D29
247 - D24_D26_D28_D30
248 - D25_D27_D29_D31
249 - D1_D2
250 - D3_D4
251 - D5_D6
252 - D7_D8
253 - D9_D10
254 - D11_D12
255 - D13_D14
256 - D15_D16
257 - D17_D18
258 - D19_D20
259 - D21_D22
260 - D23_D24
261 - D25_D26
262 - D27_D28
263 - D29_D30
264 - D1_D2_D3_D4
265 - D3_D4_D5_D6
266 - D5_D6_D7_D8
267 - D7_D8_D9_D10
268 - D9_D10_D11_D12
269 - D11_D12_D13_D14
270 - D13_D14_D15_D16
271 - D15_D16_D17_D18
272 - D17_D18_D19_D20
273 - D19_D20_D21_D22
274 - D21_D22_D23_D24
275 - D23_D24_D25_D26
276 - D25_D26_D27_D28
277 - D27_D28_D29_D30

View File

@ -0,0 +1,71 @@
#include <assert.h>
class random_generator_t
{
private:
unsigned int a; // (sqrt(5)-1)/2 = 0.61803398875
unsigned int b;
unsigned int last_val;
unsigned int sd;
public:
void forth() {
last_val = a*last_val + b;
}
random_generator_t(unsigned int seed = 1)
: a(2654435769), b(seed), last_val(1), sd(seed){
forth();
}
unsigned int item() const {
return last_val;
}
void reset() {
last_val = 1;
b = sd;
forth();
}
};
void sort(int len, int arr[] )
{
int tmp;
int again;
int i;
for(again=1; again; )
for( again=0, i=0; i < (len-1); ++i){
assert(0<=i && i+1 <len);
if( arr[i] > arr[i+1] ){
tmp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = tmp;
again = 1;
}
}
}
int main()
{
const unsigned int arr_size = 10000; //50000;
int arr[arr_size];
int i;
random_generator_t rand;
for(i=0; i!=arr_size; ++i){
arr[i] = rand.item();
rand.forth();
}
sort(arr_size, arr);
}

View File

@ -0,0 +1,63 @@
#include "util/ElfReader.hpp"
#include <elf.h>
#include "../CapstoneDisassembler.hpp"
using namespace fail;
bool show_mapping(fail::CapstoneToFailTranslator *ctof, unsigned llvmid)
{
const CapstoneToFailTranslator::reginfo_t& failreg = ctof->getFailRegisterInfo(llvmid);
std::cout /*<< reg_info.getName(llvmid)*/ << "(" << std::dec << llvmid << "->";
if (&failreg != &ctof->notfound) {
std::cout << failreg.id;
} else {
std::cout << "NOTFOUND!";
}
std::cout << ") ";
return &failreg != &ctof->notfound;
}
int main(int argc, char* argv[]) {
std::string file;
if(argc > 1){
std::cout << "Trying to disassemble: " << argv[1] << std::endl;
file = argv[1];
} else {
std::cerr << "No file to disassemble :(" << std::endl;
return -1;
}
ElfReader *m_elf = new ElfReader(file.c_str());
CapstoneDisassembler disas(m_elf);
disas.disassemble();
CapstoneDisassembler::InstrMap &instr_map = disas.getInstrMap();
std::cout << "Map Size: " << instr_map.size() << std::endl;
CapstoneDisassembler::InstrMap::const_iterator itr;
fail::CapstoneToFailTranslator *ctof = disas.getTranslator();
for (itr = instr_map.begin(); itr != instr_map.end(); ++itr){
const CapstoneDisassembler::Instr &instr = (*itr).second;
std::cout << std::hex << (*itr).first << " | " << instr.opcode << std::endl;
std::cout << std::dec << "USES: ";
for (std::vector<uint16_t>::const_iterator it = instr.reg_uses.begin();
it != instr.reg_uses.end(); ++it) {
show_mapping(ctof, *it);
}
std::cout << " | DEFS: ";
for (std::vector<uint16_t>::const_iterator it = instr.reg_defs.begin();
it != instr.reg_defs.end(); ++it) {
show_mapping(ctof, *it);
}
if (instr.conditional_branch) {
std::cout << "(conditional branch)";
}
std::cout << std::endl;
}
}

View File

@ -0,0 +1,4 @@
g++ -m32 bubble.cc -o x86
g++ -m64 bubble.cc -o x86_64
arm-none-eabi-g++ -mcpu=cortex-m3 bubble.cc -o armm3
arm-none-eabi-g++ -mcpu=arm9 bubble.cc -o arm9

View File

@ -0,0 +1,163 @@
Triple: x86_64-unknown-unknown
Number of Registers: 160
0 - NOREG
1 - AH
2 - AL
3 - AX
4 - BH
5 - BL
6 - BP
7 - BPL
8 - BX
9 - CH
10 - CL
11 - CR0
12 - CR1
13 - CR2
14 - CR3
15 - CR4
16 - CR5
17 - CR6
18 - CR7
19 - CR8
20 - CR9
21 - CR10
22 - CR11
23 - CR12
24 - CR13
25 - CR14
26 - CR15
27 - CS
28 - CX
29 - DH
30 - DI
31 - DIL
32 - DL
33 - DR0
34 - DR1
35 - DR2
36 - DR3
37 - DR4
38 - DR5
39 - DR6
40 - DR7
41 - DS
42 - DX
43 - EAX
44 - EBP
45 - EBX
46 - ECX
47 - EDI
48 - EDX
49 - EFLAGS
50 - EIP
51 - EIZ
52 - ES
53 - ESI
54 - ESP
55 - FP0
56 - FP1
57 - FP2
58 - FP3
59 - FP4
60 - FP5
61 - FP6
62 - FS
63 - GS
64 - IP
65 - MM0
66 - MM1
67 - MM2
68 - MM3
69 - MM4
70 - MM5
71 - MM6
72 - MM7
73 - R8
74 - R8B
75 - R8D
76 - R8W
77 - R9
78 - R9B
79 - R9D
80 - R9W
81 - R10
82 - R10B
83 - R10D
84 - R10W
85 - R11
86 - R11B
87 - R11D
88 - R11W
89 - R12
90 - R12B
91 - R12D
92 - R12W
93 - R13
94 - R13B
95 - R13D
96 - R13W
97 - R14
98 - R14B
99 - R14D
100 - R14W
101 - R15
102 - R15B
103 - R15D
104 - R15W
105 - RAX
106 - RBP
107 - RBX
108 - RCX
109 - RDI
110 - RDX
111 - RIP
112 - RIZ
113 - RSI
114 - RSP
115 - SI
116 - SIL
117 - SP
118 - SPL
119 - SS
120 - ST0
121 - ST1
122 - ST2
123 - ST3
124 - ST4
125 - ST5
126 - ST6
127 - ST7
128 - XMM0
129 - XMM1
130 - XMM2
131 - XMM3
132 - XMM4
133 - XMM5
134 - XMM6
135 - XMM7
136 - XMM8
137 - XMM9
138 - XMM10
139 - XMM11
140 - XMM12
141 - XMM13
142 - XMM14
143 - XMM15
144 - YMM0
145 - YMM1
146 - YMM2
147 - YMM3
148 - YMM4
149 - YMM5
150 - YMM6
151 - YMM7
152 - YMM8
153 - YMM9
154 - YMM10
155 - YMM11
156 - YMM12
157 - YMM13
158 - YMM14
159 - YMM15