6

我是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

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

4

2 回答 2

2

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

主.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使用它们的差异进行更新。

于 2018-06-10T21:21:08.643 回答
2

下面的代码应该可以达到预期的效果。

#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 标准库的一部分,如下所示

于 2017-04-09T21:22:33.953 回答