查看原文
其他

ollvm CrackMe算法分析

ddsf 看雪学院 2021-03-07
本文为看雪论坛优秀文章
看雪论坛作者ID:ddsf



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


该题看法:样本是经过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位结果。



第二个函数sub_1494C4()函数分析


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


用 IDA 动态调试附加上程序:



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



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



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


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

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



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

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



- End -





看雪ID:ddsf

https://bbs.pediy.com/user-476191.htm 

*本文由看雪论坛 ddsf 原创,转载请注明来自看雪社区。



推荐文章++++

手把手教你入门V8漏洞利用

Android微信逆向--实现发朋友圈动态

病毒样本半感染型分析的方法

对宝马车载apps协议的逆向分析研究

x86_64架构下的函数调用及栈帧原理


好书推荐






公众号ID:ikanxue
官方微博:看雪安全
商务合作:wsc@kanxue.com




“阅读原文”一起来充电吧!

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存