数据结构逆向分析-Map

map是一个典型的二叉树结构,准确的来说是一个平衡二叉树或者红黑树,特点是数据存储是有序的存储。

参考侯杰老师的stl源码剖析,map里面采用的是RB-TREE也就是红黑树

map存储的数据是以键值对的形式来存储的,Key:Value

优势:查找数据效率高,因为是平衡二叉树

缺点:插入数据效率低,因为要插入后变成平衡二叉树。

开始分析:

采用比较简单的代码:

#include<map>
using std::map;
using std::pair;

int main()
{
map<int, int> MyMap;
int SizeMap = sizeof(MyMap);
MyMap.insert(pair<int, int>(1, 100));
MyMap.insert(pair<int, int>(2, 300));
MyMap.insert(pair<int, int>(3, 150));
MyMap.insert(pair<int, int>(4, 200));
MyMap.insert(pair<int, int>(5, 170));
MyMap.insert(pair<int, int>(6, 180));
MyMap.insert(pair<int, int>(7, 90));




return 0;
}

然后画图表示一下:这就是初始化一个map的内存图,从分析stl的经验上来看MyMap中的第一个指针指向的这个0081e5f8又指回去了好像stl容器都有个这个东西,猜测来讲没啥用。然后这个后面的0081F5F8很有可能是一个指向整个平衡二叉树的头,然后第三个000很有可能就是一个size来记录节点的个数,当然这是我们的猜测,还要看内存来说话。

执行第一条插入指令:

    MyMap.insert(pair<int, int>(1, 100));

成了这样:

再来猜测一下,首先这个MyMap的第一个字段肯定是没啥用了,然后最后一个字段确实是里面的大小,然后第二个字段指向的内容,很有可能是指向来了根节点,然后节点的内容里面,最后两个字段是来存放 key->value键值对的。有一些字段暂时不知道有啥用,继续往下弄几个看看。

执行第二条和第三条指令:

    MyMap.insert(pair<int, int>(2, 300));
MyMap.insert(pair<int, int>(3, 150));

首先这里的平衡二叉树应该是这样的:

如果所有箭头都标出来会比较乱,所以这里只用了一些关键的:

由此可以推出来,这个map第二个字段指向的应该是一个总领作用的结构体,其中第二个字段指向的是平衡二叉树的根节点,然后第一个和第三个字段是什么意思暂时不知道,最后一个结束字段的0101也不知道,然后数据节点的话,通过对根节点猜测,第一个字段应该指向的是左节点,第三个字段指向的是右节点。

目前的结果是这样:

再参考侯杰老师的stl源码剖析书后:

可以确定很多东西了:

根据侯杰老师的定义重新写代码分析:

由于目前只有cdcd后面哪两个字节的内容不知道了,这里我选择根据官方书重新写代码来观察这个字段的内容:

#include<map>
using std::map;
using std::pair;

int main()
{
map<int, int> MyMap;
int SizeMap = sizeof(MyMap);
MyMap.insert(pair<int, int>(5, 100));
MyMap.insert(pair<int, int>(6, 300));
MyMap.insert(pair<int, int>(8, 150));
MyMap.insert(pair<int, int>(7, 200));
MyMap.insert(pair<int, int>(11, 170));
MyMap.insert(pair<int, int>(10, 180));
MyMap.insert(pair<int, int>(12, 90));
MyMap.insert(pair<int, int>(13, 400));
MyMap.insert(pair<int, int>(15, 400));


return 0;
}

这里画图太麻烦,我只画比较关键的内容了:

可以看到内容只有0和1,我测试是平衡二叉树的平衡因子,但是不对,如果是平衡因子的画13为啥是0001,由于这个底层是红黑树,所以这里我猜是用来标记红黑的。

红黑树的性质:

规则1:节点是红色或黑色的;
规则2:根节点是黑色的;
规则3:每个叶子节点都是黑色的空节点(NIL节点);
规则4:每个红色节点的两个子节点都是黑色的(从每个叶子到根的所有路径上不可能有两个连续的红色节点);
规则5:从任一节点到其每个叶子节点的所有路径都包含相同数目的黑色节点;
将红黑树的节点默认颜色设置为红色,是为尽可能减少在插入新节点对红黑树造成的影响。

也就是说8肯定是黑色,那么默认是红色的情况下6,11是红色,而红色不能连续,红色的子节点必须是黑色,则5,7,10,13肯定是黑色,而默认是红色,且不会影响别的那么12,15也就是红色。

破案了:情况非常吻合,红色为0000,黑色为0001。

数据结构逆向分析-Map的更多相关文章

  1. 数据结构逆向分析-List

    数据结构逆向分析-List 首先STL中的List就是一个链表,但是肯定C++用了很多封装,所以这里我们来一探究竟. 开始 首先先写一些简单的分析的源代码: #include<iostream& ...

  2. 数据结构逆向分析-Vector

    数据结构逆向分析-Vector 这个应该是家喻户晓了的东西把,如果说C/C++程序员Vector都不用的话,可能就是一个不太好的程序员. Vector就是一个STL封装的动态数组,数组大家都知道是通过 ...

  3. C++反汇编与逆向分析技术揭秘

    C++反汇编-继承和多重继承   学无止尽,积土成山,积水成渊-<C++反汇编与逆向分析技术揭秘> 读书笔记 一.单类继承 在父类中声明为私有的成员,子类对象无法直接访问,但是在子类对象的 ...

  4. 一文了解安卓APP逆向分析与保护机制

    "知物由学"是网易云易盾打造的一个品牌栏目,词语出自汉·王充<论衡·实知>.人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不会知道."知物 ...

  5. Android逆向分析工具表

    逆向分析工具表 工具 描述 网址 androidterm Android Terminal Emulator http://code.google.com/p/androidterm/ droidbo ...

  6. RE-1 逆向分析基础

    逆向分析基础 0x01-0x0C 本笔记使用汇编指令为x86架构下汇编指令,ARM架构汇编指令不做介绍 0x01. 关于RE 逆向工程(Reverse Engineering RE) 逆向分析方法: ...

  7. 从Android设备中提取内核和逆向分析

    本文博客链接:http://blog.csdn.net/qq1084283172/article/details/57074695 一.手机设备环境 Model number: Nexus 5 OS ...

  8. 【C++】从零开始的CS:GO逆向分析1——寻找偏移与基址的方法

    [C++]从零开始的CS:GO逆向分析1--寻找偏移与基址的方法   前言:此文章主要用于提供方法与思路,fps游戏基本都能如此找偏移,文章里找的偏移比较少,主要用来演示寻找思路,文章的后记中会附一个 ...

  9. paip.提升性能---并行多核编程哈的数据结构list,set,map

    paip.提升性能---并行多核编程哈的数据结构list,set,map vector/copyonwritearraylist 都是线程安全的. 或者经过包装的list ::: collection ...

随机推荐

  1. Visio操作【未完】

    Visio 1.如何操作文档 新建基本框图和空白框图 单击基本框图打开后有模具 空白框图打开之后并没有形状 左下角发现有 更改纸张方向大小 自动调整大小: 如果我们选择形状进入到我们的页面,如果放到边 ...

  2. 1009 Product of Polynomials (25分) 晚上脑子就是容易僵住

    #include<iostream> using namespace std; struct { int a; double b; }poly[1001]; double a[2001]; ...

  3. ATM取款机优化需求的用例设计

    案例设计需求 有一个ATM取款系统,现对于取款功能进行了如何需求变更:碑只能取面额是100元(如取500,输出5张100元),现在功能修改为,可以取面额是10元.50元和100元的,其余功能不变,用户 ...

  4. Aspen.net core 身份认证

  5. docker ubuntu中文乱码

    docker ubuntu18.04 使用cat查看中文正常,使用vim查看中文乱码. 解决此问题需要修改"/etc/profile"文件. 1.修改前查看本地使用的语言环境: l ...

  6. 十七:使用JDBC处理MySQL大数据

    一.基本概念 大数据也称之为LOB(Large Objects),LOB又分为:clob和blob,clob用于存储大文本,blob用于存储二进制数据,例如图像.声音.二进制文等. 在实际开发中,有时 ...

  7. 深入浅出Mybatis系列(五)---配置详解之settings设置

    settings 中的设置是非常关键的,它们会改变 MyBatis 的运行时行为.下表描述了设置中各项的意图.默认值等. 设置参数 描述 有效值 默认值 cacheEnabled 该配置影响的所有映射 ...

  8. CNN的Pytorch实现(LeNet)

    CNN的Pytorch实现(LeNet)   上次写了一篇CNN的详解,可是累坏了老僧我.写完后拿给朋友看,朋友说你这Pytorch的实现方式对于新人来讲会很不友好,然后反问我说里面所有的细节你都明白 ...

  9. 解析ThreadPoolExecutor类是如何保证线程池正确运行的

    摘要:对于线程池的核心类ThreadPoolExecutor来说,有哪些重要的属性和内部类为线程池的正确运行提供重要的保障呢? 本文分享自华为云社区<[高并发]通过源码深度解析ThreadPoo ...

  10. jdbc操作mysql(一)

    java.sql包 在使用jdbc之前,我们先看看有关操作jdbc会用到的几个类和接口,通过查看官方文档可知 DriverManager:用于管理一组JDBC驱动程序的基本服务,即管理数据库中的所有驱 ...