0

Ive PTRACE_ATTACH and PCONT to a process. Ive also verified the process is still attached, and thats running, yet I cant PTRACE_DETACH (errno : No such process). Im puzzled after doing all the validations. It all happens in void DETACH().

My understanding is that PTRACE_CONT doesnt detach from the process so I should still be able to detach properly. If its not detaching then it means its not attaching properly. but from my validations its attached. I PTRACE_CONT bc I want my tracee program to continue moving(otherwise the image freezes) and remain attached.

Edit: It seems like the problem is that Im trying to detach in another function, PTRACE_DETACH works but if I add this after PTRACE_CONT.

        kill(targetPid, SIGSTOP);
        waitpid(targetPid, nullptr, 0);

        if (ptrace(PTRACE_DETACH, targetPid, nullptr, nullptr) == -1) {
            wxLogError("Failed to detach from process: %s", strerror(errno));
        } else {
            wxLogMessage("Successfully detached from process %d", targetPid);
            isAttached = false;
            wxThreadEvent *event = new wxThreadEvent(wxEVT_THREAD, EVT_DETACH_SUCCESS);
            event->SetString("Successfully detached from process " + std::to_string(targetPid));
            wxQueueEvent(m_parent, event);
        }
#include <wx/wx.h>
#include <wx/thread.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <string>
#include <dirent.h>
#include <libgen.h>
#include <fcntl.h>
#include <signal.h> // Add this include at the top of your file
#include <fstream>

// Define new event types
wxDEFINE_EVENT(EVT_ATTACH_SUCCESS, wxThreadEvent);
wxDEFINE_EVENT(EVT_DETACH_SUCCESS, wxThreadEvent);

class WorkerThread : public wxThread {
public:
    WorkerThread(wxEvtHandler *parent) : wxThread(wxTHREAD_JOINABLE), m_parent(parent), targetPid(-1), isAttached(false) {}

    ~WorkerThread() override {
        if (IsRunning()) {
            Detach();
        }
    }

    wxThread::ExitCode Entry() override {
        std::string processName = "dura";
        int pipefd[2];
        if (pipe(pipefd) == -1) {
            wxLogError("pipe failed: %s", strerror(errno));
            return (wxThread::ExitCode)0;
        }

        pid_t childPid = fork();
        if (childPid == -1) {
            wxLogError("fork failed: %s", strerror(errno));
            return (wxThread::ExitCode)0;
        }

        if (childPid == 0) {  // Child process
            close(pipefd[0]);  // Close read end
            dup2(pipefd[1], STDOUT_FILENO);  // Redirect stdout to pipe
            execlp("pgrep", "pgrep", processName.c_str(), nullptr);
            wxLogError("execlp failed: %s", strerror(errno));
            exit(EXIT_FAILURE);
        } else {  // Parent process
            close(pipefd[1]);  // Close write end

            int status;
            waitpid(childPid, &status, 0);

            if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {  // Process found
                char buf[32];
                read(pipefd[0], buf, sizeof(buf) - 1);
                targetPid = strtoul(buf, nullptr, 10);

                if (ptrace(PTRACE_ATTACH, targetPid, nullptr, nullptr) == -1) {
                    wxLogError("Failed to attach to process: %s", strerror(errno));
                    return (wxThread::ExitCode)0;
                } else {
                    this->targetPid = targetPid;
                    isAttached = true;;
                    wxLogMessage("Successfully attached to process %ld", targetPid);
                    wxThreadEvent* event = new wxThreadEvent(wxEVT_THREAD, EVT_ATTACH_SUCCESS);
                    event->SetString("Successfully attached to process " + std::to_string(targetPid));
                    wxQueueEvent(m_parent, event);
                }

                // Check if the process is still alive after attaching
                if (isAttached && targetPid != -1 && kill(targetPid, 0) == 0) {
                    wxLogMessage("Process is still alive after attaching.");
                } else {
                    wxLogError("Failed to attach properly or process does not exist.");
                    return (wxThread::ExitCode)0;
                }

                //Wait for the process to stop
                waitpid(targetPid, nullptr, 0);

                // Continue the process
                if (ptrace(PTRACE_CONT, targetPid, nullptr, nullptr) == -1) {
                    wxLogError("Failed to continue the process: %s", strerror(errno));
                }

                // Wait for the process to stop again after continuing
                waitpid(targetPid, nullptr, 0);

                while(!TestDestroy()) {
                    wxThread::This()->Sleep(1000);  // 1 second sleep
                }
            } else if (WIFEXITED(status)) {  // Process not found or error executing pgrep
                wxLogError("Process %s not found or error executing pgrep.", processName.c_str());
            }
        }

        while(!TestDestroy()) {
            wxThread::This()->Sleep(1000);  // 1 second sleep
        }

        return (wxThread::ExitCode)0;
    }

    void Detach() {
            if (isAttached && targetPid != -1) {
                int result = kill(targetPid, 0);
                if (result == 0) {
                    // Process is still alive, check if it is attached
                    if (ptrace(PTRACE_ATTACH, targetPid, nullptr, nullptr) == -1 && errno == ESRCH) {
                        // Process is not attached, no need to detach
                        wxLogMessage("Process %ld is not attached", targetPid);
                        isAttached = false;
                    } else {
                        // Process is attached, proceed with detachment
                        if (ptrace(PTRACE_DETACH, targetPid, nullptr, nullptr) == -1) {
                            wxLogError("Failed to detach from process: %s", strerror(errno));
                        } else {
                            wxLogMessage("Successfully detached from process %ld", targetPid);
                            isAttached = false;
                        }
                    }
                } else if (result == -1) {
                    // Process is not alive
                    wxLogError("Process %ld is not alive", targetPid);
                }
            } else {
                wxLogError("Failed to detach from process: No such process");
            }
    }

private:
    wxEvtHandler *m_parent;
    pid_t targetPid;
    bool isAttached;
};

class MyFrame : public wxFrame {
public:
    MyFrame() : wxFrame(NULL, wxID_ANY, "Hello wxWidgets") {
        m_panel = new wxPanel(this);
        m_attachBtn = new wxButton(m_panel, wxID_ANY, "Attach");
        m_detachBtn = new wxButton(m_panel, wxID_ANY, "Detach");
        m_textCtrl = new wxTextCtrl(m_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
                                    wxTE_MULTILINE | wxTE_READONLY);

        wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
        sizer->Add(m_attachBtn, 0, wxEXPAND | wxALL, 5);
        sizer->Add(m_detachBtn, 0, wxEXPAND | wxALL, 5);
        sizer->Add(m_textCtrl, 1, wxEXPAND | wxALL, 5);
        m_panel->SetSizer(sizer);

        Bind(wxEVT_COMMAND_BUTTON_CLICKED, &MyFrame::OnAttach, this, m_attachBtn->GetId());
        Bind(wxEVT_COMMAND_BUTTON_CLICKED, &MyFrame::OnDetach, this, m_detachBtn->GetId());
        Bind(EVT_ATTACH_SUCCESS, &MyFrame::OnAttachSuccess, this);
        Bind(EVT_DETACH_SUCCESS, &MyFrame::OnDetachSuccess, this);

        m_workerThread = nullptr;
    }

    void OnAttach(wxCommandEvent &event) {
        m_workerThread = new WorkerThread(this);
        if (m_workerThread->Run() != wxTHREAD_NO_ERROR) {
            wxLogError("Could not create the worker thread!");
            delete m_workerThread;
            m_workerThread = nullptr;
        }
        m_textCtrl->AppendText("Attaching to process...\n");
    }

    void OnDetach(wxCommandEvent &event) {
        if (m_workerThread) {
            m_workerThread->Detach();  // Detach from process
            m_workerThread->Delete();  // Signals the thread to exit its main loop
            m_workerThread->Wait();    // Waits for the thread to exit
            delete m_workerThread;
            m_workerThread = nullptr;
        }
    }

    void OnAttachSuccess(wxThreadEvent &event) {
        m_textCtrl->AppendText(event.GetString() + "\n");
    }

    void OnDetachSuccess(wxThreadEvent &event) {
        m_textCtrl->AppendText("Successfully detached from process.\n");
    }

private:
    wxPanel *m_panel;
    wxButton *m_attachBtn;
    wxButton *m_detachBtn;
    wxTextCtrl *m_textCtrl;
    WorkerThread *m_workerThread;
};

class MyApp : public wxApp {
public:
    bool OnInit() override {
        MyFrame *frame = new MyFrame();
        frame->Show();
        return true;
    }
};

wxIMPLEMENT_APP(MyApp);
Olivia22
  • 131
  • 7

0 Answers0