【Android安全-魔改MD5 后续分析】此文章归类为:Android安全。
算法的流程等信息都发布在上一篇文章了
1 | https: / / bbs.kanxue.com / thread - 285248.htm
|
但是上次在本地没有算出来一样的值,本文进行补充
上文魔改点
回顾一下上文的两个魔改点
魔改点1
魔改点2
分析方法
这次不在IDA中硬看了,直接使用 unidbg trace一份日志
1 2 3 4 5 6 7 8 9 10 | String traceFile = "myTraceCodeFile" ;
PrintStream traceStream = null ;
try {
traceStream = new PrintStream( new FileOutputStream(traceFile), true );
} catch (FileNotFoundException e) {
e.printStackTrace();
}
emulator.traceCode(module.base, module.base + module.size).setRedirect(traceStream);
emulator.traceCode(module.base + 0x8230 ,module.base + 0x9834 );
|
然后标准MD5代码,单步调试,一步步看结果哪里不对
没有技巧,纯头铁,就一步步执行再挨个对比结果,每个结果结算都跟trace的相应位置的日志进行对比,一步步还原
这次发现了新的魔改点
新魔改点
新魔改点1
在前面几轮没有问题,但是对比到后面就会慢慢发现,长度不对了起来
标准MD5(Py版) 这里结果长度一直都是8位
因为无论是FF、GG、HH、II 计算中都有 & 0xFFFFFFFF
but,在trace日志中随便找个靠后的变量赋值
鼠标放在变量赋值上,然后按TAB键转汇编
然后就可以看到地址是 0x8e60
然后在trace日志中搜索8e60,可以看到结果 0x5ec99fddc9848902 长度明显比原来的8长一倍
所以在这里 新的魔改点1 &0xFFFFFFFF 改成 &0xFFFFFFFFFFFFFFFF
新魔改点2
由于每轮计算都有循环左移,这里可以看下标准的循环左移
1 2 | def left_rotate(x, amount):
return ((x << amount) | (x >> ( 32 - amount))) & 0xFFFFFFFF
|
这里可以看到左移计算 先左移amount然后与右移32 - amount的结果异或,左移加上右移的数字应该等于32
然后观察可以发现
他的amount居然是32,然后右移的27,而且左移变成了乘法
同样的后面可以看到相同的魔改
踩坑注意点
注意点1
本来感觉没啥问题了,但是一跑,结果不一样,大概看了下,前面的结果都没事,但是到最后就不对了
经过一步步单步调试对比结果,发现之前的一个魔改点
1 | v124 = (((word_1 + v116 + ((v123 | ~v118) ^ v121) + 0x85845DD1 ) << 21 ) | ((word_1 + v116 + ((v123 | ~v118) ^ v121) + 0x85845DD1 ) >> 11 ))
|
这一步的运算结果不一致,但是我看每个入参数值都是一样的,而且手动逐步运算发现结果没问题,但是整行运行就不对,看了下括号也没问题。
最后直接把异或右边的(words[1] + v116 + ((v123 | ~v118) ^ v121)
拆开赋值变量问题解决
注意点2
虽然前面的64轮计算长度都是16,也就是每一轮计算结果要 & 0xFFFFFFFFFFFFFFFF,但是到最后运算结果与初始IV相加时,长度又变回了8,也就是 & 0xFFFFFFFF,否则结果不一致。
总结(从这次分析学到的东西)
先放结果把
一、魔改算法经验
如果魔改算法不只改了K表、初始IV这种常数;涉及计算过程修改的,就别当标准算法挨个对比了,太费眼睛了,而且万一粗心跳过一点,直接g;
直接当非标准算法扣下来得了,我对比了两天才踩完坑,如果复制粘贴扣算法几十分钟搞定(不过本次分析是为了学习md5还是自己看看把)。
二、分析经验
多利用trace日志,我之前是unidbg逐步调试然后挨个看寄存器值,这样太不方便了,累挺,不如直接看trace日志,不用管格式啥的
三、算法还原尽量别用Java
类型转换太折磨了,类型转换太折磨了,类型转换太折磨了
重要的事情说三遍
更多【Android安全-魔改MD5 后续分析】相关视频教程:www.yxfzedu.com