从C程序更改堆栈内存

时间:2013-03-11 16:30:53

标签: c

我是stackoverflow的新手,所以我提前为我犯的任何错误道歉。

我最近遇到过这个C拼图。该计划如下。

#include<stdio.h>

void change()
{

}

int main()
{
 printf("\nHello");
 change();
 printf("\nHai");
 printf("\nHow are you?");
 return 0;
}

预期的输出是,

Hello
Hai
How are you?

问题要求我们通过在函数change()

中添加一些代码来更改输出
Hello
How are you?

您不应该在main()中进行任何更改。

我试图通过避免语句printf(“\ nHai”)来更改存储在堆栈内存中的函数change()的返回地址。但是当我使用gcc编译时,我遇到了错误。

我在change()中添加的代码如下所示。

void change()
{
 char ch;
 *(&ch+10)+=20;
} 

使用

固定添加到ch(10和20)的值
objdump -d ./a.out

我希望收到一些解决问题的建议。提前感谢您的时间和耐心。

2 个答案:

答案 0 :(得分:2)

你很亲密。以下是x86-64上的linux。

main.c中:

#include <stdio.h>

void change()
{
    char dummy;

    /* skip local variable and rbp */
    *(long*)(&dummy + sizeof(dummy) + sizeof(long*)) += 0x40055e - 0x400554;
}

int main()
{
    printf("Hello\n");
    change();
    printf("Hi\n");
    printf("How are you?\n");
    return 0;
}

输出:

$ gcc -fno-stack-protector -o main main.c
$ ./main
Hello
How are you?

来自objdump我们得到:

    40054f: e8 c8 ff ff ff          callq  40051c <change>
->  400554: bf 1a 06 40 00          mov    $0x40061a,%edi
    400559: e8 92 fe ff ff          callq  4003f0 <puts@plt>
->  40055e: bf 1e 06 40 00          mov    $0x40061e,%edi
    400563: e8 88 fe ff ff          callq  4003f0 <puts@plt>

过程:

首先在main.c中使用一个小的任意差异。然后编译并运行objdump -d main以获取实际的偏移并更新main.c与它们的区别。

答案 1 :(得分:1)

以下代码应达到预期效果。

#include<stdio.h>
#include <stdlib.h>

void change()
{
printf("\nHow are you?"); 
exit(0);
}

int main()
{
 printf("\nHello");
 change();
 printf("\nHai");
 printf("\nHow are you?");
 return 0;
}

此代码将导致程序打印“Hello”然后执行change()函数,该函数将打印“你好吗?”在换行符上然后退出程序。 exit()函数是c标准库的一部分,可以看作Here