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 <iomanip>
#include <iostream>
#include <linux/elf.h>
#include <signal.h>
#include <sys/ptrace.h>
#include <sys/uio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
Debugger::Debugger(const std::string& prog_name) : program_name(prog_name) {
std::cout << "[+] Debugger initialized for program: " << program_name << "\n";
Debugger::Debugger(const std::string &prog_name) : program_name(prog_name) {
std::cout << "[+] Debugger initialized for program: " << program_name << "\n";
}
void Debugger::run() {
child_pid = fork();
if (child_pid == 0) {
run_target();
} else if (child_pid > 0) {
run_debugger();
} else {
std::cerr << "[!] fork() failed.\n";
}
child_pid = fork();
if (child_pid == 0) {
run_target();
} else if (child_pid > 0) {
run_debugger();
} else {
std::cerr << "[!] fork() failed.\n";
}
}
void Debugger::run_target() {
std::cout << "[+] Child process started.\n";
ptrace(PTRACE_TRACEME, 0, nullptr, nullptr);
execl(program_name.c_str(), program_name.c_str(), nullptr);
std::cout << "[+] Child process started.\n";
ptrace(static_cast<__ptrace_request>(PTRACE_TRACEME), 0, nullptr, nullptr);
execl(program_name.c_str(), program_name.c_str(), nullptr);
}
void Debugger::run_debugger() {
int status;
waitpid(child_pid, &status, 0);
std::cout << "[+] Debugger attached to PID: " << child_pid << "\n";
int status;
waitpid(child_pid, &status, 0);
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);
waitpid(child_pid, &status, 0);
std::cout << "[+] Single stepping...\n";
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() {
std::cout << "Breakpoints:\n";
for (const auto& bp : breakpoints) {
std::cout << bp << std::endl;
}
std::cout << "Breakpoints:\n";
for (const auto &bp : breakpoints) {
std::cout << bp << std::endl;
}
}
void Debugger::set_breakpoint(pid_t pid, std::intptr_t addr) {
Breakpoint bp(pid, addr);
bp.enable();
breakpoints.push_back(bp);
std::cout << "[+] Breakpoint set at address: " << std::hex << addr << std::dec << "\n";
Breakpoint bp(pid, addr);
bp.enable();
breakpoints.push_back(bp);
std::cout << "[+] Breakpoint set at address: " << std::hex << addr << std::dec
<< "\n";
}
void Debugger::remove_breakpoint(pid_t pid, std::intptr_t addr) {
auto it = std::remove_if(breakpoints.begin(), breakpoints.end(),
[pid, addr](const Breakpoint& bp) {
return bp.get_address() == addr && bp.is_enabled();
});
if (it != breakpoints.end()) {
it->disable();
breakpoints.erase(it, breakpoints.end());
std::cout << "[+] Breakpoint removed at address: " << std::hex << addr << std::dec << "\n";
} else {
std::cout << "[-] No breakpoint found at address: " << std::hex << addr << std::dec << "\n";
}
auto it = std::remove_if(breakpoints.begin(), breakpoints.end(),
[pid, addr](const Breakpoint &bp) {
return bp.get_address() == addr && bp.is_enabled();
});
if (it != breakpoints.end()) {
it->disable();
breakpoints.erase(it, breakpoints.end());
std::cout << "[+] Breakpoint removed 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";
std::string command;
while (true) {
std::cout << "debugger> ";
std::getline(std::cin, command);
if (command == "exit") {
break;
} else if (command == "list") {
breakpoint_list();
} else if (command.substr(0, 3) == "set") {
std::intptr_t addr = std::stol(command.substr(4), nullptr, 16);
set_breakpoint(child_pid, addr);
} else if (command.substr(0, 6) == "remove") {
std::intptr_t addr = std::stol(command.substr(7), nullptr, 16);
remove_breakpoint(child_pid, addr);
} else {
std::cout << "Unknown command: " << command << "\n";
}
// Attention: ce code est spécifique à l'architecture AArch64
void Debugger::print_registers(pid_t pid) {
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, pid, (void*)NT_PRSTATUS, &io) == -1) {
perror("ptrace(PTRACE_GETREGSET)");
return;
}
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 "Breakpoint.hpp"
class Debugger {
public:
Debugger(const std::string& prog_name);
@@ -14,7 +15,13 @@ public:
void set_breakpoint(pid_t pid, std::intptr_t addr);
void remove_breakpoint(pid_t pid, std::intptr_t addr);
void run();
void print_registers(pid_t pid);
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:
void run_target();