我用的好搜小说版本是1.8.183,需要测试的请自行下载
点击一个小说,抓包之,在androidKill中搜索关键字encode_sign
打开关键字所在的类;
进去查看,在静态代码块加载了个动态链接库,核心的加密算法写在了native层
上IDA,进行动态调试,将断点下在urlEncodeFromJNI这个方法处:
然后手机上点击一部小说,运行到strlen的时候,将请求的链接传了进来
请求的链接长度为87
再次传进来一个参数,并计算其长度,这个参数是当前的时间戳
将0x97个内存长度初试化为0
将时间戳链接到请求链接后边
链接以后的结果
我们来看看连续三次的链接,然后记下这个缓冲区的地址:
继续申请长度为0x58的内存,并将其填充为0
调用md5Init初始化md5计算需要的数据结构
计算需要进行md5的数据段的长度
开始计算md5,在这里的md5Update函数中,传递了缓冲区地址,要进行哈希运算的地址,长度,这个长度等于拼接后的字符串的长度
在放字符串的后边的内存地址,再申请一个16个字节的空间,并用0初始化
调用MD5Final方法计算md5值
申请0x20个字节的内存,并用0填充
sprintf这里是个循环,执行和很多次,然后在刚才的缓冲区添加了一堆字符串,md5final方法计算而来的值并不是字符串,是一些十六进制的字符,sprintf将这些字符按照assic码转换成人能够看清的字符。总之md5+sprinf的值为在cmd5网站上计算的人眼能识别的字母,不了解可以等sprintf循环过去去看看给缓冲区写的值,这些值和CMD5网站计算出来的一样
将0x98长度的内存初始化为0
这个strcat将第一次拼接好的字符串连接到第一次计算的md5的值后边:
我们来看看链接完成后的结果
初始化0x58个字节的内存,为MD5Init初始化用
将刚才初始化的内存的地址给md5Init
计算所有需要md5的字符串长度(不明白一只计算长度干啥,也没有仔细分析)
调用md5Update函数,这里注意了:md5Update函数的第三个参数,为需要计算的字符串的长度,这里为0xa8,第一次我就是卡在这里了,全部计算,当然结果不对
到这个sprintf又和上一个sprintf的作用一样,不多解释
最终的计算结果为链接中的encode_sign值
总结一下计算过程:
1.将请求链接中的部分字段提取出来,加上时间戳,"eha",格式如下:
http://reader.m.so.com/app/index.php?m=Api&c=BookIntro&bid=3227333191007413155&uid=0dbc710c48e3d9ac0ebde
b116de326fe&ver=183&src=napp_sz1490169346086eha
2.计算步骤一中的哈希得到哈希结果
3.将步骤1中的字符串拼接到步骤二中计算的哈希结果后面
4.将步骤3中的字符串取前168(0xA8)位进行哈希,得到的结果就是连接中的
encode_sign字段
实验证明:
1.请求链接:
GET /app/index.php?m=Api&c=BookIntro&bid=3534808458083825046&uid=0dbc710c48e3d9ac0
ebdeb116de326fe&ver=183&src=napp_sz&encode_id=201703221490176124881&encode_sign=5
e9a514b1304f56b5a26f799e1d176df
2.制作成步骤1中的需要哈希的部分:
http://reader.m.so.com/app/index.php?m=Api&c=BookIntro&bid=3534808458083825046&uid=0dbc710c48e3d9ac0ebdeb116de326fe&ver
=183&src=napp_sz1490176124881eha
3.计算这个字符串的哈希:
3.将这个哈希放在第一次哈希的字符串前边:
a6d06f88cecbc5ca342f6d204f15191ahttp://reader.m.so.com/app/index.php?m=Api&c=BookIntro&bid=3534808458083825046&uid=0dbc710c48e3d9ac0ebdeb116de326
fe&ver=183&src=napp_sz1490176124881eha
4.取前168位(上一步中红色部分)做哈希:
我们来对比一下原来请求链接中的哈希:
分析正确