-
Notifications
You must be signed in to change notification settings - Fork 8
/
disasm.cpp
99 lines (67 loc) · 1.62 KB
/
disasm.cpp
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// STD
#include <algorithm>
// x86
#include "disasm.hpp"
#include "instruction_prefix.hpp"
#include "instruction_rex.hpp"
#include "instruction_opcode.hpp"
#include "instruction_operand.hpp"
#include "instruction_modrm.hpp"
std::uint8_t* x86::disassembler::buffer()
{
return this->m_buffer.data();
}
size_t x86::disassembler::buffer_size()
{
return this->m_buffer.size();
}
void x86::disassembler::handle_opcode(x86::instruction& instr, std::uint8_t*& buffer)
{
instr.opcode().buffer().emplace_back(*buffer);
++buffer;
instr.opcode_initialised() = true;
}
void x86::disassembler::handle_operand(x86::instruction& instr, std::uint8_t*& buffer)
{
const auto search = x86::operand::info.find(instr.opcode().as<std::uint32_t>());
if (search != x86::operand::info.end())
{
const auto info = search->second;
auto size = info.size;
if (info.modrm)
{
size += reinterpret_cast<x86::modrm*>(buffer)->data_size();
}
for (size_t i = 0; i < size; i++, buffer++)
instr.operand().buffer().emplace_back(*buffer);
}
instr.operand_initialised() = true;
}
void x86::disassembler::handle_prefix(x86::instruction& instr, std::uint8_t*& buffer)
{
for (size_t i = 0; i < 4; i++)
{
if (x86::prefix::is(*buffer))
{
instr.prefix().append(*buffer);
++buffer;
continue;
}
else
{
break;
}
}
instr.prefix_initialised() = true;
}
void x86::disassembler::handle_rex(x86::instruction& instr, std::uint8_t*& buffer)
{
auto rex = reinterpret_cast<x86::rex*>(buffer);
// 0100, REX
if (rex->id == 0x04)
{
instr.rex() = *rex;
++buffer;
}
instr.rex_initialised() = true;
}