[C++逆向] 7 变量在内存中的位置和访问方式
| 变量类型 | 作用域 | 可访问 |
|---|---|---|
| 全局变量 | 进程作用域 | 整个进程可访问 |
| 静态变量 | 文件作用域 | 当前代码文件可访问 |
| 局部变量 | 函数作用域 | 函数内可访问 |
| {}内变量 | 块作用域 | 只能在{}内访问 |
块作用域举例
全局变量和局部变量的区别
- 全局变量
- 在PE文件中,一般是.data节表
- 在程序执行之前就已经存在了(有内存地址)
- 程序退出时销毁
- 全局变量直接通过立即数寻址
- 先定义的在低地址,后定义变量在高地址(实践得知,Release版本中不是这样的)
用户在运行文件的时候,操作系统线分析这个PE中的数据,将各个节中的数据填入对应的虚拟地址中,此时全局变量已经存在了,等PE的分析和加载完成之后,才开始执行入口点的代码,因此全局变量不受作用域影响,程序的任何位置都可以被访问到。
通过变量2访问变量1 (但是该代码在Release版本中不成立 书上的bug 哈哈)

- 局部变量
- 生命周期和函数相同
- 超出作用域之后。由栈平衡操作来释放局部变量的空间
- 通过esp或者ebp寻址
- {} 块变量
- 在{}内的局部变量生命周期和函数一样,但是编译器会编译前检查语法,限制块外代码对其访问
局部静态变量
局部静态变量实际上和全局变量是一样的,都保存再执行文件的数据区,局部静态变量会预先被当作全局变量处理,初始化实际上只是赋值
和全局变量内存结构和访问原理上是一样的,相当于全局静态变量,等价u有限制外部源码文件访问的全局变量
- 编译器通过名称粉碎法使得其他作用域对局部静态变量不可见。
- 也即是在编译器及对静态变量重新命名
有意思的

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

结果居然是五个0,为什么呢?我各种仔细检查代码,发现啥问题都没有。通过调试发现,第7行执行过后,j变量还是0。
最后,书上给了答案,原因是因为为了保证局部静态变量只能被初始化一次,编译器在局部静态变量内存周围做了一个标记,每次通过检查标记判断是否已经被初始化了。如果初始化了就直接跳过。
但是!!!!!!!!!
经过我实际操作发现,上面的方法是vc6的方法,在我用的vs2019中似乎使用了新的方法。。。

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


堆变量
- 通过malloc或者new申请的空间变量,就是在堆中。
- 内存中,对结构的每个节点都是使用双向链表的形式储存的
[C++逆向] 7 变量在内存中的位置和访问方式的更多相关文章
- Java变量在内存中的存储
目录 Java变量在内存中的存储 成员变量 局部变量 总结 Java变量在内存中的存储 以下探究成员变量和局部变量在内存中的存储情况. package com.my.pac04; /** * @aut ...
- vs中调试程序查看变量在内存中的内容的方法
vs中调试程序 查看变量在内存中的内容的方法 https://blog.csdn.net/guojg1988/article/details/42922149 原文链接:http://www.sows ...
- JavaScript中的变量在内存中的具体存储形式
栈内存和堆内存 JavaScript中的变量分为基本类型和引用类型 基本类型是保存在栈内存中的简单数据段,它们的值都有固定的大小,保存在栈空间,通过按值访问 引用类型是保存在堆内存中的对象,值大小不固 ...
- string字符串常量池在内存中的位置
这里仅仅是举个简单的样例说明字符串常量池在内存中的位置. 闲言少叙,直接上代码. <span style="font-size: large;">import java ...
- JavaScript 变量类型 保存内存中的位置 和 引用
1. JavaScript变量 基本类型值在内存中占据固定大小的空间 因此被保存在栈内存中. 从一个变量向另一个变量复制基本来下的值 会创建这个值得一个副本. 引用类型的值是对象 保存在堆内存中. 包 ...
- 详解Python变量在内存中的存储
这篇文章主要是对python中的数据进行认识,对于很多初学者来讲,其实数据的认识是最重要的,也是最容易出错的.本文结合数据与内存形态讲解python中的数据,内容包括: 引用与对象 可变数据类型与不可 ...
- python中变量在内存中的存储与地址关系解析、浅度/深度copy、值传递、引用传递
---恢复内容开始--- 1.变量.地址 变量的实现方式有:引用语义.值语义 python语言中变量的实现方式就是引用语义,在变量里面保存的是值(对象)的引用(值所在处内存空间的地址).采用这种方式, ...
- C++类成员在内存中的存储及对齐方式
前言:数据对齐的基本理论参见文章:http://www.cnblogs.com/MyBlog-Richard/articles/5993448.html 一.空类的大小 C++中空类的大小是1,这是因 ...
- Linux从头学03:如何告诉 CPU,代码段、数据段、栈段在内存中什么位置?
作 者:道哥,10+年的嵌入式开发老兵. 公众号:[IOT物联网小镇],专注于:C/C++.Linux操作系统.应用程序设计.物联网.单片机和嵌入式开发等领域. 公众号回复[书籍],获取 Linux. ...
- Objective-C 中self.与_访问方式的区别
Objective-C中属性self.a与_a访问的区别: 在OC中我们可以通过指令@property定义属性. OC对属性封装了许多方法,同时也会自动实现一些方法,相比实例变量,感觉更加面向对象些. ...
随机推荐
- Seata配置参考
注意:mysql.redis等连接密码需修改为相应值 Seata-Server 环境 版本:1.4.2 OS: CentOS Linux release 7.5.1804 (Core) ip:192. ...
- Android APP升级时解析程序包时出现问题
一个新的测试机在自动下载升级安装更新版本APP时,报出"解析程序包时出现问题"错误.原因众说纷纭, 一番搜索,下面的回答比较全面: https://stackoverflow.co ...
- 你对iframe知道多少
iframe 嵌套第三方页面出现的问题 我们需要通过一个接口获取被嵌套的地址. 然后将改地址赋值给iframe的src中,代码如下 <template> <div> <i ...
- 从零开始配置 vim(9)——初始配置
虽然本系列文章叫做从0开始配置vim,似乎我们从一开始就要写vimrc配置文件,但是我们并没有这么做.我们先经过几篇文章了解了下面的几个内容 如何设置vim属性,从而改变vim的特征 配置快捷键,以提 ...
- 【三】AI Studio 项目详解——单机多机训练分布式训练--PARL
相关文章 [一]-环境配置+python入门教学 [二]-Parl基础命令 [三]-Notebook.&pdb.ipdb 调试 [四]-强化学习入门简介 [五]-Sarsa&Qlear ...
- 【深度学习项目三】ResNet50多分类任务【十二生肖分类】
相关文章: [深度学习项目一]全连接神经网络实现mnist数字识别 [深度学习项目二]卷积神经网络LeNet实现minst数字识别 [深度学习项目三]ResNet50多分类任务[十二生肖分类] 『深度 ...
- AnyCAD程序无法启动的问题解决方法
在某些电脑上会出现基于AnyCAD开发的程序无法启动的问题,如: System-ArgumentEcception: Please check the dependendes 解决方法 安装最新的VS ...
- ChatGPT 火了,一大批开源平替也来了
ChatGPT 凭一己之力让全球为 AI 沸腾,引发了科技巨头之间的聊天机器人军备竞赛. 众所周知,ChatGPT 的背后技术是 GPT(Generative Pre-trained Transf ...
- SUM和IF使用求部分和
GROUP BY可以按照某一列的不同值进行分组,然后将不同组的数据可以利用聚合函数进行汇总取值. --我们可以在老师表里面求解不同班级的老师分别有多少名 SELECT class_id,COUNT(t ...
- ASP.NET Core分布式项目实战(运行Consent Page)--学习笔记
任务21:运行Consent Page 修改 Config.cs 中的 RequireConsent 为 true,这样登录的时候就会跳转到 Consent 页面 修改 ConsentControll ...
