在main()之外访问流程的参数

时间:2018-11-06 16:02:02

标签: c arguments

是否可以在main函数内部之外的其他地方访问进程的参数?

我无法在main函数中添加代码。测试软件会为我创建一个测试驱动程序,并且我只能在测试驱动程序的特定部分(不是主要功能)内添加代码。我想在这段代码中更改流程参数(确切地说,我想在派生后更改流程名称……)

3 个答案:

答案 0 :(得分:4)

除了将argv的值保存在输入main()之外,没有其他可移植的方法来访问#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; } 的值,这在问题的条件下是不可能的。

但是,基于初始堆栈的预期布局,大多数操作系统都存在不可移植的解决方案。例如,以下内容应在Linux上运行(但不能保证,无论是明确的还是隐含的):

environ

该代码来自对here创建的堆栈进行反向工程。假定setenv仍具有启动时分配的值,如果应用程序在调用此函数之前已调用putenvargc argv[0] ... argv[argc - 1] 0 environ[0] ... 0 ,则情况并非如此。 (但是,它们很少见。)作为参考,栈的相关部分看起来像这样(所有条目都是指针的大小):

argv

循环从终止argc数组的NULL开始,向后看直到遇到整数,该整数将是constructor的正确值。一个看起来像整数的地址可能会欺骗它,但是在Linux中这是极不可能的,因为用于argv字符串的地址永远不会太小而不会与一个小整数混淆。


上面的代码是作为一个函数编写的,但是可能是在问题的上下文中。显然,可以将其复制到其他函数中,所以这不是问题。

但是,如果您能够在可执行文件中插入函数和全局变量,则可以使用GCC / Clang main()函数属性来利用构造函数的常规(但不是通用)实现。任何此类函数均在调用main()之前执行,并传递与传递char** saved_argv; int saved_argc; void saveargv(int argc, char** argv) __attribute__((constructor)) { saved_argc = argc; saved_argv = argv; } 相同的参数。至少在Linux和OS X上,以及在其他类似Unix的系统上,这应该至少可以工作:

sensu_gem

答案 1 :(得分:0)

您可以回溯堆栈并转到main(如果可以找到它),在那里您得到arg值,然后更改它们

答案 2 :(得分:0)

仅适用于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);
}