summaryrefslogtreecommitdiffhomepage
path: root/dev/LibDebugger
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-04-24 10:44:30 +0200
committerAmlal El Mahrouss <amlal@nekernel.org>2025-04-24 10:44:30 +0200
commit7a23ee18ecae27c1e0201dbbb8ab781c48e859ba (patch)
treea44bce0362e68f20a99e70115809e214b3e8d3d4 /dev/LibDebugger
parenteba5377ba1578695f2978ffa6443e4d2b27dc614 (diff)
dev, dbg: Improve POSIXMachContract, but it still has some rough edges
on breakpoints. Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/LibDebugger')
-rw-r--r--dev/LibDebugger/DebuggerContract.h5
-rw-r--r--dev/LibDebugger/POSIXMachContract.h111
-rw-r--r--dev/LibDebugger/src/POSIXMachContract.cc56
3 files changed, 84 insertions, 88 deletions
diff --git a/dev/LibDebugger/DebuggerContract.h b/dev/LibDebugger/DebuggerContract.h
index 540ad08..d5f62c2 100644
--- a/dev/LibDebugger/DebuggerContract.h
+++ b/dev/LibDebugger/DebuggerContract.h
@@ -25,8 +25,9 @@ namespace LibDebugger
DebuggerContract(const DebuggerContract&) = default;
public:
- virtual bool Attach(ProcessID pid) noexcept = 0;
- virtual bool Break(CAddress addr) noexcept = 0;
+ virtual bool Attach(std::string path, std::string argv, ProcessID& pid) noexcept = 0;
+ virtual bool Breakpoint(std::string symbol) noexcept = 0;
+ virtual bool Break() noexcept = 0;
virtual bool Continue() noexcept = 0;
virtual bool Detach() noexcept = 0;
diff --git a/dev/LibDebugger/POSIXMachContract.h b/dev/LibDebugger/POSIXMachContract.h
index 1962202..a65bde8 100644
--- a/dev/LibDebugger/POSIXMachContract.h
+++ b/dev/LibDebugger/POSIXMachContract.h
@@ -21,16 +21,25 @@
#include <unistd.h>
#include <stdint.h>
-#ifdef __APPLE__
+#include <filesystem>
+
#include <mach/mach.h>
#include <mach/mach_error.h>
+#include <mach-o/dyld.h>
+#include <dlfcn.h>
+
+LC_IMPORT_C kern_return_t mach_vm_write(
+ vm_map_t target_task,
+ mach_vm_address_t address,
+ vm_offset_t data,
+ mach_msg_type_number_t dataCnt);
+
#define PTRACE_ATTACH PT_ATTACHEXC
#define PTRACE_DETACH PT_DETACH
#define PTRACE_POKETEXT PT_WRITE_I
#define PTRACE_CONT PT_CONTINUE
#define PTRACE_PEEKTEXT PT_READ_I
-#endif
namespace LibDebugger::POSIX
{
@@ -47,85 +56,85 @@ namespace LibDebugger::POSIX
POSIXMachContract(const POSIXMachContract&) = default;
public:
- BOOL Attach(ProcessID pid) noexcept override
+ BOOL Attach(std::string path, std::string argv, ProcessID& pid) noexcept override
{
-#ifdef __APPLE__
+ pid = fork();
+
if (pid == 0)
- return false;
+ {
+ std::vector<char*> argv_arr;
- this->m_pid = pid;
- return true;
-#else
+ argv_arr.push_back(const_cast<char*>(path.c_str()));
+ argv_arr.push_back(const_cast<char*>(argv.c_str()));
+ argv_arr.push_back(nullptr);
- if (ptrace(PTRACE_ATTACH, pid, nullptr, 0) == -1)
- {
- return false;
+ execv(path.c_str(), argv_arr.data());
+
+ _exit(1);
}
- this->m_pid = pid;
+ m_path = path;
+ m_pid = pid;
+
+ pid = this->m_pid;
- waitpid(m_pid, nullptr, 0);
+ this->Break();
return true;
-#endif
}
- BOOL Break(CAddress addr) noexcept override
+ BOOL Breakpoint(std::string symbol) noexcept override
{
-#ifdef __APPLE__
- task_read_t task;
- task_for_pid(mach_task_self(), m_pid, &task);
- kern_return_t ret = task_suspend(task);
-
- return ret == KERN_SUCCESS;
-#else
- uintptr_t original_data = ptrace(PTRACE_PEEKTEXT, m_pid, addr, 0);
- if (original_data == -1)
+ if (!m_path.empty() && std::filesystem::exists(m_path) && !std::filesystem::is_regular_file(m_path))
{
- return false;
- }
+ auto handle = dlopen(m_path.c_str(), RTLD_LAZY);
- constexpr uint8_t kInt3x86 = 0xCC;
+ if (handle == nullptr)
+ {
+ return false;
+ }
- uintptr_t data_with_int3 = (original_data & ~0xFF) | kInt3x86; // Insert INT3 (0xCC)
+ auto addr = dlsym(handle, symbol.c_str());
- if (ptrace(PTRACE_POKETEXT, m_pid, addr, data_with_int3) == -1)
- {
- return false;
- }
+ if (addr == nullptr)
+ {
+ return false;
+ }
- m_breakpoints[reinterpret_cast<uintptr_t>(addr)] = original_data; // Store original data
+ task_read_t task;
+ task_for_pid(mach_task_self(), m_pid, &task);
- return true;
-#endif
+ uint32_t brk_inst = 0xD43E0000;
+
+ mach_vm_write(task, (mach_vm_address_t)addr, (vm_offset_t)&brk_inst, sizeof(addr));
+ }
+
+ return false;
}
- BOOL Continue() noexcept override
+ BOOL Break() noexcept override
{
-#ifdef __APPLE__
task_read_t task;
task_for_pid(mach_task_self(), m_pid, &task);
- kern_return_t ret = task_resume(task);
+
+ kern_return_t ret = task_suspend(task);
return ret == KERN_SUCCESS;
-#else
- if (ptrace(PTRACE_CONT, m_pid, nullptr, 0) == -1)
- {
+ }
- return false;
- }
+ BOOL Continue() noexcept override
+ {
+ task_read_t task;
+ task_for_pid(mach_task_self(), m_pid, &task);
- int status;
- waitpid(m_pid, &status, 0);
+ kern_return_t ret = task_resume(task);
- return WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP;
-#endif
+ return ret == KERN_SUCCESS;
}
BOOL Detach() noexcept override
{
-#ifdef __APPLE__
this->Continue();
task_read_t task;
@@ -134,12 +143,10 @@ namespace LibDebugger::POSIX
kern_return_t kr = mach_port_deallocate(mach_task_self(), task);
return kr = KERN_SUCCESS;
-#else
- return ptrace(PTRACE_DETACH, m_pid, nullptr, 0) == -1;
-#endif
}
private:
- ProcessID m_pid{0};
+ ProcessID m_pid{0};
+ std::string m_path;
};
} // namespace LibDebugger::POSIX
diff --git a/dev/LibDebugger/src/POSIXMachContract.cc b/dev/LibDebugger/src/POSIXMachContract.cc
index cfce841..4dbd7bb 100644
--- a/dev/LibDebugger/src/POSIXMachContract.cc
+++ b/dev/LibDebugger/src/POSIXMachContract.cc
@@ -14,6 +14,13 @@ static BOOL kKeepRunning = false;
static LibDebugger::POSIX::POSIXMachContract kDebugger;
static LibDebugger::ProcessID kPID = 0L;
static LibDebugger::CAddress kActiveAddress = nullptr;
+static std::string kPath = "";
+
+#define kBlank "\e[0;30m"
+#define kRed "\e[0;31m"
+#define kWhite "\e[0;97m"
+
+#define kStdOut (std::cout << kRed << "dbg: " << kWhite)
/// @internal
/// @brief Handles CTRL-C signal on debugger.
@@ -26,7 +33,7 @@ static void dbgi_ctrlc_handler(std::int32_t _)
auto list = kDebugger.Get();
- kDebugger.Break(kActiveAddress);
+ kDebugger.Break();
pfd::notify("Debugger Event", "Breakpoint hit!");
@@ -40,8 +47,8 @@ LIBCOMPILER_MODULE(DebuggerMachPOSIX)
if (argc >= 3 && std::string(argv[1]) == "-p" &&
argv[2] != nullptr)
{
- kPID = std::stoi(argv[2]);
- kDebugger.Attach(kPID);
+ kPath = argv[2];
+ kDebugger.Attach(kPath, argv[3], kPID);
}
::signal(SIGINT, dbgi_ctrlc_handler);
@@ -60,29 +67,26 @@ LIBCOMPILER_MODULE(DebuggerMachPOSIX)
cmd == "cont" ||
cmd == "continue")
{
- kDebugger.Continue();
- kKeepRunning = true;
+ if (kDebugger.Continue())
+ {
+ kKeepRunning = true;
+
+ kStdOut << "[+] Continuing...\n";
- std::cout << "[+] Continuing...\n";
- pfd::notify("Debugger Event", "Continuing...");
+ pfd::notify("Debugger Event", "Continuing...");
+ }
}
if (cmd == "d" ||
cmd == "detach")
kDebugger.Detach();
- if (cmd == "attach" ||
- cmd == "pid" ||
- cmd == "a")
+ if (cmd == "start")
{
- std::cout << "[?] Enter a PID to attach on: ";
-
+ kStdOut << "[?] Enter a argument to use: ";
std::getline(std::cin, cmd);
- kPID = std::stoi(cmd.c_str());
-
- pfd::notify("Debugger Event", "Attach process: " + std::to_string(kPID));
- kDebugger.Attach(kPID);
+ kDebugger.Attach(kPath, cmd, kPID);
}
if (cmd == "exit")
@@ -93,34 +97,18 @@ LIBCOMPILER_MODULE(DebuggerMachPOSIX)
break;
}
-#ifndef __APPLE__
if (cmd == "break" ||
cmd == "b")
{
- std::cout << "[?] Enter an address/symbol to add a break on: ";
+ kStdOut << "[?] Enter a symbol to break on: ";
std::getline(std::cin, cmd);
- auto addr = std::stoul(cmd.c_str(), nullptr, 16);
-
- try
- {
- pfd::notify("Debugger Event", "Add Breakpoint at: " + std::to_string(addr));
- }
- catch (...)
+ if (kDebugger.Breakpoint(cmd))
{
pfd::notify("Debugger Event", "Add Breakpoint at: " + cmd);
}
-
- LibDebugger::CAddress breakpoint_addr = reinterpret_cast<LibDebugger::CAddress>(addr);
-
- if (breakpoint_addr)
- {
- kActiveAddress = breakpoint_addr;
- kDebugger.Break(kActiveAddress);
- }
}
-#endif // ifndef __APPLE__
}
return EXIT_SUCCESS;