tujia民宿X-TJH及请求数据unidbg实现

tujia民宿X-TJH及请求数据unidbg实现

环境

app 8.45.0

Java层

image-20220115175957610

jadx搜索x-tjh

image-20220114094819029

com.tujia.libs.engine.model.TJRequest.g

image-20220114094910472

com.tujia.gundam.Gundam.a

com.tujia.gundam.Gundam.encrypt

image-20220114095059033

最终X-TJH是调用encrypt函数,请求数据是调用BodyEncrypt函数,这两个函数都是在libtujia_encrypt.so中。

hook看看输入

android hooking watch class_method com.tujia.gun dam.Gundam.encrypt --dump-args --dump-return
android hooking watch class_method com.tujia.gun dam.Gundam.bodyEncrypt --dump-args --dump-return

固定参数

为了方便之后的逆向,frida固定输入,然后看看加密结果。

function call_encrypt() {
    var Gundam = Java.use("com.tujia.gundam.Gundam");
    var body = "{\"code\":\"hello everhu\"}";
    var ret = Gundam.encrypt(
        "key=nodeApiConfig",
        "Mozilla/5.0",
        "LON=null;LAT=null;",
        body,
        body.length,
        1642084337
        );
    console.log(ret);
}
image-20220115173630928
function call_bodyEncrypt() {
    var Gundam = Java.use("com.tujia.gundam.Gundam");
    var salt = "everever";
    var body = "{\"code\":\"hello everhu\"}";
    var ret = Gundam.bodyEncrypt(
        "3",
        1642126567,
        salt,
        salt.length,
        body,
        body.length
    );
    console.log(ret);
}
image-20220115173653851

unidbg实现

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

    public static String pkgName = "com.tujia.hotel";
    public static String apkPath = "unidbg-android/src/test/java/com/tujia/tujia8450.apk";
    public static String soPath = "";

    public TuJia() {
        emulator = AndroidEmulatorBuilder.for32Bit().setProcessName(pkgName).build();
        Memory memory = emulator.getMemory();
        memory.setLibraryResolver(new AndroidResolver(23));
        vm = emulator.createDalvikVM(new File(apkPath));
        vm.setJni(this);
        vm.setVerbose(true);
        DalvikModule dm = vm.loadLibrary("tujia_encrypt", true);
        module = dm.getModule();
        dm.callJNI_OnLoad(emulator);
    }

    public static void main(String[] args) {
        TuJia test = new TuJia();
    }
}
image-20220114102849839
@Override
public DvmObject callStaticObjectMethod(BaseVM vm, DvmClass dvmClass, String signature, VarArg varArg) {
    switch (signature) {
        case "com/tujia/hotel/TuJiaApplication->getInstance()Lcom/tujia/hotel/TuJiaApplication;": {
            return vm.resolveClass("com/tujia/hotel/TuJiaApplication").newObject(null);
        }
    }
    return super.callStaticObjectMethod(vm, dvmClass, signature, varArg);
}
image-20220114103058398
@Override
public DvmObject callObjectMethod(BaseVM vm, DvmObject dvmObject, String signature, VarArg varArg) {
    switch (signature) {
        case "com/tujia/hotel/TuJiaApplication->getPackageName()Ljava/lang/String;": {
            return new StringObject(vm, pkgName);
        }
    }
    return super.callObjectMethod(vm, dvmObject, signature, varArg);
}
image-20220114103250647
case "com/tujia/hotel/TuJiaApplication->getPackageManager()Landroid/content/pm/PackageManager;": {
    return vm.resolveClass("android/content/pm/PackageManager").newObject(null);
}
image-20220114103435638
case "java/security/MessageDigest->getInstance(Ljava/lang/String;)Ljava/security/MessageDigest;": {
    try {
        MessageDigest digest = MessageDigest.getInstance(varArg.getObjectArg(0).getValue().toString());
        return vm.resolveClass("java/security/MessageDigest").newObject(digest);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
}
image-20220114103802311
case "java/security/MessageDigest->digest([B)[B": {
    MessageDigest digest = (MessageDigest) dvmObject.getValue();
    byte[] data = digest.digest((byte[]) varArg.getObjectArg(0).getValue());
    return new ByteArray(vm, data);
}
image-20220114104057496

JNI_OnLoad补完了,开始调用。

public void call_encrypt() {
    List list = new ArrayList<>(10);
    list.add(vm.getJNIEnv());
    list.add(vm.addLocalObject(0);
    // url params
    list.add(vm.addLocalObject(new StringObject(vm, "key=nodeApiConfig")));
    // user-agent
    list.add(vm.addLocalObject(new StringObject(vm, "Mozilla/5.0")));
    // X-App-Client
    list.add(vm.addLocalObject(new StringObject(vm, "LON=null;LAT=null;")));
    // POST body
    String body = "{\"code\":\"hello everhu\"}";
    System.out.println("Body length:" + body.getBytes(StandardCharsets.UTF_8).length);
    list.add(vm.addLocalObject(new StringObject(vm, body)));
    list.add(body.getBytes(StandardCharsets.UTF_8).length);
    // ts
    list.add(1642084337L);

    Number ret = module.callFunction(emulator, 0x36a9, list.toArray());
    System.out.println("encrypt ret: " + vm.getObject(ret.intValue()).getValue().toString());
}

public static void main(String[] args) {
    TuJia test = new TuJia();
    test.call_encrypt();
}

image-20220115173445530
public void call_bodyEncrypt() {
        List list = new ArrayList<>(10);
        list.add(vm.getJNIEnv());
        list.add(0);

        // ver
        list.add(vm.addLocalObject(new StringObject(vm, "3")));
        // ts
        list.add(1642126567L);
        // salt
        String salt = "everever";
        list.add(vm.addLocalObject(new StringObject(vm, salt)));
        list.add(salt.getBytes(StandardCharsets.UTF_8).length);
        // body
        String body = "{\"code\":\"hello everhu\"}";
        list.add(vm.addLocalObject(new StringObject(vm, body)));
        list.add(body.getBytes(StandardCharsets.UTF_8).length);

        Number ret = module.callFunction(emulator, 0x380d, list.toArray());
        System.out.println("bodyEncrypt ret: " + vm.getObject(ret.intValue()).getValue().toString());
    }

image-20220117162407730

完整实现

package com.tujia;

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.array.ByteArray;
import com.github.unidbg.memory.Memory;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

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

    public static String pkgName = "com.tujia.hotel";
    public static String apkPath = "unidbg-android/src/test/java/com/tujia/tujia8450.apk";
    public static String soPath = "";

    public TuJia() {
        emulator = AndroidEmulatorBuilder.for32Bit().setProcessName(pkgName).build();
        Memory memory = emulator.getMemory();
        memory.setLibraryResolver(new AndroidResolver(23));
        vm = emulator.createDalvikVM(new File(apkPath));
        vm.setJni(this);
        vm.setVerbose(true);
        DalvikModule dm = vm.loadLibrary("tujia_encrypt", true);
        module = dm.getModule();
        dm.callJNI_OnLoad(emulator);

        emulator.attach().addBreakPoint(module.base + 0x302c+1);
    }

    @Override
    public DvmObject callStaticObjectMethod(BaseVM vm, DvmClass dvmClass, String signature, VarArg varArg) {
        switch (signature) {
            case "com/tujia/hotel/TuJiaApplication->getInstance()Lcom/tujia/hotel/TuJiaApplication;": {
                return vm.resolveClass("com/tujia/hotel/TuJiaApplication").newObject(null);
            }
            case "java/security/MessageDigest->getInstance(Ljava/lang/String;)Ljava/security/MessageDigest;": {
                try {
                    MessageDigest digest = MessageDigest.getInstance(varArg.getObjectArg(0).getValue().toString());
                    return vm.resolveClass("java/security/MessageDigest").newObject(digest);
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                }
            }
        }
        return super.callStaticObjectMethod(vm, dvmClass, signature, varArg);
    }

    @Override
    public DvmObject callObjectMethod(BaseVM vm, DvmObject dvmObject, String signature, VarArg varArg) {
        switch (signature) {
            case "com/tujia/hotel/TuJiaApplication->getPackageName()Ljava/lang/String;": {
                return new StringObject(vm, pkgName);
            }
            case "com/tujia/hotel/TuJiaApplication->getPackageManager()Landroid/content/pm/PackageManager;": {
                return vm.resolveClass("android/content/pm/PackageManager").newObject(null);
            }
            case "java/security/MessageDigest->digest([B)[B": {
                MessageDigest digest = (MessageDigest) dvmObject.getValue();
                byte[] data = digest.digest((byte[]) varArg.getObjectArg(0).getValue());
                return new ByteArray(vm, data);
            }
        }
        return super.callObjectMethod(vm, dvmObject, signature, varArg);
    }

    public void call_encrypt() {
        List list = new ArrayList<>(10);
        list.add(vm.getJNIEnv());
        list.add(0);
        // url params
        list.add(vm.addLocalObject(new StringObject(vm, "key=nodeApiConfig")));
        // user-agent
        list.add(vm.addLocalObject(new StringObject(vm, "Mozilla/5.0")));
        // X-App-Client
        list.add(vm.addLocalObject(new StringObject(vm, "LON=null;LAT=null;")));
        // POST body
        String body = "{\"code\":\"hello everhu\"}";
        System.out.println("Body length:" + body.getBytes(StandardCharsets.UTF_8).length);
        list.add(vm.addLocalObject(new StringObject(vm, body)));
        list.add(body.getBytes(StandardCharsets.UTF_8).length);
        // ts
        list.add(1642084337L);

        Number ret = module.callFunction(emulator, 0x36a9, list.toArray());
        System.out.println("encrypt ret: " + vm.getObject(ret.intValue()).getValue().toString());
    }

    public void call_bodyEncrypt() {
        List list = new ArrayList<>(10);
        list.add(vm.getJNIEnv());
        list.add(0);

        // ver
        list.add(vm.addLocalObject(new StringObject(vm, "3")));
        // ts
        list.add(1642126567L);
        // salt G-TJS
        String salt = "everever";
        list.add(vm.addLocalObject(new StringObject(vm, salt)));
        list.add(salt.getBytes(StandardCharsets.UTF_8).length);
        // body
        String body = "{\"code\":\"hello everhu\"}";
        list.add(vm.addLocalObject(new StringObject(vm, body)));
        list.add(body.getBytes(StandardCharsets.UTF_8).length);

        Number ret = module.callFunction(emulator, 0x380d, list.toArray());
        System.out.println("bodyEncrypt ret: " + vm.getObject(ret.intValue()).getValue().toString());
    }

    public static void main(String[] args) {
        TuJia test = new TuJia();
        test.call_encrypt();
//        test.call_bodyEncrypt();
    }
}






你可能感兴趣的:(tujia民宿X-TJH及请求数据unidbg实现)