0xcafebabe 发布的文章

ByteAPK

Flutter rust bridge
ByteCTF{},总长度45
flag被通过ffi传到rust,然后utf8转成c string,去掉了ByteCTF{和后面的},传到一个函数里面check

unsigned char arr1[] =
{
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 
  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 
  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 
  0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 
  0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 
  0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
unsigned int enc[32] = {
    0x0001EE59, 0x0000022A, 0x00001415, 0x00040714, 0x000013E0, 0x000008B8, 0xFFFDCEA0, 0x0000313B, 
    0x0003D798, 0xFFFFFE6B, 0x00000C4E, 0x00023884, 0x0000008D, 0x00001DB4, 0xFFFC1328, 0x00001EAC, 
    0x00043C64, 0x0000142B, 0xFFFFF622, 0x00023941, 0xFFFFEF6D, 0x0000120C, 0xFFFBD30F, 0x00001EBE, 
    0x00045158, 0xFFFFEF66, 0x00001D3F, 0x0004C46B, 0xFFFFF97A, 0x00001BFD, 0xFFFBA235, 0x00001ED2
};

__int64 __fastcall final_enc(unsigned __int8 *flag_intern, __int64 a2)
{
  __int64 v2; // x9
  __int64 v3; // x9
  __int64 v4; // x9
  __int64 v5; // x9
  __int64 v6; // x9
  __int64 v7; // x9
  __int64 v8; // x9
  __int64 v9; // x9
  unsigned int v10; // w11
  int v11; // w13
  __int64 v12; // x9
  __int64 v13; // x9
  __int64 v14; // x9
  __int64 v15; // x9
  __int64 v16; // x9
  unsigned int v18; // w10
  int v19; // w13
  __int64 v20; // x9
  __int64 v21; // x9
  __int64 v22; // x9
  __int64 v23; // x9
  __int64 v24; // x9
  unsigned int v25; // w10
  int v26; // w13
  __int64 v27; // x9
  __int64 v28; // x9
  __int64 v29; // x9
  __int64 v30; // x9
  __int64 v31; // x9
  unsigned int v32; // w8
  int v33; // w11
  unsigned __int64 v34; // x20
  __int64 v35; // x21
  unsigned int v36; // w22
  int v37; // w8
  __int64 v38; // x10
  int v39; // w9
  unsigned __int64 v40; // x8
  __int64 v41; // x9
  unsigned __int64 v42; // x10
  unsigned __int64 v43; // x8
  int v44; // w12
  int v45; // w14
  int v46; // w3
  int v47; // w13
  int v48; // w2
  int v49; // w16
  int v50; // w15
  int v51; // w17
  int v52; // w6
  int v53; // w4
  int v54; // w12
  int *v55; // x13
  __int64 v57; // [xsp+8h] [xbp-48h] BYREF
  __int64 v58; // [xsp+10h] [xbp-40h]
  unsigned __int64 v59; // [xsp+18h] [xbp-38h]

  v57 = 0LL;
  v58 = 4LL;
  if ( a2 != 36 )
    return 0LL;
  v2 = arr1[*flag_intern];
  if ( (_DWORD)v2 == 36 )
    return 0LL;
  v3 = arr1[flag_intern[v2]] + v2;
  if ( v3 == 36 )
    return 0LL;
  v4 = v3 + arr1[flag_intern[v3]];
  if ( v4 == 36 )
    return 0LL;
  v5 = v4 + arr1[flag_intern[v4]];
  if ( v5 == 36 )
    return 0LL;
  v6 = v5 + arr1[flag_intern[v5]];
  if ( v6 == 36 )
    return 0LL;
  v7 = v6 + arr1[flag_intern[v6]];
  if ( v7 == 36 )
    return 0LL;
  v8 = v7 + arr1[flag_intern[v7]];
  if ( v8 == 36 )
    return 0LL;
  v9 = v8 + arr1[flag_intern[v8]];
  if ( v9 == 36 )
    return 0LL;
  v10 = flag_intern[v9];
  if ( (char)flag_intern[v9] < 0 )
  {
    if ( v10 < 0xE0 )
    {
      v10 = flag_intern[v9 + 1] & 0x3F | ((v10 & 0x1F) << 6);
    }
    else
    {
      v11 = flag_intern[v9 + 2] & 0x3F | ((flag_intern[v9 + 1] & 0x3F) << 6);
      if ( v10 < 0xF0 )
        v10 = v11 | ((v10 & 0x1F) << 12);
      else
        v10 = flag_intern[v9 + 3] & 0x3F | (v11 << 6) & 0xFFE3FFFF | ((v10 & 7) << 18);
    }
  }
  if ( v10 != 45 )
    return 0LL;
  v12 = v9 + arr1[flag_intern[v9]];
  if ( v12 == 36 )
    return 0LL;
  v13 = v12 + arr1[flag_intern[v12]];
  if ( v13 == 36 )
    return 0LL;
  v14 = v13 + arr1[flag_intern[v13]];
  if ( v14 == 36 )
    return 0LL;
  v15 = v14 + arr1[flag_intern[v14]];
  if ( v15 == 36 )
    return 0LL;
  v16 = v15 + arr1[flag_intern[v15]];
  if ( v16 == 36 )
    return 0LL;
  v18 = flag_intern[v16];
  if ( (char)flag_intern[v16] < 0 )
  {
    if ( v18 < 0xE0 )
    {
      v18 = flag_intern[v16 + 1] & 0x3F | ((v18 & 0x1F) << 6);
    }
    else
    {
      v19 = flag_intern[v16 + 2] & 0x3F | ((flag_intern[v16 + 1] & 0x3F) << 6);
      if ( v18 < 0xF0 )
        v18 = v19 | ((v18 & 0x1F) << 12);
      else
        v18 = flag_intern[v16 + 3] & 0x3F | (v19 << 6) & 0xFFE3FFFF | ((v18 & 7) << 18);
    }
  }
  if ( v18 != 45 )
    return 0LL;
  v20 = v16 + arr1[flag_intern[v16]];
  if ( v20 == 36 )
    return 0LL;
  v21 = v20 + arr1[flag_intern[v20]];
  if ( v21 == 36 )
    return 0LL;
  v22 = v21 + arr1[flag_intern[v21]];
  if ( v22 == 36 )
    return 0LL;
  v23 = v22 + arr1[flag_intern[v22]];
  if ( v23 == 36 )
    return 0LL;
  v24 = v23 + arr1[flag_intern[v23]];
  if ( v24 == 36 )
    return 0LL;
  v25 = flag_intern[v24];
  if ( (char)flag_intern[v24] < 0 )
  {
    if ( v25 < 0xE0 )
    {
      v25 = flag_intern[v24 + 1] & 0x3F | ((v25 & 0x1F) << 6);
    }
    else
    {
      v26 = flag_intern[v24 + 2] & 0x3F | ((flag_intern[v24 + 1] & 0x3F) << 6);
      if ( v25 < 0xF0 )
        v25 = v26 | ((v25 & 0x1F) << 12);
      else
        v25 = flag_intern[v24 + 3] & 0x3F | (v26 << 6) & 0xFFE3FFFF | ((v25 & 7) << 18);
    }
  }
  if ( v25 != 45 )
    return 0LL;
  v27 = v24 + arr1[flag_intern[v24]];
  if ( v27 == 36 )
    return 0LL;
  v28 = v27 + arr1[flag_intern[v27]];
  if ( v28 == 36 )
    return 0LL;
  v29 = v28 + arr1[flag_intern[v28]];
  if ( v29 == 36 )
    return 0LL;
  v30 = v29 + arr1[flag_intern[v29]];
  if ( v30 == 36 )
    return 0LL;
  v31 = v30 + arr1[flag_intern[v30]];
  if ( v31 == 36 )
    return 0LL;
  v32 = flag_intern[v31];
  if ( (char)flag_intern[v31] < 0 )
  {
    if ( v32 < 0xE0 )
    {
      v32 = flag_intern[v31 + 1] & 0x3F | ((v32 & 0x1F) << 6);
    }
    else
    {
      v33 = flag_intern[v31 + 2] & 0x3F | ((flag_intern[v31 + 1] & 0x3F) << 6);
      if ( v32 < 0xF0 )
        v32 = v33 | ((v32 & 0x1F) << 12);
      else
        v32 = flag_intern[v31 + 3] & 0x3F | (v33 << 6) & 0xFFE3FFFF | ((v32 & 7) << 18);
    }
  }
  if ( v32 != 45 )
    return 0LL;
  v34 = 0LL;
  v35 = 0LL;
  while ( 1 )
  {
    v36 = flag_intern[v35];
    if ( (char)flag_intern[v35] < 0 )
    {
      v37 = flag_intern[v35 + 1] & 0x3F;
      if ( v36 < 0xE0 )
      {
        v35 += 2LL;
        v36 = v37 & 0xFFFFF83F | ((v36 & 0x1F) << 6);
      }
      else
      {
        v38 = v35 + 3;
        v39 = flag_intern[v35 + 2] & 0x3F | (v37 << 6);
        if ( v36 < 0xF0 )
        {
          v36 = v39 | ((v36 & 0x1F) << 12);
          v35 += 3LL;
        }
        else
        {
          v35 += 4LL;
          v36 = flag_intern[v38] & 0x3F | (v39 << 6) & 0xFFE3FFFF | ((v36 & 7) << 18);
        }
      }
    }
    else
    {
      ++v35;
    }
    if ( v36 != 45 )
      break;
LABEL_55:
    if ( v35 == 36 )
      goto LABEL_67;
  }
  if ( v36 != 0x110000 )
  {
    if ( v34 == v57 )
      sub_3B688(&v57, a2);
    *(_DWORD *)(v58 + 4 * v34++) = v36;
    v59 = v34;
    goto LABEL_55;
  }
LABEL_67:
  v40 = v34 >> 3;
  v41 = 0LL;
  if ( (v34 & 7) != 0 )
    ++v40;
  v42 = v40 + 1;
  v43 = 8LL;
  while ( --v42 )
  {
    if ( v43 > v34 )
      goto LABEL_88;
    if ( v43 - 8 >= 0x19 )
    {
      v43 = 40LL;
      v34 = 32LL;
LABEL_88:
      panic(v43, v34, (__int64)&off_801E0);
    }
    v45 = *(_DWORD *)(v58 + v41 * 4 + 8);
    v44 = *(_DWORD *)(v58 + v41 * 4 + 12);
    v46 = *(_DWORD *)(v58 + v41 * 4);
    v47 = *(_DWORD *)(v58 + v41 * 4 + 4);
    v48 = *(_DWORD *)(v58 + v41 * 4 + 16);
    v49 = *(_DWORD *)(v58 + v41 * 4 + 20);
    v50 = *(_DWORD *)(v58 + v41 * 4 + 24);
    v51 = *(_DWORD *)(v58 + v41 * 4 + 28);
    if ( v51 + v47 * v44 * v49 - (v46 + v50 + v45 * v48) == enc[v41] )
    {
      v52 = v46 * v49;
      if ( v44 - v48 - v46 * v49 + v51 * v47 + v45 + v50 == enc[v41 + 1]
        && v52 - (v48 + v51 * v47) + v45 + v50 * v44 == enc[v41 + 2] )
      {
        v53 = v48 * v46;
        if ( v47 + v48 * v46 - (v51 + v45) + v50 * v49 * v44 == enc[v41 + 3]
          && v49 * v44 + v47 + v45 * v48 - (v50 + v51 * v46) == enc[v41 + 4]
          && v52 + v47 * v44 + v45 - (v50 + v48 * v51) == enc[v41 + 5]
          && v51 - v47 + v45 * v49 + v50 - v53 * v44 == enc[v41 + 6] )
        {
          v43 += 8LL;
          v54 = v44 - v51 - (v47 + v49);
          v55 = &enc[v41];
          v41 += 8LL;
          if ( v54 + v53 + v50 * v45 == v55[7] )
            continue;
        }
      }
    }
    if ( v57 )
      c_free(v58, 4 * v57, 4LL);
    return 0LL;
  }
  if ( v57 )
    c_free(v58, 4 * v57, 4LL);
  return 1LL;
}

通过观察,注意到前面的一堆是在检验是否是UUID,后面则是一个标准的z3题目。
exp

from regadgets import *
from z3 import *

enc = [
    0x0001EE59, 0x0000022A, 0x00001415, 0x00040714, 0x000013E0, 0x000008B8, 0xFFFDCEA0, 0x0000313B, 
    0x0003D798, 0xFFFFFE6B, 0x00000C4E, 0x00023884, 0x0000008D, 0x00001DB4, 0xFFFC1328, 0x00001EAC, 
    0x00043C64, 0x0000142B, 0xFFFFF622, 0x00023941, 0xFFFFEF6D, 0x0000120C, 0xFFFBD30F, 0x00001EBE, 
    0x00045158, 0xFFFFEF66, 0x00001D3F, 0x0004C46B, 0xFFFFF97A, 0x00001BFD, 0xFFFBA235, 0x00001ED2
]

for j in range(4):
    x = [BitVec(f"x{i+1}", 32) for i in range(8)]
    x1, x2, x3, x4, x5, x6, x7, x8 = tuple(i for i in x)
    s = Solver()
    for i in x:
        s.add(i > 0x20, i < 0x80)
    s.add(x8 + x2 * x4 * x6 - (x1 + x7 + x3 * x5) == enc[0+j*8])
    v52 = x1 * x6
    s.add(x4 - x5 - x1 * x6 + x8 * x2 + x3 + x7 == enc[1+j*8])
    s.add(v52 - (x5 + x8 * x2) + x3 + x7 * x4 == enc[2+j*8])
    v53 = x5 * x1
    s.add(x2 + x5 * x1 - (x8 + x3) + x7 * x6 * x4 == enc[3+j*8])
    s.add(x6 * x4 + x2 + x3 * x5 - (x7 + x8 * x1) == enc[4+j*8])
    s.add(v52 + x2 * x4 + x3 - (x7 + x5 * x8) == enc[5+j*8])
    s.add(x8 - x2 + x3 * x6 + x7 - v53 * x4 == enc[6+j*8])
    v54 = x4 - x8 - (x2 + x6)
    s.add(v54 + v53 + x7 * x3 == enc[7+j*8])
    
    if s.check() == sat:
        m = s.model()
        for i in x:
            l = m[i].as_long()
            print(l2b(l).decode(),end='')
            # 32e750c8fb214562af22973fb5176b9c
            # ByteCTF{32e750c8-fb21-4562-af22-973fb5176b9c}

x64_extension

AES-256 密钥扩增魔改
2024-09-20T16:26:55.png
2024-09-20T16:26:31.png

from regadgets import *
k = bytes([0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f])
iv = bytes([0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0])
a = AES(k)
data = open('flag.txt.enc', 'rb').read()
print(a.decrypt_cbc(data, iv))
# b"Hey Sekai CTF Player, I hope you are fine and are enjoying the CTF. Keep going, here is your reward! The flag is SEKAI{Pl34Se_It'5_jUs7_@_wAaaarmUp}\n"

SEKAI{Pl34Se_It'5_jUs7_@_wAaaarmUp}

迷宫

逆天题目,答案直接给你了。

FindTheKey

.so的JNI_OnLoad中,最后调用了sub_B004(前面都是frida检测),疑似是某个加固软件的,见了很多次。

int __fastcall sub_B004(JNIEnv *a1)
{
  jobject v2; // [sp+38h] [bp-E8h]
  jobject v3; // [sp+3Ch] [bp-E4h]
  jsize j; // [sp+40h] [bp-E0h]
  jobject ObjectArrayElement; // [sp+44h] [bp-DCh]
  jsize i; // [sp+48h] [bp-D8h]
  jobject v7; // [sp+4Ch] [bp-D4h]
  struct _jmethodID *v8; // [sp+50h] [bp-D0h]
  struct _jmethodID *v9; // [sp+54h] [bp-CCh]
  struct _jmethodID *v10; // [sp+58h] [bp-C8h]
  jclass v11; // [sp+5Ch] [bp-C4h]
  jobject v12; // [sp+60h] [bp-C0h]
  jobject v13; // [sp+64h] [bp-BCh]
  jobject v14; // [sp+68h] [bp-B8h]
  jobject v15; // [sp+6Ch] [bp-B4h]
  jobject v16; // [sp+70h] [bp-B0h]
  struct _jmethodID *v17; // [sp+74h] [bp-ACh]
  jclass v18; // [sp+78h] [bp-A8h]
  struct _jfieldID *v19; // [sp+7Ch] [bp-A4h]
  jclass v20; // [sp+80h] [bp-A0h]
  struct _jfieldID *v21; // [sp+84h] [bp-9Ch]
  jclass v22; // [sp+88h] [bp-98h]
  jobject clazz_loader; // [sp+8Ch] [bp-94h]
  struct _jmethodID *v24; // [sp+90h] [bp-90h]
  jclass v25; // [sp+94h] [bp-8Ch]
  jclass main_activity; // [sp+98h] [bp-88h]
  struct _jmethodID *v27; // [sp+9Ch] [bp-84h]
  struct _jmethodID *v28; // [sp+A0h] [bp-80h]
  void *v29; // [sp+A4h] [bp-7Ch]
  jmethodID StaticMethodID; // [sp+A8h] [bp-78h]
  jclass v31; // [sp+ACh] [bp-74h]
  void *ptr; // [sp+B4h] [bp-6Ch]
  void *v33; // [sp+B8h] [bp-68h]
  jint v34; // [sp+BCh] [bp-64h]
  struct _jmethodID *read__; // [sp+C0h] [bp-60h]
  jclass v36; // [sp+C4h] [bp-5Ch]
  jbyteArray _array_; // [sp+C8h] [bp-58h]
  jobject v38; // [sp+CCh] [bp-54h]
  struct _jmethodID *v39; // [sp+D0h] [bp-50h]
  size_t size; // [sp+D4h] [bp-4Ch]
  struct _jmethodID *v41; // [sp+D8h] [bp-48h]
  jclass v42; // [sp+DCh] [bp-44h]
  jobject v43; // [sp+E0h] [bp-40h]
  jstring v44; // [sp+E4h] [bp-3Ch]
  struct _jmethodID *v45; // [sp+ECh] [bp-34h]
  jclass v46; // [sp+F0h] [bp-30h]
  jobject v47; // [sp+F4h] [bp-2Ch]
  struct _jmethodID *MethodID; // [sp+F8h] [bp-28h]
  jclass v49; // [sp+FCh] [bp-24h]
  jobject ObjectField; // [sp+100h] [bp-20h]
  jobject StaticObjectField; // [sp+104h] [bp-1Ch]
  struct _jfieldID *FieldID; // [sp+108h] [bp-18h]
  struct _jfieldID *StaticFieldID; // [sp+10Ch] [bp-14h]
  jclass Class; // [sp+110h] [bp-10h]

  Class = FindClass(a1, asc_1F0A0);             // android/app/ActivityThread
  StaticFieldID = GetStaticFieldID(a1, Class, aWgqvvajpegpmrm, aDiflzgalIxxIkA);
  FieldID = GetFieldID(a1, Class, byte_1F280, byte_1F2A0);
  StaticObjectField = GetStaticObjectField(a1, Class, StaticFieldID);
  ObjectField = GetObjectField(a1, StaticObjectField, FieldID);
  v49 = FindClass(a1, aTHus5Jj5JjvsyN);         // android/app/Application
  MethodID = GetMethodID(a1, v49, byte_1F2D8, byte_1F2F0);
  v47 = CallObjectMethodV(a1, ObjectField, MethodID);
  v46 = FindClass(a1, byte_1F320);              // android/content/res/AssetManager
  v45 = GetMethodID(a1, v46, byte_1F341, byte_1F350);
  v44 = NewStringUTF(a1, aOKzLg);               // asset.bin
  v43 = CallObjectMethodV(a1, v47, v45, v44);
  v42 = FindClass(a1, aFicuhncDhisbis);         // android/content/res/AssetFileDescriptor
  v41 = GetMethodID(a1, v42, byte_1F3C8, byte_1F3D2);// getLength
  size = CallLongMethodV(a1, v43, v41);
  v39 = GetMethodID(a1, v46, "7(=6X", byte_1F3E0);// open
  v38 = CallObjectMethodV(a1, v47, v39, v44);
  _array_ = NewByteArray(a1, size);
  v36 = FindClass(a1, byte_1F410);              // java/io/InputStream
  read__ = GetMethodID(a1, v36, aRead, byte_1F429);// read ([BII)I
  v34 = CallIntMethodV(a1, v38, read__, _array_, 0, size);
  v33 = malloc(size);
  if ( v34 >= 1 )
    GetByteArrayRegion(a1, (int)_array_, 0, size, (int)v33);
  ptr = malloc(size);
  sub_AC38(unk_1F431, v33, size, ptr);          // RC4(goodluck)
  SetByteArrayRegion(a1, (int)_array_, 0, size, (int)ptr);
  if ( ptr )
    free(ptr);
  if ( v33 )
    free(v33);
  v31 = FindClass(a1, byte_1F440);
  StaticMethodID = GetStaticMethodID(a1, v31, byte_1F454, byte_1F460);
  v29 = (void *)sub_A234(a1, v31, StaticMethodID, size);
  v28 = GetMethodID(a1, v31, byte_1F479, byte_1F480);// put ([B)Ljava/nio/ByteBuffer;
  v27 = GetMethodID(a1, v31, byte_1F49A, byte_1F4B0);// position (I)Ljava/nio/Buffer;
  CallObjectMethodV(a1, v29, v28, _array_);
  CallObjectMethodV(a1, v29, v27, 0);
  main_activity = FindClass(a1, byte_1F4D0);    // com/ctf/findthekey/MainActivity
  v25 = FindClass(a1, a388v587V);               // java/lang/Class
                                                // 
  v24 = GetMethodID(a1, v25, byte_1F500, byte_1F510);// getClassLoader
  clazz_loader = CallObjectMethodV(a1, main_activity, v24);
  v22 = FindClass(a1, byte_1F530);
  v21 = GetFieldID(a1, v22, byte_1F54E, aVVlsq5icin);// pathList Ldalvik/system/DexPathList;
  v20 = FindClass(a1, byte_1F580);              // dalvik/system/DexPathList
  v19 = GetFieldID(a1, v20, ":;&\x1B2;3;0*-^", byte_1F5B0);// dexElements [Ldalvik/system/DexPathList$Element;
  v18 = FindClass(a1, byte_1F5E0);              // dalvik/system/InMemoryDexClassLoader
  v17 = GetMethodID(a1, v18, "k>9>#iW", byte_1F610);
  v16 = NewObjectV(a1, v18, v17, v29, clazz_loader);
  v15 = GetObjectField(a1, v16, v21);
  v14 = GetObjectField(a1, v15, v19);
  v13 = GetObjectField(a1, clazz_loader, v21);
  v12 = GetObjectField(a1, v13, v19);
  v11 = FindClass(a1, byte_1F640);              // java/util/ArrayList
  v10 = GetMethodID(a1, v11, aJoo, byte_1F660);
  v9 = GetMethodID(a1, v11, aCxveevn7, byte_1F680);
  v8 = GetMethodID(a1, v11, "k>9>#iW", byte_1F696);
  v7 = NewObjectV(a1, v11, v8);
  for ( i = 0; i < GetArrayLength(a1, v14); ++i )
  {
    ObjectArrayElement = GetObjectArrayElement(a1, v14, i);
    CallBooleanMethodV(a1, v7, v10, ObjectArrayElement);
  }
  for ( j = 0; j < GetArrayLength(a1, v12); ++j )
  {
    v3 = GetObjectArrayElement(a1, v12, j);
    CallBooleanMethodV(a1, v7, v10, v3);
  }
  v2 = CallObjectMethodV(a1, v7, v9);
  return SetObjectField(a1, (int)v13, (int)v19, (int)v2);
}

显然是读取了Assets的asset.bin,然后走rc4解密

int __fastcall sub_AC38(const char *k, char *key, unsigned int len, char *buf)
{
  char S[256]; // [sp+34h] [bp-114h] BYREF

  rc4_init(k, S);
  rc4_crypt(S, key, buf, len);
  return 0;
}
int __fastcall rc4_init(const char *k, const char *S)
{
  int j; // [sp+18h] [bp-20h]
  int i; // [sp+1Ch] [bp-1Ch]
  int v5; // [sp+20h] [bp-18h]
  signed int v6; // [sp+24h] [bp-14h]

  v6 = strlen(k);
  v5 = 0;
  for ( i = 0; i <= 255; ++i )
    S[i] = i;
  for ( j = 0; j <= 255; ++j )
  {
    v5 = ((unsigned __int8)k[j % v6] + v5 + (unsigned __int8)S[j]) % 256;
    swap(&S[j], &S[v5]);
  }
  return 0;
}
int __fastcall rc4_crypt(char *S, char *a2, char *dest, unsigned int len)
{
  unsigned int i; // [sp+1Ch] [bp-24h]
  int v6; // [sp+20h] [bp-20h]
  int v7; // [sp+24h] [bp-1Ch]

  v7 = 0;
  v6 = 0;
  for ( i = 0; i < len; ++i )
  {
    v7 = (v7 + 1) % 256;
    v6 = (v6 + (unsigned __int8)S[v7]) % 256;
    swap(&S[v7], &S[v6]);
    dest[i] = S[(unsigned __int8)(S[v7] + S[v6])] ^ a2[i];
  }
  return 0;
}
int __fastcall swap(_BYTE *a1, _BYTE *a2)
{
  int result; // r0
  int v3; // [sp+8h] [bp-Ch]

  v3 = (unsigned __int8)*a1;
  *a1 = *a2;
  result = v3;
  *a2 = v3;
  return result;
}

然后解密了asset.bin就可以直接拖入jadx了
2024-09-18T09:07:20.png
覆盖Util.java,换表base64+rc4,就可以CyberChef解了。