va falloir parser l'opcode....
sinon ajout de plusieur methode
This commit is contained in:
+125
-31
@@ -1,11 +1,14 @@
|
||||
#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) {
|
||||
Debugger::Debugger(const std::string &prog_name) : program_name(prog_name) {
|
||||
std::cout << "[+] Debugger initialized for program: " << program_name << "\n";
|
||||
}
|
||||
|
||||
@@ -22,7 +25,7 @@ void Debugger::run() {
|
||||
|
||||
void Debugger::run_target() {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -30,18 +33,89 @@ void Debugger::run_debugger() {
|
||||
int status;
|
||||
waitpid(child_pid, &status, 0);
|
||||
std::cout << "[+] Debugger attached to PID: " << child_pid << "\n";
|
||||
|
||||
DEBUGING();
|
||||
|
||||
ptrace(PTRACE_CONT, child_pid, nullptr, nullptr);
|
||||
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";
|
||||
}
|
||||
|
||||
void Debugger::single_step(void){
|
||||
int status;
|
||||
|
||||
std::cout << "[+] Single stepping...\n";
|
||||
ptrace(PTRACE_SINGLESTEP, child_pid, nullptr, nullptr);
|
||||
waitpid(child_pid, &status, 0);
|
||||
}
|
||||
|
||||
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 = ®s;
|
||||
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 = ®s;
|
||||
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 = ®s;
|
||||
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) {
|
||||
for (const auto &bp : breakpoints) {
|
||||
std::cout << bp << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -50,41 +124,61 @@ 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";
|
||||
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) {
|
||||
[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";
|
||||
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";
|
||||
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 = ®s;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user