一天一个宏指令
在 IDA 反编译中,编译器计算出来的 习语 会通过IDA 反序列为 特殊的指令,这个叫 宏指令 这块的内容 也是很重要的内容,因为很多东西都是离不开这部分的内容 进行分析逻辑
**CFADD **指令
**这个 CFADD 指令的 简单解释是 **返回两个参数相加后的进位标志位
直接用当前的 案例进行解释,例如说,在当前案例中 有下述代码块
v7 = v24;
v8 = __CFADD__((_DWORD)v24, 8 * a3);
刚才 已经说了,CFADD 指令就是 当前 两个操作参数 进行相加的操作,那么 其实可以看看 对应的Trace 日志
[libCrypt.so 0x01e1c] 0x40001e1c: "adds w8, w9, w21, lsl #3" w9=0x0 w21=0x6 => nzcv: N=0, Z=0, C=0, V=0 w8=0x30
简单的分析已经得知,w21 实际上就是 输入的明文长度 我们入参输入的是 123456,那么 对应的 w21是0x6
在 伪代码中 显示的是 **8*a3 在汇编中(逆向多是以汇编为主) ** lsl #3 那么就是 把原本输入的 w21 左移 << 3
再加上 **w9 **得出最终的结果 **w8 ** 已知 **w9 **是 **0, **那么简单来计算一下 print(6<<3)
对比一下, 符合Trace 出来的日志, 0x30 , 那么现在就又多掌握了一个基本的 宏指令 CDADD
**ROL4 **指令
再多讲一个,ROL4 指令 简单解释就是 循环左移
可以记忆一个小细节问题 部分加密算法是 全局贯穿着 循环左移的使用 例如
- MD5 主要使用 循环左移(ROL)
- SHA-1/SHA-256 也使用 ROL
- SM3 (国密3) 也使用 循环左移
def rol(num, count):
#
# 循环左移
"""
:param num:
:param count:
:return:
"""
b = (num & 0xffffffff) << count
return (b & 0xffffffff) + (b >> 32)
MD5的魔改方向
在 如今 安卓逆向的 行业来说,各种卷王 层出不跌。那么 魔改算法,就是某些卷王提出的一些方案,让保护提升安全性
这里呢 就简单介绍了一下 加密常数表的修改和四个初始化向量的修改,其他的内容,可以关注公众号
加群,后面会有更多的魔改/OLLVM/小众算法的实战内容,文章,视频分享
加密常数表修改
现在 结合 标准 MD5 加密的代码 去看一看 什么是 加密码表的修改
标准常数表 T
MD5 加密 标准的常数表是 64 个常数,这也是 MD5 加密比较明显的特征点,结合该案例去看一看,就简单结合 Trace 去看一看。
例如 在该案例的 Sub_AD8 函数中 就能发现大量的计算 如果细心一点就能看出来,常数表是 64 个常数,那么实际上 最终的轮计算也是分为 64 调用
这 **64 ** 次调用 可以简单的称之为 **Round 1…4 **
Round 1 | 逻辑函数 ff | 16 轮次 |
---|---|---|
Round 2 | 逻辑函数 gg | 16 轮次 |
Round 3 | 逻辑函数 hh | 16 轮次 |
Round 4 | 逻辑函数 ii | 16 轮次 |
那么 现在就结合 Trace 日志 简单的 看看 每个轮次的 加密的是 T 常量表里面的内容 是否是被修改过的 我们简单的去找 两三个位置吧
任意挑了 几个位置的 **T **表中的 常量 直接去 Trace 里面 搜一下,就很明显,都是存在的,那么其实就可以判断,T 表应该大概率没有被修改过的
修改 T 表的 魔改方式 其实是 频率 很高的,相对来说 技术成本低,就很容易出现在 魔改 MD5 的场景下
四个初始化向量修改
要 谈论 魔改之前,还是应该先看一看 标准情况下,四个初始化向量 是什么?
A = 0x67452301 B = 0xefcdab89 C = 0x98badcfe D = 0x10325476
那么 现在知道了 四个初始化的 IV 的值了 ,现在就应该要知道,这四个值 应该是用到哪里,怎么去找? 在这里我 写一个 示意图
初始状态:A=0x67452301, B=0xEFCDAB89, C=0x98BADCFE, D=0x10325476
===============================================================
处理第1个512-bit块:
运行64轮压缩函数 → 更新A/B/C/D
将新A/B/C/D加到旧值上 → 得到新的链式值
===============================================================
处理第2个512-bit块:
用新的A/B/C/D继续压缩 → 再次更新 → 再次累加
===============================================================
...
处理完最后一块:
最终A/B/C/D → 拼接 → 128-bit MD5哈希
那么 就已经 简单知道了 四个初始化的 IV 是用到了 与每一个 消息块计算的过程中,但是 四个初始化的 IV 会变化吗?会变化的!
这个操作 还是非常明显的 在 MD5 加密的末尾 是有一个明显的 四个初始化向量 写回 的操作 ,那么 现在要做的事情就是 根据伪代码去定位疑似写回位置
四个 初始化 IV 写回的位置是在 标准 MD5 加密的末尾,那么 同样 我们也可以去看 该 MD5 伪代码的末尾…
*a2,a2[1],a[2],a2[3]
这个 很明显是一个入参值,那么就 Hook 简单的看一看
这里呢 要注意一下 在内存中是以小端序的形式体现出来的,a2 的入参是 看前面的 16 个字节 每四个字节分为一组,第一轮次的初始化向量是没问题的
但是 在这里 第二轮次 就已经发现 四个初始化的 IV 是被修改的 已经变了, 先不管这里的地方 继续往下看看。
经过 简单的分析 得知,入参为
"bcae572b84d20c385d6d9d2d7d9e645da29da3c0user/login18953675221WA89qByLlDeaGjmVNzXm/w=="
经过了 三轮的 MD5 加密 四个 IV 其中 第一轮是正常的,第二轮是被修改的,第三轮是 正常的
轮函数逻辑变换修改
加密前填充的修改
加密后消息体的破坏
逻辑分析
在 分析 里面逻辑加密之前呢 我们已经知道 有经过了 三次的 MD5 加密,那么 想一想,最终加密输出的值是一个 32 位的长度,但是有三次 MD5 加密的操作,那么三次的 MD5 肯定不会 平白无故 的出现,那么 现在应该做的事情就是 输出 三次 MD5 加密的结果
加密轮次 | 四个初始化 IV | 加密结果 |
---|---|---|
第一轮 MD5 | 01 23 45 67 89 AB CD EF FE DC BA 98 76 54 32 10 | 09a03358 |
第二轮 MD5 | 09 A0 33 58 DA 58 1B E6 4E 42 9B CF CC 19 55 A3 | 4b8e8dd8 |
第三轮 MD5 | 01 23 45 67 89 AB CD EF FE DC BA 98 76 54 32 10 | eae2f8f6 |
上面可能有些是我写的有问题,别问,问就是 看的眼睛花
第一次 MD5
那么 实际上 就是 发现,第一次加密出来的结果 实际上 就是 第二次加密的时候 使用的 四个初始化 IV 那么 我们应该尝试一下 进行 第一次 MD5 加密
bcae572b84d20c385d6d9d2d7d9e645da29da3c0user/login18953675221WA8
===========MD5===========
a5a18a787d4d84316767a34df258103e
调用 标准的 MD5 之后 发现 结果还是不一样,现在就要思考,为什么会不一样?到底是还有哪里被魔改了? 现在对比一下 标准情况下 加密前的消息体
有点 明显啊 他就取了 前 64 个字节 对应就是 512bit 后面不够 64 个字节的 也没有填充 直接 **delete **
所以 现在就可以 尝试一下 第一次加密了 就按照 原本他的逻辑 取去,但是需要,需要你原本的明文数据就要够 64 个字节 如果不够的话 就会报错
贴一下辅证
"add w22, w7, w24" w7=0x38415731 w24=0x2fde0b31 => w22=0x681f6262
第二次 MD5
现在 开始 讲一下 第二次 MD5
这里 我就简单讲一讲 需要注意点的 就是 第二次加密的时候 4 个初始化的 IV 就是 第一次 MD5 加密的结果
加密数据的内容就是 传输的明文数据 第一次 MD5 是取前 64 位 第二次加密的就是 前 64 位后面的内容 也就是 [64:str_len]
但是 大家看 这个明文数据的数据 是有填充的 看它的 前 64 个字节 有没有发现的 多了一个 02?
这块的 内容 我就直接说了, 就不做过多详细的讲解了,认真看一看 伪代码 就能看出来,实际上 他是有一个判断的 如果长度 判断 256 大于小于 如果 然后会在 **填充 a8 的后面 加入 0x02 或者是 0x03 **
第三次 MD5
我就不在这里多赘述了,后面会有视频在 B 站上发出,后面如果对这部分感兴趣的 都可以关注一下,第三次的 MD5 就是一个标准的 MD5 第二次 MD5 结果 进行 Base64 编码 然后进行 MD5 加密 直接看一下
通过私信联系获取加群方式
通过私信联系获取加群方式
通过私信联系获取加群方式