吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4754|回复: 75
收起左侧

[Android 原创] 某吱 app 逆向

  [复制链接]
P.Y.G-亮亮 发表于 2022-7-24 11:52

可以说是用了技巧吧 静态分析也是可以分析出来的

1.   事情起因

闲的

2.   使用jadx反编译apk文件(无壳)进行静态分析

2.1 搜索guid参数 定位代码位置 (选择第三个)

    public static String a() {
        StringBuffer stringBuffer = new StringBuffer();
        ExtraInfo b = b();
        stringBuffer.append("?userid=" + b.userid);
        stringBuffer.append("&adimei=" + Utils.b());
        stringBuffer.append("&adoaid=" + Utils.o());
        stringBuffer.append("&adandroidid=" + Utils.k());
        stringBuffer.append("&deviceid=" + Utils.j());
        stringBuffer.append("&platform=android");
        stringBuffer.append("&network=" + b.network);
        stringBuffer.append("&version=" + b.version);
        stringBuffer.append("&rand=" + b.rand);
        stringBuffer.append("&netspeed=1024");
        stringBuffer.append("&time=" + b.time);
        stringBuffer.append("&channel=" + AppEnvLite.k());
        stringBuffer.append("&dui=" + Utils.j());
        stringBuffer.append("&imei=" + Utils.b());
        stringBuffer.append("&guid=" + Security.init(AppEnvLite.d(), b, AppEnvLite.c));
        try {
            stringBuffer.append("&device=" + URLEncoder.encode(Build.DEVICE, "utf-8"));
            stringBuffer.append("&devicebrand=" + URLEncoder.encode(Build.BRAND, "utf-8"));
            stringBuffer.append("&devicemanufacturer=" + URLEncoder.encode(Build.MANUFACTURER, "utf-8"));
            stringBuffer.append("&model=" + URLEncoder.encode(DeviceUtils.b, "utf-8"));
            stringBuffer.append("&androidversion=" + URLEncoder.encode(Build.VERSION.RELEASE, "utf-8"));
            stringBuffer.append("&androidversioncode=" + URLEncoder.encode(Integer.valueOf(Build.VERSION.SDK_INT).toString(), "utf-8"));
        } catch (Throwable unused) {
        }
        try {
            stringBuffer.append("&smid=" + ShumeiUtilsLite.a());
            stringBuffer.append("&sm_deviceid=" + ShumeiUtilsLite.a());
        } catch (Throwable unused2) {
        }
        try {
            boolean c = EmulatorCheck.a().c();
            stringBuffer.append("&isEmulator=" + c);
        } catch (Exception unused3) {
        }
        return stringBuffer.toString();
    }
stringBuffer.append("&guid=" + Security.init(AppEnvLite.m35467d(), b, AppEnvLite.f56796c));

2.2 先看看他传参具体是什么

1. AppEnvLite.m35467d() 是一个 Context 类型的对象
    public static Context m35467d() {
        return f56806m;
    }
2. b 是由  m32322b 函数返回的一个自定义数据类型
ExtraInfo b = m32322b();

// m32322b 函数
public static ExtraInfo m32322b() {
        long currentTimeMillis = System.currentTimeMillis() / 1000;
        double random = Math.random();
        String aQ = UserUtilsLite.m28409aQ();
        if (aQ == null || aQ.length() < 2) {
            aQ = YoukeHelper.m27267a();
        }
        ExtraInfo extraInfo = new ExtraInfo();
        extraInfo.userid = aQ.trim();
        extraInfo.deviceId = C4681Utils.m27396j();
        extraInfo.network = m32309h(AppEnvLite.m35467d());
        extraInfo.version = AppEnvLite.m35462i();
        extraInfo.rand = String.valueOf(random);
        extraInfo.time = String.valueOf(currentTimeMillis);
        return extraInfo;
}
// ExtraInfo 数据类型
public class ExtraInfo {
    public String deviceId;
    public String network;
    public String rand;
    public String time;
    public String userid;
    public String version;
}
3. AppEnvLite.f56796c 是一个固定值
public static String f56796c = "3fwwdqy5jkozihv2naqebb0adsw7wsaq";

2.3 分析 Security.init 函数

进入 Security 类可以看到 他是进行了一个so库的调用 我们把他的 so 库文件拿出来
package com.huajiao.utils;

import android.content.Context;

/* loaded from: classes2.dex */
public class Security {
    public static native String convertKey(String str);

    public static native String decode(String str, String str2);

    public static native String init(Context context, ExtraInfo extraInfo, String str);

    static {
        System.loadLibrary("hjsecurity");
    }
}

2.   ida静态分析

ida -> Exports -> 找到 Java_com_huajiao_utils_Security_init 函数 -> 进入
进去以后 按F5生成 伪C代码  Ctrl+F9 加载JIN文件  并处理一下函数类型
int __fastcall Java_com_huajiao_utils_Security_init(_JNIEnv *env, jclass context, jclass extraInfo, jstring str)
{
  jclass v6; // r8
  const struct JNINativeInterface *functions; // r0
  int v8; // r0
  int v9; // r5
  int v10; // r1
  int v11; // r11
  int v12; // r10
  int v13; // r9
  void *v14; // r5
  int v15; // r2
  int v16; // r8
  int v17; // r0
  signed int v18; // r1
  char *v19; // r3
  signed int v20; // r5
  int v21; // r0
  int v22; // r3
  int v23; // r4
  int v24; // r9
  int v25; // r8
  int v26; // r5
  size_t v28; // [sp+0h] [bp-C0h] BYREF
  int v29; // [sp+4h] [bp-BCh]
  char *v30; // [sp+8h] [bp-B8h]
  size_t *v31; // [sp+Ch] [bp-B4h]
  void *v32; // [sp+10h] [bp-B0h]
  int v33; // [sp+14h] [bp-ACh]
  _JNIEnv *v34; // [sp+18h] [bp-A8h]
  char v35[16]; // [sp+1Ch] [bp-A4h] BYREF
  int v36[14]; // [sp+2Ch] [bp-94h]
  jstring v37; // [sp+64h] [bp-5Ch]
  void *v38; // [sp+68h] [bp-58h]
  jstring v39; // [sp+6Ch] [bp-54h]
  jstring v40; // [sp+70h] [bp-50h]
  void *v41; // [sp+74h] [bp-4Ch]
  jstring v42; // [sp+78h] [bp-48h]
  jstring v43; // [sp+7Ch] [bp-44h]
  void *v44; // [sp+80h] [bp-40h]
  jstring v45; // [sp+84h] [bp-3Ch]
  void *v46; // [sp+88h] [bp-38h]
  jstring v47; // [sp+8Ch] [bp-34h]
  void *v48; // [sp+90h] [bp-30h]
  jstring v49; // [sp+94h] [bp-2Ch]
  void *v50; // [sp+98h] [bp-28h]

  v32 = &_stack_chk_guard;
  v6 = env->functions->GetObjectClass(env, str);
  v37 = env->functions->NewStringUTF(env, "deviceid=");
  v38 = (void *)infoFiled(env, str, v6, "deviceId");
  v36[0] = env->functions->GetStringLength((JNIEnv *)env, v37);
  v36[1] = env->functions->GetStringLength((JNIEnv *)env, v38);
  v39 = env->functions->NewStringUTF(env, "netspeed=1024");
  v36[2] = env->functions->GetStringLength((JNIEnv *)env, v39);
  v40 = env->functions->NewStringUTF(env, "network=");
  v41 = (void *)infoFiled(env, str, v6, "network");
  v36[3] = env->functions->GetStringLength((JNIEnv *)env, v40);
  v36[4] = env->functions->GetStringLength((JNIEnv *)env, v41);
  v42 = env->functions->NewStringUTF(env, "platform=android");
  v36[5] = env->functions->GetStringLength((JNIEnv *)env, v42);
  v43 = env->functions->NewStringUTF(env, "rand=");
  v44 = (void *)infoFiled(env, str, v6, "rand");
  v36[6] = env->functions->GetStringLength((JNIEnv *)env, v43);
  v36[7] = env->functions->GetStringLength((JNIEnv *)env, v44);
  v45 = env->functions->NewStringUTF(env, "time=");
  v46 = (void *)infoFiled(env, str, v6, "time");
  v36[8] = env->functions->GetStringLength((JNIEnv *)env, v45);
  v36[9] = env->functions->GetStringLength((JNIEnv *)env, v46);
  v47 = env->functions->NewStringUTF(env, "userid=");
  v48 = (void *)infoFiled(env, str, v6, "userid");
  v36[10] = env->functions->GetStringLength((JNIEnv *)env, v47);
  v36[11] = env->functions->GetStringLength((JNIEnv *)env, v48);
  v49 = env->functions->NewStringUTF(env, "version=");
  v50 = (void *)infoFiled(env, str, v6, "version");
  v36[12] = env->functions->GetStringLength((JNIEnv *)env, v49);
  functions = env->functions;
  v34 = env;
  v36[13] = functions->GetStringLength(&env->functions, v50);
  v8 = 0;
  v9 = 0;
  while ( v8 != 14 )
  {
    v10 = v36[v8++];
    v9 += v10;
  }
  v30 = aEac63e66d8c4a6;
  v28 = strlen(aEac63e66d8c4a6);
  v29 = v28 + v9;
  v31 = &v28;
  v33 = (int)&v28 - ((v28 + v9 + 8) & 0xFFFFFFF8);
  v11 = 0;
  v12 = 0;
  while ( v11 != 14 )
  {
    v13 = 0;
    v14 = *(&v37 + v11);
    v15 = (int)v34->functions->GetStringUTFChars(&v34->functions, v14, 0);
    v16 = v36[v11];
    v17 = v33 + v12;
    while ( v13 < v16 )
    {
      *(_BYTE *)(v17 + v13) = *(_BYTE *)(v15 + v13);
      ++v13;
    }
    v34->functions->ReleaseStringUTFChars(&v34->functions, v14, (const char *)v15);
    v12 += v16;
    ++v11;
  }
  v18 = 0;
  v19 = v30;
  v20 = v28;
  v21 = v33 + v12;
  while ( v18 < v20 )
  {
    *(_BYTE *)(v21 + v18) = v19[v18];
    ++v18;
  }
  v22 = v33;
  v23 = (int)v34;
  *(_BYTE *)(v33 + v29) = 0;
  v24 = (*(int (__fastcall **)(int, int))(*(_DWORD *)v23 + 668))(v23, v22);
  v25 = (*(int (__fastcall **)(int, int))(*(_DWORD *)v23 + 656))(v23, v24);
  v26 = (*(int (__fastcall **)(int, int, _DWORD))(*(_DWORD *)v23 + 676))(v23, v24, 0);
  j_MD5(v26, v25, v35);
  (*(void (__fastcall **)(int, int, int))(*(_DWORD *)v23 + 680))(v23, v24, v26);
  return j_byteArrayToHex(v23, v35, 16);
}
v6 = env->functions->GetObjectClass(env, str); // 获取一个java类型
v37 = env->functions->NewStringUTF(env, "deviceid=");  // cstring-> jstring
v38 = (void *)infoFiled(env, str, v6, "deviceId"); // 取java类的 某一参数值
v36[0] = env->functions->GetStringLength((JNIEnv *)env, v37);  // 取jstring 的长度
因为C我也不是不会 但是能看懂几个函数就行  到时候使用 frida  hook  我们看到 最后是 使用 J_md5 进行加密的
  j_MD5(v26, v25, v35);
套娃????
// attributes: thunk
int __fastcall j_MD5(int a1, int a2, int a3)
{
  return MD5(a1, a2, a3);
}
最后函数 是MD5   我们就Hook 这个函数   写代码
void *__fastcall MD5(int a1, int a2, void *a3)
{
  void *v5; // r4
  _BYTE v7[92]; // [sp+0h] [bp-78h] BYREF

  v5 = &unk_A03C;
  if ( a3 )
    v5 = a3;
  if ( !j_MD5_Init(v7) )
    return 0;
  j_MD5_Update(v7, a1, a2);
  j_MD5_Final(v5, v7);
  j_OPENSSL_cleanse((int)v7, 0x5Cu);
  return v5;
}

3. frida hook

let SoName = "libhjsecurity.so";

function HookSoMd5() {
    let FuncAddr_MD5 = Module.findExportByName(SoName, "MD5")
    if (FuncAddr_MD5 != null) {
        console.log("Hook MD5函数 地址:" + FuncAddr_MD5)
        Interceptor.attach(FuncAddr_MD5, {
            onEnter: function (args) {
                console.log("[MD5] arge :", args[0].readCString())
            },
            onLeave: function (retval) {
                console.log("[MD5] retval:", hexdump(retval))
            }
        })
    }
}
function main() {
    HookSoMd5()
}
setImmediate(main)
注意:在Hook之前请先点击一下登录
frida -U -F -l .\Hook.js

[Mi MIX 2S::花吱 ]-> [MD5] arge : deviceid=c90d4cae48099b77fa3995042a961d6fnetspeed=1024network=wifiplatform=androidrand=0.8669308120110475time=1658394061userid=900270713970272598version=1.11.19.69eac63e66d8c4a6f0303f00bc76d0217c
[MD5] retval:            0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
ff84867c  ba cd 8f 98 3a 91 ed ff bf b2 1e 12 52 b8 fa 90  ....:.......R...
ff84868c  09 00 00 00 20 00 00 00 0d 00 00 00 08 00 00 00  .... ...........
ff84869c  04 00 00 00 10 00 00 00 05 00 00 00 12 00 00 00  ................
ff8486ac  05 00 00 00 0a 00 00 00 07 00 00 00 12 00 00 00  ................
ff8486bc  08 00 00 00 0a 00 00 00 81 00 00 00 91 00 00 00  ................
ff8486cc  a1 00 00 00 b5 00 00 00 c1 00 00 00 d1 00 00 00  ................
ff8486dc  e9 00 00 00 f1 00 00 00 01 01 00 00 11 01 00 00  ................
ff8486ec  29 01 00 00 35 01 00 00 41 01 00 00 55 01 00 00  )...5...A...U...
ff8486fc  f0 5d 7e 5c f0 5d 7e 5c 00 00 00 00 10 2a 80 ea  .]~\.]~\.....*..
ff84870c  98 03 87 13 70 10 87 13 3e 49 61 15 50 f9 0b 70  ....p...>Ia.P..p
ff84871c  60 00 87 13 20 bc 0e 70 d3 6d 9e c5 48 87 84 ff  `... ..p.m..H...
ff84872c  20 bc 0e 70 24 91 b6 df d4 93 84 ff 04 00 00 00   ..p$...........
ff84873c  20 a1 65 15 80 b1 58 15 98 03 87 13 f0 b7 5b 15   .e...X.......[.
ff84874c  07 00 00 00 06 00 00 00 00 00 40 3f 00 00 00 00  ..........@?....
ff84875c  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
ff84876c  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
deviceid=c90d4cae48099b77fa3995042a961d6fnetspeed=1024network=wifiplatform=androidrand=0.8669308120110475time=1658394061userid=900270713970272598version=1.11.19.69eac63e66d8c4a6f0303f00bc76d0217c
这一段就是 guid 生成的源文本了
直接md5加密 就好了 (注意替换需要的内容) 后面 eac63e66d8c4a6f0303f00bc76d0217c 是固定的

免费评分

参与人数 18威望 +1 吾爱币 +33 热心值 +18 收起 理由
rsdmain1o + 1 太叼了
Zz4794zZ + 1 + 1 谢谢@Thanks!
blabla1234 + 1 + 1 热心回复!
skiss + 1 + 1 谢谢@Thanks!
ddddhm + 1 + 1 我很赞同!
genon + 1 + 1 用心讨论,共获提升!
yechuze + 1 我很赞同!
LiLittleCat + 1 用心讨论,共获提升!
kingzswang + 1 用心讨论,共获提升!
努力加载中 + 1 + 1 热心回复!
笙若 + 1 + 1 谢谢@Thanks!
lingyun011 + 1 + 1 热心回复!
walykyy + 1 + 1 用心讨论,共获提升!
XXFFKK + 1 + 1 用心讨论,共获提升!
年轻真是可怕 + 1 + 1 我很赞同!
正己 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
李佑辰 + 1 + 1 我很赞同!
夜步城 + 1 + 1 来学习一下

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

李佑辰 发表于 2022-7-24 14:47
看起来不错的样子!
Maogoyi 发表于 2022-7-24 15:35
mahengyuan 发表于 2022-7-24 15:37
han1058349250 发表于 2022-7-24 15:53
看看大佬们的思路
w547890 发表于 2022-7-24 16:38
看看大佬们的思路
yeduwuren 发表于 2022-7-24 16:40
万分葱白,可惜不懂,我要好好学习天天向上
魔神哥哥bivi 发表于 2022-7-24 16:54
看起来很好啊~感谢分享
v12608 发表于 2022-7-24 16:55
看起来不错
pfy 发表于 2022-7-24 17:40
如果是套壳的怎么破?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 13:41

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表