ollvm CrackMe算法分析
2020-04-02 22:16:16 Author: bbs.pediy.com(查看原文) 阅读量:275 收藏

[原创] ollvm CrackMe算法分析

5小时前 245

题目来源:看雪论坛培训班

该题看法:样本是经过ollvm混淆后的 基本逻辑很混乱 会添加大量取反运算+固定数值 导致一条简单运算会变成


原本应该大概这样

unsigned int v90 = (~0xa3& 0x5E58FB3C | 0xa3& 0xA1A704C3) ^ (~0x33& 0x5E58FB3C | 0x33 & 0xA1A704C3);    //ret 90

然后继续提取就行了吧~

基本解题思路:定位到关键位置 关键参数结果数值 提取无意义运算

(本人只是学员,只是实验过程中自己的一些看法) 

拿到样本 先运行看看


发现一个点击按钮 生成一段密钥 用jadx打开apk整体看看


 加载hello-jni.so 有一个public native String sign1(String str); 函数 点击按钮调用 参数为随机生成的16位字符


Ok进入 so文件看看吧 用ida 打开 

定位到 public native String sign1(String str); 搜索导出函数并没有 应该动态调试 进入JNI_OnLoad

发现混淆到不行样子直接 用frida hook RegisterNatives 注册函数吧(用网上搜索)



把应用调试模式启动 用frida附加上启动 (注意要打开ddms)具体操作论坛有 


jni 函数 sign1 offset: 0x10be8 注册地址找到了 那直接开干吧 跳转到  0x10be8


用idapro动态调试初步跑了一下参数记录 发现 sub_1494C4(&Out_Md5_Buff, 16LL, &Out_en_Buff) 执行完毕就是加密结果了 

但具体参数怎么来的呢 

参数1 Out_Md5_Buff 来源 sub_14141C()

参数2 是固定16位(加密后十六进制时长度)

参数3 &Out_en_Buff 就是结果了

Out_Md5_Buff() 来源于sub_14141C()下面开始分析 

sub_14141C() 函数分析

函数原型 sub_14141C(InputStr, inputlen, &Out_Md5_Buff)

参数1 为随机生成的字符

参数2  为随机生成的长度

参数3  输出的加密结果

进入函数内部


逻辑混淆没法正常看,把参数处理一下 搜索参数看看有没有发现 直接搜加密输出变量


都跳转去看看 



没办法看清楚逻辑 用frida hook看看参数返回

发现被调用了一次 调用地址为 0x142804 

sub_1390B8(“s123456789”, 0xa, _Out_Md5_Buff); 

_Out_Md5_Buff  = 


这个就是加密后结果 继续跟踪

进入函数 继续搜索Out_Md5_Buff 看看谁在调用


都是sub_131ADC()调用 继续用frida看看参数返回

被调用了一次 调用地址0x13BA34 参数1:


不清楚是什么 感觉很像一个结构(应该是md5_ctx后面分析发现的)

然后加密结果也相同 那肯定加密就在里面了 我们进去看看


进入 sub_131ADC()函数 继续搜索输出变量


这里应该就是加密算法了 乍一看感觉有点眼熟那 加上返回的加密是32位 有理由怀疑是md5 

搜了搜md5算法


感觉挺像的 返回调用函数地址看看 用什么值加密的


继续frida hook sub_10BB08() 看看 

一共被调用4次 

sub_10BB08(md5_ctx,421d38d938156606164a15d2e7f822d9,0x20) //  MD5Update() 调用地址 0x139da0

sub_10BB08(md5_ctx,s123456789,0xa) //  MD5Update() 调用地址 0x13ba28

下面两次是在md5内部调用()                   //sub_131ADC()   MD5Final() 

参数长度


sub_10BB08(md5_ctx, bits,0x8) //  MD5Update(context, bits, 8)

由于md5加密是通过 MD5Update()添加加密字符 上面调试发现分别添加了 

MD5Update(421d38d938156606164a15d2e7f822d9)

MD5Update(s123456789)

md5( 421d38d938156606164a15d2e7f822d9s123456789 )就可以得出加密结果

那么  421d38d938156606164a15d2e7f822d9 这个字符串怎么来的呢 我们跳转到调用地址 0x139da0


搜索v523引用看看 


点击最后一个跳转到 点击aCef3do3ndofbaa看看数据



明显数据对不上 先hook sub_161F8()看看参数返回


数据是正确的呢 猜测在之前已经解密了 点击数据搜索引用看看发现 点击进入下面几个 都是同一个函数



继续查找引用



 .init_array 有三个函数 字符串是在第二个解密的

第一个函数基本分析完毕了~ 
总结: MD5Update(InputStr16)生成的16位字符  MD5Update(Salt) 固定salt值 得出的32位结果

函数逻辑混淆无法f5了 直接 trace来记录然后分析看看 

用 IDA 动态调试附加上程序 


定位到函数头部下断点 修改一下脚本地址信息 计算函数地址 填写脚本 trace


设置tarce保存路径 跑起来吧~最后大概15万条记录ok 开始分析 搜索结果看看


这就是我们的加密结果了 最后是异或得出的 就是随着记录一步步看参数结果 


有时候知道最后是异或出来的 得到这个关键参数应该试试随机组合看看结果 

过程就不写了 短短续续找了几天 发现混淆大概都是将 参数 取反计算一遍~  


基本方法就是 定位到 关键加密段 会分成很多段 把参数 结果 分析出来 然后 对照trace跑的结果过程 慢慢对照~ 会有很多取反运算

具体参考开头 该题看法 88~

2020安全开发者峰会(2020 SDC)议题征集 中国.北京 7月!


文章来源: https://bbs.pediy.com/thread-258585.htm
如有侵权请联系:admin#unsafe.sh