跳过c代码中的下一条指令

时间:2013-12-27 18:52:51

标签: c buffer-overflow

大家好:我试着跳过指令

void func(char *str) { 
   char buffer[24]; 
   int *ret; 
   strcpy(buffer, str); 
} 

int main(int argc, char **argv) { 
  int x;
  x = 0;
  func(argv[1]);
  x = 1; 
  printf("%d\n”, x); 
} 

如何使用*ret中定义的指针funct()来修改函数的返回地址,我可以跳过x=1

2 个答案:

答案 0 :(得分:2)

在生产代码中使用它是个坏主意!(从dvnrrs的注释中复制的原因。)这是未定义的行为;它严重滥用(假设)有关堆栈布局方式的知识,以及编译指令的大小。这注定要失败,尤其是在打开优化的情况下。

请注意,以这种方式修改局部变量旁边的内存是不正确的C代码,并且它会产生未定义的行为。我认为你的问题没有标准的C解决方案,所以如果你想这样做,最好的办法是特定于架构的汇编代码。下面的代码碰巧在我的GCC上使用C在i386上工作,但它仍然是未定义的行为,因此它本身就很脆弱,并且可以在编译器或ABI中的任何更改中停止工作。

这为我打印42:

#include <stdio.h>

void func(char *str) {
  (&str)[-1] += 2;
} 

int main(int argc, char **argv) { 
  (void)argc; (void)argv;
  int x;
  x = 42;
  func(argv[1]);
  x = 137; 
  printf("%d\n",x); 
  return 0;
}

在Linux i386上编译并运行:

$ gcc -m32 -W -Wall -s -O0 t.c && ./a.out
42

答案 1 :(得分:0)

你不能用C做到这一点;最接近的是the setjmp() and longjmp() functions,但这些不适用于您的确切情况。

正如其他人在评论中指出的那样,最好的办法可能是给你的函数一个返回值,然后在调用者中检查返回值,以决定接下来要运行的代码。您的示例代码看起来像是一个人为的测试用例,因此我不确定您要完成的是什么。