查看: 554|回复: 0

4399游戏盒最新算法讲解

[复制链接]

3123

主题

3123

帖子

50

积分

超级版主

Rank: 8Rank: 8

积分
50
发表于 2021-7-31 13:42:12 | 显示全部楼层 |阅读模式
第一次发教程 出现问题请见谅
这次是最新版本的4399游戏盒登陆密码加密讲解和两个sign的讲解  

由于我测试的时候是无法对这个APP进行IDA调试的 所以就静态分析了一下


  1. POST https://mapi.4399api.net/user/box/android/v1.0/log-in.html HTTP/1.1
  2. User-Agent: 4399GameCenter/5.2.0.39 (android;Nexus 6P;6.0;1440x2392;WIFI;1376.416;yaoqing)
  3. mareacode: 350100
  4. a-id: decd74ca59799d58
  5. e-id: 867981022896164
  6. m-id: D4%3A61%3A4E%3A13%3A10%3A1F
  7. s-id:
  8. mauth:
  9. mudid: 1085glt3vuUywD5g808eZb67a
  10. pauth:
  11. SM-DEVICEID: 2019101514035076086dc3e7e2dc00afe0043881a46e18018036cbcdd51ca5
  12. mdeviceId: 867981022896164
  13. mauthcode:
  14. Content-Type: application/x-www-form-urlencoded
  15. Content-Length: 161
  16. Host: mapi.4399api.net
  17. Connection: Keep-Alive
  18. Accept-Encoding: gzip
  19. password=JE%2FYTsyiLwE%3D&deviceIdentifier=867981022896164&dateline=1571863440&sign=c80c8c800fa61cccc02e12e87da33620&model=Nexus%206P&username=13665098754&info=1
复制代码
这是抓到的登陆包
大概能看到两个参数需要处理 一个password 一个sign

反编译

找到关键点

跟进以后就是Native函数了 这里我们从名字就能大概知道password是一个DESCBC类型的加密(不排除重写) 我们也只是猜测


  1. public class AppNativeHelper {
  2. static {
  3. try {
  4. SoFix.loadLibrary (BaseApplication.getApplication (), "m4399");
  5. Log.d ("AppNativeHelper", "load libm4399.so");
  6. }
  7. catch (SoLoadFailureException v0) {
  8. v0.printStackTrace ();
  9. }
  10. }
  11. public AppNativeHelper () {
  12. super ();
  13. }
  14. public static native int applyPatch (String arg0, String arg1, String arg2) {
  15. }
  16. public static native int delayRestartProcess (String arg0, String arg1, long arg2) {
  17. }
  18. public static final native String desCbcDecrypt (String arg0) {
  19. }
  20. public static final native String desCbcEncrypt (String arg0) {
  21. }
复制代码
拿出libm4399.so拖进IDA进行处理  

这个So是动态注册函数

所以我们进入Jni_onload 导入头文件 找到RegisterNatives函数
RegisterNatives中第三个参数就是我们注册Java函数的实际地址



进去以后是DCD格式的 第一项是函数名 第二项好像是格式还是啥 重要的是第三项 这就是我们的函数地址了 找到我们要的函数 然后找到函数地址


然后进来这个函数


  1. int __fastcall sub_17024(int a1, int a2)
  2. {
  3.   int v2; // r4
  4.   int v3; // r5
  5.   char *v4; // r6
  6.   int v5; // r0
  7.   int v6; // r3
  8.   char v7; // r2
  9.   int v8; // r4

  10.   v2 = a2;
  11.   v3 = a1;
  12.   v4 = sub_17274(9, 1);
  13.   v5 = 0;
  14.   do
  15.   {
  16.     v6 = (dword_1B040[-v5] + 101) >> 15;
  17.     v7 = v6 ^ 151;
  18.     if ( v6 >= 102 )
  19.       v7 = v6;
  20.     v4[-v5--] = v7;
  21.   }
  22.   while ( v5 != -8 );                           // 循环8次 获取DESkey
  23.   v8 = sub_64B8(v3, v2, v4);                    // //进入加密函数
  24.   sub_17284(v4);
  25.   return v8;
  26. }
复制代码


通过前前后后的分析 这里就是获取Key的重要地方了 从一个地址里面取值出来 然后循环处理8次 然后我们进入dword_1B040看




看不出什么猫腻 我们转换一下格式 先转Double再转为array IDA右键就有




然后我用js翻译了这小段so逻辑理清楚后一下子就明白了


  1. function get(a) {
  2.     v6 = (a + 101) >> 15;
  3.     v7 = v6 ^ 151;
  4.     if (v6 >= 102) {
  5.         v7 = v6;
  6.     }
  7.     return v7
  8. }
  9. function a() {
  10.     arr = [0x3A7F9B, 0xFFDAFF9B, 0x3EFF9B, 0xFFD9FF9B, 0xFFCFFF9B, 0xFFEB7F9B, 0x3B7F9B, 0xFFD37F9B];
  11.     var aa = new Array();
  12.     for (var i = 0; i < 8; i++) {
  13.         aa.push(get(arr))
  14.     }
  15.     return aa
  16. }
复制代码


这里返回的就应该是key数组了 {117,-223,126,-221,-201,-192,119,-208}
然后转换到易语言的字节集就是{117,33,126,35,55,64,119,48}文本为u!~#7@w0 (这里的转换就是由于其他语言的byte取值范围 -128~ 127) 易语言好像没上限 所以我们只需要把-的给他加上256就能变成易语言的字节集了)

到这一步我们已经拿到了KEY了

现在就差一步IV了

前面一直没说

因为这个so函数名全是匿名的 所以在分析的时候很难去判断这个函数到底是干嘛的 这种so分析起来就需要自己花点时间和结合经验来操作了

这里我都给大家分析完了





我们已经找到了最关键的加密点了 而且我们现在key也有了 只差IV了

sub_4720这个匿名函数其实就是DES_cbc_encrypt

void DES_ncbc_encrypt(const unsigned char *input,unsigned char *output,
              long length,DES_key_schedule *schedule,DES_cblock *ivec,
              int enc);

这是DES_cbc_encrypt参数的定义

依次是输入流 输出流 长度 key iv flag

恰好能 对应上我们的函数 所以 iv应该就是我们&v11所指向的值了


  1. .text:00006618 ; 20:   v12 = 0xEFCDAB90;
  2. .text:00006618                 LDR     R0, =0xEFCDAB90
  3. .text:0000661A                 STR     R0, [SP,#0xB0+var_9C]
  4. .text:0000661C ; 21:   v11 = 0x78563412;
  5. .text:0000661C                 LDR     R0, =0x78563412
  6. .text:0000661E                 STR     R0, [SP,#0xB0+var_A0]
复制代码
这里V11在我们的伪C代码中只赋值了0x78563412  但在汇编里面他实际是赋值了0xEFCDAB90 和0x78563412的 所以我们的iv应该就是0x1234567890ABCDEF

在我们运行的时候 取值事从后往前取得 两个一组 这个我确实也不太明白具体原因 也是在无名侠前辈哪里学得 也就是 EF CD AB 90 78 56 34 12 这样来拼接得

好了 现在我们key iv都有了 我们在不排除有变异得情况下可以来测试一下能不能解开密文




成功解开

这次so分析得难点其实就在于无法动态调试获取key或者IV 每一步逻辑都需要自己去看
其次就是全是匿名函数 需要自己花点时间去查看每个函数的功能

但总统上还是不算难得 只是需要慢慢琢磨一下得

实在是太累了 如果大家对登陆得sign和签到得sign有想法我下次再给大家写文章把




游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

快捷回复 【不要灌水喔,臭宝!】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则