使用指针算法更改另一个函数中变量的值。

时间:2016-02-04 03:58:43

标签: c function pointers

#include <stdio.h>

void interrupt();

int main() {
 int n = 8;
 char c = 'Z';
 interrupt();
 printf("%d%c\n", n, c);
}

void interrupt() {
 printf("Run normally\n");
 //ADD CODE...
}

目前,此功能将输出&#34; 8Z&#34;无论interrupt()方法做什么。我试图修改它,以便打印&#34; 3Y&#34;不改变原始main函数中的任何内容,只使用interrupt()函数(不允许传递参数!)。我被允许在interrupt()函数中使用变量,但我很困惑,因为你如何获得&#39; n&#39;和&#39; c&#39;没有制作全局变量,这会破坏这个问题的目的。由于堆栈的地址每次运行都会改变,因此似乎不是一种做指针运算的方法(这是我需要做的事情),因此我有点困惑和卡住。 / p>

2 个答案:

答案 0 :(得分:2)

免责声明:请勿在生产代码中尝试使用此功能

我把它作为一个谜题并继续解决它。您说您不能修改main。我冒昧地稍微修改main - 打印nc的地址。

int main()
{
   int n = 8;
   char c = 'Z';

   printf("%p %p\n", &n, &c);

   interrupt();
   printf("%d%c\n", n, c);
}

我还修改了interrupt一点,也打印了一个地址的值。

void interrupt() {
   int i = 10;
   char* np = (char*)&i;
   char* cp = (char*)&i;

   printf("%p %p\n", np, cp);
   printf("%p\n", &i);
}

当我运行程序时,我得到以下输出:

0x22cb0c 0x22cb0b
0x22cabc 0x22cabc
0x22cabc
8Z

从输出中,我能够计算&nmain&iinterrupt之间的偏移量,以及&cmain之间的偏移量{1}}和&i中的interrupt。现在,我可以操纵偏移量,使np中的cpinterrupt指向n中的cmain

void interrupt() {
   int i = 10;
   char* np = (char*)&i;
   char* cp = (char*)&i;

   np += (0x22cb0c - 0x22cabc);
   cp += (0x22cb0b - 0x22cabc);

   *(int*)np = 3;
   *cp = 'Y';

   printf("%p %p\n", np, cp);
   printf("%p\n", &i);
}

interrupt进行更改后,我得到以下输出:

0x22cb0c 0x22cb0b
0x22cb0c 0x22cb0b
0x22cabc
3Y

通过稍微改变main来完成任务。如果您根本不允许更改它,则必须使用其他程序来计算偏移量。

答案 1 :(得分:1)

通过@Alex Skalozub所说的,您可以获得堆栈偏移并修改调用函数中的局部变量。

您可以: 1.研究编译器和OS手册以计算堆栈偏移量。

或者 2.编写一个小函数来在运行时获取它。如下所示。

int get_stack_offset(void)
{
    long dummy1;
    return dummy_call(&dummy1) + sizeof(dummy1);
}

int dummy_call(int address)
{
    long dummy2;
    return &dummy2 - address;
}

然后你可以

void interrupt() {
    printf("Run normally\n");
    int stack_offset = get_stack_offset();
    char* c_address = (char*) (&stack_offset - stack_offset);
    int* n_address = (int*) (c_address - sizeof(char));

    // Then, modify them
    *c_address = 'Y';
    *n_address = 3;

    // Other
    // ...
}

*假设堆栈正在增加。当它减少时,你需要反转+/-运算符。

*我不考虑对齐,也许你需要。

*这是一个很好的解释,你可以参考。  Does stack grow upward or downward?