

码龄10年
暂无认证
34135访问
1
等级
8获赞
3
评论
热门文章
-
一.某岛之人物对象及其加密函数解析
2147
-
一.《传奇M》装备栏遍历的突破口
1790
-
二.某龙端游中LUA的分析和调用
1539
-
一.《轩辕传奇》周围遍历之二叉树
1386
-
一.《UE4奥丁》人物最大属性
1331
最新评论
-
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.找到这个全局变量地址
5.观察结构体内存 注意:在xdbg这个内存窗口地址是 右到左 地址在增加 不是左到右 所以你会看到48在右边
6.这里我们为了好看 双击这个0049A000地址 可以看到偏移量
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.你会惊奇的发现这些值是什么啊!怎么看不懂!
8.我们一个一个的看 每个数据都是紧密的挨着一起的 这会使得我们观察数据很费劲
四.通过指针+偏移来获取结构体里面的值
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.设置内存对齐可以让结构体在内存中的排列方式变得不易于找数据


评论列表