喜马拉雅音频文件导出

前言

  平时喜欢用喜马拉雅听广播一般都离线下载后听,但是手机的空间不足,有些音频又不想删,因此想把音频文件导出,然后就可以任性删啦。   

环境

iPad Mini 2(8.4,已越狱)
macOS Sierra 10.12.3
喜马拉雅v5.4.57

流程

  • ssh登录到iPad
  • cycripyt寻找喜马拉雅的进程并注入
  • 寻找沙盒路径
  • 寻找音频文件
  • 导出音频文件
  • 后续处理

准备

先用喜马拉雅下载一些感兴趣的音频

ssh登录

1
ssh root@your_device_ip

cycripyt找进程

为避免干扰,先关闭其他进程,打开喜马拉雅应用,用ps指令获取当前运行进程列表

根据路径加名字判断那个ting进程即为喜马拉雅的进程

使用cycript注入

1
iPad:~ root# cycript -p ting

直接输出UIApp 看应用单例对象是什么

1
2
cy# UIApp
#"<XMUIApplication: 0x144e228a0>"

是喜马拉雅的全拼,应该就是这个了,如果还要确定,可以输入exit(0)就会发现喜马拉雅被关闭了。

寻找沙盒路径

1
[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]

结果如下

1
#"file:///var/mobile/Containers/Data/Application/88888888-0E68-49E6-AB14-457891C5BCFF/Documents/"

沙盒路径找到了,接下来找音频路径

可以离开cycript

寻找音频路径

我们知道iOS沙盒一般包含了3个目录

  • Documents
  • Library
  • tmp

StoreKit应该是内购而创建的

排除tmp,StoreKit,第一感觉是音频文件在Documents,cd到该目录查看,反正错了也不要紧,再试就好了

.db数据库文件排除,umengrt应该是友盟统计,分享之类的,chat聊天的

有一个iDoc的目录,尝试进入,

Download目录,那应该很明显了,进去

尝试过直接发送到电脑,确实是音频

1
2
$ file /Users/Jason/Desktop/Download/00a6b52f49f757bece6676c658789222
/Users/Jason/Desktop/Download/00a6b52f49f757bece6676c658789222: ISO Media, Apple iTunes ALAC/AAC-LC (.M4A) Audio

但音频文件的命名是确有点奇怪,应该是使用了类似SDWebImage那种网络图片缓存框架,音频名可能用了md5之类避免冲突,没关系,在应用显示出正常的音频名称,所以肯定会有地方保存映射关系的,上一级在Documents中,发现了名为ting.sqlite的文件,是个sqlite文件,看是不是在数据库保存着映射关系

因为手机上不太好执行sqlite,先用cat看看数据库文件大概的内容

看上去应该是是在该文件中映射关系

导出音频文件

关于导出音频文件,可以使用iTools或直接使用终端先打包再使用scp发送

1
2
iPad:xxx# tar -cvzf apps.tar.gz ./Download
...

mac上执行

1
» ~  scp root@192.168.1.174:/var/mobile/Containers/Data/Application/88888888-0E68-49E6-AB14-45710CC5BCFF/Documents/iDoc/apps.tar.gz ~/Desktop/apps.tar.gz

传输成功到mac上,接着就进入后续处理操作

类似的得到ting.sqlite文件

后续处理

主要是根据根据ting.sqlite处理音频的文件名

打开终端

1
2
3
4
5
» ~/Desktop  sqlite3 ting.sqlite
Enter ".help" for usage hints.
sqlite> .tables
adData_table download_table
sqlite>

查询download_table

1
sqlite> select * from download_table;

记录的格式如下:

里面确实包含的文件名

证明:映射关系确实存在

先要了解sqlite3shell的脚本怎么交互,即从sqlite中得到的数据如何传递到shell

查了一下

sqlite3shell交互大概 有两种方式

  • echo / cat 通过管道传输进去 此时sqlite3 作为 接收端

  • sqlite3 xxx ‘查表语句’ 直接sqlite3执行查表语句,最后可以通过管道传给shell处理

在这里选择了第2种

sqlite3文档

大致思路是用awk + sed得到音频名与乱码名,在用mv去修改名称

参考脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/bin/bash

## modify the path when you change the place which to store the music file

## 工程目录,自定义
music_file_path="xxx_Path"
cd ${music_file_path}

## obtain datas
sqlite3 ting.sqlite 'select * from download_table' | awk -F "|" -v OFS='|' '{print $18,$3,$2}' > mapper

sed -i "" "s/ /_/g" ./mapper
sed -i "" "s/:/_/g" ./mapper
sed -i "" "s/:/_/g" ./mapper
sed -i "" "s/-/_/g" ./mapper
sed -i "" "s/,/_/g" ./mapper
sed -i "" "s/-/_/g" ./mapper
sed -i "" "s/?/_/g" ./mapper
sed -i "" "s/、/_/g" ./mapper

## foreach the download directory to find the music name
for f in ./download/*
do
## .download文件 代表还未下载 过掉
# echo ${f##*.}
if [ ${f##*.}x != "download"x ]; then
cache_name=`basename ${f}`
music_name=$(grep -r ${cache_name} ./mapper | awk -F "|" -v OFS='|' '{print $3}')

echo ${cache_name}
echo ${music_name}
# echo ./download/${music_name}.mp3
mv ./download/${cache_name} ./download/${music_name}.mp3

fi
done

效果图

最后试听了一下,音频文件能正常播放,没有问题

参考

Mac终端环境走代理 CentOS远程登陆SSH配置
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×