RoboDBG
Loading...
Searching...
No Matches
debugger.registers.cpp
1
2#include "debugger.h"
3
4namespace RoboDBG {
5 // ===========================
6 // GET REGISTER
7 // ===========================
8
9 #ifdef _WIN64
10 int64_t Debugger::getRegister(HANDLE hThread, Register64 reg) {
11 CONTEXT ctx = {};
12 ctx.ContextFlags = CONTEXT_ALL;
13
14 if (!GetThreadContext(hThread, &ctx)) {
15 std::cerr << "GetThreadContext failed: " << GetLastError() << "\n";
16 return -1;
17 }
18
19 switch (reg) {
20 case Register64::RAX: return ctx.Rax;
21 case Register64::RBX: return ctx.Rbx;
22 case Register64::RCX: return ctx.Rcx;
23 case Register64::RDX: return ctx.Rdx;
24 case Register64::RSI: return ctx.Rsi;
25 case Register64::RDI: return ctx.Rdi;
26 case Register64::RBP: return ctx.Rbp;
27 case Register64::RSP: return ctx.Rsp;
28 case Register64::R8: return ctx.R8;
29 case Register64::R9: return ctx.R9;
30 case Register64::R10: return ctx.R10;
31 case Register64::R11: return ctx.R11;
32 case Register64::R12: return ctx.R12;
33 case Register64::R13: return ctx.R13;
34 case Register64::R14: return ctx.R14;
35 case Register64::R15: return ctx.R15;
36 case Register64::RIP: return ctx.Rip;
37 }
38
39 return -1;
40 }
41
42 void Debugger::setRegister(HANDLE hThread, Register64 reg, int64_t value) {
43 CONTEXT ctx = {};
44 ctx.ContextFlags = CONTEXT_ALL;
45
46 if (!GetThreadContext(hThread, &ctx)) {
47 std::cerr << "GetThreadContext failed: " << GetLastError() << "\n";
48 return;
49 }
50
51 switch (reg) {
52 case Register64::RAX: ctx.Rax = value; break;
53 case Register64::RBX: ctx.Rbx = value; break;
54 case Register64::RCX: ctx.Rcx = value; break;
55 case Register64::RDX: ctx.Rdx = value; break;
56 case Register64::RSI: ctx.Rsi = value; break;
57 case Register64::RDI: ctx.Rdi = value; break;
58 case Register64::RBP: ctx.Rbp = value; break;
59 case Register64::RSP: ctx.Rsp = value; break;
60 case Register64::R8: ctx.R8 = value; break;
61 case Register64::R9: ctx.R9 = value; break;
62 case Register64::R10: ctx.R10 = value; break;
63 case Register64::R11: ctx.R11 = value; break;
64 case Register64::R12: ctx.R12 = value; break;
65 case Register64::R13: ctx.R13 = value; break;
66 case Register64::R14: ctx.R14 = value; break;
67 case Register64::R15: ctx.R15 = value; break;
68 case Register64::RIP: ctx.Rip = value; break;
69 }
70
71 SetThreadContext(hThread, &ctx);
72 }
73 #else
74 int32_t Debugger::getRegister(HANDLE hThread, Register32 reg) {
75 CONTEXT ctx = {};
76 ctx.ContextFlags = CONTEXT_ALL;
77
78 if (!GetThreadContext(hThread, &ctx)) {
79 std::cerr << "GetThreadContext failed: " << GetLastError() << "\n";
80 return -1;
81 }
82
83 switch (reg) {
84 case Register32::EAX: return ctx.Eax;
85 case Register32::EBX: return ctx.Ebx;
86 case Register32::ECX: return ctx.Ecx;
87 case Register32::EDX: return ctx.Edx;
88 case Register32::ESI: return ctx.Esi;
89 case Register32::EDI: return ctx.Edi;
90 case Register32::EBP: return ctx.Ebp;
91 case Register32::ESP: return ctx.Esp;
92 case Register32::EIP: return ctx.Eip;
93 }
94
95 return -1; // unreachable if all cases covered
96 }
97
98 void Debugger::setRegister(HANDLE hThread, Register32 reg, int value) {
99 CONTEXT ctx = {};
100 ctx.ContextFlags = CONTEXT_ALL;
101
102 if (!GetThreadContext(hThread, &ctx)) {
103 std::cerr << "GetThreadContext failed: " << GetLastError() << "\n";
104 return;
105 }
106
107 switch (reg) {
108 case Register32::EAX: ctx.Eax = value; break;
109 case Register32::EBX: ctx.Ebx = value; break;
110 case Register32::ECX: ctx.Ecx = value; break;
111 case Register32::EDX: ctx.Edx = value; break;
112 case Register32::ESI: ctx.Esi = value; break;
113 case Register32::EDI: ctx.Edi = value; break;
114 case Register32::EBP: ctx.Ebp = value; break;
115 case Register32::ESP: ctx.Esp = value; break;
116 case Register32::EIP: ctx.Eip = value; break;
117 }
118
119 SetThreadContext(hThread, &ctx);
120 }
121
122 #endif
123
124
125 #ifdef _WIN64
126 void Debugger::setFlag(HANDLE hThread, Flags64 flag, bool enabled) {
127 SuspendThread(hThread);
128
129 CONTEXT ctx = {};
130 ctx.ContextFlags = CONTEXT_FULL;
131
132 if (!GetThreadContext(hThread, &ctx)) {
133 std::cerr << "GetThreadContext failed\n";
134 ResumeThread(hThread);
135 return;
136 }
137
138 if (enabled)
139 ctx.EFlags |= static_cast<DWORD64>(flag);
140 else
141 ctx.EFlags &= ~static_cast<DWORD64>(flag);
142
143 if (!SetThreadContext(hThread, &ctx)) {
144 std::cerr << "SetThreadContext failed\n";
145 }
146
147 ResumeThread(hThread);
148 }
149
150 bool Debugger::getFlag(HANDLE hThread, Flags64 flag) {
151 SuspendThread(hThread);
152
153 CONTEXT ctx = {};
154 ctx.ContextFlags = CONTEXT_FULL;
155
156 if (!GetThreadContext(hThread, &ctx)) {
157 std::cerr << "GetThreadContext failed\n";
158 ResumeThread(hThread);
159 return false;
160 }
161
162 bool result = (ctx.EFlags & static_cast<DWORD64>(flag)) != 0;
163 ResumeThread(hThread);
164 return result;
165 }
166
167 #else
168
169 void Debugger::setFlag(HANDLE hThread, Flags32 flag, bool enabled) {
170 SuspendThread(hThread);
171
172 CONTEXT ctx = {};
173 ctx.ContextFlags = CONTEXT_FULL;
174
175 if (!GetThreadContext(hThread, &ctx)) {
176 std::cerr << "GetThreadContext failed\n";
177 ResumeThread(hThread);
178 return;
179 }
180
181 if (enabled)
182 ctx.EFlags |= static_cast<DWORD>(flag);
183 else
184 ctx.EFlags &= ~static_cast<DWORD>(flag);
185
186 if (!SetThreadContext(hThread, &ctx)) {
187 std::cerr << "SetThreadContext failed\n";
188 }
189
190 ResumeThread(hThread);
191 }
192
193 bool Debugger::getFlag(HANDLE hThread, Flags32 flag) {
194 SuspendThread(hThread);
195
196 CONTEXT ctx = {};
197 ctx.ContextFlags = CONTEXT_FULL;
198
199 if (!GetThreadContext(hThread, &ctx)) {
200 std::cerr << "GetThreadContext failed\n";
201 ResumeThread(hThread);
202 return false;
203 }
204
205 bool result = (ctx.EFlags & static_cast<DWORD>(flag)) != 0;
206 ResumeThread(hThread);
207 return result;
208 }
209
210 #endif
211}
int32_t getRegister(HANDLE hThread, Register32 reg)
Reads a 32-bit general-purpose register.
void setFlag(HANDLE hThread, Flags32 flag, bool enabled)
Sets or clears a status flag in EFLAGS.
bool getFlag(HANDLE hThread, Flags32 flag)
Reads a status flag from EFLAGS.
void setRegister(HANDLE hThread, Register32 reg, int32_t value)
Writes a 32-bit general-purpose register.
Main Debugger file.
Flags32
x86 CPU status flags.
Definition debugger.h:132
Register32
32-bit x86 general-purpose registers.
Definition debugger.h:160
@ EIP
Instruction Pointer.
Definition debugger.h:162