这一次我们要通过逆向分析的视角分析一下普通局部变量,静态局部变量,全局变量,静态全局变量,const全局变量的差异 我们需要将上面的代码编译为可执行程序,然后我们使用x64dbg对上面的程序进行分析 局部变量我们需要关注 local_variable_demo 接口,下面的图为这个接口反汇编内容 在上面的返回编结果中我们需要关注三个位置,第一个位置 sub esp, 0xD8,这条指令的含义是对 esp 寄存器中的内容减 0xD8,esp寄存器使我们的栈顶指针,栈又是向下增长的,所以对esp做减法相当于开辟了一段栈空间,而我们的局部变量就是要保存在这里开辟的栈空间上的 第二个位置 mov dword ptr ss:[ebp-0x8], 0x4,对栈上 ebp-0x8 处的位置上写入 0x04,ebp-0x8就是我们的局部变量,而0x04也就是我们的初始值了 第三个位置 mov edx, dword ptr ss:[ebp-0x8],是从栈 ebp-0x8 位置上,也就是我们的局部变量上读取数据并存储到寄存器 edx 中。那么为什么要将局部变量上的值存储到 edx 寄存器中呢?我们可以看到下一条指令是 push edx,这条指令的作用是将edx中的值作为printf的参数压到栈上,因为push指令的操作数不能是内存,所以需要先将值保存到 edx 寄存器中,再通过 edx 压入到栈上 我们可以发现静态局部变量就只有一个使用的语句,将静态变量中的值复制到了 ecx 寄存器中,那静态变量初始化的过程哪去了呢? 这是因为静态变量在程序编译的时候就已经完成了初始化的工作,如果静态变量初始化的值不为0,那么静态变量的地址会指向数据段,在编译时就将值直接写入到了数据段中,我们可以看到我们反汇编的结果中也确实指向了数据段,如果初始值为0,就会被分配到.bss段 我们可以看到const局部变量和普通的局部变量是一样的,那是如何做到const变量的值不可修改的呢?答案是const 变量不能修改是编译器做的检查,当发现修改const变量时就会提示编译错误 全局变量我们要看 global_variable_demo 接口 从上图中我们可以看出三种全局变量都在数据段,看起来是一样的,但是我们看一下变量的地址,g_global_init 的地址为 0xBAA020,g_static_global_int 的地址为 0xBAA024,g_const_global_int 的地址为 0xBA7B40,我们可以发现普通全局变量和静态全局变量的存储空间是挨着的,而const全局变量的地址就远了很多这是为什么呢? 我们来看一下内存布局 我们可以发现 g_global_init 和 g_static_global_int 在.data 段,该数据段是可写的,而const全局变量由于不可写入,所以被放在了只读数据段 .rdata 中 接下来要简单的说一下安全性问题,我们通过上面已经可以看到,程序的数据就保存在栈上和数据段中,我们可以很轻易的就行查找和篡改,那么我们如何防范我们的程序被人恶意分析数据和篡改呢? 我们可以使用 Virbox protector 工具对我们的程序进行保护,保护后的程序其他人就没有办法进行调试了,同时也可以让我们的程序变得无法分析,还有内存校验等等功能,让我们的程序和数据变的安全 ——END——前言
一只Demo
int g_global_int = 0x01;
staticint g_static_global_int = 0x02;
constint g_const_global_int = 0x03;
void local_variable_demo()
{
int local_int = 0x04;
staticint static_local_int = 0x05;
constint const_local_int = 0x06;
printf("%d, %d, %d\n", local_int, static_local_int, const_local_int);
}
void global_variable_demo()
{
printf("%d, %d, %d\n", g_global_int, g_static_global_int, g_const_global_int);
}
int main()
{
local_variable_demo();
global_variable_demo();
return0;
}局部变量
普通局部变量
静态局部变量
const 局部变量
全局变量
安全问题
CC++逆向分析之变量
本文来自投稿,不代表本站立场,如若转载,请注明出处:https://blog.firsource.cn/news/1825.html