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<Object> 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<Object> 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<Object> 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<Object> 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();
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容