吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8520|回复: 20
收起左侧

[Android 原创] 音悦台下载加密算法s2k分析

  [复制链接]
无名侠 发表于 2016-4-23 23:30
这是我给我学生准备的一个例子。

音悦台在下载的时候会发一个包:
[Asm] 纯文本查看 复制代码
1
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已经为我们提供了输出功能,那就再好不过了。
如图: iop.png
注意“+”不属于参数的一部分,这是开发者为了好看吧。

输入参数是一串我们看不懂的东西,其实这个是服务器返回的,查询这个字符串的封包如下(id就是下载文件的ID了):
GET http://mapi.yinyuetai.com/download/statistics.json?D-A=0&id=2553946
返回json数据,s字段就是输入参数。

s2k才是核心函数,我们继续分析:
a1是输入字符串,a2应该是一个很长的缓冲区
[Asm] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
.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)



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

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


免费评分

参与人数 4吾爱币 +1 热心值 +4 收起 理由
飞枫亦矢 + 1 + 1 谢谢@Thanks!
linmu123 + 1 我很赞同!
油菜芽 + 1 用心讨论,共获提升!
q4506727 + 1 不错,你可以做一个软件。。。应该会有人用.

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

a4431693 发表于 2016-4-23 23:43
比我厉害,哈哈。。。。。至少你看懂了
chenjingyes 发表于 2016-4-24 00:28
stayoulove 发表于 2016-4-24 02:27
Mir丶翰林 发表于 2016-4-24 07:39
厉害 学习了
Programmer 发表于 2016-4-25 03:57
赞。。。。。。。。。
junxuan 发表于 2016-4-26 19:25
没明白,有详细点的代码吗?
liaoxueyong 发表于 2016-4-26 20:37
路过 不过也看看
Gordon0918 发表于 2016-6-22 22:39
膜拜ing!!
沧晓 发表于 2016-6-24 07:28 来自手机
表示膜拜
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-4-17 20:58

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表