首页
社区
课程
招聘
[原创] libtiny unidbg简单补环境
发表于: 8小时前 284

[原创] libtiny unidbg简单补环境

8小时前
284

模拟执行libtiny.so计算x-mini相关的参数。

先搭建基础框架, 代码如下:

运行结果:

按照hook顺序调用初始化函数,

运行需要补充的环境:

这是主要需要补充的函数之一,也是开始比较重要的点, 先简单补充如下,通过第一个参数int来写分支补充不同的功能。

这样补充,有报错,需要把DvmMethod类的构造函数权限改成public, 接着给DvmClass函数中增加一个setMethodId的函数,

仿造DvmClass中getMethodID相关的函数,简单粗暴的给添加到对应的map中。

补充之后报错如上所示

进入第一层报错信息,代码如上所示,这里没有实现,直接抛出异常,接下来尝试补全这里的实现,

大致仿造函数_ToReflectedMethod函数的实现和需要补充的函数,猜测这里可能需要从DvmMethod对象获取到MethodIDlong类型。所以补充如下:

补充之后运行结果如上,第一个初始化函数成功执行完成。

继续第二个初始化函数

运行

开补:

运行

运行

第二个初始化函数执行完成。

第三个初始化函数

运行

不用补,直接能执行。

初始化函数调用完成之后,正式进入参数计算相关的调用。

运行

运行

运行

补, DvmField类构造函数权限public

运行

运行

运行

运行

运行

运行

运行

运行

运行

运行

运行

补,这里注意有特殊情况

运行

运行

运行

补,这里注意输入参数

运行

运行

运行

进入报错位置,看到报错是因为dvmMehtod是null,并且根据前面的日志,大概率是和android/content/Intent相关的问题,但是并没有补充过,这个类相关的环境,继续向前看,应该是分支环境没有补充,

看到309143350情况没有补全,顺带将其他没有补全的情况也都给补全。

运行

运行

运行

补, 注意这里的调用又是有参数的

运行

运行

运行

运行

运行

运行

运行

运行

运行

运行

运行

从上图中可以看出,出错的位置是prctl系统调用中有不支持的option类型,简单粗暴无脑补全即可,网上搜索prctl.h对应头文件简单看一下对应的值,

运行

运行

运行

运行

完成。

一切都以能跑出结果为主。

public class Xhs859Tiny extends AbstractJni {
    private final AndroidEmulator emulator;
    private final VM vm;
    private final Module module;
 
    private final DvmClass tinyT;
 
    Xhs859Tiny() {
        // 创建模拟器
        emulator = AndroidEmulatorBuilder.for64Bit()
                .setProcessName("com.xingin.xhs")
                .addBackendFactory(new Unicorn2Factory(true))
                .build();
 
        final Memory memory = emulator.getMemory(); // 模拟器的内存操作接口
        memory.setLibraryResolver(new AndroidResolver(23)); // 设置系统类库解析
 
        vm = emulator.createDalvikVM(new File("data/xhs8_59_0.apk")); // 创建安卓虚拟机
        vm.setVerbose(true); // 设置是否打印Jni调用细节
        vm.setJni(this);
 
        new MediaNdkModule(emulator, vm).register(memory);
        new AndroidModule(emulator, vm).register(memory);
        new JniGraphics(emulator, vm).register(memory);
 
        DalvikModule dm = vm.loadLibrary("tiny", true);
        module = dm.getModule(); // 加载好的libttEncrypt.so对应为一个模块
        dm.callJNI_OnLoad(emulator);
        tinyT = vm.resolveClass("com/xingin/tiny/internal/t");
    }
 
    public static void main(String[] args) {
        Xhs859Tiny demo =  new Xhs859Tiny();
         
    }
}
public class Xhs859Tiny extends AbstractJni {
    private final AndroidEmulator emulator;
    private final VM vm;
    private final Module module;
 
    private final DvmClass tinyT;
 
    Xhs859Tiny() {
        // 创建模拟器
        emulator = AndroidEmulatorBuilder.for64Bit()
                .setProcessName("com.xingin.xhs")
                .addBackendFactory(new Unicorn2Factory(true))
                .build();
 
        final Memory memory = emulator.getMemory(); // 模拟器的内存操作接口
        memory.setLibraryResolver(new AndroidResolver(23)); // 设置系统类库解析
 
        vm = emulator.createDalvikVM(new File("data/xhs8_59_0.apk")); // 创建安卓虚拟机
        vm.setVerbose(true); // 设置是否打印Jni调用细节
        vm.setJni(this);
 
        new MediaNdkModule(emulator, vm).register(memory);
        new AndroidModule(emulator, vm).register(memory);
        new JniGraphics(emulator, vm).register(memory);
 
        DalvikModule dm = vm.loadLibrary("tiny", true);
        module = dm.getModule(); // 加载好的libttEncrypt.so对应为一个模块
        dm.callJNI_OnLoad(emulator);
        tinyT = vm.resolveClass("com/xingin/tiny/internal/t");
    }
 
    public static void main(String[] args) {
        Xhs859Tiny demo =  new Xhs859Tiny();
         
    }
}
public void callInit() {
    String method = "a(I[Ljava/lang/Object;)Ljava/lang/Object;";
    int i = 1853701372;
    ArrayObject objArr = new ArrayObject();
    // 返回结果应该是null
    DvmObject result = tinyT.callStaticJniMethodObject(emulator, method, i, objArr);
    System.out.println(result);
}
public void callInit() {
    String method = "a(I[Ljava/lang/Object;)Ljava/lang/Object;";
    int i = 1853701372;
    ArrayObject objArr = new ArrayObject();
    // 返回结果应该是null
    DvmObject result = tinyT.callStaticJniMethodObject(emulator, method, i, objArr);
    System.out.println(result);
}
// 补环境
@Override
public DvmObject<?> callStaticObjectMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {
    switch (signature) {
        case "com/xingin/tiny/internal/t->b(I[Ljava/lang/Object;)Ljava/lang/Object;": {
            int i = vaList.getIntArg(0);
            System.out.println("Tiny.t.b i=" + i);
            switch (i) {
                case -1939572706: {
                    ArrayObject arrayObject = vaList.getObjectArg(1);
                    DvmClass clazz = (DvmClass) arrayObject.getValue()[0];
                    String methodName = (String) arrayObject.getValue()[1].getValue();
                    DvmObject[] signatureArgs = (DvmObject[]) arrayObject.getValue()[2].getValue();
                    System.out.println(signatureArgs);
 
                    StringBuilder methodSignature = new StringBuilder("(");
                    for (DvmObject signatureArg : signatureArgs) {
                        if (signatureArg.getValue().getClass() == String.class) {
                            System.out.println(signatureArg.getValue().getClass().getName());
                            methodSignature.append("L")
                                    .append(signatureArg.getValue().getClass().getName().replaceAll("\\.", "/"))
                                    .append(";");
                        } else {
                            methodSignature.append(signatureArg.getValue().getClass().getName());
                        }
                    }
                    methodSignature.append(")Ljava/lang/Object;");
                    System.out.println(methodName + " " + methodSignature);
                    DvmMethod dvmMethod = new DvmMethod(clazz, methodName, methodSignature.toString(), true);
                    DvmObject result = vm.resolveClass("java/lang/reflect/Method").newObject(dvmMethod);
                    clazz.setMethodId(result.hashCode(), dvmMethod);
 
                    System.out.println("setMethodId " + Integer.toHexString(result.hashCode()));
                    return result;
                }
            }
        }
    }
    return super.callStaticObjectMethodV(vm, dvmClass, signature, vaList);
}
// 补环境
@Override
public DvmObject<?> callStaticObjectMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {
    switch (signature) {
        case "com/xingin/tiny/internal/t->b(I[Ljava/lang/Object;)Ljava/lang/Object;": {
            int i = vaList.getIntArg(0);
            System.out.println("Tiny.t.b i=" + i);
            switch (i) {
                case -1939572706: {
                    ArrayObject arrayObject = vaList.getObjectArg(1);
                    DvmClass clazz = (DvmClass) arrayObject.getValue()[0];
                    String methodName = (String) arrayObject.getValue()[1].getValue();
                    DvmObject[] signatureArgs = (DvmObject[]) arrayObject.getValue()[2].getValue();
                    System.out.println(signatureArgs);
 
                    StringBuilder methodSignature = new StringBuilder("(");
                    for (DvmObject signatureArg : signatureArgs) {
                        if (signatureArg.getValue().getClass() == String.class) {
                            System.out.println(signatureArg.getValue().getClass().getName());
                            methodSignature.append("L")
                                    .append(signatureArg.getValue().getClass().getName().replaceAll("\\.", "/"))
                                    .append(";");
                        } else {
                            methodSignature.append(signatureArg.getValue().getClass().getName());
                        }
                    }
                    methodSignature.append(")Ljava/lang/Object;");
                    System.out.println(methodName + " " + methodSignature);
                    DvmMethod dvmMethod = new DvmMethod(clazz, methodName, methodSignature.toString(), true);
                    DvmObject result = vm.resolveClass("java/lang/reflect/Method").newObject(dvmMethod);
                    clazz.setMethodId(result.hashCode(), dvmMethod);
 
                    System.out.println("setMethodId " + Integer.toHexString(result.hashCode()));
                    return result;
                }
            }
        }
    }
    return super.callStaticObjectMethodV(vm, dvmClass, signature, vaList);
}
public void setMethodID(int methodID, DvmMethod dvmMethod) {
    if (!staticMethodMap.containsKey(methodID)) {
        staticMethodMap.put(methodID, dvmMethod);
    }
    if (!methodMap.containsKey(methodID)) {
        methodMap.put(methodID, dvmMethod);
    }
}
public void setMethodID(int methodID, DvmMethod dvmMethod) {
    if (!staticMethodMap.containsKey(methodID)) {
        staticMethodMap.put(methodID, dvmMethod);
    }
    if (!methodMap.containsKey(methodID)) {
        methodMap.put(methodID, dvmMethod);
    }
}
Pointer _FromReflectedMethod = svcMemory.registerSvc(new Arm64Svc() {
    @Override
    public long handle(Emulator<?> emulator) {
        RegisterContext context = emulator.getContext();
        UnidbgPointer jmethodID = context.getPointerArg(1);
        return jmethodID.toIntPeer();
//                throw new UnsupportedOperationException();
    }
});
Pointer _FromReflectedMethod = svcMemory.registerSvc(new Arm64Svc() {
    @Override
    public long handle(Emulator<?> emulator) {
        RegisterContext context = emulator.getContext();
        UnidbgPointer jmethodID = context.getPointerArg(1);
        return jmethodID.toIntPeer();
//                throw new UnsupportedOperationException();
    }
});
public void callInit2() {
    String method = "a(I[Ljava/lang/Object;)Ljava/lang/Object;";
    int i = -1681571521;
    ArrayObject objArr = new ArrayObject(
            new StringObject(vm, "ECFAAF01"),
            new StringObject(vm, "vivo"),
            DvmInteger.valueOf(vm, 0),
            DvmBoolean.valueOf(vm, true),
            DvmBoolean.valueOf(vm, false),
            DvmBoolean.valueOf(vm, false),
            vm.resolveClass("java/lang/Float").newObject(1.0),
            DvmBoolean.valueOf(vm, false),
            DvmBoolean.valueOf(vm, false),
            DvmBoolean.valueOf(vm, false),
            DvmBoolean.valueOf(vm, false),
            DvmBoolean.valueOf(vm, false)
    );
    DvmObject result = tinyT.callStaticJniMethodObject(emulator, method, i, objArr);
    System.out.println(result);
}
public void callInit2() {
    String method = "a(I[Ljava/lang/Object;)Ljava/lang/Object;";
    int i = -1681571521;
    ArrayObject objArr = new ArrayObject(
            new StringObject(vm, "ECFAAF01"),
            new StringObject(vm, "vivo"),
            DvmInteger.valueOf(vm, 0),
            DvmBoolean.valueOf(vm, true),
            DvmBoolean.valueOf(vm, false),
            DvmBoolean.valueOf(vm, false),
            vm.resolveClass("java/lang/Float").newObject(1.0),
            DvmBoolean.valueOf(vm, false),
            DvmBoolean.valueOf(vm, false),
            DvmBoolean.valueOf(vm, false),
            DvmBoolean.valueOf(vm, false),
            DvmBoolean.valueOf(vm, false)
    );
    DvmObject result = tinyT.callStaticJniMethodObject(emulator, method, i, objArr);
    System.out.println(result);
}
@Override
public float callFloatMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {
    switch (signature) {
        case "java/lang/Float->floatValue()F":{
            return ((Double) dvmObject.getValue()).floatValue();
        }
    }
    return super.callFloatMethodV(vm, dvmObject, signature, vaList);
}
@Override
public float callFloatMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {
    switch (signature) {
        case "java/lang/Float->floatValue()F":{
            return ((Double) dvmObject.getValue()).floatValue();
        }
    }
    return super.callFloatMethodV(vm, dvmObject, signature, vaList);
}
@Override
public boolean callBooleanMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {
    switch (signature) {
        case "java/lang/Boolean->booleanValue()Z": {
            return (boolean) dvmObject.getValue();
        }
    }
    return super.callBooleanMethodV(vm, dvmObject, signature, vaList);
}
@Override
public boolean callBooleanMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {
    switch (signature) {
        case "java/lang/Boolean->booleanValue()Z": {
            return (boolean) dvmObject.getValue();
        }
    }
    return super.callBooleanMethodV(vm, dvmObject, signature, vaList);
}
case 1004337890: {
    return new StringObject(vm, "/data/user/0/com.xingin.xhs");
}
case 1004337890: {
    return new StringObject(vm, "/data/user/0/com.xingin.xhs");
}
public void callInit3() {
    String method = "a(I[Ljava/lang/Object;)Ljava/lang/Object;";
    int i = 830009223;
    ArrayObject objArr = new ArrayObject();
    DvmObject result = tinyT.callStaticJniMethodObject(emulator, method, i, objArr);
    System.out.println(result);
 
}
public void callInit3() {
    String method = "a(I[Ljava/lang/Object;)Ljava/lang/Object;";
    int i = 830009223;
    ArrayObject objArr = new ArrayObject();
    DvmObject result = tinyT.callStaticJniMethodObject(emulator, method, i, objArr);
    System.out.println(result);
 

[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

收藏
免费 23
支持
分享
最新回复 (9)
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
666
8小时前
0
雪    币: 3001
活跃值: (3240)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
666
7小时前
0
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
666
6小时前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
666
6小时前
0
雪    币: 54
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
666
5小时前
0
雪    币: 7
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
感谢分享
2小时前
0
雪    币: 2
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
111
2小时前
0
雪    币: 8650
活跃值: (6417)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
感谢分享
1小时前
0
雪    币: 375
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
感谢分享
21分钟前
0
游客
登录 | 注册 方可回帖
返回