From c29ae7a65c636b8d1fa37c6589278dcdee97658f Mon Sep 17 00:00:00 2001 From: Dennis Brentjes Date: Mon, 19 Sep 2016 17:38:23 +0200 Subject: Started working on a x86 emulator. --- emulate/emulator.hpp | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 emulate/emulator.hpp (limited to 'emulate/emulator.hpp') diff --git a/emulate/emulator.hpp b/emulate/emulator.hpp new file mode 100644 index 0000000..e894042 --- /dev/null +++ b/emulate/emulator.hpp @@ -0,0 +1,113 @@ +#pragma once + +#include "cpustate.hpp" + +#include "le_parse_util.hpp" + +#include +#include + +#include +#include + +class Emulator { +public: + CpuState cpu; + + std::map> opcode_handlers; + + + + void handle_I_JMP(_DInst inst) { + if(inst.ops[0].type == O_PC || inst.ops[0].type == O_PTR || inst.ops[0].type == O_DISP) { + binparse::Offset32 target = binparse::Offset32(INSTRUCTION_GET_TARGET(&inst)); + cpu.eip() = target; + } else if (inst.ops[0].type == O_SMEM) { + throw UnhandledInstruction(); + } else { + throw UnrecognizedInstruction(); + } + } + void handle_I_STI(_DInst) { + cpu.intf() = 1; + } + + void handle_I_AND(_DInst inst) { + std::cout << inst.ops[0].size << std::endl; + //get_op(0, inst) &= get_op(1, inst); + } + +public: + Emulator(binparse::Offset32 init_eip, binparse::Offset32 init_esp) + : cpu() + { + cpu.eip() = init_eip; + cpu.esp() = init_esp; + + #define REGISTER_HANDLER(OPCODE) opcode_handlers[OPCODE] = std::bind(&Emulator::handle_##OPCODE, this, std::placeholders::_1) + + REGISTER_HANDLER(I_JMP); + REGISTER_HANDLER(I_STI); + REGISTER_HANDLER(I_AND); + + #undef REGISTER_HANDLER + } + + struct UnhandledInstruction : public std::runtime_error { + UnhandledInstruction() + : std::runtime_error("Encountered unhandled instruction") + {} + }; + + struct UnrecognizedInstruction : public std::runtime_error { + UnrecognizedInstruction() + : std::runtime_error("Encountered unhandled instruction") + {} + }; + + void handle_instruction(_DInst inst) { + opcode_handlers.at(inst.opcode)(inst); + } + +}; + +void emulate(std::string file_path) { + std::ifstream file_stream(file_path, std::ios::binary); + file_stream.unsetf(std::ios::skipws); + auto file = le::parse_file(file_stream); + auto binary = load_binary(file); + + _CodeInfo ci; + _DecodeType dt = Decode32Bits; + + auto code_object = file.object_table.entries.at(file.le_header.EIP_object); + auto initial_eip = code_object.reloc_base_address + file.le_header.EIP; + + auto data_object = file.object_table.entries.at(file.le_header.ESP_object); + auto initial_esp = data_object.reloc_base_address + file.le_header.ESP; + + Emulator emulator(initial_eip, initial_esp); + + unsigned int decodedInstructionsCount; + + bool run = true; + while(run) { + ci.code = binary.data() + emulator.cpu.eip(); + ci.nextOffset = emulator.cpu.eip(); + ci.codeLen = binary.size() - emulator.cpu.eip(); + ci.codeOffset = emulator.cpu.eip(); + ci.dt = dt; + ci.features = DF_NONE; + + _DInst decinst; + distorm_decompose(&ci, &decinst, 1, &decodedInstructionsCount); + + emulator.cpu.eip() += decinst.size; + + _DecodedInst inst; + distorm_format64(&ci, &decinst, &inst); + std::cout << "CurrentInstruction: " << std::hex << std::setw(8) << std::setfill('0') << inst.offset << ":\t" << inst.mnemonic.p << " " << inst.operands.p << std::endl; + + emulator.handle_instruction(decinst); + } +} -- cgit v1.2.3-70-g09d2