首页
社区
课程
招聘
[原创] 车机OTA包解密
发表于: 2025-1-16 11:35 22510

[原创] 车机OTA包解密

2025-1-16 11:35
22510

唉,一言难尽,我的良马(ju)车机系统终于更新了,上了想要的功能,福音呀,盼了很久,终于更新了。

我就想着将OTA包里面的apk,直接提取出来,升级就行了,不需要更新车机系统了,结果失败!

拿到了心心念的OTA升级包,一打开。

哦豁~~~~

它竟然做了加密的,,,好惨

我就想着,既然这里做了加密,那么车机系统在拿到包后,肯定也需要进行解密才能去安装呀,于似乎带着好奇去看了看

在车机交流群里面,顺利拿到了负责车机升级的apk,拖进jadx 里面,找关键字,HuOs

还真找到了。

这不就是我升级的路径,和包格式嘛 .zip

跟着调用栈一路静态分析,结果追到了解密方法:

这里发现 包被进行了 "AES/CBC/PKCS5Padding" 的加密,车机系统拿到文件,进行解密后,再安装

又上一个步骤发现,是通过获取 "ckey" 的值,

然后使用 解密,对这个文件进行解密,获取前16 字节,作为系统包的aes key

想要解密这个就得两个步骤:

1、获取到这个ckey 这个文件 (万能的车友群 把文件给了我)

2、拿到 decrypt 的代码实现逻辑 (万能的车友群 把文件给了我)

步骤2 走了一些弯路

起初以为 decrypt 这个代码的实现是放在 boot-framework.vdex 、最后通过搜索,发现是放在

boot-ext.vdex 里面的。

这里就需要使用两个工具

最终打开,

解密方法则是将 文件的值,与一个key ,进到native 里面 计算出来

那么我们还需要获取到这个token :

通过静态分析,获取token的 通过获取升级 apk 下的一些文件值,在native 里面进行判断,最后返回出结果。

起初,我以为需要在native 里面进行计算,最后反编译进去一看,,

这...... 好家伙只是将获取的数据进行了对比,然后直接返回token, 想复杂了。。。。

前面既然已经拿到了 token ,那我们直接使用Unidbg 将 token 值,和ckey 的值传入,计算出结果即可

拿到key 了,返回第一步,使用AES/CBC/PKCS5Padding 解密,获得ota包

然后使用 开源工具

payload-dumper-go 将 payload.bin 提取出 system.img 即可:

就拿到了 想要的apk了

整体弄下来,花了一下午的时间,最开始想的太难了,动手起来,多亏了 万能的车群 提供了相应的文件进行分析,万事开头难,做起来就顺了。

整体分析难道不大,都是一些基础的调用,和简单的知识点结合就行。

int __fastcall Java_com_***_***_***_WhiteBoxNativeImpl_connectionToNativeVerifyDigest(JNIEnv *a1, int a2, int a3, size_t a4, int a5, int a6, size_t a7, int a8, int a9, int a10, int a11)
{
  _DWORD *v13; // r9
  const char *v14; // r5
  const char *v15; // r10
  int v16; // r0
  const char *v17; // r5
  jbyte *v18; // r4
  jbyte *v19; // r6
  jstring (*v20)(JNIEnv *, const char *); // r2
  const char *v21; // r1
  const char *v23; // r4
  void *v24; // r9
  const char *v25; // r10
  jbyte *v26; // r4
  jbyte *v27; // r5
  const char *v28; // [sp+1Ch] [bp-2Ch]
  const char *v29; // [sp+24h] [bp-24h]
 
  v13 = malloc(0x20u);
  v14 = (*a1)->GetStringUTFChars(a1, a9, 0);
  v15 = (*a1)->GetStringUTFChars(a1, a5, 0);
  if ( !j_readFileFromApk(v14, v15, v13) )
  {
    _android_log_print(4, "LeosinAcsctl: digest", "can't find file, LINE = %d", 275);
LABEL_8:
    v20 = (*a1)->NewStringUTF;
    v21 = "can't find file";
    return (int)v20(a1, v21);
  }
  v29 = v14;
  v16 = j_calculateDigest(a1, v13, a10);
  if ( !v16 || (v17 = (const char *)v16, !v13[4]) )
  {
    _android_log_print(4, "LeosinAcsctl: digest", "unsupproted signAlg, LINE = %d", 281);
    v20 = (*a1)->NewStringUTF;
    v21 = "unsupproted signAlg";
    return (int)v20(a1, v21);
  }
  v18 = (*a1)->GetByteArrayElements(a1, a3, 0);
  v19 = (jbyte *)malloc(a4);
  qmemcpy(v19, v18, a4);
  if ( strncmp(v17, v19, a4) )
  {
    _android_log_print(4, "LeosinAcsctl: digest", "mainfiestFileDigest is wrong, LINE = %d", 290);
    v20 = (*a1)->NewStringUTF;
    v21 = "mainfiestFileDigest is wrong";
    return (int)v20(a1, v21);
  }
  (*a1)->ReleaseByteArrayElements(a1, (jbyteArray)a3, v18, 2);
  (*a1)->ReleaseStringUTFChars(a1, (jstring)a5, v15);
  free(v19);
  free(v13);
  v23 = (*a1)->GetStringUTFChars(a1, a8, 0);
  v24 = malloc(0x20u);
  if ( !j_readFileFromApk(v29, v23, v24) )
  {
    _android_log_print(4, "LeosinAcsctl: digest", "can't find file, LINE = %d", 301);
    goto LABEL_8;
  }
  v28 = v23;
  v25 = (const char *)j_calculateDigest(a1, v24, a11);
  v26 = (*a1)->GetByteArrayElements(a1, a6, 0);
  v27 = (jbyte *)malloc(a4);
  qmemcpy(v27, v26, a7);
  __android_log_print(4, "LeosinAcsctl: digest", "dexClassDigestLen is %d", a7);
  __android_log_print(4, "LeosinAcsctl: digest", "dexClassDigestArr is %s", v27);
  __android_log_print(4, "LeosinAcsctl: digest", "dexClassDigest is %s", v25);
  if ( !strncmp(v27, v25, a7) )
  {
    (*a1)->ReleaseByteArrayElements(a1, (jbyteArray)a6, v26, 2);
    (*a1)->ReleaseStringUTFChars(a1, (jstring)a8, v28);
    free(v27);
    free(v24);
    (*a1)->ReleaseStringUTFChars(a1, (jstring)a9, v29);
    v20 = (*a1)->NewStringUTF;
    v21 = "****";
  }
  else
  {
    _android_log_print(4, "LeosinAcsctl: digest", "can't find file, LINE = %d", 313);
    v20 = (*a1)->NewStringUTF;
    v21 = "dexclass digest is wrong";
  }
  return (int)v20(a1, v21);
}
int __fastcall Java_com_***_***_***_WhiteBoxNativeImpl_connectionToNativeVerifyDigest(JNIEnv *a1, int a2, int a3, size_t a4, int a5, int a6, size_t a7, int a8, int a9, int a10, int a11)
{
  _DWORD *v13; // r9
  const char *v14; // r5
  const char *v15; // r10
  int v16; // r0
  const char *v17; // r5
  jbyte *v18; // r4
  jbyte *v19; // r6
  jstring (*v20)(JNIEnv *, const char *); // r2
  const char *v21; // r1
  const char *v23; // r4
  void *v24; // r9
  const char *v25; // r10
  jbyte *v26; // r4
  jbyte *v27; // r5
  const char *v28; // [sp+1Ch] [bp-2Ch]
  const char *v29; // [sp+24h] [bp-24h]
 
  v13 = malloc(0x20u);
  v14 = (*a1)->GetStringUTFChars(a1, a9, 0);
  v15 = (*a1)->GetStringUTFChars(a1, a5, 0);
  if ( !j_readFileFromApk(v14, v15, v13) )
  {
    _android_log_print(4, "LeosinAcsctl: digest", "can't find file, LINE = %d", 275);
LABEL_8:
    v20 = (*a1)->NewStringUTF;

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 5天前 被ty1937编辑 ,原因: 有点儿隐晦
收藏
免费 99
支持
分享
最新回复 (84)
雪    币: 105
活跃值: (4880)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
6666666666666666666666666
2025-1-16 11:48
0
雪    币: 144
活跃值: (328)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
6666666666666666666666666
2025-1-16 12:08
0
雪    币: 220
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
55555555太强了
2025-1-16 13:39
0
雪    币: 1549
活跃值: (3125)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
666
2025-1-16 13:48
0
雪    币: 383
活跃值: (202)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
你的分享对大家帮助很大,非常感谢!
2025-1-16 13:57
0
雪    币: 5
活跃值: (242)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
7
666
2025-1-16 14:20
0
雪    币: 708
活跃值: (670)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
好几年前的项目了还在升级呀,现在新项目好像都在锁adb,这种锁adb的咋开
2025-1-16 14:40
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
6666
2025-1-16 16:29
0
雪    币: 8
活跃值: (832)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
666666
2025-1-16 17:01
0
雪    币: 4244
活跃值: (2817)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
什么车友群这么强
2025-1-16 18:49
0
雪    币: 260
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
11
2025-1-16 19:13
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
11
2025-1-16 19:58
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
6666666
2025-1-16 21:13
0
雪    币: 184
活跃值: (682)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
牛逼
2025-1-17 07:55
0
雪    币: 24
活跃值: (1055)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
学习一哈
2025-1-17 08:44
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
17
1
2025-1-17 08:53
0
雪    币: 796
活跃值: (1639)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
18
66666666666
2025-1-17 09:21
0
雪    币: 200
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
666666
2025-1-17 09:45
0
雪    币: 2787
活跃值: (2857)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
20
《万能的车群》
2025-1-17 11:43
0
雪    币: 84
活跃值: (1948)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
有点意思
2025-1-17 12:33
1
雪    币: 1261
活跃值: (2338)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
万能的车友群
2025-1-17 14:27
0
雪    币: 315
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
23
群聊帮大忙了
2025-1-17 15:01
0
雪    币: 1519
活跃值: (4187)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
24
太有意思
2025-1-17 15:08
0
雪    币: 8894
活跃值: (4150)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
真有点意思
2025-1-17 15:12
2
游客
登录 | 注册 方可回帖
返回