[英]access to process' arguments outside main()
是否可以在main
函數內部以外的其他地方訪問進程的參數?
我處於無法在main
函數中添加代碼的情況。 測試軟件為我創建了一個測試驅動程序,我只能在測試驅動程序的特定部分(不是主要功能)中添加代碼。 我想在這段代碼中更改進程參數(准確地說,我想在 fork 之后更改進程名稱......)
除了在進入main()
時將其保存之外,沒有其他可移植的方法來訪問argv
的值,這在問題的條件下是不可能的。
但是,基於初始堆棧的預期布局,大多數操作系統都存在不可移植的解決方案。 例如,以下應該在 Linux 上工作(但不保證,既不明確也不暗示):
#include <stdint.h>
/* This code is unsafe and unportable. But it might work for you. */
char** getargv(void) {
extern char** environ;
char **argv = environ - 1;
for (char** e = argv; (uintptr_t)(argv[-1]) != e - argv; --argv) { }
return argv;
}
該代碼來自對此處創建的堆棧進行逆向工程。 它假定environ
仍然具有在啟動時分配的值,如果應用程序在調用此函數之前調用了setenv
或putenv
,則情況可能並非如此。 (雖然這些非常罕見。)作為參考,堆棧的相關部分如下所示(所有條目都是指針的大小):
argc
argv[0]
...
argv[argc - 1]
0
environ[0]
...
0
循環從終止argv
數組的 NULL 開始,然后向后查看,直到遇到一個整數,這將是argc
的正確值。 它可能會被一個看起來像整數的地址所迷惑,但在 Linux 中這是極不可能的,因為用於 argv 字符串的地址永遠不會小到與小整數混淆。
上面的代碼是作為函數編寫的,但在可能不可能的問題的上下文中。 顯然,它可以被復制到其他一些函數中,所以這不是問題。
但是,如果您能夠在可執行文件中插入一個函數和一個全局變量,則可以利用 GCC/Clang constructor
函數屬性來利用構造函數的通常(但不是通用的)實現。 任何此類函數都在調用main()
之前執行,並傳遞與傳遞main()
相同的參數。 這應該至少適用於 Linux 和 OS X,也很可能適用於其他類 Unix 系統:
char** saved_argv;
int saved_argc;
void saveargv(int argc, char** argv) __attribute__((constructor)) {
saved_argc = argc;
saved_argv = argv;
}
您可以回溯堆棧並轉到 main(如果您能找到它),在那里您獲得 arg 值然后更改它們
其他僅適用於 linux 的解決方案,請使用 /proc/NNN/cmdline。 例子 :
int pid;
char procPathName[256];
int fcl;
pid = getpid();
snprintf(procPathName, 255, "/proc/%ld/cmdline", pid);
fcl = open(procPathName, 0);
if (fcl == -1)
{
/* error */
}
else
{
char buffer[1024];
int bufferLen;
bufferLen = read(fcl, buffer, 1023);
close(fcl);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.