-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcore.cpp
More file actions
138 lines (109 loc) · 3.54 KB
/
core.cpp
File metadata and controls
138 lines (109 loc) · 3.54 KB
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "core.h"
#include "utils.h"
#include "insnfmt.h"
void Registers::set_reg(const cs_insn insn)
{
if (insn.detail->x86.op_count == 2) {
if (insn.detail->x86.operands[0].type == X86_OP_REG && insn.detail->x86.operands[1].type == X86_OP_IMM) {
uint16_t value = insn.detail->x86.operands[1].imm;
switch (insn.detail->x86.operands[0].reg) {
case X86_REG_AL:
this->al = value;
break;
case X86_REG_AH:
this->ah = value;
break;
case X86_REG_AX:
this->ax = value;
break;
case X86_REG_BL:
this->bl = value;
break;
case X86_REG_BH:
this->bh = value;
break;
case X86_REG_BX:
this->bx = value;
break;
case X86_REG_CL:
this->cl = value;
break;
case X86_REG_CH:
this->ch = value;
break;
case X86_REG_CX:
this->cx = value;
break;
case X86_REG_DL:
this->dl = value;
break;
case X86_REG_DH:
this->dh = value;
break;
case X86_REG_DX:
this->dx = value;
break;
default:
break;
}
}
}
}
enum class CA_Mode { Uncond, Cond };
static bool check_address(std::map<uint64_t, Analyzer::Address>& l, const uint64_t addr, CA_Mode m)
{
auto it = l.find(addr);
if (it != l.end()) {
switch (m) {
case CA_Mode::Uncond:
if (it->second.type == Analyzer::Address_type::Call || it->second.type == Analyzer::Address_type::Jump)
if (it->second.value == addr)
return true;
return false;
case CA_Mode::Cond:
if (it->second.type == Analyzer::Address_type::JmpX && !it->second.visited) {
it->second.visited = true;
print_label(it->second);
}
}
}
return false;
}
uint64_t rt_disasm(const Binary& b, Disasm::Disassembler& d, Analyzer::Address& a, std::map<uint64_t, Analyzer::Address>& addr_list)
{
a.visited = true;
static Gap g;
static Registers reg;
uint64_t addr = a.value;
size_t size = b.size;
const uint8_t *code = &b.data.at(addr);
cs_insn *insn = cs_malloc(d.handle);
g.next_addr = a.value;
g.fill_gap(b);
//fprintf(stderr, "DEBUG: g.next_addr 0x%06lx, g.last_addr 0x%06lx, gap size %zu\n", g.next_addr, g.last_addr, g.next_addr - g.last_addr);
print_label(a);
while (cs_disasm_iter(d.handle, &code, &size, &addr, insn)) {
reg.set_reg(*insn);
g.last_addr = addr;
if (print_insn_r(*insn, reg.ah))
break;
if (check_address(addr_list, addr, CA_Mode::Uncond) || cs_insn_group(d.handle, insn, CS_GRP_RET) ||
cs_insn_group(d.handle, insn, CS_GRP_IRET) || addr >= b.fsize)
break;
check_address(addr_list, addr, CA_Mode::Cond);
}
cs_free(insn, 1);
return g.last_addr;
}
void ls_disasm(const Binary& b, Disasm::Disassembler& d)
{
printf(".start:\n");
uint64_t addr = b.entry;
size_t size = b.size;
const uint8_t *code = &b.data.at(addr);
cs_insn *insn = cs_malloc(d.handle);
while (cs_disasm_iter(d.handle, &code, &size, &addr, insn)) {
print_insn(*insn);
}
cs_free(insn, 1);
}