Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从C程序更改堆栈内存_C - Fatal编程技术网

从C程序更改堆栈内存

从C程序更改堆栈内存,c,C,我是stackoverflow的新手,所以我为我犯的任何错误提前道歉 我最近遇到了这个C难题。程序如下所示 #include<stdio.h> void change() { } int main() { printf("\nHello"); change(); printf("\nHai"); printf("\nHow are you?"); return 0; } 这个问题要求我们通过在functionchange()中添加一些代码来如下更改输出 您不应该在m

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

我最近遇到了这个C难题。程序如下所示

#include<stdio.h>

void change()
{

}

int main()
{
 printf("\nHello");
 change();
 printf("\nHai");
 printf("\nHow are you?");
 return 0;
}
这个问题要求我们通过在functionchange()中添加一些代码来如下更改输出

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

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

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

void change()
{
 char ch;
 *(&ch+10)+=20;
} 
添加到ch(10和20)的值通过使用

objdump -d ./a.out

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

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

#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;
}
#包括
#包括
无效更改()
{
printf(“\n您是谁?”);
出口(0);
}
int main()
{
printf(“\nHello”);
改变();
printf(“\nHai”);
printf(“\n您是谁?”);
返回0;
}

此代码将使程序打印“Hello”,然后执行change()函数,该函数将在换行符上打印“你好吗?”然后退出程序。exit()函数是c标准库的一部分,正如您所看到的。以下是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;
}
从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>
40054f:e8 c8 ff ff callq 40051c
->400554:bf 1a 06 40 00 mov$0x40061a,%edi
400559:e8 92 fe ff ff callq 4003f0
->40055e:bf 1e 06 40 00 mov$0x40061e,%edi
400563:e8 88 fe ff ff callq 4003f0
过程:


首先在
main.c
中使用一个小的任意差异。然后编译并运行<代码> ObjDop-d主< /代码>以获得实际的偏移量并更新代码>主页。C < /代码>与它们的不同。

您能发布您所得到的错误吗?我认为如果您必须依靠未定义的行为来实现结果,那么这是一个很差的“谜题”。这些知识一文不值,除非你是系统安全专业人士。这很简单,只要添加
printf(“\n你是谁?”);出口(0)
change()
@Praetorian:LOL。。。好吧,我承认失败并收回我先前的评论。漂亮-D我陷入了OP的思路。我不同意“可怜的拼图”和结束问题。答案中的偏移量确实是局部的,但推导它们的技术是通用的。这将是堆栈布局和低级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?
    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>