app逆向之安卓native层安全逆向分析(五):unidbg黑盒调用

前言

继续跟着龙哥的unidbg学习:SO逆向入门实战教程五:qxs_白龙~的博客-CSDN博客

还是那句,我会借鉴龙哥的文章,以一个初学者的角度,加上自己的理解,把内容丰富一下,尽量做到不在龙哥的基础上画蛇添足,哈哈。感谢观看的朋友

 

分析

 

首先,安装app,发现龙哥给的apk包已经安装不上,网上重新找了个最新版,安装后,正常打开,然后,抓个包:

 

 

ok,这个sfsecurity参数就是今天的重点了。

这个app有ajm的壳,没事,脱壳手段上,结果搞半天没脱出来,卧槽了,而且还有 frida反调试

 

脱壳机也不在身边,那没法,直接黑盒调用,unidbg就是干这个的。

 

调试

1.搭架子

运行没问题

不过这里,unidbg并没有打印出来我们要的方法和地址 

 

2.ida找地址

这时候就需要用ida找地址了,结果发现,这个so文件有点奇怪,搜不到,但是在导出表里看得到,这就很奇怪了,根据分析,猜测是有一定的保护,也没办法通过F5反编译 

 

很快就找到这里了,【0xAB2C】 ,注意,这里我用的是最新版,所以地址跟龙哥博客的地址不一样

 

3.黑盒调用&补环境

这里,我选用的是32位,所以得加1,因为我把apk解包,从lib\armeabi-v7a里找的这个so文件,所以他一定是32位的(根据安卓开发规范)

 

ok,报了个环境的错,补一补:

 

 ok,又有新的报错,继续补:

 

ok,搞定

 

这里,由于我是根据龙哥的博客,知道是哪个so方法,所以直接黑盒调用,也没有用objection hook,它有frida反调试(objection基于frida),那就尴尬了,所以这里没法验证hook值和主动调用值是否一致了。那就暂时这样,反正值是有了

 

完整代码:

package com.qxs;

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.*;
import com.github.unidbg.linux.android.dvm.api.Binder;
import com.github.unidbg.linux.android.dvm.api.ServiceManager;
import com.github.unidbg.memory.Memory;

import java.io.File;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.UUID;

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

    qxs() {
        // 创建模拟器实例,进程名建议依照实际进程名填写,可以规避针对进程名的校验
        emulator = AndroidEmulatorBuilder.for32Bit().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\\qxs\\com.sfacg.apk"));
        // 加载目标SO
        DalvikModule dm = vm.loadLibrary(new File("unidbg-android\\src\\test\\java\\com\\qxs\\libsfdata.so"), true); // 加载so到虚拟内存
        //获取本SO模块的句柄,后续需要用它
        module = dm.getModule();
        vm.setJni(this); // 设置JNI
        vm.setVerbose(true); // 打印日志

        dm.callJNI_OnLoad(emulator); // 调用JNI OnLoad
    }
    public static void main(String[] args) {
        qxs test = new qxs();
        System.out.println(test.sfsecurity());
    }
    public String sfsecurity(){
        List<Object> list = new ArrayList<>(10);
        list.add(vm.getJNIEnv());
        list.add(0);
        DvmObject<?> context = vm.resolveClass("android/content/Context").newObject(null);
        list.add(vm.addGlobalObject(context));
        list.add(vm.addLocalObject(new StringObject(vm,"test")));
        Number number =  module.callFunction(emulator,0xAB2C+1,list.toArray());
        String result = vm.getObject(number.intValue()).getValue().toString();
        return result;
    }
    @Override
    public DvmObject<?> callStaticObjectMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {
        switch (signature) {
            case "java/util/UUID->randomUUID()Ljava/util/UUID;":
                return dvmClass.newObject(UUID.randomUUID());
        }
        return super.callStaticObjectMethodV(vm, dvmClass, signature, vaList);
    }

    @Override
    public DvmObject<?> callObjectMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {
        switch (signature) {
            case "java/util/UUID->toString()Ljava/lang/String;":
                String uuid = dvmObject.getValue().toString();
                return new StringObject(vm, uuid);
        }
        return super.callObjectMethodV(vm, dvmObject, signature, vaList);
    }
}

 

知识点总结

本篇和上一篇感觉的挺简单的,所以没有啥总结的

posted @ 2023-04-26 16:15  Eeyhan  阅读(350)  评论(0编辑  收藏  举报