簡體   English   中英

在 main() 之外訪問進程的參數

[英]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仍然具有在啟動時分配的值,如果應用程序在調用此函數之前調用了setenvputenv ,則情況可能並非如此。 (雖然這些非常罕見。)作為參考,堆棧的相關部分如下所示(所有條目都是指針的大小):

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM