我試圖將一個程序從Windows移植到Linux。
當我發現Linux上沒有「真正的」ReadProcessMemory
副本時遇到問題;我搜索了一個替代方案,並發現ptrace
,一個功能強大的流程調試器。
我在C++中快速編寫了兩個小控制檯應用程序,以便在程序中使用它之前測試ptrace
。Linux:有沒有一種方法可以在不停止/暫停進程的情況下使用ptrace(SIGSTOP)?
TestApp
這是tracee;它每隔50毫秒不斷打印兩個整數,同時每次增加1個值。
#include <QCoreApplication>
#include <QThread>
#include <iostream>
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);
int value = 145;
int i = 0;
do {
cout << "i: " << i << " " << "Value: " << value << endl;
value++;
i++;
Sleeper::msleep(50);
} while (true);
return a.exec();
}
MemoryTest
這是示蹤劑;它會詢問進程名稱並使用命令pidof -s
檢索PID,然後ptrace
將附加到進程並每隔500毫秒檢索一次內存地址的值10次。
#include <QCoreApplication>
#include <QThread>
#include <iostream>
#include <string>
#include <sys/ptrace.h>
#include <errno.h>
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;
long status = ptrace(PTRACE_ATTACH, pid, NULL, NULL);
cout << "Status: " << status << endl;
cout << "Error: " << errno << endl;
unsigned long addr = 0x; // Example address, not the true one
int i = 0;
do {
status = ptrace(PTRACE_PEEKDATA, pid, addr, NULL);
cout << "Status: " << status << endl;
cout << "Error: " << errno << endl;
i++;
Sleeper::msleep(500);
} while (i < 10);
status = ptrace(PTRACE_DETACH, pid, NULL, NULL);
cout << "Status: " << status << endl;
cout << "Error: " << errno << endl;
return a.exec();
}
一切工作正常,但TestApp暫停(SIGSTOP),直到ptrace
從中分離。
此外,當它附加到進程時,狀態爲0,錯誤爲2;它第一次嘗試檢索內存地址值時失敗,狀態-1和錯誤3.是否正常?
有沒有辦法阻止ptrace向進程發送SIGSTOP信號? 我已經嘗試過使用PTRACE_SEIZE
代替PTRACE_ATTACH
,但它不工作:狀態-1和錯誤3.
更新:前MemoryTest使用Sleeper
「辦,而」循環修復了第一個問題內存地址值檢索,即使秒,毫秒或微秒的值爲0.爲什麼?
非常感謝您的回答。我沒有看看/ proc,因爲我想用一個更簡單的方法;如果這是不可能的,我會嘗試使用內存映射文件。我使用Debian 8 x64,這不應該是問題;我的猜測是'PTRACE_SEIZE'需要以與'PTRACE_ATTACH'不同的方式使用,但是我找不到任何特定的文檔。 –
對不起這兩條評論,我按了Enter以爲它打破了界限;我編輯了評論,但5分鐘後無法更新。 'addr'值只是一個例子,正確的工作正常。關於錯誤代碼,它們不應該是個問題,因爲程序工作正常。 –
我現在看到你在代碼中的評論,說這個地址就是一個例子,抱歉應該更好地閱讀它。如果它有用,請'接受'我的回答,因爲我試圖在Stack Overflow上建立我的聲望。 你是正確的,ptrace調用比操作/ proc文件更簡單。然而,/ proc區有很多信息。如果您正在學習有關Linux調試和流程結構的知識,這將是一個富有成效的研究領域。 PTRACE_CONT在程序中工作? –