查找某阅读 app 的下载位置
本帖最后由 明月照我还 于 2020-12-13 12:57 编辑>刚学习不久,正好最近遇到一个问题,拿来练练手
## 起因
最近使用某阅读应用看书,app 的阅读体验并不好,所以想要找到下载的文件导入到其他阅读器阅读,但是常规方法并没有找到,所以反编译看下下载位置。
## 准备
工具:jadx, DB Browser;
一部有 root 权限的手机;
## 查找过程
1. 首先读取包名:cn.com.bookan
2. adb shell dumpsys window 获取书刊阅读的界面类名是 EpubReaderActivity
3.
在阅读页面下方有下载按钮,点击下载后,会有一个提示:下载中,请到“书架”-“我的下载”中查看", 在 EpubReaderActivity 中搜索提示的字符串,可以找到下载按钮的点击逻辑:
```
/* access modifiers changed from: package-private */
@OnClick({2131296832})
public void onDownloadClick(View view) {
LogUtil.m15486a(this.f8694j, 20007, 3);
if (!NetUtil.m15279a(this)) {
MyToast.m16477a(this, getString(C1300R.string.net_error), 0).show();
} else if (FusionField.m13348ac() > 0 || DBScanRecord.m13484a().mo19549a(this.f8694j)) {
new CountDownTimer(1000, 200) {
public void onFinish() {
if (FusionField.f10257s == 1) {
DBDownload.m13459a().mo19524b(EpubReaderActivity.this.f8694j, "epub");
DBDownload.m13459a().mo19522a(GsonUtil.m15346a(EpubReaderActivity.this.f8694j), 100, EpubReaderActivity.this.f8694j, "epub");
} else {
DBDownload.m13459a().mo19521a(EpubReaderActivity.this.f8694j, "epub");
DBDownload.m13459a().mo19525b(GsonUtil.m15346a(EpubReaderActivity.this.f8694j), 100, EpubReaderActivity.this.f8694j, "epub");
}
EpubReaderActivity.this.itemReaderBotomOpdoneContainer.setVisibility(0);
EpubReaderActivity.this.itemReaderBotomOpopContainer.setVisibility(8);
}
public void onTick(long j) {
int unused = EpubReaderActivity.this.f8678ab = EpubReaderActivity.this.f8678ab + 20;
EpubReaderActivity.this.itemReaderBottomDownloadText.setText(EpubReaderActivity.this.getString(C1300R.string.reader_download_ing));
EpubReaderActivity.this.itemReaderBottomDownloadImg.setImageResource(C1300R.C1301drawable.btn_download_resume);
EpubReaderActivity.this.itemReaderBottomDownloadProgress.setVisibility(0);
EpubReaderActivity.this.itemReaderBottomDownloadProgress.setProgress(EpubReaderActivity.this.f8678ab);
}
}.start();
Toast.makeText(this, "下载中,请到“书架”-“我的下载”中查看", 0).show();
} else {
new MyDialogNotice(this, String.format(getString(C1300R.string.right_download), new Object[]{FusionField.m13362aq(), FusionField.m13363ar()})).show();
}
}
```
可以发现应该是这块逻辑做的下载操作:
```
if (FusionField.f10257s == 1) {
DBDownload.m13459a().mo19524b(EpubReaderActivity.this.f8694j, "epub");
DBDownload.m13459a().mo19522a(GsonUtil.m15346a(EpubReaderActivity.this.f8694j), 100, EpubReaderActivity.this.f8694j, "epub");
} else {
DBDownload.m13459a().mo19521a(EpubReaderActivity.this.f8694j, "epub");
DBDownload.m13459a().mo19525b(GsonUtil.m15346a(EpubReaderActivity.this.f8694j), 100, EpubReaderActivity.this.f8694j, "epub");
}
```
虽然混淆了,但是下载应该是通过 mo19522a 或 mo19525b 方法,跟进去看下:
理解错了,这俩应该是线程操作:
```
/* renamed from: b */
public void mo19525b(String str, int i, IssueInfo issueInfo, String str2) {
ThreadPoolUtil.m15065a().mo21766a((Runnable) new C3138c(str, i, issueInfo, str2));
ThreadPoolUtil.m15065a().mo21767b();
}
```
不过在它上面正好有 run 方法:
```
public void run() {
if (StringUtil.m15053c(this.f10398b)) {
Debug.m15248e("DBDownloadinsert mcontent is null", new Object);
return;
}
SQLiteDatabase writableDatabase = MagookDBHelper.m13490a().getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("content", this.f10398b);
contentValues.put(NotificationCompat.CATEGORY_PROGRESS, Integer.valueOf(this.f10399c));
contentValues.put("userid", String.valueOf(FusionField.m13414m()));
contentValues.put("issueid", this.f10400d.getResourceType() == 5 ? this.f10400d.getResourceId() : this.f10400d.getIssueId());
contentValues.put("personid", Integer.valueOf(FusionField.m13320P()));
contentValues.put("readtype", this.f10401e);
long insert = writableDatabase.insert(MagookDBHelper.C3166i.f10503a, (String) null, contentValues);
Debug.m15248e("progress DB: " + this.f10399c, new Object);
Debug.m15244a("DBDownload insert result=%s content=%s", Long.valueOf(insert), this.f10398b);
DownloadItemModel downloadItemModel = new DownloadItemModel();
downloadItemModel.setItem((IssueInfo) GsonUtil.m15344a(this.f10398b, IssueInfo.class));
downloadItemModel.setProgress(this.f10399c);
downloadItemModel.setReadType(this.f10401e);
if (!FusionField.f10261w.containsKey(this.f10400d.getResourceType() == 5 ? this.f10400d.getResourceId() : this.f10400d.getIssueId())) {
FusionField.f10261w.put(this.f10400d.getResourceType() == 5 ? this.f10400d.getResourceId() : this.f10400d.getIssueId(), downloadItemModel);
PreferenceUtil.m14946a("isSynchDownload", true);
}
}
}
```
看到这里可以确定是存到 SQLITE 中了:
```
SQLiteDatabase writableDatabase = MagookDBHelper.m13490a().getWritableDatabase();
```
进MagookDBHelper 看下:
```
public void onCreate(SQLiteDatabase sQLiteDatabase) {
sQLiteDatabase.execSQL("CREATE TABLE IF NOT EXISTS download(_id INTEGER PRIMARY KEY AUTOINCREMENT, issueid INTEGER,progress INTEGER,userid INTEGER,content TEXT,readtype TEXT)");
sQLiteDatabase.execSQL("create table IF NOT EXISTS readrecord(_id INTEGER PRIMARY KEY AUTOINCREMENT, issueid INTEGER,userid INTEGER,content TEXT)");
sQLiteDatabase.execSQL("create table IF NOT EXISTS collection(_id INTEGER PRIMARY KEY AUTOINCREMENT, issueid INTEGER,userid INTEGER,content TEXT)");
sQLiteDatabase.execSQL("CREATE TABLE IF NOT EXISTS downloadsingleperson(_id INTEGER PRIMARY KEY AUTOINCREMENT, issueid INTEGER,progress INTEGER,userid INTEGER,personid INTEGER,content TEXT,readtype TEXT)");
sQLiteDatabase.execSQL("create table IF NOT EXISTS readrecordsingleperson(_id INTEGER PRIMARY KEY AUTOINCREMENT, issueid INTEGER,userid INTEGER,personid INTEGER,content TEXT)");
sQLiteDatabase.execSQL("create table IF NOT EXISTS collectionsingleperson(_id INTEGER PRIMARY KEY AUTOINCREMENT, issueid INTEGER,userid INTEGER,personid INTEGER,content TEXT)");
Debug.m15248e("Error inserting: createSQL: " + "create table IF NOT EXISTS message(_id INTEGER PRIMARY KEY AUTOINCREMENT, messageid INTEGER,status INTEGER,type INTEGER,isdelete INTEGER,title VARCHAR(256),url TEXT,content TEXT,resources TEXT,creattime VARCHAR(32))", new Object);
sQLiteDatabase.execSQL("create table IF NOT EXISTS message(_id INTEGER PRIMARY KEY AUTOINCREMENT, messageid INTEGER,status INTEGER,type INTEGER,isdelete INTEGER,title VARCHAR(256),url TEXT,content TEXT,resources TEXT,creattime VARCHAR(32))");
sQLiteDatabase.execSQL("create table IF NOT EXISTS searchhistory(_id INTEGER PRIMARY KEY AUTOINCREMENT,userid INTEGER,restype INTEGER,resourcetype INTEGER,searchtype INTEGER,content TEXT)");
sQLiteDatabase.execSQL("create table IF NOT EXISTS readpositionrecord(_id INTEGER PRIMARY KEY AUTOINCREMENT, issueid INTEGER,page INTEGER,userid INTEGER)");
sQLiteDatabase.execSQL("create table IF NOT EXISTS audiopositionrecord(_id INTEGER PRIMARY KEY AUTOINCREMENT, issueid INTEGER,resourceid INTEGER,position INTEGER,userid INTEGER,personid INTEGER,playissueid INTEGER)");
sQLiteDatabase.execSQL("create table IF NOT EXISTS scanrecord(_id INTEGER PRIMARY KEY AUTOINCREMENT, resourceType INTEGER,resourceid INTEGER,issueid)");
}
```
看不出来放在哪个表了,去手机中 把 DB 拖出来看下:
adb pull /data/data/cn.com.bookan/databases/ .
注意:这个命令需要 root 权限。
看着 books.db 比较像,就是体积有点小,使用 DB Browser 打开看下:
猜测 Files 里面可能有想要的东西,切换到 浏览数据,过滤 Files:
看到一个存储路径 /storage/emulated/0/.bookan/file/487514
把这个文件取下来,放到手机里打开,确实就是刚才下载的文件。
## 至此,找到了这个 apk 下载的文件位置:
/storage/emulated/0/.bookan/file 不用这么麻烦吧,直接在文件管理器里查找文件名不就可以了吗 Gif 发表于 2020-12-13 10:59
楼主大大,能帮忙找一下 咪咕阅读 下载的书在哪里吗,网上也找不到(要是会编程的话,也许根据楼主的思路找 ...
/storage/emulated/0/Reader/Books/
使用文件管理器可以在手机中看到这个路径,不同文件管理器看到的路径名称不同,一般手机自带的管理器上,Reader 是在你的根目录。
另外,咪咕用的是 .meb 格式,不是常见的电子书格式,不好找到能用的阅读器,所以就算取出来了用处也不大.... 66666牛皮 牛🐮,学习了 这个还是有用的 这个还是有用的 也正好有这个需求,正好参考下楼主的,感谢 楼主牛皮!马! 楼主也是牛 楼主大大,能帮忙找一下 咪咕阅读 下载的书在哪里吗,网上也找不到(要是会编程的话,也许根据楼主的思路找找吧,很遗憾。。。。)
页:
[1]
2