码龄10年 暂无认证

34135
访问
1
等级

8
获赞
3
评论

最新评论

  • 20240228阿⑤

    积分乍获得

  • 20231124ziher

    666

  • 20230909八月老师

    什麼時候發佈易語言支持庫呢

三.结构体在内存中的表现形式

Heart 2023-04-25 09:00:19 发布 732

分类专栏: 数据分析 文章标签: C C++ 逆向 结构体内存布局

一.结构体

1.我们在之前讲过结构体struct 都知道struct 可以存放很多不同数据类型的数据

2.这必将导致一个问题出现

3.我们的结构体需要内存对齐

4.如果不对齐 会导致内存排列很错乱(除非一些特殊需求 比如:我们在逆向找数据的时候 变得有些困难 不能一眼看出是什么类型的数据)

5.好 这里我们给大家举个例子看一下

二.举例

1.我们在之前讲过 默认是8字节

#include #include "windows.h"
typedef struct  INFO
{
    char flag;
    int id;
    float fd;
}INFO;
INFO info = {'H',1001,666.66f};
int main()
{
    printf("%c-%d-%f\n", info.flag, info.id, info.fd);
    printf("Hello Heart");
    system("pause");
    return 0;
}

我们编译一下 用xdbg看一下在内存中的对齐是怎么样子的

2.我们附加XDBG

3.ctrl+G 输入_main 来到main函数

4.找到这个全局变量地址

20230519582158.png

5.观察结构体内存 注意:在xdbg这个内存窗口地址是 右到左 地址在增加 不是左到右 所以你会看到48在右边

573685710226452.png

6.这里我们为了好看 双击这个0049A000地址 可以看到偏移量

50875910246618.png

7.这个偏移量我们再内存对齐的时候已经给大家说过了

8.此时我们发现数据很整齐 这使得我们观察数据变得尤其的简单

9.有经验的同学也能立马看出这些数据的类型是什么 起码基本上不会差太多

三.举例

1.经过我们上面的发现 内存对齐是有优势的

2.但是上面也说过 我们可以改变内存对齐 来使内存存放不规律

3.好现在 我们改下内存对齐看看此时在内存的表现是怎么样的

4.只需要加上 #pragma pack(push,1) #pragma pack(pop)就行

#include #include "windows.h"
#pragma pack(push,1)//这里!
typedef struct  INFO
{
    char flag;
    int id;
    float fd;
}INFO;
#pragma pack(pop)//这里!
INFO info = {'H',1001,666.66f};
int main()
{
    printf("%c-%d-%f\n", info.flag, info.id, info.fd);
    printf("Hello Heart");
    system("pause");
    return 0;
}

5.我们这里修改的是1字节对对齐

6.重复上述举例1观察下内存

7.你会惊奇的发现这些值是什么啊!怎么看不懂!

497160511239287.png

8.我们一个一个的看 每个数据都是紧密的挨着一起的 这会使得我们观察数据很费劲

134400711235842.png

四.通过指针+偏移来获取结构体里面的值

1.这里我们暂时吧内存对齐设置为默认8

2.就算我们把对齐数设置为1 也能正确获取 因为我们借助了offsetof函数

#include #include "windows.h"
typedef struct INFO
{
    char flag;
    int id;
    float fd;
}INFO;
INFO info = {'H',1001,666.66f};
int main()
{
    char c = *((char*)(&info));
    printf("c=%c\n", c);
    int id = *((int*)((DWORD)(&info) + offsetof(INFO, id)));
    printf("id=%d\n", id);
    printf("%c-%d-%f\n", info.flag, info.id, info.fd);
    printf("Hello Heart");
    system("pause");
    return 0;
}

3.效果是一样的

4.但是实际上我们再找数据的时候 不知道结构体的类型长什么样的 因为我们的宏函数offsetof是需要知道变量名和结构体类型的

5.所以实际我们再数据中找的偏移就是这个函数算出来的偏移

五.总结

1.结构体的成员变量在结构体中排列的方式依据于对齐方式

2.结构体变量的地址就是结构体的首地址 也是我们结构体第一个成员变量的地址

3.我们的偏移量是依据与结构体首地址开始算的

4.设置内存对齐可以让结构体在内存中的排列方式变得不易于找数据


Heart1
0 0 上传作业
X
    网友评论 0条评论 0人参与
    请登陆会员1

    表情

    评论列表

×