summaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
authorAmlal <amlal.elmahrouss@icloud.com>2025-01-27 02:11:12 +0100
committerAmlal <amlal.elmahrouss@icloud.com>2025-01-27 02:11:12 +0100
commit2fd3475239d4258ca4407ffb2c0720d90d711d6c (patch)
treef56bbe4a03196ff41d197a617c263dbb13658ef4 /tools
parent2b2ac6e8c5dd2b3234b74d38833066dcd483267b (diff)
ADD: `dbg` C++ debugger program.
META: Ran format command with correct C++ extensions. Signed-off-by: Amlal <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/dbg.cc154
-rwxr-xr-xtools/dbg.sh2
-rw-r--r--tools/necc.cc3
3 files changed, 158 insertions, 1 deletions
diff --git a/tools/dbg.cc b/tools/dbg.cc
new file mode 100644
index 0000000..40769a6
--- /dev/null
+++ b/tools/dbg.cc
@@ -0,0 +1,154 @@
+/***
+ (C) 2025 Amlal El Mahrouss
+ */
+
+#include <iostream>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/user.h>
+#include <unistd.h>
+#include <unordered_map>
+#include <stdint.h>
+
+namespace Dbg
+{
+ /// \brief Debug Interface class in C++
+ /// \author Amlal El Mahrouss
+ class Interface final
+ {
+ public:
+ Interface() = default;
+ ~Interface() = default;
+
+ Interface& operator=(const Interface&) = default;
+ Interface(const Interface&) = default;
+
+ void Attach(pid_t pid)
+ {
+ this->pid = pid;
+
+ if (ptrace(PTRACE_ATTACH, this->pid, nullptr, nullptr) == -1)
+ {
+ perror("DBG: Attach");
+ exit(1);
+ }
+
+ waitpid(pid, nullptr, 0);
+ std::cout << "[+] Attached to process: " << pid << std::endl;
+ }
+
+ void SetBreakpoint(void* addr)
+ {
+ long original_data = ptrace(PTRACE_PEEKTEXT, pid, addr, nullptr);
+ if (original_data == -1)
+ {
+ perror("DBG: Peek");
+ exit(1);
+ }
+
+ long data_with_int3 = (original_data & ~0xFF) | 0xCC; // Insert INT3 (0xCC)
+ if (ptrace(PTRACE_POKETEXT, pid, addr, data_with_int3) == -1)
+ {
+ perror("DBG: Poke");
+ exit(1);
+ }
+
+ std::cout << "[+] Breakpoint set at: " << addr << std::endl;
+ breakpoints[reinterpret_cast<uintptr_t>(addr)] = original_data; // Store original data
+ }
+
+ void ContinueExecution()
+ {
+ if (ptrace(PTRACE_CONT, pid, nullptr, nullptr) == -1)
+ {
+ perror("DBG: Cont");
+ exit(1);
+ }
+
+ int status;
+ waitpid(pid, &status, 0);
+
+ if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP)
+ {
+ std::cout << "[!] Breakpoint hit!" << std::endl;
+ }
+ }
+
+ void Detach()
+ {
+ if (ptrace(PTRACE_DETACH, pid, nullptr, nullptr) == -1)
+ {
+ perror("DBG: Detach");
+ exit(1);
+ }
+
+ std::cout << "[-] Detached from process: " << pid << std::endl;
+ }
+
+ std::unordered_map<uintptr_t, long>& Breakpoints()
+ {
+ return breakpoints;
+ }
+
+ private:
+ pid_t pid;
+ std::unordered_map<uintptr_t, long> breakpoints;
+ };
+} // namespace Dbg
+
+int main(int argc, char* argv[])
+{
+ if (!argv[1])
+ {
+ std::cout << "[?] Attach to process using it's PID.\n";
+ return EXIT_FAILURE;
+ }
+
+ pid_t pid = std::stoi(argv[1]);
+
+ Dbg::Interface debugger;
+ debugger.Attach(pid);
+
+ while (true)
+ {
+ std::string cmd;
+ std::getline(std::cin, cmd);
+
+ if (cmd == "c" ||
+ cmd == "cont")
+ debugger.ContinueExecution();
+
+ if (cmd == "d" ||
+ cmd == "detach")
+ debugger.Detach();
+
+ if (cmd == "attach")
+ {
+ std::cout << "[?] Enter a PID to attach on: ";
+
+ std::getline(std::cin, cmd);
+ pid = std::stoi(argv[1]);
+ debugger.Attach(pid);
+ }
+
+ if (cmd == "exit")
+ {
+ std::exit(0);
+ }
+
+ if (cmd == "b" ||
+ cmd == "break")
+ {
+ std::cout << "[?] Enter an address to break on: ";
+
+ std::getline(std::cin, cmd);
+ void* breakpoint_addr = reinterpret_cast<void*>(std::stoul(cmd.c_str(), nullptr, 16));
+
+ if (breakpoint_addr)
+ debugger.SetBreakpoint(breakpoint_addr);
+ }
+ }
+
+ return 0;
+}
diff --git a/tools/dbg.sh b/tools/dbg.sh
new file mode 100755
index 0000000..8624b93
--- /dev/null
+++ b/tools/dbg.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+g++ dbg.cc -o dbg
diff --git a/tools/necc.cc b/tools/necc.cc
index 9e59f48..56dd5cc 100644
--- a/tools/necc.cc
+++ b/tools/necc.cc
@@ -59,7 +59,8 @@ int main(int argc, char const* argv[])
arg += ".pp";
args_list_cxx.push_back(arg);
- } else if (strstr(argv[index_arg], ".c"))
+ }
+ else if (strstr(argv[index_arg], ".c"))
{
std::printf("necc: error: C is not ready yet.\n");
return EXIT_FAILURE;