首页
社区
课程
招聘
逆向分析sign算法(题目出自看雪高研班2021年11月份作业)
发表于: 2022-7-17 18:27 18207

逆向分析sign算法(题目出自看雪高研班2021年11月份作业)

2022-7-17 18:27
18207

还原的代码在附件中,编译:g++ main.cpp base64.c

纯c算法的逆向,有很多的ollvm,所以这道题完成以后可以更加熟悉处理ollvm的程序。

经过初步分析算法的输入为MainActivity类的firstInstallTime,packageCodePath,randomLong,startTime四个成员变量,与MainActivity.randomLong无关
固定住输入好分析:
老方法,使用frida固定住这四个变量的输入方便记录分析,我这里四个变量的取值为:

经过算法的输出为36b0d7a02b934a38fffd51f0be37c661fdf6896e81d82c4dde65fb194268e9cd00c301110281011c028100c302810071007100c300bd0190023e014a01a30281022a00a8020400be014a01900156015602e2023e010b022a011101a3010b02c702c7012c012d01c10208019c0147012c0294023a01d100a900a70249008601ca007202b60135009e02d601e001e002a2028b028b00c3012b028101c100be014a0281007101a3ahryb3qMnhySa3mLbQeOakeQb3ySaK==

三段结果:
结果分为三段,三段由不同的算法处理,由sprintf组装,具体的逻辑在sub_12AE4

再分析过程中发现sha256的常数:0x6a09e667,0xbb67ae85,实现函数为sub_1B1E8,但这个实现是个sha256的变种,输入的字符串有时为64个字节未做padding的字符串,通过nop掉ollvm的控制块,修复真实块的关系,以及还原ollvm指令替换,得到的sub_1B1E8函数的代码片段为:

像这样的代码有64处,和sha256的处理吻合。

sub_26300我这里用了trace的方式还原,代码片段如下:

其实里边的指令是指令替换,一大堆的操作最后可能就是做了一个异或,只不过当时没看注意。

第二段算法的还原代码为:

其中dword_5C008为642个int长度的数组,元素列表为:

当时看到这么大的数组,就怀疑是不是哪个算法的常量,我没看出来,但可以确定的是确实是个常量数组。

是一个改了字典表的base64,字典表如下:

也就是"0123456789-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ="
还原代码如下:

cls.startTime.value = 0x17d472e9806;
cls.firstInstallTime.value = 0x17d41d64983;
cls.randomLong.value = 0x49536c10125ac000;
cls.packageCodePath.value = "/data/app/com.kanxue.ollvm_ndk_11-7sJSh-MLUIRVBOWzGqFjjw==/base.apk";
cls.startTime.value = 0x17d472e9806;
cls.firstInstallTime.value = 0x17d41d64983;
cls.randomLong.value = 0x49536c10125ac000;
cls.packageCodePath.value = "/data/app/com.kanxue.ollvm_ndk_11-7sJSh-MLUIRVBOWzGqFjjw==/base.apk";
 
v231 = *v594;
    v232 = *v588;
    v233 = *v590;
    v234 = (unsigned int)*v591;
    v235 = *v592;
    v587 = a2_arg + 1;
    v654 = a2_arg + 1;
    v236 = a2_arg[1] << 24;
    v237 = (*v654 ^ 0xFF00FFFF) & *v654;
    v238 = ((*v654 << 8) ^ 0xFF00FF00) & (*v654 << 8);
    v657 = HIBYTE(a2_arg[1]);
    v658 = v237;
    v659 = v657 | (v658 >> 8);
    v660 = v238;
    v239 = v659 | v236;
    v656 = v239 | v660;
    v655 = v656;
    v581 = v656;
    sub_26300(v231, v661, v232, v589, v233, v234, v235, v593, v656 + 1899447441); //2
 
    v240 = *v593;
    v241 = *v594;
    v242 = *v589;
    v243 = *v590;
    v244 = (unsigned int)*v591;
    v654 = a2_arg + 2;
    v245 = a2_arg[2] << 24;
    v246 = a2_arg[2] & 0xFF0000;
    v247 = (a2_arg[2] << 8) & 0xFF0000;
    v657 = HIBYTE(a2_arg[2]);
    v658 = v246;
    v659 = v657 | (v658 >> 8);
    v660 = v247;
    v656 = v659 | v245 | v660;
    v655 = v656;
    v582 = v656;
    sub_26300(v240, v241, v661, v588, v242, v243, v244, v592, v656 - 1245643825); //3
 
    v248 = *v592;
    v249 = *v593;
    v250 = *v594;
    v251 = *v588;
    v252 = *v589;
    v253 = *v590;
    v587 = a2_arg + 3;
    v654 = a2_arg + 3;
    v254 = a2_arg[3] << 24;
    v255 = a2_arg[3] & 0xFF0000;
    v256 = (a2_arg[3] << 8) & 0xFF0000;
    v657 = HIBYTE(a2_arg[3]);
    v658 = v255;
    v659 = v657 | (v658 >> 8);
    v660 = v256;
    v257 = v659 | v254;
    v656 = v257 | v660;
    v655 = v656;
    v578 = v656;
    sub_26300(v248, v249, v250, &v661, v251, v252, v253, v591, v656 - 373957723); //4
v231 = *v594;
    v232 = *v588;
    v233 = *v590;
    v234 = (unsigned int)*v591;
    v235 = *v592;
    v587 = a2_arg + 1;
    v654 = a2_arg + 1;
    v236 = a2_arg[1] << 24;
    v237 = (*v654 ^ 0xFF00FFFF) & *v654;
    v238 = ((*v654 << 8) ^ 0xFF00FF00) & (*v654 << 8);
    v657 = HIBYTE(a2_arg[1]);
    v658 = v237;
    v659 = v657 | (v658 >> 8);
    v660 = v238;
    v239 = v659 | v236;
    v656 = v239 | v660;
    v655 = v656;
    v581 = v656;
    sub_26300(v231, v661, v232, v589, v233, v234, v235, v593, v656 + 1899447441); //2
 
    v240 = *v593;
    v241 = *v594;
    v242 = *v589;
    v243 = *v590;
    v244 = (unsigned int)*v591;
    v654 = a2_arg + 2;
    v245 = a2_arg[2] << 24;
    v246 = a2_arg[2] & 0xFF0000;
    v247 = (a2_arg[2] << 8) & 0xFF0000;
    v657 = HIBYTE(a2_arg[2]);
    v658 = v246;
    v659 = v657 | (v658 >> 8);
    v660 = v247;
    v656 = v659 | v245 | v660;
    v655 = v656;
    v582 = v656;
    sub_26300(v240, v241, v661, v588, v242, v243, v244, v592, v656 - 1245643825); //3
 
    v248 = *v592;
    v249 = *v593;
    v250 = *v594;
    v251 = *v588;
    v252 = *v589;
    v253 = *v590;
    v587 = a2_arg + 3;
    v654 = a2_arg + 3;
    v254 = a2_arg[3] << 24;
    v255 = a2_arg[3] & 0xFF0000;
    v256 = (a2_arg[3] << 8) & 0xFF0000;
    v657 = HIBYTE(a2_arg[3]);
    v658 = v255;
    v659 = v657 | (v658 >> 8);
    v660 = v256;
    v257 = v659 | v254;
    v656 = v257 | v660;
    v655 = v656;
    v578 = v656;
    sub_26300(v248, v249, v250, &v661, v251, v252, v253, v591, v656 - 373957723); //4
 
...
w15 = 0x324F4353;
w16 = 0xA7EA7AC2;
w13 = w4 >> 0xB;
w14 = w4 << 0x15;
w19 = w15 & (~w13);
w21 = w13 & (~w15);
w22 = w15 & (~w14);
w14 = w14 & (~w15);
w19 = w19 | w21;
w15 = w16 & (~w6);
w21 = w22 | w14;
w22 = w16 & (~w5);
w5 = w5 & (~w16);
w14 = w6 & (~w16);
w23 = w15 | w14;
w5 = w22 | w5;
w17 = w4 >> 0x19 | w4 << (32 - 0x19);
w19 = w19 ^ w21;
w5 = w23 ^ (~w5);
w20 = *w7_ptr;
w21 = w19 & (~w17);
w19 = w17 & (~w19);
...
...
w15 = 0x324F4353;
w16 = 0xA7EA7AC2;
w13 = w4 >> 0xB;
w14 = w4 << 0x15;
w19 = w15 & (~w13);
w21 = w13 & (~w15);
w22 = w15 & (~w14);
w14 = w14 & (~w15);
w19 = w19 | w21;
w15 = w16 & (~w6);
w21 = w22 | w14;
w22 = w16 & (~w5);
w5 = w5 & (~w16);
w14 = w6 & (~w16);
w23 = w15 | w14;
w5 = w22 | w5;
w17 = w4 >> 0x19 | w4 << (32 - 0x19);
w19 = w19 ^ w21;
w5 = w23 ^ (~w5);
w20 = *w7_ptr;
w21 = w19 & (~w17);
w19 = w17 & (~w19);
...
void padding()
{
  size_t str_len = APK_PATH.length();
  size = this->RoundUp64(str_len + 1 + 8);
  data = new unsigned char[size];
  memcpy(data, APK_PATH.c_str(), str_len);
  order_of_0x80 = str_len + 1;
  data[str_len] = 0x80;
  size_t padding_len = str_len * 8 + 0x200;
  data[size - 1] = padding_len;
  data[size - 2] = padding_len >> 8;
  data[size - 3] = padding_len >> 16;
  data[size - 4] = padding_len >> 24;
  data[size - 5] = padding_len >> 32;
  data[size - 6] = padding_len >> 40;
  data[size - 7] = padding_len >> 48;
  data[size - 8] = padding_len >> 56;
}
void padding()
{
  size_t str_len = APK_PATH.length();
  size = this->RoundUp64(str_len + 1 + 8);
  data = new unsigned char[size];
  memcpy(data, APK_PATH.c_str(), str_len);
  order_of_0x80 = str_len + 1;
  data[str_len] = 0x80;
  size_t padding_len = str_len * 8 + 0x200;
  data[size - 1] = padding_len;
  data[size - 2] = padding_len >> 8;
  data[size - 3] = padding_len >> 16;
  data[size - 4] = padding_len >> 24;
  data[size - 5] = padding_len >> 32;
  data[size - 6] = padding_len >> 40;

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 4
支持
分享
打赏 + 80.00雪花
打赏次数 1 雪花 + 80.00
 
赞赏  Editor   +80.00 2022/09/20 恭喜您获得“雪花”奖励,安全圈有你而精彩!
最新回复 (1)
雪    币: 859
活跃值: (915)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
太强了,完全看不懂啊。
2022-8-6 18:08
0
游客
登录 | 注册 方可回帖
返回
//