吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4999|回复: 11
收起左侧

[原创] 一起读反汇编代码之变量在映像中的存放及访问

  [复制链接]
雪魔王遗风 发表于 2019-9-19 00:22
不知道小白有没有这样的困惑,就是单独一条的汇编语句能读懂,但是好几条组合到一起就感觉云里雾里了
那你就适合跟我们一起来读反汇编代码了,把基础指令的反汇编代码读懂才能逆向出一些更难的算法,今天我们一起来读的就是反汇编的基础部分———变量在映像中的存放及访问。


上一节我们一起观察了函数的局部变量在栈帧中的存放,但是C++中可不只有局部变量这一种,其他几种变量也是存放在栈帧中的吗?访问它们的方式又是怎样的呢?今天我们就一起来看一看局部变量、全局变量、静态局部变量、静态全局变量这四种变量



一.局部变量及全局变量
从定义方式来看,局部变量就是定义在函数内的变量;全局变量就是定义在函数外的变量。
那么这两种变量在内存中究竟是怎样存储的呢,访问它们的方式又是否相同呢?
上一节我们一起看了函数的调用,知道了函数的局部变量是存放在当前函数的栈帧中的。
因为函数调用完成后会清除该函数的栈帧,所以局部变量才有了生命周期。
而我们知道全局变量的生命周期是跟程序一样长的,那么它还能存放在栈帧/栈空间中吗?

这里我们定义了两个变量,一个全局变量、一个局部变量
QQ拼音截图20190918233509.png

看一下反汇编的结果
QQ拼音截图20190918212042.png
这个参数2(局部变量)[ebp-4],是不是很熟悉,就是上一章我们讲过的局部变量。
再看全局变量,发现是立即数寻址,其是直接存放在内存地址中的。
现在有理由猜测全局变量的值是存在于PE文件中的,因为根据其是立即数寻址我们能判断它在内存中的地址是固定的,而程序运行时文件又是映射到内存中去的,所以既然它在内存映像中的地址是固定的那么在PE文件中的地址也应该是固定的。
这里补充一句:PE文件加载到内存中的时候,文件并不是原封不动的加载,而是根据各节区头中定义的节区起始地址、节区大小等信息加载的。所以磁盘文件中的PE与内存中的PE具有不同的形态,而我们又把内存中的形态称为“映像”。
这里涉及到了一些PE知识,精力有限而且PE知识又比较多所以我这就不多说了,以后有能力有精力了可能会发一篇制作PEView的帖子和大家一起学习一下PE格式。
哈哈,思路再转回来,我们猜想全局变量在PE文件中的地址是固定的,那么我们就看看呗
这里涉及到RVA(相对虚拟地址)和RAW(文件偏移)之间的转换,其实就是在内存中的地址和在磁盘中的地址之间的转换,因为前面说了,这两个地址是不同的。

这里有个公式RAW=RVA-VA+RawOffset
哈哈,我直接解释下吧,虽然PE文件是映射到内存中去的,但是地址间仍然是有关系的,我们知道PE文件是一段一段的,有数据段、代码段等等,那么数据存放的地址跟段首的偏移值应该是固定的。举个例子,两个数组,一个是从1~10,一个是从11~20,现在第一个数组的第5个数要被映射到第二个数组中去,我们会把它放在哪呢,是15对不对,为什么想把它放在15这个位置呢,因为5-1=4,而15-11也等于4,对不对,这个偏移量是固定的。
而PE文件映射到内存中也是这样

我们首先查看0042 4d8c这个地址在哪个区段
QQ拼音截图20190918215847.png
很明显是在.data段,再减去段首地址,得出偏移地址是d8c

再试用Stud_PE工具查看.data段在PE文件中的起始地址(吾爱工具包中也有)
QQ拼音截图20190918220246.png
是24000,所以得知我们的全局变量在PE文件中的地址应该是24d8c

使用winHex查看
QQ拼音截图20190918220559.png
果不其然,我们的全局变量正安静地在里面躺着呢。
所以我们可以下这么个结论:全局变量的初始值在链接时就被写入到所创建的PE文件中去了,当PE文件执行时,数据被映射到内存中去之后,全局变量就已经存在了。

二.全局静态变量和局部静态变量
在我们观察这几种变量的反汇编代码之前,我们先讲一讲C++中的关键字static
一谈到static关键字,可能很多人想到不就是用来定义一个静态变量的吗,当然这是static的一个作用,除此之外它其实还有些别的作用:
1.用于隐藏变量
这个甚至是static最重要的作用,就是用于隐藏变量及函数,我们有时编程的时候会同时编译多个文件,而如果你在A.c中定义的变量和函数没有加static前缀,那么你在b.c中就也能使用这些变量和函数,换句话说,不加static的变量和函数具有全局可见性。
2.保持变量内容的持久化
静态变量会在程序刚开始运行的时候完成初始化,也是唯一的一次(等一下会解释这是什么意思),共有两种变量存放在静态存储区--静态变量和全局变量,不过静态变量会控制其可见范围。
3.默认变量的初始化为零
直接上图
QQ拼音截图20190918222804.png
带有static前缀,哪怕你不初始化,它也默认为0

好了说完static修饰符,我们正式来看看全局静态变量和局部静态变量
全局静态变量我就不说了:) ,它的存储跟访问方式跟全局变量差不多,只不过由于static修饰符,限制了外部源文件访问。

前面我们说过局部静态变量只会被初始化一次,我们验证一下
QQ拼音截图20190918223922.png
我们大胆猜测一下,上面这段代码,究竟会输出什么呢,是全部都是0,还是输出0~9呢?

QQ拼音截图20190918224040.png
猜对了吗,果然全都是0,因为前面说过,静态变量只会被初始化一次

那么我们大胆猜测一下,编译器是如何知道这个变量是被初始化过了呢,是这个变量有一个标志位标志它被初始化过了呢;还是就是专门划分了一个区域,里面放的全是被赋过值的静态变量,然后里面的值不再被允许初始化了;还是说有一张表,里面放着指向初始化过的静态变量的指针,凡是指向的静态变量都不能初始化了,还是别的什么原因呢。
我们一起来看看反汇编代码

QQ拼音截图20190918230111.png
进到main函数里,发现这么一段代码,典型的for循环语句,我们进到循环中的call去看看,应该就是调用my_printf函数了
QQ拼音截图20190918231749.png
发现前四行代码就是将427C4C中的值传给eax,然后又进行了是否等于0的判断,不等于0则跳转。
如果不跳转呢,发现用一个or 1将这个值变成了1,然后又将传进来的参数([ebp+8])赋给了一个变量,这个变量就是我们定义的静态局部变量,因为你发现之后这个变量会作为printf的参数压栈。
那么我们就知道了,是因为有一个标志位,它用来标志这个局部静态变量有没有被赋值,如果赋过值,那么标志位变为1,以后都会直接跳过赋值阶段。


最后再附上源码跟程序:https://www.lanzouj.com/i68yd6h
好了,到这里今天的学习就结束了,能力有限,可能会有疏漏之处,欢迎在评论区指出。
感谢各位看官!
如果觉得这篇帖子对你有一点帮助的话,希望能动动小手帮忙给下免费的评分,谢谢大家了!

免费评分

参与人数 13威望 +1 吾爱币 +18 热心值 +12 收起 理由
Hmily + 1 + 7 + 1 用心讨论,共获提升!
长歌暖 + 1 我很赞同!
1qaz + 1 + 1 谢谢@Thanks!
keyyan + 1 + 1 谢谢@Thanks!
whc2001 + 1 + 1 谢谢@Thanks!
天空藍 + 1 + 1 用心讨论,共获提升!
wangxp + 1 + 1 谢谢@Thanks!
heimu360 + 1 我很赞同!
v8888v + 1 + 1 用心讨论,共获提升!
lookerJ + 1 + 1 用心讨论,共获提升!
javafu159357 + 1 + 1 用心讨论,共获提升!
daniel7785 + 1 用心讨论,共获提升!
朱朱你堕落了 + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 雪魔王遗风 发表于 2019-9-19 22:47
keyyan 发表于 2019-9-19 21:49
楼主您好,按你说的在易语言试了下静态变量,好像不会都一样吧???

我记得易语言其实就是C语言衍生出来的,所以变化应该不会太大。
那为什么你的结果不一样呢,其实是因为你的rr=tt是在给静态变量赋值,并不是在初始化,静态变量只能初始化一次不假,但哪有不能赋值的道理是不。
直接上图
QQ拼音截图20190919223722.png

QQ拼音截图20190919224309.png

有用的话,希望能给个免费的评分哦,爱你!
IBinary 发表于 2019-9-19 10:08
挺不错了. 看下C++反汇编与逆向解密.里面都有说. 不过实践出真知. 特别是静态变量这里. 标志赋值从而保证静态变量不被修改. 其实如果可以的话.看看附近. 附近不只有标志. 应该还有其它内容.
hackyou 发表于 2019-9-19 02:52
还有一种比较特殊的情况是把变量分配到寄存器中。
JuncoJet 发表于 2019-9-19 08:32
第一个代码会非法访问吧?0x1314不可读(闪电逃
fangchang819 发表于 2019-9-19 09:40
进来学习!谢谢提供!
keyyan 发表于 2019-9-19 21:49
楼主您好,按你说的在易语言试了下静态变量,好像不会都一样吧???
静态变量.png
whc2001 发表于 2019-9-20 08:26
学习一下,顺便楼主ID自带音频剪辑(滑稽
keyyan 发表于 2019-9-20 08:33
本帖最后由 keyyan 于 2019-9-20 08:34 编辑
雪魔王遗风 发表于 2019-9-19 22:47
我记得易语言其实就是C语言衍生出来的,所以变化应该不会太大。
那为什么你的结果不一样呢,其实是因为 ...

好的,大概理解您的意思,谢谢!!!期待您的PE教程
1qaz 发表于 2019-9-20 08:44
谢谢,多学习一下这种技术文章。期待后续
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-16 16:37

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表