开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 11331|回复: 11
收起左侧

[技术专题] 某吱app 逆向教程

[复制链接]
结帖率:100% (38/38)
发表于 2022-7-24 11:50:40 | 显示全部楼层 |阅读模式   江西省赣州市
一个小技巧吧没什么技术含量

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 是固定的

评分

参与人数 2好评 +2 精币 +5 收起 理由
宝宝好疼 + 1 + 3 共同努力,共同进步
金胖子 + 1 + 2 新技能已get√

查看全部评分


头像被屏蔽
发表于 2022-8-15 11:58:54 | 显示全部楼层   江苏省宿迁市
回复 支持 反对

使用道具 举报

发表于 2022-8-3 14:15:18 | 显示全部楼层   广东省广州市
谢谢分享
回复 支持 反对

使用道具 举报

发表于 2022-7-27 09:59:50 高大上手机用户 | 显示全部楼层   广东省惠州市
新手看不懂{:3_55:}{:3_55:}{:3_55:}
回复 支持 反对

使用道具 举报

结帖率:83% (10/12)
发表于 2022-7-26 20:57:32 | 显示全部楼层   安徽省滁州市
吾爱上面那一篇也你发的吧
回复 支持 反对

使用道具 举报

结帖率:83% (10/12)
发表于 2022-7-24 14:40:14 | 显示全部楼层   山东省枣庄市
tttlw 发表于 2022-7-24 14:18
Mix2s   自己**原生系统

谢谢
回复 支持 反对

使用道具 举报

结帖率:100% (38/38)

签到天数: 20 天

 楼主| 发表于 2022-7-24 14:18:50 | 显示全部楼层   江西省赣州市
金胖子 发表于 2022-7-24 14:04
问一下楼主hook用的什么手机

Mix2s   自己**原生系统
回复 支持 反对

使用道具 举报

结帖率:83% (10/12)
发表于 2022-7-24 14:04:04 | 显示全部楼层   山东省枣庄市
问一下楼主hook用的什么手机
回复 支持 反对

使用道具 举报

结帖率:39% (7/18)

签到天数: 4 天

发表于 2022-7-24 13:52:48 | 显示全部楼层   河南省周口市
那个app。让我弟弟们也去实战一下
回复 支持 反对

使用道具 举报

签到天数: 2 天

发表于 2022-7-24 12:54:12 | 显示全部楼层   黑龙江省哈尔滨市
学习了 顶顶顶
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

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