Linux中程序的栈帧分析以及修改函数地址

下面有一段代码:

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

void fun()
{
   printf("i am the evil func\n");
   exit(1);
}

int fun1(int a,int b)
{
    int *p=&a;
    p--;
    *p=fun;
    int c=0xcccc;
    return c;
}

int main()
{
    printf("begin run..\n");
    int a=0xaaaa;
    int b=0xbbbb;
    fun1(a,b);
    printf("right end");
    return 0;
    
}

linux下执行结果:

main调用fun1调用fun---exit退出

对于此结果的问题:

明明没有调用fun函数,为什么会执行fun函数,函数是如何进行跳转的?

栈帧是怎么样保存信息并返回的?

分析原因:

查看汇编代码中的重要的栈段

简易栈帧图

下面一个程序通过指针访问变量y的值,而不是变量名y

#include <stdio.h>

int fun(int x,int y)
{
    int *p = x;
    p--;
    return *p;
}

int main()
{
    int x=1;
    int y=2;
    int ret=fun(x,y);
    printf("y的值是%d\n"ret);
    return 0;
}

原理就是p-->x,p--之后,p指向y

此时*p访问的就是y的值

时间: 2025-01-04 14:32:48

Linux中程序的栈帧分析以及修改函数地址的相关文章

程序运行 栈帧分析 以及 修改栈帧中数据以及函数地址

1 在栈帧中 修改函数调用地址 使得程序运行 跳转到 自己指定的函数 而原程序的作者完全不知道这段程序的执行中已经执行了别人的代码[可能是恶意的] 2 修改栈帧中的变量的值 不通过变量名 如 修改变量b的值 不通过变量b的名称 [这需要对变量在栈帧中的分布有一定的了解 ] 压栈是 a先压栈 b后压栈 压栈时 栈顶向低地址方向前进 变量a在变量b的上面 变量a的地址 0xbfa92d88 变量b的地址 0xbfa92d84

小程序的栈帧分析

函数调用另一个词语表示叫作过程.一个过程调用包括将数据和控制从代码的一部分传递到另一部分.另外,它还必须在进入时为过程的局部变量分配空间,并在推出时释放这些空间.而数据传递,局部变量的分配和释放通过操纵程序栈来实现. 栈帧也叫过程活动记录,是编译器用来实现过程函数调用的一种数据结构. 下面的一段代码,在main函数中并没有调用使虚拟机重启的函数,但是虚拟机为什么会重启? 这个原因就与栈帧有关,以下的图是对这个程序的解析 利用栈帧的知识,还可以不用b,但是可以改变b变量的值. 以下是结果:

Linux 下函数栈帧分析

1.关于栈 对于程序,编译器会对其分配一段内存,在逻辑上可以分为代码段,数据段,堆,栈 代码段:保存程序文本,指令指针EIP就是指向代码段,可读可执行不可写 数据段:保存初始化的全局变量和静态变量,可读可写不可执行 BSS:未初始化的全局变量和静态变量 堆(Heap):动态分配内存,向地址增大的方向增长,可读可写可执行 栈(Stack):存放局部变量,函数参数,当前状态,函数调用信息等,向地址减小的方向增长,非常非常重要,可读可写可执行.如下图所示: 首先必须明确一点也是非常重要的一点,栈是向下

Linux下栈帧分析

我们知道C语言中,每个栈帧对应着一个未运行完的函数.栈帧中保存了该函数的返回地址和局部变量.栈帧也叫过程活动记录,是编译器用来实现函数调用的一种数据结构.那么在Linux下gcc编译器栈帧是怎么实现的呢? 首先来看下面这段代码: 这段代码的运行结果是会导致虚拟机重启.通过代码可以看到我们在fun函数中写了让系统重启的代码然而我们在main函数中并没有调用fun函数,却仍旧导致了系统重启. 首先要我们知道栈是从高地址向低地址生长的,每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需

c函数调用过程原理及函数栈帧分析

转载自地址:http://blog.csdn.net/zsy2020314/article/details/9429707       今天突然想分析一下函数在相互调用过程中栈帧的变化,还是想尽量以比较清晰的思路把这一过程描述出来,关于c函数调用原理的理解是很重要的. 1.关于栈 首先必须明确一点也是非常重要的一点,栈是向下生长的,所谓向下生长是指从内存高地址->低地址的路径延伸,那么就很明显了,栈有栈底和栈顶,那么栈顶的地址要比栈底低.对x86体系的CPU而言,其中 ---> 寄存器ebp(

C++反汇编第二讲,反汇编中识别虚表指针,以及指向的虚函数地址

讲解之前,了解下什么是虚函数,什么是虚表指针,了解下语法,(也算复习了) 开发知识为了不码字了,找了一篇介绍比较好的,这里我扣过来了,当然也可以看原博客链接: http://blog.csdn.net/hackbuteer1/article/details/7558868 一丶虚函数讲解(复习开发,熟悉内存模型) 1.复习开发知识 首先:强调一个概念 定义一个函数为虚函数,不代表函数为不被实现的函数. 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数. 定义一个函数为纯虚函数,才代表函数

Linux中程序包管理

u    无论我们使用哪种操作系统,仅使用操作系统自带的程序包一般都满足不了我们的使用需求,所以我们都需要安装程序.这篇博文我们来讲解一下在Linux操作系统中我们该如何安装程序. 本篇文章会涉及rpm管理程序包.yum管理程序包.yum仓库的指定.自己编译源码安装程序.简要介绍一下该如何自己建立一个yum仓库给其他主机提供程序包. 一.rpm管理程序包 (1)如何获取安装包 1)系统发行版的光盘或者官方的文件服务器(或者镜像站点): http://mirrors.aliyun.com/ htt

Linux中关于安装包的分析。——Arvin

初接解LINUX的,同样都是for linux,但rpm.tar.gz.deb包还是有很大区别的,这种区别可使安装过程进行不下去.那我们应该下载什么格式的包呢? rpm包-在红帽LINUX.SUSE.Fedora可以直接进行安装,但在Ubuntu中却无法识别: deb包-是Ubuntu的专利,在Ubuntu中双击deb包就可以进入自动安装进程: tar.gz包-在所有的Linux版本中都能使用,但安装过程也最麻烦.要先解压缩,然后在“终端”里用cd 命令进入刚才解压的目录,再找到安装链接文件安装

linux中curl指令的简要分析

curl是一种命令行工具,作用是发出网络请求,然后得到和提取数据,显示在"标准输出"(stdout)上面. 它支持多种协议,下面举例讲解如何将它用于网站开发. 一.查看网页源码 直接在curl命令后加上网址,就可以看到网页源码.我们以网址www.sina.com为例(选择该网址,主要因为它的网页代码较短): $ curl www.sina.com <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <