va falloir parser l'opcode....

sinon ajout de plusieur methode
This commit is contained in:
YANNIS
2025-05-28 02:56:16 +02:00
parent a944e717cf
commit e1af309f8c
2 changed files with 160 additions and 59 deletions
+153 -59
View File
@@ -1,90 +1,184 @@
#include "Debugger.hpp" #include "Debugger.hpp"
#include <iomanip>
#include <iostream> #include <iostream>
#include <linux/elf.h>
#include <signal.h>
#include <sys/ptrace.h> #include <sys/ptrace.h>
#include <sys/uio.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
#include <signal.h>
Debugger::Debugger(const std::string& prog_name) : program_name(prog_name) { Debugger::Debugger(const std::string &prog_name) : program_name(prog_name) {
std::cout << "[+] Debugger initialized for program: " << program_name << "\n"; std::cout << "[+] Debugger initialized for program: " << program_name << "\n";
} }
void Debugger::run() { void Debugger::run() {
child_pid = fork(); child_pid = fork();
if (child_pid == 0) { if (child_pid == 0) {
run_target(); run_target();
} else if (child_pid > 0) { } else if (child_pid > 0) {
run_debugger(); run_debugger();
} else { } else {
std::cerr << "[!] fork() failed.\n"; std::cerr << "[!] fork() failed.\n";
} }
} }
void Debugger::run_target() { void Debugger::run_target() {
std::cout << "[+] Child process started.\n"; std::cout << "[+] Child process started.\n";
ptrace(PTRACE_TRACEME, 0, nullptr, nullptr); ptrace(static_cast<__ptrace_request>(PTRACE_TRACEME), 0, nullptr, nullptr);
execl(program_name.c_str(), program_name.c_str(), nullptr); execl(program_name.c_str(), program_name.c_str(), nullptr);
} }
void Debugger::run_debugger() { void Debugger::run_debugger() {
int status; int status;
waitpid(child_pid, &status, 0); waitpid(child_pid, &status, 0);
std::cout << "[+] Debugger attached to PID: " << child_pid << "\n"; std::cout << "[+] Debugger attached to PID: " << child_pid << "\n";
ptrace(PTRACE_SINGLESTEP, child_pid, nullptr, nullptr);
waitpid(child_pid, &status, 0);
go_until_x0_filled();
print_registers(child_pid);
get_opcode();
single_step();
print_registers(child_pid);
get_opcode();
std::cout << "[+] Child process exited.\n";
}
DEBUGING(); void Debugger::single_step(void){
int status;
ptrace(PTRACE_CONT, child_pid, nullptr, nullptr); std::cout << "[+] Single stepping...\n";
waitpid(child_pid, &status, 0); ptrace(PTRACE_SINGLESTEP, child_pid, nullptr, nullptr);
waitpid(child_pid, &status, 0);
}
std::cout << "[+] Child process exited.\n"; void Debugger::go_until_x0_filled(void)
{
while (1)
{
if (get_x0() != 0)
break ;
single_step();
}
}
uint32_t Debugger::get_opcode(void){
struct user_pt_regs {
uint64_t regs[31]; // x0-x30
uint64_t sp; // Stack Pointer
uint64_t pc; // Program Counter
uint64_t pstate; // Processor State
} regs;
struct iovec io;
io.iov_base = &regs;
io.iov_len = sizeof(regs);
if (ptrace(PTRACE_GETREGSET, child_pid, (void*)NT_PRSTATUS, &io) == -1) {
perror("ptrace(PTRACE_GETREGSET)");
return 0;
}
return ptrace(PTRACE_PEEKTEXT, child_pid, regs.pc, nullptr);
}
uint64_t Debugger::get_x0(void) {
struct user_pt_regs {
uint64_t regs[31]; // x0-x30
uint64_t sp; // Stack Pointer
uint64_t pc; // Program Counter
uint64_t pstate; // Processor State
} regs;
struct iovec io;
io.iov_base = &regs;
io.iov_len = sizeof(regs);
if (ptrace(PTRACE_GETREGSET, child_pid, (void*)NT_PRSTATUS, &io) == -1) {
perror("ptrace(PTRACE_GETREGSET)");
return 0;
}
return regs.regs[0]; // x0 is the first register
}
uint64_t Debugger::get_pc(void) {
struct user_pt_regs {
uint64_t regs[31]; // x0-x30
uint64_t sp; // Stack Pointer
uint64_t pc; // Program Counter
uint64_t pstate; // Processor State
} regs;
struct iovec io;
io.iov_base = &regs;
io.iov_len = sizeof(regs);
if (ptrace(PTRACE_GETREGSET, child_pid, (void*)NT_PRSTATUS, &io) == -1) {
perror("ptrace(PTRACE_GETREGSET)");
return 0;
}
return regs.pc; // Return the program counter
} }
void Debugger::breakpoint_list() { void Debugger::breakpoint_list() {
std::cout << "Breakpoints:\n"; std::cout << "Breakpoints:\n";
for (const auto& bp : breakpoints) { for (const auto &bp : breakpoints) {
std::cout << bp << std::endl; std::cout << bp << std::endl;
} }
} }
void Debugger::set_breakpoint(pid_t pid, std::intptr_t addr) { void Debugger::set_breakpoint(pid_t pid, std::intptr_t addr) {
Breakpoint bp(pid, addr); Breakpoint bp(pid, addr);
bp.enable(); bp.enable();
breakpoints.push_back(bp); breakpoints.push_back(bp);
std::cout << "[+] Breakpoint set at address: " << std::hex << addr << std::dec << "\n"; std::cout << "[+] Breakpoint set at address: " << std::hex << addr << std::dec
<< "\n";
} }
void Debugger::remove_breakpoint(pid_t pid, std::intptr_t addr) { void Debugger::remove_breakpoint(pid_t pid, std::intptr_t addr) {
auto it = std::remove_if(breakpoints.begin(), breakpoints.end(), auto it = std::remove_if(breakpoints.begin(), breakpoints.end(),
[pid, addr](const Breakpoint& bp) { [pid, addr](const Breakpoint &bp) {
return bp.get_address() == addr && bp.is_enabled(); return bp.get_address() == addr && bp.is_enabled();
}); });
if (it != breakpoints.end()) { if (it != breakpoints.end()) {
it->disable(); it->disable();
breakpoints.erase(it, breakpoints.end()); breakpoints.erase(it, breakpoints.end());
std::cout << "[+] Breakpoint removed at address: " << std::hex << addr << std::dec << "\n"; std::cout << "[+] Breakpoint removed at address: " << std::hex << addr
} else { << std::dec << "\n";
std::cout << "[-] No breakpoint found at address: " << std::hex << addr << std::dec << "\n"; } else {
} std::cout << "[-] No breakpoint found at address: " << std::hex << addr
<< std::dec << "\n";
}
} }
void Debugger::DEBUGING() {
std::cout << "[+] Entering debugging loop. Type 'exit' to quit.\n"; // Attention: ce code est spécifique à l'architecture AArch64
std::string command; void Debugger::print_registers(pid_t pid) {
while (true) { struct user_pt_regs {
std::cout << "debugger> "; uint64_t regs[31]; // x0-x30
std::getline(std::cin, command); uint64_t sp; // Stack Pointer
if (command == "exit") { uint64_t pc; // Program Counter
break; uint64_t pstate; // Processor State
} else if (command == "list") { } regs;
breakpoint_list();
} else if (command.substr(0, 3) == "set") { struct iovec io;
std::intptr_t addr = std::stol(command.substr(4), nullptr, 16); io.iov_base = &regs;
set_breakpoint(child_pid, addr); io.iov_len = sizeof(regs);
} else if (command.substr(0, 6) == "remove") {
std::intptr_t addr = std::stol(command.substr(7), nullptr, 16); if (ptrace(PTRACE_GETREGSET, pid, (void*)NT_PRSTATUS, &io) == -1) {
remove_breakpoint(child_pid, addr); perror("ptrace(PTRACE_GETREGSET)");
} else { return;
std::cout << "Unknown command: " << command << "\n";
}
} }
std::ios old_fmt(nullptr);
old_fmt.copyfmt(std::cout);
std::cout << std::hex << std::setfill('0');
std::cout << "==== Register Dump (AArch64) ====" << std::endl;
for (int i = 0; i < 31; i++) {
std::cout << "x" << std::dec << std::setw(2) << std::right << i
<< " = 0x" << std::hex << std::setw(16) << regs.regs[i] << "\n";
}
std::cout << " sp = 0x" << std::setw(16) << regs.sp << std::endl;
std::cout << " pc = 0x" << std::setw(16) << regs.pc << std::endl;
std::cout << " pstate = 0x" << std::setw(16) << regs.pstate << std::endl;
std::cout.copyfmt(old_fmt);
} }
+7
View File
@@ -6,6 +6,7 @@
#include <algorithm> #include <algorithm>
#include "Breakpoint.hpp" #include "Breakpoint.hpp"
class Debugger { class Debugger {
public: public:
Debugger(const std::string& prog_name); Debugger(const std::string& prog_name);
@@ -14,7 +15,13 @@ public:
void set_breakpoint(pid_t pid, std::intptr_t addr); void set_breakpoint(pid_t pid, std::intptr_t addr);
void remove_breakpoint(pid_t pid, std::intptr_t addr); void remove_breakpoint(pid_t pid, std::intptr_t addr);
void run(); void run();
void print_registers(pid_t pid);
void DEBUGING(void); void DEBUGING(void);
void go_until_x0_filled(void);
void single_step(void);
uint64_t get_x0(void);
uint64_t get_pc(void);
uint32_t get_opcode(void);
private: private:
void run_target(); void run_target();