Android逆向-实战so分析-某洲_v3.5.8_unidbg学习

1.unidbg的介绍

unidbg是一款基于unicorn的用来模拟执行二进制程序的逆向工具,可以让安全研究人员直接在PC上运行android或ios的动态库文件并调用其中的方法,来看下该工具支持的功能。
支持功能如下:

  • 支持模拟执行JNI调用API,以便可以调用JNI_OnLoad
  • 支持JavaVM,JNIEnv
  • 支持模拟syscalls调用
  • 支持ARM32和ARM64
  • 基于HookZz实现的inline hook
  • 基于xHook实现的import hook
  • 支持iOS fishhook、substrate、whale hook
  • 支持简单的控制台调试器、gdb、IDA、android调试器服务器、指令跟踪、内存读/写跟踪。
  • 支持iOS objc和Swift运行

2.unidbg的安装

2.1.下载unidbg工具

下载地址:unidbg

2.2.导入IDEA

打开IDEA,点击Import Project按钮。
这里需要说明一下,可能有些小伙伴一打开IDEA不是下图页面而是以往的项目页面,这种情况则直接在IDEA工具的File->New下面点击Project from Existing Sources…按钮一样可以进入到下一步的页面。
在这里插入图片描述
进入这个页面后将前面下载好的unidbg源码路径填入之后点击OK按钮。
在这里插入图片描述
然后会弹出下面这个页面,让我们选择项目类型,选择Maven项目,点击Finish按钮后IDEA就会开始导入工作。
在这里插入图片描述
这时候可能需要稍微等待一会,IDEA在导入项目的时候会下载一些依赖,记得保持网络通畅,之后等就完事儿了。

2.3.验证导入是否成功

等IDEA将整个项目导入完成后可以看到和下图类似的页面,主要看下左边红框中的内容,这是整个项目的视图,可以看到整个unidbg项目包含了unidbg-android、unidbg-api、unidbg-ios共三个子项目。
在这里插入图片描述
我们在unidbg-android子项目中找到作者给我们提供的测试类"com.bytedance.frameworks.core.encrypt",然后点击运行TTEncrypt.main方法。
在这里插入图片描述
如果运行结果如下,则表示整个项目导入成功。在这里插入图片描述
之后开始我们正式的分析工作。

3.unidbg的使用

3.1.目标方法静态分析

成功测试完作者给出的例子后,我们可以找一些例子来简单学习下unidbg的使用,这里直接使用白龙大佬博客中的例子(liboasiscore.so)。
首先看下本次需要调用的目标方法,目标方法在target.dex文件中,这个文件是白龙大佬脱壳出来的,对脱壳感兴趣的小伙伴可以试下脱壳。之前也有说过常用脱壳方法"实战sign分析-某某合伙人_v4.0.9"
样本APK:绿洲_v3.5.8
这里我们直接将target.dex丢到JEB工具中并定位到com.weibo.xvideo.NativeApi类,这是个全是Native方法的类,本次要模拟执行的方法是名为s的native方法,包含两个参数,参数1是个byte型数组,参数2是个boolean型变量。
在这里插入图片描述
现在有了目标方法,但我们并不知道这个方法是在哪里实现的,所以还需要找到这个方法的实现地址,这样我们才能使用unidbg进行模拟执行。
根据NativeApi构造函数中的System.loadLibrary可知这些native方法都在liboasiscore.so中实现的,使用解压软件可在原apk中的以下目录找到这个so文件。
这里需要注意你自己的测试机是多少位的系统,我这里是64位的,所以选用的是arm64-v8a目录下的so。
在这里插入图片描述
找到目标方法所在的so之后,可以使用IDA工具对这个so进行静态分析,以此来拿到目标方法的地址。
但本次目标方法的地址单纯的使用IDA静态分析并不能直接获取,一般如果native方法使用静态绑定可通过在IDA的函数窗口搜索java等关键字即可定位到目标方法,这里主要得益于静态绑定的方法命名需要按照固定的格式的原因,而本次目标方法采用的是动态绑定的方法,动态绑定就没有必须按照固定格式命名这么个限制,所以需要先找到so中动态绑定目标方法的位置,才能定位到目标方法代码实现的位置。
在这里插入图片描述
一般so对native方法动态绑定的实现都放在JNI_OnLoad方法中,首先定位到JNI_OnLoad方法,再去找动态绑定的实现。
在这里插入图片描述
找到JNI_OnLoad方法后又发现这个方法实际上被OLLVM混淆过,这样看来想通过静态分析找到目标方法的位置就不太现实了,到此我们的静态分析结束,下面开始我们的动态分析过程。
之前的动态分析都是采用Frida框架对应用中的一些关键方法进行hook的方式来分析的,这次采用另一种方式来实现动态分析—模拟执行。

3.2.模拟执行目标方法

打开前面配置好的unidbg工程,在工程的unidbg-android子项目的src/test/java/目录下创建一个com.sina.oasis.Oasis类并继承自AbstractJni类,主要用来编写我们的模拟执行so的代码,并将目标so文件liboasiscore.so和原apk也放到该目录下。
在这里插入图片描述
整个框架准备完毕后开始在com.sina.oasis.Oasis类中编写模拟执行的代码。
因为目标方法s是在JNI_OnLoad方法中实现的动态绑定,所以需要先实现对JNI_OnLoad方法的模拟执行。
JNI_OnLoad方法模拟执行如下:

package com.sina.oasis;

import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Module;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.AbstractJni;
import com.github.unidbg.linux.android.dvm.DalvikModule;
import com.github.unidbg.linux.android.dvm.DalvikVM;
import com.github.unidbg.linux.android.dvm.VM;
import com.github.unidbg.linux.android.dvm.array.ByteArray;
import com.github.unidbg.memory.Memory;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class Oasis extends AbstractJni {
   
    private final AndroidEmulator emulator;
    private final VM vm;
    private final Module module;

    Oasis(){
   
        // 创建一个模拟器实例,进程名建议依照实际的进程名填写,可以规避一些so中针对进程名校验
        emulator = AndroidEmulatorBuilder.for64Bit().setProcessName("com.sina.oasis").build();
        // 设置模拟器的内存操作接口
        final Memory memory = emulator.getMemory();
        // 设置系统类库解析
        memory.setLibraryResolver(new AndroidResolver(23));
        // 创建Android虚拟机,传入APK,Unidbg可以替我们做部分签名校验的工作
        vm = emulator.createDalvikVM(new File("unidbg-android/src/test/java/com/sina/oasis/lvzhou.apk"));
        // 加载so到虚拟内存,第二个参数的意思表示是否执行动态库的初始化代码
        DalvikModule dm = vm.loadLibrary(new File("unidbg-android/src/test/java/com/sina/oasis/liboasiscore.so"),true);
        // 获取so模块的句柄
        module = dm.getModule();
        // 设置JNI
        vm.setJni(this);
        // 打印日志
        vm.setVerbose(true);
        // 调用JNI方法
        dm.callJNI_OnLoad(emulator);
  • 7
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值