1.Redis7.0源码阅读:哈希表扩容、哈希缩容以及rehash
2.mimikatz源码分析-lsadump模块(注册表)
3.String源码分析(1)--哈希篇
4.Hermes源码分析(二)——解析字节码
5.ç»è¿å¡å·´DUMP LSASSå
å
6.Fastjson库parseObject/parseArray方法:表字段名和实体类属性的值游智能匹配研究(源码向)
Redis7.0源码阅读:哈希表扩容、缩容以及rehash
当哈希值相同发生冲突时,戏源希算戏Redis 码哈使用链表法解决,将冲突的法游键值对通过链表连接,但随着数据量增加,哈希c 通达源码冲突加剧,值游查找效率降低。戏源希算戏负载因子衡量冲突程度,码哈负载因子越大,法游冲突越严重。哈希为优化性能,值游Redis 戏源希算戏需适时扩容,将新增键值对放入新哈希桶,码哈减少冲突。法游
扩容发生在 setCommand 部分,其中 dictKeyIndex 获取键值对索引,判断是否需要扩容。_dictExpandIfNeeded 函数执行扩容逻辑,条件包括:不在 rehash 过程中,哈希表初始大小为0时需扩容,或负载因子大于1且允许扩容或负载因子超过阈值。
扩容大小依据当前键值对数量计算,如哈希表长度为4,实际有9个键值对,扩容至(最小的2的n次幂大于9)。子进程存在时,dict_can_resize 为0,反之为1。fork 子进程用于写时复制,100套特效源码确保持久化操作的稳定性。
哈希表缩容由 tryResizeHashTables 判断负载因子是否小于0.1,条件满足则重新调整大小。此操作在数据库定时检查,且无子进程时执行。
rehash 是为解决链式哈希效率问题,通过增加哈希桶数量分散存储,减少冲突。dictRehash 函数完成这一任务,移动键值对至新哈希表,使用位运算优化哈希计算。渐进式 rehash 通过分步操作,减少响应时间,适应不同负载情况。定时任务检测服务器空闲时,进行大步挪动哈希桶。
在 rehash 过程中,数据查询首先在原始哈希表进行,若未找到,则在新哈希表中查找。rehash 完成后,哈希表结构调整,原始表指向新表,新表内容返回原始表,实现 rehash 结果的整合。
综上所述,Redis 通过哈希表的扩容、缩容以及 rehash 动态调整哈希桶大小,优化查找效率,windows nt 3.5 源码确保数据存储与检索的高效性。这不仅提高了 Redis 的性能,也为复杂数据存储与管理提供了有力支持。
mimikatz源码分析-lsadump模块(注册表)
mimikatz是一款内网渗透中的强大工具,本文将深入分析其lsadump模块中的sam部分,探索如何从注册表获取用户哈希。
首先,简要了解一下Windows注册表hive文件的结构。hive文件结构类似于PE文件,包括文件头和多个节区,每个节区又有节区头和巢室。其中,巢箱由HBASE_BLOCK表示,巢室由BIN和CELL表示,整体结构被称为“储巢”。通过分析hive文件的结构图,可以更直观地理解其内部组织。
在解析过程中,需要关注的关键部分包括块的签名(regf)和节区的签名(hbin)。这些签名对于定位和解析注册表中的数据至关重要。
接下来,深入解析mimikatz的解析流程。在具备sam文件和system文件的情况下,主要分为以下步骤:获取注册表system的句柄、读取计算机名和解密密钥、获取注册表sam的句柄以及读取用户名和用户哈希。若无sam文件和system文件,mimikatz将直接通过官方API读取本地机器的注册表。
在mimikatz中,虚拟网卡游戏源码会定义几个关键结构体,包括用于标识操作的注册表对象和内容的结构体(PKULL_M_REGISTRY_HANDLE)以及注册表文件句柄结构体(HKULL_M_REGISTRY_HANDLE)。这些结构体包含了文件映射句柄、映射到调用进程地址空间的位置、巢箱的起始位置以及用于查找子键和子键值的键巢室。
在获取注册表“句柄”后,接下来的任务是获取计算机名和解密密钥。密钥位于HKLM\SYSTEM\ControlSet\Current\Control\LSA,通过查找键值,将其转换为四个字节的密钥数据。利用这个密钥数据,mimikatz能够解析出最终的密钥。
对于sam文件和system文件的操作,主要涉及文件映射到内存的过程,通过Windows API(CreateFileMapping和MapViewOfFile)实现。这些API使得mimikatz能够在不占用大量系统资源的情况下,方便地处理大文件。
在获取了注册表系统和sam的句柄后,mimikatz会进一步解析注册表以获取计算机名和密钥。对于密钥的获取,mimikatz通过遍历注册表项,定位到特定的键值,并通过转换宽字符为字节序列,最终组装出密钥数据。
接着,解析过程继续进行,获取用户名和用户哈希。在解析sam键时,mimikatz首先会获取SID,kol网站对接源码然后遍历HKLM\SAM\Domains\Account\Users,解析获取用户名及其对应的哈希。解析流程涉及多个步骤,包括定位samKey、获取用户名和用户哈希,以及使用samKey解密哈希数据。
对于samKey的获取,mimikatz需要解密加密的数据,使用syskey作为解密密钥。解密过程根据加密算法(rc4或aes)有所不同,但在最终阶段,mimikatz会调用系统函数对数据进行解密,从而获取用户哈希。
在完成用户哈希的解析后,mimikatz还提供了一个额外的功能:获取SupplementalCreds。这个功能可以解析并解密获取对应用户的SupplementalCredentials属性,包括明文密码及哈希值,为用户提供更全面的哈希信息。
综上所述,mimikatz通过解析注册表,实现了从系统中获取用户哈希的高效功能,为内网渗透提供了强大的工具支持。通过深入理解其解析流程和关键结构体的定义,可以更好地掌握如何利用mimikatz进行深入的安全分析和取证工作。
String源码分析(1)--哈希篇
本文基于JDK1.8,从Java中==符号的使用开始,解释了它判断的是对象的内存地址而非内容是否相等。接着,通过分析String类的equals()方法实现,说明了在比较字符串时,应使用equals()而非==,因为equals()方法可以准确判断字符串内容是否相等。
深入探讨了String类作为“值类”的特性,即它需要覆盖Object类的equals()方法,以满足比较字符串时逻辑上相等的需求。同时,强调了在覆盖equals()方法时也必须覆盖hashCode()方法,以确保基于散列的集合(如HashMap、HashSet和Hashtable)可以正常工作。解释了哈希码(hashcode)在将不同的输入映射成唯一值中的作用,以及它与字符串内容的关系。
在分析String类的hashcode()方法时,介绍了计算哈希值的公式,包括使用这个奇素数的原因,以及其在计算性能上的优势。进一步探讨了哈希碰撞的概念及其产生的影响,提出了防止哈希碰撞的有效方法之一是扩大哈希值的取值空间,并介绍了生日攻击这一概念,解释了它如何在哈希空间不足够大时制造碰撞。
最后,总结了哈希碰撞与散列表性能的关系,以及在满足安全与成本之间找到平衡的重要性。提出了确保哈希值的最短长度的考虑因素,并提醒读者在理解和学习JDK源码时,可以关注相关公众号以获取更多源码分析文章。
Hermes源码分析(二)——解析字节码
前面一节 讲到字节码序列化为二进制是有固定的格式的,这里我们分析一下源码里面是怎么处理的这里可以看到首先写入的是魔数,他的值为
对应的二进制见下图,注意是小端字节序
第二项是字节码的版本,笔者的版本是,也即 上图中的4a
第三项是源码的hash,这里采用的是SHA1算法,生成的哈希值是位,因此占用了个字节
第四项是文件长度,这个字段是位的,也就是下图中的为0aa,转换成十进制就是,实际文件大小也是这么多
后面的字段类似,就不一一分析了,头部所有字段的类型都可以在BytecodeFileHeader.h中看到,Hermes按照既定的内存布局把字段写入后再序列化,就得到了我们看到的字节码文件。
这里写入的数据很多,以函数头的写入为例,我们调用了visitFunctionHeader方法,并通过byteCodeModule拿到函数的签名,将其写入函数表(存疑,在实际的文件中并没有看到这一部分)。注意这些数据必须按顺序写入,因为读出的时候也是按对应顺序来的。
我们知道react-native 在加载字节码的时候需要调用hermes的prepareJavaScript方法, 那这个方法做了些什么事呢?
这里做了两件事情:
1. 判断是否是字节码,如果是则调用createBCProviderFromBuffer,否则调用createBCProviderFromSrc,我们这里只关注createBCProviderFromBuffer
2.通过BCProviderFromBuffer的构造方法得到文件头和函数头的信息(populateFromBuffer方法),下面是这个方法的实现。
BytecodeFileFields的populateFromBuffer方法也是一个模版方法,注意这里调用populateFromBuffer方法的是一个 ConstBytecodeFileFields对象,他代表的是不可变的字节码字段。
细心的读者会发现这里也有visitFunctionHeaders方法, 这里主要为了复用visitBytecodeSegmentsInOrder的逻辑,把populator当作一个visitor来按顺序读取buffer的内容,并提前加载到BytecodeFileFields里面,以减少后面执行字节码时解析的时间。
Hermes引擎在读取了字节码之后会通过解析BytecodeFileHeader这个结构体中的字段来获取一些关键信息,例如bundle是否是字节码格式,是否包含了函数,字节码的版本是否匹配等。注意这里我们只是解析了头部,没有解析整个字节码,后面执行字节码时才会解析剩余的部分。
evaluatePreparedJavaScript这个方法,主要是调用了HermesRuntime的 runBytecode方法,这里hermesPrep时上一步解析头部时获取的BCProviderFromBuffer实例。
runBytecode这个方法比较长,主要做了几件事情:
这里说明一下,Domain是用于垃圾回收的运行时模块的代理, Domain被创建时是空的,并跟随着运行时模块进行传播, 在运行时模块的整个生命周期内都一直存在。在某个Domain下创建的所有函数都会保持着对这个Domain的强引用。当Domain被回收的时候,这个Domain下的所有函数都不能使用。
未完待续。。。
ç»è¿å¡å·´DUMP LSASSå å
æè§æè¿è¢«é®çæå¤çä¸ä¸ªé®é¢å°±æ¯å¨å ç½æ¨ªå移å¨çè¿ç¨ä¸æä¹ç»è¿ä¸äºææ¯è½¯ä»¶ï¼æ¯å¦å¡å·´æ¯åºï¼æ¥è·åLSASSè¿ç¨éé¢ç¨æ·çä¸äºå¯ç åå¸å¼ï¼ä¸é¢å°±ä»ç»ä¸ç§æç®åçæ¹æ³ãè¿éçç»è¿åçå°±æ¯è°ç¨AddSecurityPackageAå½æ°æ¥è®©LSASSè¿ç¨ä¸»å¨å è½½æ们æä¾çDLLæ件ï¼èå¨DLLå è½½åä¼ç´æ¥DUMPèªå·±å®¿ä¸»è¿ç¨LSASSçå åï¼ä»¥æ¤æ¥æåç»è¿æ软çéå¶ã
Talk is cheap. Show me the code!
ä¸é¢å°±æ¯å è½½å¨SSPæ ¸å¿æºç ï¼
åä¸é¢å°±æ¯DLLæ ¸å¿æºç ï¼
æ»çæ¥è¯´ï¼æ ¸å¿æºç ä¸è¶ è¿è¡ã
Fastjson库parseObject/parseArray方法:表字段名和实体类属性的智能匹配研究(源码向)
项目中,数据来源从数据库转向HTTP请求获取JSON,面对无需mybatis映射的问题,团队成员产生了疑问:在未配置映射的情况下,实体类属性的驼峰命名与JSON键的任意书写为何能实现智能匹配?
深入分析Fastjson库源码,发现其确实具备智能匹配机制。以parseArray方法为例,首先解析JSON数据,其核心在于文本解析器lexer,它与智能匹配功能紧密相关。最终,解析流程导向JavaBeanDeserializer类中的parseField方法,此方法是智能匹配的关键所在。
进入parseField方法,可窥见其分段处理逻辑:首先通过TypeUtils工具类的fnv1a__lower和fnv1a__extract方法处理JSON键,通过哈希值比较实现初步匹配。fnv1a__extract通过去除下划线、短横线及大写字符,实现字符格式化处理,以适应常见的驼峰命名规则。
进一步深入,smartMatch方法在处理过程中,先通过fnv1a__lower进行大小写转换,再利用Arrays.binarySearch进行二分查找,以高效定位匹配项。当查找失败,即返回负值时,通过fnv1a__extract方法进一步去除下划线和短横线,实现对标准命名规则的适应。
增加理解维度,smartMatch方法后续逻辑涉及对特定前缀如“is”的处理,允许在以“is”开头的键匹配时,跳过“is”部分进行匹配,确保JSON中的“isName”也能与数据表字段正确关联。
综上,Fastjson库在反序列化过程中,通过一系列逻辑处理实现对表字段名和实体类属性的智能匹配。具体步骤如下:
1. 首先,将JSON键转为小写,检查是否直接匹配表字段。若匹配,后续处理;若未匹配,继续下一步。
2. 然后,去除JSON键中的下划线和短横线,转为小写,再次检查与表字段的匹配情况。如匹配,后续处理;若未匹配且键以“is”开头,执行第三步。
3. 最终,对于以“is”开头的键,在去除“is”后再次尝试匹配,确保所有可能的匹配关系得到考虑。