gpt4 book ai didi

c - 直接跳转到函数的某些部分

转载 作者:太空狗 更新时间:2023-10-29 16:05:45 24 4
gpt4 key购买 nike

我想知道如何完成这个拼图。我需要能够打印通常反向打印的内容。通常这会打印,hello there。我需要它来打印 there hello。我只能在注释的地方添加代码。

以下是我的一些行不通的想法。

  • 我想过使用堆来存储一些数据,但我不能,因为 stdlib.h 不包括在内。
  • 不能使用 goto 因为我不能添加标签,而我想要的 goto 都在一行中
  • 不能使用递归,因为没有输入参数,也没有要修改的全局变量。
  • 想不出汇编可以提供帮助的方法,但嘿,也许吧?
  • 我不能做任何明显的事情,比如调用 printf 并提前退出程序。
  • 关于函数指针的想法?我仍然不明白他们会如何提供帮助。

#include <stdio.h>
void f1(); void f2(); void f3();

int main() { f1(); printf("\n"); return 0; }

void f1() { f2(); printf(" there "); }

void f2() { f3(); printf(" hello "); }

void f3(){
int x;
//Can add whatever under here
}

最佳答案

我认为 int x; 的唯一目的是在不使用内联汇编的情况下获取堆栈指针。

具体如何执行此操作的解决方案将取决于您的平台、您使用的编译器以及您使用的优化级别。

我会说首先你需要分析调用堆栈。

你可以这样做-

int i;
for (i = 0; i< 10; i++) {
printf ("%p\n", *(void**)((char*) &x - i * 8)); // I am assumming 64 bit machines. If 32 bit replace 8 with 4
}

这将为您提供堆栈中前 10 个 8 字节的值。现在您需要找到两个看起来像返回地址的地址。识别它们的一种方法是打印 f1 和 f2 的函数指针值并查看接近它们的值。

您现在知道存储它们的索引。继续交换它们。

为了交换它们,假设索引是 12 和 14。

那么你可以这样做-

*(void**)&x = *((void**)&x + 12);
*((void**)&x + 12) = *((void**)&x + 14);
*((void**)&x + 14) = *(void**)&x;

还要确保在获得索引后不要更改堆栈布局。这意味着不要删除/添加任何变量。不要将 & 运算符应用于任何新变量(或从任何变量中删除),也不要删除任何函数调用。

还有另一个建议 - 除了使用 int x,您可以声明另一个 unsigned long long y 并将其用于交换。因为它有足够的字节来保存一个指针(在 64 位机器上)。通常在 int x 的情况下也会有填充,这应该可以避免您遇到问题但更安全。

关于c - 直接跳转到函数的某些部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43106850/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com