diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-04-24 10:44:30 +0200 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal@nekernel.org> | 2025-04-24 10:44:30 +0200 |
| commit | 7a23ee18ecae27c1e0201dbbb8ab781c48e859ba (patch) | |
| tree | a44bce0362e68f20a99e70115809e214b3e8d3d4 /dev/LibDebugger | |
| parent | eba5377ba1578695f2978ffa6443e4d2b27dc614 (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.h | 5 | ||||
| -rw-r--r-- | dev/LibDebugger/POSIXMachContract.h | 111 | ||||
| -rw-r--r-- | dev/LibDebugger/src/POSIXMachContract.cc | 56 |
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; |
