作者:无名侠
声明:只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
交流群:无名移动逆向小分队 471525564
音悦台在下载的时候会发一个包:
http://mapi.yinyuetai.com/download/statistics.json?D-A=0&s=3dcfae0fd9ff76e83ef2c2eef357ebdebK37u4&id=2553946
其中S参数是在SO库中完成计算的。
通过搜索download关键字能很快定位到下载位置,然后能找到com/yinyuetai/utils/S2K这个类完成了加密工作。
这个类中有一个native函数:
private static native s2k(Ljava/lang/String;)Ljava/lang/String;
SO库名是:
s2k_chris
用IDA载入这个SO,在导出表中搜索“Java”,能快速筛选所有对Java层的接口。
导出函数:
Java_com_yinyuetai_utils_S2K_s2k
这个函数的流程很简单:
1、Log输出输入参数。
2、调用s2k函数。
3、Log输出s2k函数返回结果
4、对char * 字符串进行转换并返回。
既然这个SO已经为我们提供了输出功能,那就再好不过了。
注意“+”不属于参数的一部分,这是开发者为了好看吧。
输入参数是一串我们看不懂的东西,其实这个是服务器返回的,查询这个字符串的封包如下(id就是下载文件的ID了):
GET http://mapi.yinyuetai.com/download/statistics.json?D-A=0&id=2553946
返回json数据,s字段就是输入参数。
s2k才是核心函数,我们继续分析:
a1是输入字符串,a2应该是一个很长的缓冲区
.text:0000190C ; int __fastcall s2k(const char *a1, char *a2)
.text:0000190C EXPORT s2k
.text:0000190C s2k ; CODE XREF: Java_com_yinyuetai_utils_S2K_s2k+5Ap
.text:0000190C
.text:0000190C var_E0 = -0xE0
.text:0000190C var_DC = -0xDC
.text:0000190C var_D8 = -0xD8
.text:0000190C var_D4 = -0xD4
.text:0000190C var_D0 = -0xD0
.text:0000190C var_CC = -0xCC
.text:0000190C var_C8 = -0xC8
.text:0000190C var_C4 = -0xC4
.text:0000190C var_C0 = -0xC0
.text:0000190C var_BC = -0xBC
.text:0000190C var_B8 = -0xB8
.text:0000190C var_B4 = -0xB4
.text:0000190C var_B0 = -0xB0
.text:0000190C var_AC = -0xAC
.text:0000190C var_A4 = -0xA4
.text:0000190C var_4C = -0x4C
.text:0000190C dest = -0x44
.text:0000190C var_24 = -0x24
.text:0000190C
.text:0000190C PUSH {
R4-R7,LR}
.text:0000190E MOV R7, R9
.text:00001910 MOV R6, R8
.text:00001912 PUSH {
R6,R7}
.text:00001914 LDR