Linux: is there a way to use ptrace without stopping/pausing the process (SIGSTOP)?

后端 未结 2 1378
有刺的猬
有刺的猬 2021-01-21 09:01

I\'m trying to port a program from Windows to Linux.
I encountered a problem when I found out that there isn\'t a \"real\" ReadProcessMemory counterpart on Linu

2条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-01-21 09:25

    After a lot of research I'm pretty sure that there isn't a way to use ptrace without stopping the process.
    I found a real ReadProcessMemory counterpart, called process_vm_readv, which is much more simple.

    I'm posting the code in the hope of helping someone who is in my (previous) situation.

    Many thanks to mkrautz for his help coding MemoryTest with this beautiful function.

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    using namespace std;
    
    class Sleeper : public QThread
    {
    public:
        static void usleep(unsigned long usecs){QThread::usleep(usecs);}
        static void msleep(unsigned long msecs){QThread::msleep(msecs);}
        static void sleep(unsigned long secs){QThread::sleep(secs);}
    };
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        char process_name[50];
        cout << "Process name: ";
        cin >> process_name;
    
        char command[sizeof(process_name) + sizeof("pidof -s ")];
        snprintf(command, sizeof(command), "pidof -s %s", process_name);
    
        FILE* shell = popen(command, "r");
        char pidI[sizeof(shell)];
        fgets(pidI, sizeof(pidI), shell);
        pclose(shell);
    
        pid_t pid = atoi(pidI);
    
        cout << "The PID is " << pid << endl;
    
        if (pid == 0)
            return false;
    
        struct iovec in;
        in.iov_base = (void *) 0x012345; // Example address, not the true one
        in.iov_len = 4;
    
        uint32_t foo;
    
        struct iovec out;
        out.iov_base = &foo;
        out.iov_len = sizeof(foo);
    
        do {
            ssize_t nread = process_vm_readv(pid, &out, 1, &in, 1, 0);
            if (nread == -1) {
                fprintf(stderr, "error: %s", strerror(errno));
            } else if (nread != in.iov_len) {
                fprintf(stderr, "error: short read of %li bytes", (ssize_t)nread);
            }
            cout << foo << endl;
            Sleeper::msleep(500);
        } while (true);
    
        return a.exec();
    }
    

提交回复
热议问题