C - 如何在运行 main 函数之前更改它的参数



在下面的代码中,我想在不修改主函数的情况下更改主函数的参数。

最近,我阅读了AFL模糊测试工具的代码,对于forkserver,我不明白如何将参数传递给目标程序,所以我编写了这个简单的程序。

我尝试使用管道重定向 stdin 并将参数写入 stdin,但它不起作用。

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
__attribute__((constructor))
void __start() {
static unsigned char tmp[4];
int count = 0;
pid_t pid;
int status;
while(count < 3){
pid = fork();
if(pid < 0) _exit(1);
if(!pid){
//how to pass "hello" to main without modfiying main function.
return;
}
count++;
if(count == 3) _exit(1);
}
//_exit(0);
}
int main(int argc, char** argv){
for(int i = 0; i < argc; i++){
printf("%d %sn", i, argv[i]);
}
return 0;
}

如果 argv 中的"hello",argc 应该是 2,输出应该是 "1 hello"。

在调用 Cint main(int argc, char **argv)方法之前修改 C 运行时环境的int argc参数计数器。 - - - = = = (;讨厌的黑客;) = = = - - - .

. . .

我正在使用:

  • 目前可用于OS X High Sierra的最新C++编译器,
  • 使用brew以当前标准方式安装。

若要重现下面的结果argc.cpp代码清单,请执行以下任一操作:

  • 更新您的Mac OS设置以反映我的,
  • 在 Ubuntu 64 上安装 GNU 编译器
  • 为您的特定设置安装 GNU 编译器

argc.cpp :

#include <stdio.h>
__attribute__((constructor)) void start(int argc, char **argv)
{
int * pc = (int *) argv - 2; // NASTY HACK TO GET C RUNTIME argc * ;)
printf("argc = %d n", *pc); // the original argc, on most systems ;)
int NUMBER_OF_PARAMETERS_NEEDED_FOR_FUZZING = 1; // Replace this line 
// with the simple/complex logic needed for fuzz testing (fuzzing)
if(!(argc > NUMBER_OF_PARAMETERS_NEEDED_FOR_FUZZING)){ 
argc = NUMBER_OF_PARAMETERS_NEEDED_FOR_FUZZING + 1;
*pc = argc; // NASTY HACK TO OVERWRITE C RUNTIME argc ;)
} 
// *pc = 2; // uncomment this to see that you can also reduce argc
argv[1] = "hello"; // Example setting of a fuzzy argument
// Add more lines, a loop, etc... here to set more fuzzy arguments 
for (int i = 0; i < argc; i++) {
printf("%s: argv[%d] = '%s'n", __FUNCTION__, i, argv[i]);
}
printf("argc = %d n", argc); // the possibly modified argc
}
int main(int argc, char **argv)
{
for (int i = 0; i < argc; i++) {
printf("%s: argv[%d] = '%s'n", __FUNCTION__, i, argv[i]);
}
printf("argc = %d n", argc); // the possibly modified argc
return 0;
}
<小时 />

Mac OS 终端:

>编译:
$ /usr/local/bin/c++-9 argc.cpp -o argc

运行0参数,原始int argc = 1

$ ./argc
argc = 1 
start: argv[0] = './argc'
start: argv[1] = 'hello'
argc = 2 
main: argv[0] = './argc'
main: argv[1] = 'hello'
argc = 2 

运行3参数,原始int argc = 4

$ ./argc 1 2 3
argc = 4 
start: argv[0] = './argc'
start: argv[1] = 'hello'
start: argv[2] = '2'
start: argv[3] = '3'
argc = 4 
main: argv[0] = './argc'
main: argv[1] = 'hello'
main: argv[2] = '2'
main: argv[3] = '3'
argc = 4 
<小时 />

运行,以展示argc减速能力,

  • 取消注释第 13 行并重新编译(硬编码argc = 2)后:
*pc = 2; // uncomment this to see that you can also reduce argc

与上述相同的3参数,原始int argc = 4

$ ./argc 1 2 3
argc = 4 
start: argv[0] = './argc'
start: argv[1] = 'hello'
start: argv[2] = '2'
start: argv[3] = '3'
argc = 4 
main: argv[0] = './argc'
main: argv[1] = 'hello'
argc = 2 

如果系统上初始化C 运行时环境,类似于列表:

  • 初始化代码首先由 GNU C 库的 ELF 启动代码运行,

您可能需要:

  • 通过将本地C 运行时环境与上面的 GNU 示例进行比较来研究差异,和/或
  • 实验性地修改我的代码,直到它适合你。例如:在argv的位置之前和之后int 指针,看看你在那里找到了什么......

如果您发现破解当前的C 运行时环境太难,请尝试:

  • 在 Ubuntu 64 上安装 GNU 编译器,
  • 为您的特定设置安装 GNU 编译器。

以下是此黑客工作的方式/原因:

  1. 适用于您的设置的C Runtime Environment函数(有多种可能性)将int argc, char **argv, char **envp参数保存在某些内存位置 - 幸运的是,在我的设置中,这些参数相邻。
  2. 在我的64 bit系统上,由于内存对齐规则,int argc地址将仅比char **argv指向的内存多sizeof(int)1个,这就是为什么int * pc = (int *) argv - 2;行中的- 2- 1的原因。
<小时 />
╦ ╦  ╔═╗  ╔═╗  ╔═╗  ╦ ╦       ╦ ╦  ╔═╗  ╔═╗  ╦╔═  ╦  ╔╗╔  ╔═╗ ╦ ╦ ╦
╠═╣  ╠═╣  ╠═╝  ╠═╝  ╚╦╝  ───  ╠═╣  ╠═╣  ║    ╠╩╗  ║  ║║║  ║ ╦ ║ ║ ║
╩ ╩  ╩ ╩  ╩    ╩     ╩        ╩ ╩  ╩ ╩  ╚═╝  ╩ ╩  ╩  ╝╚╝  ╚═╝ o o o

相关内容

  • 没有找到相关文章

最新更新