使用unidbg去ollvm虚假分支反混淆
从原理上面来讲。去除虚假分支其实很简单。所以先简单说下理论。
虚假分支的混淆会在增加大量的if else分支。增加静态分析的复杂度。但是实际在动态执行的时候。很多if else实际都是没有执行的。所以去掉虚假分支其实就是删除掉那些没有执行到的代码块。那么我们只要知道目标函数中,哪些汇编代码执行了,并且记录下执行汇编的address。然后把这些汇编以外的代码全部标记为nop。然后再用ida反汇编看到的结果。就直接是去掉虚假分支的结果了。
下面我们从准备环境开始。
1、编译ollvm mkdir ~/ollvm/llvm-project-llvmorg-9.0.1/build-release
cd ~/ollvm/llvm-project-llvmorg-9.0.1/build-release
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang;clang++" ../llvm
ninja
2、配置ndk,使用ollvm的clang来进行 ...
android抓包学习的整理和归纳
最近学习了各种抓包。为了防止忘记。学到的东西必须是整理一波啊。向大佬们看齐。如果有啥地方写的不对,希望大家多多指点
抓包主要是针对网络通讯数据,客户端向服务端上报的数据拦截下来。一般都是抓取http、https、tcp、udp。想要获取到数据包。有多种方式,下面简单列一下。
抓包方式1、hook app业务层,根据业务代码逻辑找到触发请求的函数,比如按钮触发,或者触发数据上报时的提示框等方式。分析后找到发送数据的地方hook打印。
优点:不受app的防抓包手段的影响,只要能hook到就能抓到包。
缺点:必须分析app找关键点,并且每个不同的请求都要找对应的触发函数,效率太慢。
2、系统框架层的hook。直接hook系统源码发送和接受数据的地方。
优点:可以直接省略掉业务层的分析。因为业务层不论逻辑怎么样最终都是调用系统的或者是第三方的库来进行数据传输。并且通用性更好。基本不用修改就可以抓很多app的包。并且可以在这里直接打印堆栈回溯请求触发的函数,提高分析的效率。同样不受防抓包手段影响。
缺点:hook出来的抓包数据不便于我们分析和筛选。只能在日志中查找对应的数据,分析数据包会比较 ...
算法还原实战9
练习algorithmbase_80.apk
先是用frida脚本跑几个数据看看加密特征
1234567function call_encode80(input){ Java.perform(function(){ var MainActivity=Java.use("com.kanxue.algorithmbase.MainActivity"); var res=MainActivity.encodeFromJni_80(input); console.log("input:",input,"output",res); });}
然后加密几个测试数据看到了。当输入长度为16以下时。输出长度为128.输入长度为>=16并且<32时。输出长度为160。由此可以判断这应该是一个组合的非标准算法。前面组合的部分目测为某个hash算法
12345678910[AOSP on msm8996::com.kanxue.algor ...
记录一些日常使用frida经常会用到的一些小方法
整理一下之前的学习笔记。以及常用的一些frida的技巧。以备哪天快速回顾
首先是常规的java层的函数hook
123var manActivity=Java.use("com.kanxue.algorithmbase.MainActivity");var res= manActivity.encodeFromJni_71(input)console.log("input:",input,"output:",res);
然后是主动调用函数
1234567891011//主动调用静态函数var FridaActivity2 = Java.use("com.kanxue.algorithmbase.MainActivity");FridaActivity2.setStatic_bool_var(); //主动调用非静态函数Java.choose("com.example.androiddemo.Activity.FridaActivity2", { onMatch: funct ...
算法还原实战8
分析样例下载:链接: https://pan.baidu.com/s/1sl0rnYC2u0wre0YYutIwhg 密码: 26b9
练习algorithmbase_71.apk
ida打开libnative-lib.so找到encodeFromJni_171。然后frida打印下输出结果。观察看有什么特征
1234567function call_encodeFromJni_71(input){ Java.perform(function(){ var native_lib=Java.use("com.kanxue.algorithmbase.MainActivity"); var res= native_lib.encodeFromJni_71(input) console.log("input:",input,"output:",res); });}
然后主动填参数调用一下。看看长度不同的时候加密数据的特征
12345in ...
算法还原实战7
分析样例下载:链接: https://pan.baidu.com/s/13iMgWwFattwNS6PmEA16Bg 密码: avtb
练习algorithmbase_70.apk
老样子直接ida打开libnative-lib.so然后frida打印一下输入和输出
1234567891011121314function hook_java(){ Java.perform(function(){ var native_lib=Java.use("com.kanxue.algorithmbase.MainActivity"); native_lib.encodeFromJni_70.implementation=function(input){ var res=this.encodeFromJni_70(input); console.log("input:",input,"output:",res); ...
算法还原实战练习6
分析样例下载:链接: https://pan.baidu.com/s/1Df_8OhozSEE17MIuIigvhg 密码: 4tgi
练习algorithmbase_60.apk
老样子ida打开libnative-lib.so找到encodeFromJni_160。然后看到了有个byte_2F050字符串加密处理了。unidbg跑一下解开看看字符串是什么
然后打开这个使用了加密字符串的函数。发现里面是ollvm混淆过了的
这里我先静态分析一下。把每个函数打开大致的浏览下里面的内容。然后发现了两个比较特殊的函数sub_121DC和sub_C29C。这两个函数里面直接就有疑似算法部分的代码。特别是sub_C29C函数中直接看到了有base64的特征。
接下来静态分析一下sub_121DC的参数。发现第一个参数应该是一个大小为258字节的数据。可能是用来加密的表。
然后frida来hook一下。观察参数的意义。
1234567891011121314151617181920212223242526272829function hook_native(){ va ...
算法还原实战练习5
分析样例下载:链接: https://pan.baidu.com/s/1TErQmcjNbLG54yJbD31mLg 密码: j455
练习1、algorithmbase_50.apk
老样子直接ida分析libnative-lib.so。根据返回值处理找到关键函数sub_B9F4
写个frida来查一下看看参数都是些什么
12345678910111213141516171819202122232425262728293031function hook_native(){ var base_addr=Module.getBaseAddress("libnative-lib.so"); var sub_B9F4=base_addr.add(0xB9F4+1); Interceptor.attach(sub_B9F4,{ onEnter:function(args){ console.log("onEnter sub_B9F4"); t ...
算法还原实战练习4
分析样例下载:链接: https://pan.baidu.com/s/1Mb6U4D24SlG_K6n1dxszOQ 密码: ikpe
第一题algorithmbase_40.apk
直接ida打开libnative-lib.so。找到Java_com_kanxue_algorithmbase_MainActivity_encodeFromJni_140。然后根据返回值看来源。最后v15是返回的。然后v8=&v15。然后v8的值是v17逐个字节赋值的。所以关键在于v17。关键函数直接定位出来在sub_AB90.另外看v16的值。和MD5的算法有点像。可能也是一个hash算法。
接着看到里面只有一个函数sub_9AFC。直接进去看看。
进去后也只有一个函数sub_9BA4。继续进去看看是不是算法的部分
果然看到熟悉的算法部分。搜索一下常量看看有啥收获不
看到直接就是sha1的关键常量。我们验证下看看
先frida抓一下计算的结果
1input: cKGiDKZnhktnzCxsXzGP output: ec048f770484aee853187e413d1dd4f ...
算法还原实战练习3
分析样例下载:链接: https://pan.baidu.com/s/1qxkYqMovR8Fe6sO-Zr-8ow 密码: dh7g
第一题algorithmbase_32
直接ida打开找到encodeFromJni_32函数。然后F5后。发现是ollvm混淆的。然后大概的分析一下。我的分析思路是。首先是大概的翻一下参数较多的那些函数,看看是否有什么比较眼熟的函数。果然很快锁定了一个函数sub_1D920。下面贴上交为眼熟的部分
我圈出来的这几个特征和我们之前分析过的md5的特征高度的相似。v10的那些明显就是MD5的那个key。而下面是拼接的三段固定数据再加上我们的输入值。所以我们先看看那三段数据分别是什么
点开后发现字符串被加密了。所以我们用之前研究的解ollvm字符串混淆的工具unidbg或者是AndroidNativeEmu来生成一个解密的so跑一下。下面贴上解完之后的结果
然后点进去看看字符串。
知道是什么值拼接的之后。然后就简单了。先看看输出和输出的值。
1rRZrALoUFxTqxDCJHjT -> ea8caf7e47b8404d81de7979 ...
算法还原实战练习2
练习的例子
链接: https://pan.baidu.com/s/1BhKdDik8zOx_ioPNFdhQDg 密码: 0npf
第一题algorithmbase_20.apk
先是jadx打开apk。然后找到入口页面的代码如下
123456789101112131415public void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView(C0575R.layout.activity_main); final TextView textView = (TextView) findViewById(C0575R.C0578id.sample_text); ((Button) findViewById(C0575R.C0578id.button)).setOnClickListener(new View.OnClickListener() { /* class com.kanxue.algorithmba ...
还原算法实战
练习第一题的algorithmbase_10.apk连接如下
链接: https://pan.baidu.com/s/1hUyNDzd0VDzqD16X_IhiPg 密码: ocg5
首先用jadx打开目标应用。看到下面的代码
看到我们需要还原算法的函数是encodeFromJni_10。参数是随机16个ascii字符。接下来用ida打开libnative-jni.so。找到我们的目标函数。然后修改第一个参数的类型为JNIEnv*,然后把第三个参数的名称修改成input。最后把F5的代码贴到下面
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970void __fastcall Java_com_kanxue_algorithmbase_MainActivity_encodeFromJni_110(JNIEnv *a1, __int64 a2, __int64 input ...