大神论坛

找回密码
快速注册
查看: 622 | 回复: 0

[语言编程类] 大神论坛 逆向脱壳分析基础学习笔记十二 汇编 全局和局...

主题

帖子

5

积分

初入江湖

UID
20
积分
5
精华
威望
10 点
违规
大神币
68 枚
注册时间
2021-03-14 10:40
发表于 2021-03-14 18:14
本帖最后由 kay2kay 于 2021-03-14 18:14 编辑

本文为本人的滴水逆向破解脱壳学习笔记之一,为本人对以往所学的回顾和总结,可能会有谬误之处,欢迎大家指出。
陆续将不断有笔记放出,希望能对想要入门的萌新有所帮助,一起进步


所有笔记链接:

大神论坛 逆向脱壳分析基础学习笔记一 进制篇
大神论坛 逆向脱壳分析基础学习笔记二 数据宽度和逻辑运算
大神论坛 逆向脱壳分析基础学习笔记三 通用寄存器和内存读写
大神论坛 逆向脱壳分析基础学习笔记四 堆栈篇
大神论坛 逆向脱壳分析基础学习笔记五 标志寄存器 
大神论坛 逆向脱壳分析基础学习笔记六 汇编跳转和比较指令
大神论坛 逆向脱壳分析基础学习笔记七 堆栈图(重点)(需登录才能访问)
大神论坛 逆向脱壳分析基础学习笔记八 反汇编分析C语言
大神论坛 逆向脱壳分析基础学习笔记九 C语言内联汇编和调用协定
大神论坛 逆向脱壳分析基础学习笔记十 汇编寻找C程序入口(需登录才能访问)
大神论坛 逆向脱壳分析基础学习笔记十一 汇编C语言基本类型
大神论坛 逆向脱壳分析基础学习笔记十二 汇编 全局和局部 变量(需登录才能访问)
大神论坛 逆向脱壳分析基础学习笔记十三 汇编C语言类型转换(需登录才能访问)
大神论坛 逆向脱壳分析基础学习笔记十四 汇编嵌套if else(需登录才能访问)
大神论坛 逆向脱壳分析基础学习笔记十五 汇编比较三种循环(需登录才能访问)
大神论坛 逆向脱壳分析基础学习笔记十六 汇编一维数组(需登录才能访问)
大神论坛 逆向脱壳分析基础学习笔记十七 汇编二维数组 位移 乘法(需登录才能访问)
大神论坛 逆向脱壳分析基础学习笔记十八 汇编 结构体和内存对齐(需登录才能访问)
大神论坛 逆向脱壳分析基础学习笔记十九 汇编switch比较if else(需登录才能访问)
大神论坛 逆向脱壳分析基础学习笔记二十 汇编 指针(一)(需登录才能访问)
大神论坛 逆向脱壳分析基础学习笔记二十一 汇编 指针(二)(需登录才能访问)
大神论坛 逆向脱壳分析基础学习笔记二十二 汇编 指针(三)(需登录才能访问)
大神论坛 逆向脱壳分析基础学习笔记二十三 汇编 指针(四)(需登录才能访问)
大神论坛 逆向脱壳分析基础学习笔记二十四 汇编 指针(五) 系列完结(需登录才能访问)

更多逆向脱壳资源,请访问  大神论坛

全局变量和局部变量

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

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

区域功能区域属性
代码区存储程序要执行的代码可读可执行
堆栈存储参数、局部变量、临时数据操作系统分配
动态申请的、大小可变的可读可写
全局变量区存储全局变量可读可写
常量区存储常量只读

全局变量

  • 全局变量在程序编译完成后地址就已经确定下来了,只要程序启动,全局变量就已经存在了,启动后里面是否有值取决于声明时是否给定了初始值,如果没有,默认为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;
}


image-20210302201003408

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)]也就是全局变量地址里存储的内容时,可以看到

image-20210302201051165

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

不懂mainCRTStartup的可以去回顾逆向基础笔记十 汇编寻找C程序入口

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

image-20210302204819190

image-20210302204729390

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

返回顶部