zoukankan      html  css  js  c++  java
  • [C++逆向] 7 变量在内存中的位置和访问方式

    变量类型 作用域 可访问
    全局变量 进程作用域 整个进程可访问
    静态变量 文件作用域 当前代码文件可访问
    局部变量 函数作用域 函数内可访问
    {}内变量 块作用域 只能在{}内访问

    块作用域举例

    image-20200425112110704

    全局变量和局部变量的区别

    • 全局变量
      • 在PE文件中,一般是.data节表
      • 在程序执行之前就已经存在了(有内存地址)
      • 程序退出时销毁
      • 全局变量直接通过立即数寻址
      • 先定义的在低地址,后定义变量在高地址(实践得知,Release版本中不是这样的)

    用户在运行文件的时候,操作系统线分析这个PE中的数据,将各个节中的数据填入对应的虚拟地址中,此时全局变量已经存在了,等PE的分析和加载完成之后,才开始执行入口点的代码,因此全局变量不受作用域影响,程序的任何位置都可以被访问到。

    通过变量2访问变量1 (但是该代码在Release版本中不成立 书上的bug 哈哈)

    image-20200425123027424

    • 局部变量
      • 生命周期和函数相同
      • 超出作用域之后。由栈平衡操作来释放局部变量的空间
      • 通过esp或者ebp寻址
    • {} 块变量
      • 在{}内的局部变量生命周期和函数一样,但是编译器会编译前检查语法,限制块外代码对其访问

    局部静态变量

    局部静态变量实际上和全局变量是一样的,都保存再执行文件的数据区,局部静态变量会预先被当作全局变量处理,初始化实际上只是赋值

    和全局变量内存结构和访问原理上是一样的,相当于全局静态变量,等价u有限制外部源码文件访问的全局变量

    • 编译器通过名称粉碎法使得其他作用域对局部静态变量不可见。
      • 也即是在编译器及对静态变量重新命名

    有意思的

    image-20200425173706629

    以上代码执行之后结果是什么呢?

    image-20200425173743534

    结果居然是五个0,为什么呢?我各种仔细检查代码,发现啥问题都没有。通过调试发现,第7行执行过后,j变量还是0。

    最后,书上给了答案,原因是因为为了保证局部静态变量只能被初始化一次,编译器在局部静态变量内存周围做了一个标记,每次通过检查标记判断是否已经被初始化了。如果初始化了就直接跳过。

    但是!!!!!!!!!

    经过我实际操作发现,上面的方法是vc6的方法,在我用的vs2019中似乎使用了新的方法。。。

    image-20200425174220257

    这样让我很头大,但是发现了线索,就是_tls_index翻译过来就是tls索引?tls似乎听过!似乎有一个特殊的节表就是tls!通过百度,知道了tls是线程局部储存的意思。而fs里面包含了很多指针,通过查询 2Ch偏移指向的正是 线程局部储存,所以,是否可以认为,新的编译器使用了线程局部储存的方式来标记静态变量呢?

    通过修改代码,把代码改成下图,可以得到正确结果。

    image-20200425140140486

    image-20200425140108783

    堆变量

    • 通过malloc或者new申请的空间变量,就是在堆中。
    • 内存中,对结构的每个节点都是使用双向链表的形式储存的
  • 相关阅读:
    swoole 安装方法 使用即时聊天
    git的介绍以及简单应用
    curl的应用
    linux下监听和同步代码配置
    mac skim 修改背景色
    php 编译安装的一个 configure 配置
    mac mysql error You must reset your password using ALTER USER statement before executing this statement.
    yii2 控制器里 action 大小写组合造成的路由问题
    warning : json_decode(): option JSON_BIGINT_AS_STRING not implemented in xxx
    redis 自启动脚本
  • 原文地址:https://www.cnblogs.com/cjdty/p/12774310.html
Copyright © 2011-2022 走看看