Windows逆向安全(一)之基础知识(六)

全局变量和局部变量

在提及全局变量和局部变量之前,需要先谈谈程序运行时在内存中的状态

任何一个程序在运行时都会把内存分成如下几块区域:

在这里插入图片描述

全局变量

  • 全局变量在程序编译完成后地址就已经确定下来了,只要程序启动,全局变量就已经存在了,启动后里面是否有值取决于声明时是否给定了初始值,如果没有,默认为0
  • 全局变量的值可以被所有函数所修改,里面存储的是最后一次修改的值.
  • 全局变量所占内存会一直存在,直到整个进程结束.
  • 全局变量的反汇编识别:
MOV  寄存器,byte/word/dword ptr ds:[0x12345678]

上面的0x12345678是固定的地址,每次程序启动都不变

通过寄存器的宽度,或者byte/word/dword 来判断全局变量的宽度

  • 全局变量就是所谓的基址

局部变量

  • 局部变量在程序编译完成后并没有分配固定的地址
  • 在所属的方法没有被调用时,局部变量并不会分配内存地址,只有当所属的程序被调用了,才会在堆栈中分配内存
  • 当局部变量所属的方法执行完毕后,局部变量所占用的内存将变成垃圾数据.局部变量消失
  • 局部变量只能在方法内部使用,函数A无法使用函数B的局部变量
  • 局部变量的反汇编识别
    [ebp-4]
    [ebp-8]
    [ebp-0xC]

例子

#include "stdafx.h"
//全局变量
int global=0x610;
int main(int argc, char* argv[])
{
    //局部变量
        int temp=0x160;

        global=global+temp;

        return 0;
}

在这里插入图片描述

4:    #include "stdafx.h"
5:    //全局变量
6:    int global=0x610;
7:    int main(int argc, char* argv[])
8:    {
00401010   push        ebp
00401011   mov         ebp,esp
00401013   sub         esp,44h
00401016   push        ebx
00401017   push        esi
00401018   push        edi
00401019   lea         edi,[ebp-44h]
0040101C   mov         ecx,11h
00401021   mov         eax,0CCCCCCCCh
00401026   rep stos    dword ptr [edi]
9:        //局部变量
10:       int temp=0x160;
00401028   mov         dword ptr [ebp-4],160h
11:
12:       global=global+temp;
0040102F   mov         eax,[global (00428a64)]
00401034   add         eax,dword ptr [ebp-4]
00401037   mov         [global (00428a64)],eax
13:
14:       return 0;
0040103C   xor         eax,eax
15:   }
0040103E   pop         edi
0040103F   pop         esi
00401040   pop         ebx
00401041   mov         esp,ebp
00401043   pop         ebp
00401044   ret

我们可以看到相关代码在这里:

9:        //局部变量
10:       int temp=0x160;
00401028   mov         dword ptr [ebp-4],160h
11:
12:       global=global+temp;
0040102F   mov         eax,[global (00428a64)]
00401034   add         eax,dword ptr [ebp-4]
00401037   mov         [global (00428a64)],eax

我们可以很清楚地看到局部变量是直接保存在[ebp-4]也就是堆栈中的

而全局变量则是保存在一个固定的内存地址00428a64里

同时在断点刚断下的时候,就是还没运行上面的代码时,观察[global (00428a64)]也就是全局变量地址里存储的内容时,可以看到

在这里插入图片描述
我们全局变量已经初始化并被赋值了,观察整个main函数的反汇编代码,我们并没有看到全局变量赋值相关的语句,但这并不能说明程序在运行前就已经赋值了,别忘了也有可能是在mainCRTStartup中将这里初始化的,为了印证这一点,我们直接将程序用OD打开,然后会在mainCRTStartup函数执行前断下,以此来验证是否是一打开程序全局变量就已经初始化了

输入之前全局变量的地址,然后查看

在这里插入图片描述
在这里插入图片描述

可以观察到左下角数据窗口里,我们的全局变量已经初始化了,验证完毕

posted @ 2023-03-20 03:34  私ははいしゃ敗者です  阅读(7)  评论(0编辑  收藏  举报  来源