大家好:我试着跳过指令
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
答案 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,但这些不适用于您的确切情况。
正如其他人在评论中指出的那样,最好的办法可能是给你的函数一个返回值,然后在调用者中检查返回值,以决定接下来要运行的代码。您的示例代码看起来像是一个人为的测试用例,因此我不确定您要完成的是什么。