-
Notifications
You must be signed in to change notification settings - Fork 8
/
disasm.hpp
79 lines (53 loc) · 1.63 KB
/
disasm.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#pragma once
// STD
#include <vector>
#include <initializer_list>
// x86
#include "instruction.hpp"
namespace x86
{
class disassembler
{
public:
template <class T, size_t N>
disassembler(T(&buffer)[N]) : m_buffer(buffer, buffer + N) {}
disassembler(std::vector<std::uint8_t> buffer) : m_buffer(buffer) {}
std::uint8_t* buffer();
size_t buffer_size();
template <class T, class Fn>
void iterate(T offset, Fn callback)
{
for (auto instruction_pointer = this->buffer() + offset;
instruction_pointer < this->buffer() + this->buffer_size();)
{
x86::instruction instr{};
auto start = instruction_pointer;
if (!instr.prefix_initialised())
{
x86::disassembler::handle_prefix(instr, instruction_pointer);
}
if (!instr.rex_initialised())
{
// HANDLE REX PREFIX
x86::disassembler::handle_rex(instr, instruction_pointer);
}
if (!instr.opcode_initialised())
{
x86::disassembler::handle_opcode(instr, instruction_pointer);
}
if (!instr.operand_initialised())
{
x86::disassembler::handle_operand(instr, instruction_pointer);
}
instr.size() = static_cast<std::uint8_t>(instruction_pointer - start);
callback(instr, instruction_pointer);
}
}
private:
static void handle_opcode(x86::instruction& instr, std::uint8_t*& buffer);
static void handle_operand(x86::instruction& instr, std::uint8_t*& buffer);
static void handle_prefix(x86::instruction& instr, std::uint8_t*& buffer);
static void handle_rex(x86::instruction& instr, std::uint8_t*& buffer);
std::vector<std::uint8_t> m_buffer;
};
}