安卓逆向 某程 encode 算法分析

admin 2025年3月21日10:38:59评论6 views字数 6391阅读21分18秒阅读模式

点击查看每日文末留言包邮送书活动规则

样本与之前的魔改MD5是同一个so,就换了个方法,直接IDA梭哈

第一个传参是明文,第二个传参是请求体的长度

安卓逆向  某程 encode 算法分析

代码逻辑很清晰了,将明文,明文长度和输出都传进了 ctrip_enc

直接进入 ctrip_enc

安卓逆向  某程 encode 算法分析

填充模式

这里可以看到他对明文长度进行了计算,将受影响的算法提取出来

 复制代码 隐藏代码if ( (input_len & 0xF) != 0 )    input_len_10 = (input_len + 16) & 0xFFFFFFF0;else    input_len_10 = input_len + 16;// ============================== //if ( (input_len & 0xF) != 0 )    v8 = 16 - (input_len & 0xF);else    v8 = 16;//===============================//input_ = (char *)malloc(input_len_10);memcpy(input_, input, (unsignedint)input_len);memset(&input_[input_len], v8, (unsignedint)(v8 - 1) + 1LL);
安卓逆向  某程 encode 算法分析
 复制代码 隐藏代码v10 = ctrip_enc_internal((__int64)input_, input_len_10, &v12, 16, output);

v12的值上面可以看到赋值是, v12 = xmmword_112D4; 直接点过去

安卓逆向  某程 encode 算法分析

看着啥也不像,长度正好为 16,暂且将这个当做一个 IV 吧

encrypt_one 生成真实key

进入方法 ctrip_enc_internal

安卓逆向  某程 encode 算法分析
安卓逆向  某程 encode 算法分析
 复制代码 隐藏代码void __fastcall encrypt_one(_OWORD *randomkey, _OWORD *iv, unsigned __int8 **a3){// [COLLAPSED LOCAL DECLARATIONS. PRESS NUMPAD "+" TO EXPAND]aes_gen_tables();  v6 = (unsigned __int8 *)malloc(0x10uLL);  *a3 = v6;  v7 = v6;  *(_OWORD *)v6 = *randomkey;  v8 = (int8x8_t *)malloc(0x10uLL);  *(_OWORD *)v8->n64_u64 = *iv;  sbox = get_sbox();  v10 = v7[1];  v11 = v7[2];  v12 = v7[3];  v13 = *(_BYTE *)(sbox + *v7);  v14 = v7[4];  v15 = v7[5];  v16 = v7[6];  *v7 = v13;LOBYTE(v10) = *(_BYTE *)(sbox + v10);  v17 = v7[7];  v18 = v7[8];  v19 = v7[9];  v7[1] = v10;LOBYTE(v11) = *(_BYTE *)(sbox + v11);  v20 = v7[10];  v21 = v7[11];  v22 = v7[12];  v7[2] = v11;LOBYTE(v12) = *(_BYTE *)(sbox + v12);  v27.n64_u8[0] = v13;  v23 = v7[13];  v27.n64_u8[1] = v10;  v7[3] = v12;LOBYTE(v14) = *(_BYTE *)(sbox + v14);  v24 = v7[14];  v27.n64_u8[2] = v11;  v25 = v7[15];  v7[4] = v14;LOBYTE(v15) = *(_BYTE *)(sbox + v15);  v27.n64_u8[3] = v12;  v27.n64_u8[4] = v14;  v26 = 2;  v7[5] = v15;LOBYTE(v16) = *(_BYTE *)(sbox + v16);  v27.n64_u8[5] = v15;  v7[6] = v16;LOBYTE(v17) = *(_BYTE *)(sbox + v17);  v27.n64_u8[6] = v16;  v7[7] = v17;LOBYTE(v18) = *(_BYTE *)(sbox + v18);  v27.n64_u8[7] = v17;  v7[8] = v18;LOBYTE(v19) = *(_BYTE *)(sbox + v19);  v29.n64_u8[0] = v18;  v7[9] = v19;LOBYTE(v20) = *(_BYTE *)(sbox + v20);  v29.n64_u8[1] = v19;  v7[10] = v20;LOBYTE(v21) = *(_BYTE *)(sbox + v21);  v29.n64_u8[2] = v20;  v7[11] = v21;  v28 = *(_BYTE *)(sbox + v22);  v29.n64_u8[3] = v21;  v7[12] = v28;LOBYTE(v10) = *(_BYTE *)(sbox + v23);  v29.n64_u8[4] = v28;  v7[13] = v10;LOBYTE(v11) = *(_BYTE *)(sbox + v24);  v29.n64_u8[5] = v10;  v7[14] = v11;  v29.n64_u8[6] = v11;  v29.n64_u8[7] = *(_BYTE *)(sbox + v25);  v7[15] = v29.n64_u8[7];while ( 1 )  {    v30 = veor_s8(v29, v8[1]).n64_u64[0];    *(int8x8_t *)v7 = veor_s8(v27, (int8x8_t)v8->n64_u64[0]);    *((_QWORD *)v7 + 1) = v30;row_rotation(v7, 4LL1LL);if ( !v26 )break;column_rotation(v8, 4LL1LL);    v31 = get_sbox();    v32 = v8->n64_u8[1];    v27.n64_u64[0] = *(unsigned __int64 *)v7;    v29.n64_u64[0] = *(_QWORD *)(v7 + 8);    --v26;    v8->n64_u8[0] = *(_BYTE *)(v31 + v8->n64_u8[0]);    v33 = *(_BYTE *)(v31 + v32);    v34 = v8->n64_u8[2];    v8->n64_u8[1] = v33;    v35 = *(_BYTE *)(v31 + v34);    v36 = v8->n64_u8[3];    v8->n64_u8[2] = v35;    v37 = *(_BYTE *)(v31 + v36);    v38 = v8->n64_u8[4];    v8->n64_u8[3] = v37;    v39 = *(_BYTE *)(v31 + v38);    v40 = v8->n64_u8[5];    v8->n64_u8[4] = v39;    v41 = *(_BYTE *)(v31 + v40);    v42 = v8->n64_u8[6];    v8->n64_u8[5] = v41;    v43 = *(_BYTE *)(v31 + v42);    v44 = v8->n64_u8[7];    v8->n64_u8[6] = v43;    v45 = *(_BYTE *)(v31 + v44);    v46 = v8[1].n64_u8[0];    v8->n64_u8[7] = v45;    v47 = *(_BYTE *)(v31 + v46);    v48 = v8[1].n64_u8[1];    v8[1].n64_u8[0] = v47;    v49 = *(_BYTE *)(v31 + v48);    v50 = v8[1].n64_u8[2];    v8[1].n64_u8[1] = v49;    v51 = *(_BYTE *)(v31 + v50);    v52 = v8[1].n64_u8[3];    v8[1].n64_u8[2] = v51;    v53 = *(_BYTE *)(v31 + v52);    v54 = v8[1].n64_u8[4];    v8[1].n64_u8[3] = v53;    v55 = *(_BYTE *)(v31 + v54);    v56 = v8[1].n64_u8[5];    v8[1].n64_u8[4] = v55;    v57 = *(_BYTE *)(v31 + v56);    v58 = v8[1].n64_u8[6];    v8[1].n64_u8[5] = v57;    v59 = *(_BYTE *)(v31 + v58);    v60 = v8[1].n64_u8[7];    v8[1].n64_u8[6] = v59;    v8[1].n64_u8[7] = *(_BYTE *)(v31 + v60);  }free(v8);}
安卓逆向  某程 encode 算法分析
 复制代码 隐藏代码v7= v6 = *randomkey; v8->n64_u64 = *iv; sbox = get_sbox(); 

这里然后将randomkey赋值给了v7,iv赋值给了v8, 以及获取了sbox

 复制代码 隐藏代码char *get_fbox(){aes_gen_tables();  return &byte_1D090;}

点过去 byte_1D090 发现没有值,那么aes_gen_tables 实际上就是为了给这个sbox赋值

安卓逆向  某程 encode 算法分析

unidbg 看下返回结果

安卓逆向  某程 encode 算法分析

对比标准的sbox

 复制代码 隐藏代码Sbox = (0x630x7C0x770x7B0xF20x6B0x6F0xC50x300x010x670x2B0xFE0xD70xAB0x76,0xCA0x820xC90x7D0xFA0x590x470xF00xAD0xD40xA20xAF0x9C0xA40x720xC0,    。。。。。。)
安卓逆向  某程 encode 算法分析
 复制代码 隐藏代码  v10 = v7[1];  LOBYTE(v10) = *(_BYTE *)(sbox + v10);  v11 = v7[2];  LOBYTE(v11) = *(_BYTE *)(sbox + v11);

不就是取值然后把取的值当成索引嘛,直接使用 java 进行还原

 复制代码 隐藏代码privatestaticvoidtake_sbox(byte[] data) {for (int i = 0; i < data.length; i++) {int byte_data = data[i] & 0xFF;            data[i] = SBOX[byte_data];        }    }

所以,这个方法前面的那么大一串,实际上6行就能解决,实际上就是做了s盒替换

行移位+列混淆

然后就进入了一个while循环

安卓逆向  某程 encode 算法分析

里面其实就调用了两个方法

 复制代码 隐藏代码row_rotation(v7, 4LL, 1LL);column_rotation(v8, 4LL, 1LL);
安卓逆向  某程 encode 算法分析
安卓逆向  某程 encode 算法分析

可以发现值的变换情况

 复制代码 隐藏代码执行前:D4 3F 8B 24 1A 5E 7E 9D2414 7E C6 49 7F DB 9E执行后:3F 8B 24 D4 7E 9D 1A 5E C6 2414 7E 49 7F DB 9E

注意观察不难发现,他是四个字节分组,然后第一组循环左移一位,第二组循环左移两位,第三组循环左移三位,第四组循环左移四位(等于没动)

就是标准AES的 行移位

 复制代码 隐藏代码D4 3824 --->3824 D4 //左移一位1579D --->7915//左移两位24147E C6 ---> C6 24147//左移三位497F DB 9E --->497F DB 9//左移四位(等于没动)

java 还原,懒得写逻辑,直接强行换位

安卓逆向  某程 encode 算法分析

ok,开始看那个列混淆

同样unidbg打断点,查看执行前后的值

安卓逆向  某程 encode 算法分析
 复制代码 隐藏代码执行前:C0 B4 0751A4A262 B3 30738146C5F275执行后:A47F25130C507 B3 46 B4 6281C0A2375

再次尝试找到规律

 复制代码 隐藏代码C0 B4 0751A47F251A4A262 B3     30C507 B330738146 B4 628146C5F275C0A2375
安卓逆向  某程 encode 算法分析
安卓逆向  某程 encode 算法分析
安卓逆向  某程 encode 算法分析

而方法传入都很明了,只有一个v22未知,那就v22基本就是IV了

IDA点过去查看v22的值

 复制代码 隐藏代码 xmmword_112C4   DCB 0x690xD20x550xB80x320x9E0xAC0xD40xC0x2A0x9C0x8B0x680x750x875

通过验证,是标准AES没有魔改,Key和IV也是对的

encrypt_two 随机key插入密文

 复制代码 隐藏代码encrypt_two(input, input_len_10, (__int64)&randomkey, iv_len, output);
安卓逆向  某程 encode 算法分析
 复制代码 隐藏代码  v10 = input_len & 0xFFFFFFFE;  v12 = 0;  v13 = 0;  v14 = input + 1;  v15 = v10;  do  {    v16 = *(v14 - 1);    v17 = *v14;    v14 += 2;    v15 -= 2LL;    v12 += v16;    v13 += v17;  }  while ( v15 );
安卓逆向  某程 encode 算法分析
 复制代码 隐藏代码 if ( v10 != input_len ) goto LABEL_9;LABEL_11: if ( ivlen < 1 ) goto LABEL_19;LABEL_12: if ( ivlen == 1 )  {    v21 = 0LL;  }  else

然后开始执行对 randomKey 的操作

 复制代码 隐藏代码    v21 = ivlen & 0xFFFFFFFE;    v22 = 0;    v23 = (unsigned __int8 *)(randomkey + 1);    v24 = v21;    do    {      v25 = *(v23 - 1);      v26 = *v23;      v23 += 2;      v24 -= 2LL;      v11 += v25;      v22 += v26;    }    while ( v24 );

同理,和input的处理是一样的,每次循环都依次往后取两位值,分别累加在v11和v22上

 复制代码 隐藏代码*output = malloc((int)(ivlen + input_len));result = memcpy(output, input, (int)input_len); if ( ivlen >= 1 )  {    v32 = 0LL;    LODWORD(i) = 0;    do    {      v34 = v32 + (int)input_len;      v35 = *output;      v36 = *(_BYTE *)(randomkey + v32);      for ( i = ((int)i + v11) % (int)(v32 + input_len) + 1LL; v34 > i; *v37 = v38 )      {        v37 = (_BYTE *)(v35 + v34);        v38 = *(_BYTE *)(v35 + v34-- - 1);      }      ++v32;      *(_BYTE *)(v35 + i) = v36;    }    while ( v32 != ivlen );  }
安卓逆向  某程 encode 算法分析
 复制代码 隐藏代码      for ( i = ((int)i + v11) % (int)(v32 + input_len) + 1LL; v34 > i; *v37 = v38 )      {        v37 = (_BYTE *)(v35 + v34);        v38 = *(_BYTE *)(v35 + v34-- - 1);      }
安卓逆向  某程 encode 算法分析

· 今 日 推 荐 ·

安卓逆向  某程 encode 算法分析

本文内容来自吾爱破解,如有侵权请联系删除

原文始发于微信公众号(逆向有你):安卓逆向 -- 某程 encode 算法分析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年3月21日10:38:59
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   安卓逆向 某程 encode 算法分析http://cn-sec.com/archives/3865596.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息