作者:无名侠
声明:只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
交流群:无名移动逆向小分队 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     R3, =(__stack_chk_guard_ptr - 0x191E)
.text:00001916                 SUB     SP, SP, #0xC4
.text:00001918                 ADD     R5, SP, #0x94
.text:0000191A                 ADD     R3, PC ; __stack_chk_guard_ptr
.text:0000191C                 LDR     R6, [R3] ; __stack_chk_guard
.text:0000191E                 MOVS    R2, #0x4A
.text:00001920                 MOV     R9, R0
.text:00001922                 LDR     R3, [R6]
.text:00001924                 MOV     R8, R1
.text:00001926                 ADD     R0, SP, #0x9C   ; dest
.text:00001928                 STR     R3, [SP,#0xE0+var_24]
.text:0000192A                 STRB    R2, [R5]
.text:0000192C                 MOVS    R2, #0x37       ; MD5求值前缀J7k$x*U5
.text:0000192E                 STRB    R2, [R5,#1]     ; R5指向最终MD5计算的字符串缓冲区
.text:00001930                 MOVS    R2, #0x6B
.text:00001932                 STRB    R2, [R5,#2]
.text:00001934                 MOVS    R2, #0x24
.text:00001936                 STRB    R2, [R5,#3]
.text:00001938                 MOVS    R2, #0x78
.text:0000193A                 STRB    R2, [R5,#4]
.text:0000193C                 MOVS    R2, #0x2A
.text:0000193E                 STRB    R2, [R5,#5]
.text:00001940                 MOVS    R2, #0x55
.text:00001942                 STRB    R2, [R5,#6]
.text:00001944                 MOVS    R2, #0x35
.text:00001946                 MOVS    R3, #0
.text:00001948                 STRB    R2, [R5,#7]
.text:0000194A                 MOV     R1, R9          ; src
.text:0000194C                 MOVS    R2, #0x10       ; n
.text:0000194E                 STR     R3, [SP,#0xE0+dest] ; 初始化缓冲区
.text:00001950                 STR     R3, [SP,#0xE0+dest.field_0+4]
.text:00001952                 STR     R3, [SP,#0xE0+dest.field_0+8]
.text:00001954                 STR     R3, [SP,#0xE0+dest.field_0+0xC]
.text:00001956                 STR     R3, [SP,#0xE0+dest.field_0+0x10]
.text:00001958                 STR     R3, [SP,#0xE0+dest.field_0+0x14]
.text:0000195A                 STR     R3, [SP,#0xE0+dest.field_0+0x18]
.text:0000195C                 STR     R3, [SP,#0xE0+dest.field_0+0x1C]
.text:0000195E                 BLX     strncat         ; 把输入字符串拼接到R0
.text:0000195E                                         ; R5=SP+#0x94 初始串“J7k$x*U5”8字节
.text:0000195E                                         ; R0=SP+#0x9C
.text:0000195E                                         ; 实际相当于 “J7k$x*U5”+输入字符串
.text:00001962                 LDR     R0, =(aRandom_seedS - 0x196C)
.text:00001964                 MOVS    R1, R5
.text:00001966                 ADD     R7, SP, #0xE0+var_A4
.text:00001968                 ADD     R0, PC          ; "random_seed= -%s-\n"
.text:0000196A                 BLX     printf
.text:0000196E                 MOVS    R0, R7          ; R7=MD5的ctx结构
.text:00001970                 BL      MD5Init
.text:00001974                 MOVS    R0, R5          ; s
.text:00001976                 BLX     strlen
.text:0000197A                 ADD     R4, SP, #0xE0+dest.field_0+0x10
.text:0000197C                 MOVS    R2, R0
.text:0000197E                 MOVS    R1, R5          ; R5 = 刚才拼接的字符串
.text:00001980                 MOVS    R0, R7
.text:00001982                 BL      MD5Update
.text:00001986                 MOVS    R0, R7
.text:00001988                 MOVS    R1, R4
.text:0000198A                 BL      MD5Final
.text:0000198E                 LDRB    R0, [R4,#2]
.text:00001990                 LDRB    R3, [R4,#1]
.text:00001992                 LDRB    R2, [R4]
.text:00001994                 STR     R0, [SP,#0xE0+var_E0]
.text:00001996                 LDRB    R0, [R4,#3]
.text:00001998                 LDR     R1, =(a02x02x02x02x02 - 0x19A2)
.text:0000199A                 STR     R0, [SP,#0xE0+var_DC]
.text:0000199C                 LDRB    R0, [R4,#4]
.text:0000199E                 ADD     R1, PC          ; "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02"...
.text:000019A0                 STR     R0, [SP,#0xE0+var_D8]
.text:000019A2                 LDRB    R0, [R4,#5]
.text:000019A4                 STR     R0, [SP,#0xE0+var_D4]
.text:000019A6                 LDRB    R0, [R4,#6]
.text:000019A8                 STR     R0, [SP,#0xE0+var_D0]
.text:000019AA                 LDRB    R0, [R4,#7]
.text:000019AC                 STR     R0, [SP,#0xE0+var_CC]
.text:000019AE                 LDRB    R0, [R4,#8]
.text:000019B0                 STR     R0, [SP,#0xE0+var_C8]
.text:000019B2                 LDRB    R0, [R4,#9]
.text:000019B4                 STR     R0, [SP,#0xE0+var_C4]
.text:000019B6                 LDRB    R0, [R4,#0xA]
.text:000019B8                 STR     R0, [SP,#0xE0+var_C0]
.text:000019BA                 LDRB    R0, [R4,#0xB]
.text:000019BC                 STR     R0, [SP,#0xE0+var_BC]
.text:000019BE                 LDRB    R0, [R4,#0xC]
.text:000019C0                 STR     R0, [SP,#0xE0+var_B8]
.text:000019C2                 LDRB    R0, [R4,#0xD]
.text:000019C4                 STR     R0, [SP,#0xE0+var_B4]
.text:000019C6                 LDRB    R0, [R4,#0xE]
.text:000019C8                 STR     R0, [SP,#0xE0+var_B0]
.text:000019CA                 LDRB    R0, [R4,#0xF]
.text:000019CC                 STR     R0, [SP,#0xE0+var_AC]
.text:000019CE                 MOV     R0, R8          ; s
.text:000019D0                 BLX     sprintf         ; 把md5格式化成文本流
.text:000019D4                 MOV     R0, R8
.text:000019D6                 MOVS    R2, #6          ; n
.text:000019D8                 MOV     R1, R9          ; src
.text:000019DA                 ADDS    R0, #0x20       ; dest // R0=R8+32就是跳过32个字符,在MD5文本结果的后面追加6个字符。
.text:000019DA                                         ; 源字符串指针R9,也就是第一个参数。
.text:000019DC                 BLX     strncat
.text:000019E0                 LDR     R0, =(aFlash_encrypt_ - 0x19E8)
.text:000019E2                 MOV     R1, R8
.text:000019E4                 ADD     R0, PC          ; "flash_encrypt_k= -%s-\n"
.text:000019E6                 BLX     printf
.text:000019EA                 LDR     R2, [SP,#0xE0+var_24]
.text:000019EC                 LDR     R3, [R6]
.text:000019EE                 MOVS    R0, #0
.text:000019F0                 CMP     R2, R3
.text:000019F2                 BNE     loc_19FE
.text:000019F4                 ADD     SP, SP, #0xC4
.text:000019F6                 POP     {R2,R3}
.text:000019F8                 MOV     R8, R2
.text:000019FA                 MOV     R9, R3
.text:000019FC                 POP     {R4-R7,PC}

因此,这个算法的过程很简单: 取MD5(“J7k$x*U5”+输入文本)+取文本左边(输入文本,6)

经验总结:
我一开始是不知道”J7kx*U5”+输入文本是如何拼接的,因为IDA把一个缓冲区给分成了多个变量标号,所以看着很晕,动态调试的时候反应过来了。  
R5=SP+#0x94 初始串“J7kx*U5”+输入文本是如何拼接的,因为IDA把一个缓冲区给分成了多个变量标号,所以看着很晕,动态调试的时候反应过来了。 R5=SP+#0x94 初始串“J7kx*U5”8字节
R0=SP+#0x9C R0是参数拼接的位置

差值正好是8
所以R5最后指向的就是“J7k$x*U5”+参数

音悦台下载加密算法s2k分析相关推荐

  1. 4 weekend110的hdfs下载数据源码跟踪铺垫 + hdfs下载数据源码分析-getFileSystem(值得反复推敲和打断点源码)...

    Hdfs下载数据源码分析 在这里,我是接着之前的,贴下代码 package cn.itcast.hadoop.hdfs; import java.io.FileInputStream; import ...

  2. RV1108 EMMC 程序下载失败原因分析

    RV1108 EMMC 程序下载失败原因分析 目录 RV1108 EMMC 程序下载失败原因分析 1. 出现的现象 硬件环境 表现出的问题 2. 原因查找 检查硬件 3. rv1108 bootloa ...

  3. ICESat-2数据下载及处理分析随笔

    ICESat-2数据下载及处理分析随笔 ICESat-2全称是Ice,Cloud and land Elevation Satellite -2.看名字我们能知道它的任务是测ice,cloud和lan ...

  4. 民生银行直销银行手机登陆加密算法的分析

    民生银行直销银行手机登陆加密算法的分析 引言 环境的设置 认证加密算法分析 总结 引言 日常工作中,正好碰到针对银行类系统的安全测试工作,通过Burp抓包发现传输的信息都是一串加密的数据,因此,就针对 ...

  5. 怎么在python下载网站内容-分析某网站,并利用python自动登陆该网站,下载网站内容...

    本帖最后由 愤怒的小车 于 2019-5-8 09:41 编辑 一:本代码是我研究了好久才写出来,七功能主要有自动登陆.自动识别验证码.以及自动识别下载格式进行判断下载! 首先,搬上我们的主角网址,h ...

  6. RSA加密算法简单分析

    预备知识 1)RSA是第一个比较完善的公开密钥算法,它既能用于加密,也能用于数字签名.RSA以它的三个发明者Ron Rivest, Adi Shamir, Leonard Adleman的名字首字母命 ...

  7. 超简单禁止迅雷下载!(分析+方法)

    这几天局域网里总有人用迅雷下东西,搞的我网页都打不开,我试了网上公布的封锁迅雷的方法都没有效果!于是乎我决定自己研究一下迅雷!打开迅雷抓包分析,过程我就不详细说了,终于发现了迅雷挺多有意思的地方. 1 ...

  8. ios9系统无法下载应用问题分析与解决

    苹果更新系统后,最近打包的ipa包在ios9系统上无法安装(ios8可以), 提示"无法下载应用",经过一系列折腾解决了问题: 参考 http://www.cocoachina.c ...

  9. Android下载管理问题分析

    一.场景 某一天,项目组反馈问题,说文件下载的功能在某些机型上无法使用,下载文件失败. 二.问题分析 首先查看了问题表现,是一台鸿蒙系统的手机,当时手上还有其他事情,只是记了下来,后续分析. 等到实际 ...

最新文章

  1. Redis:从应用到底层,一文帮你搞定
  2. Linux笔记——linux下的语音合成系统
  3. [译]预留位置队列PRQueue:多线程程序中消息输入队列和消息输出队列保持同序...
  4. c55x 汇编语言指令,[转载]关于TMS320C55x的汇编语言中的.sym伪指令
  5. SQL中CONVERT函数全部用法对日期操作
  6. [项目管理-6]:软硬件项目管理 - 项目沟通管理(渠道、方法)
  7. php 模板对象,php面向对象--PHP模板 ppt
  8. kvm切换器linux换屏方法,kvm切换器连接图及安装方法
  9. 某广告SDK流量加解密-响应
  10. 基于OpenSSL的CA建立及证书签发(签发单域名/IP)
  11. 【论文阅读】Efficient Illuminant Estimation for Color Constancy Using Grey Pixels
  12. 【Spring】Lifecycle的使用与源码分析
  13. 烟花代码运行示例(C++,easyX)
  14. 【转自知乎】软件实施工程师-简历范文,【工作经历+项目经验+专业技能+自我评价】怎么写
  15. java.lang.UnsupportedOperationException: Currently Flink doesn‘t support individual window table-val
  16. 给20块钱买可乐,每瓶可乐3块钱,喝完之后退瓶子可以换回1块钱,问最多可以喝到多少瓶可乐?
  17. 国内渗透测试新神器--北极熊扫描器4.0
  18. TiDB 在 2021 易车 818 汽车狂欢节的应用
  19. 2021-05-16刷题
  20. Connection to tcp://39.96.3.215:1935 failed: Error number -138 occurred

热门文章

  1. [转载]使用Java编写Palm OS程序的解决方案
  2. COCO数据集简介与处理
  3. 银联+移动+三星PK微信、余额宝
  4. 不可不看 真正专业显卡技术分析评测
  5. 此服务器不支持该安装程序,macOS 提示“不能安装该软件,因为当前无法从软件更新服务器获得” 解决方法...
  6. java中等效encodeuri_encodeURI来解决URL传递时的中文问题
  7. 我用Python告诉你,充气娃娃什么感觉,呜呜呜
  8. Win10必做的性能优化
  9. 阿尔法大蛋智能机器人功能_科大讯飞机器阿尔法蛋大蛋2.0怎么样?儿童智能机器人阿尔法蛋大蛋2.0和1.0区别对比!...
  10. 奔驰,该学习小米和华为了