2020-02-23 晴 鄭州
出場人物
- 沉瓶 - 產品經理
- 飯鹹 - 程序員
工作環境
- 硬件:MacBook Pro (Retina, 13-inch, Early 2015)
- 硬件相應系統:macOS Catalina,10.15.3
- 微信版本7.0.4
需求
- 微信好友頭像照片牆
故事
沉瓶:在網上看到一些人微信頭像做成一張圖片,看着不錯,既好玩又能吸引用戶,這個能不能做。
飯鹹:獲取微信的信息方法很多,以前網頁版微信能用的時候,可以直接網頁請求獲取,網上很多開源代碼。
沉瓶:我看了,很多代碼都不更新了,是不是不能用了。
飯鹹:是的,微信關閉了服務器,這些請求自然不能做了。不過有些人直接通過對PC版本的微信進行HOOK,實現很多有意義的功能,你可以找找。
沉瓶:找到了一個,不過沒有提供可以運行的程序,還有別的方法木有了。
飯鹹:微信本身就是手機系統的,對手機進行分析就可以了,而且分析微信的文章也很多,微信程序沒有加殼,分析難度也不大,可以試試。
沉瓶:那你試試,我研究下怎麼拼接圖片去。
飯鹹:好的,盤它。
需求分析
-
- 獲取微信頭像
- 1.1 獲得數據庫文件路徑和密匙
- 1.2 將數據庫文件導出到本地
- 1.3 打開加密的數據庫文件
-
- 將頭像拼接成照片牆
實現步驟
1. 獲取微信頭像
關於獲取微信聊天記錄的方案網絡上有很多資料,本博文就是根據下面的文章學習而來的:
結合上面兩篇博文,我執行了下面的方案。
1.1 獲得數據庫文件路徑和密匙
根據資料,我們找到一份基於Xposed的源碼https://github.com/adamyi/AndroidWechatSQLiteDecrypt,該源碼可以獲得EnMicroMsg.db文件的路徑和密碼,但是未能正確的獲取加密方式,可能是因爲代碼長時間不更新的原因吧(代碼是兩年前的)。
源碼邏輯不復雜,hook了數據庫打開的操作,在這個地方,騰訊執行了數據庫的打開操作,該操作將路徑、密碼、加密方式都作爲參數傳了進來。具體代碼如下所示:
public class XModule implements IXposedHookLoadPackage {
static private String TAG = "wxSqlPwdHook";
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if (loadPackageParam.packageName.equals("com.tencent.mm")) {
XposedHelpers.findAndHookMethod(
"com.tencent.wcdb.database.SQLiteDatabase", // 被HOOK對象名
loadPackageParam.classLoader, // classLoader,固定的值,不用關心
"openDatabase", // 被HOOK對象的函數名
String.class, // 參數0:數據庫全路徑
byte[].class, // 參數1:用戶名密碼(一個加密後的7位值)
loadPackageParam.classLoader.loadClass("com.tencent.wcdb.database.SQLiteCipherSpec"), // 參數2:是一個SQLiteCipherSpec對象,該對象中包含了加密方式
loadPackageParam.classLoader.loadClass("com.tencent.wcdb.database.SQLiteDatabase$CursorFactory"), // 參數3:某工廠對象
int.class, // 參數4:Flags,未知標記
loadPackageParam.classLoader.loadClass("com.tencent.wcdb.DatabaseErrorHandler"), // 參數5:錯誤處理的句柄
int.class, // 參數6:加密方式的某個參數PoolSize
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// 參數0:數據庫全路徑
Log.i(TAG, "Path: " + param.args[0]);
// 參數1:用戶名密碼(一個加密後的7位值)
Log.i(TAG, "Password: " + new String((byte[]) param.args[1], "UTF-8"));
Formatter formatter = new Formatter();
for (byte b : (byte[]) param.args[1]) {
formatter.format("%02x", b);
}
Log.i(TAG, "Password (hex): 0x" + formatter.toString());
// 參數2:是一個SQLiteCipherSpec對象,該對象中包含了加密方式
Log.i(TAG, "CipherSpec - Cipher: " + XposedHelpers.getObjectField(param.args[2], "cipher"));
Log.i(TAG, "CipherSpec - KdfIteration: " + XposedHelpers.getIntField(param.args[2], "kdfIteration"));
Log.i(TAG, "CipherSpec - Hmac Enabled: " + XposedHelpers.getBooleanField(param.args[2], "hmacEnabled"));
Log.i(TAG, "CipherSpec - Page Size: " + XposedHelpers.getIntField(param.args[2], "pageSize"));
// 參數4:Flags,未知標記
Log.i(TAG, "Flags: " + param.args[4]);
// 參數6:加密方式的某個參數PoolSize
Log.i(TAG, "PoolSize: " + param.args[6]);
}
});
}
}
}
代碼使用的是XPosed框架,使用XposedHelpers.findAndHookMethod函數做的HOOK操作,HOOK點爲com.tencent.wcdb.database.SQLiteDatabase::openDatabase,該函數的參數分別爲:
- 參數0:數據庫全路徑
- 參數1:用戶名密碼(一個加密後的7位值)
- 參數2:是一個SQLiteCipherSpec對象,該對象中包含了加密方式
- 參數3:某工廠對象
- 參數4:Flags,未知標記
- 參數5:錯誤處理的句柄
- 參數6:加密方式的某個參數PoolSize
我使用的微信版本爲7.0.4,上述代碼未能正確的解析SQLiteCipherSpec對象值,爲了獲得該值,我對微信進行調試,發現SQLiteCipherSpec對象的成員名稱變了,如下所示:
p2 = {SQLiteCipherSpec@9102}
hmacAlgorithm = 0
hmacEnabled = false
kdfAlgorithm = 0
kdfIteration = 4000
pageSize = 1024
shadow$_klass_ = {Class@8246} "class com.tencent.wcdb.database.SQLiteCipherSpec"
shadow$_monitor_ = -2105857932
我們將這些值修改即可正常的打印出來,打印調試日誌如下所示(我這邊使用的是VirtualApp進行試驗的):
最終代碼已經上傳到github倉庫,請自取。
1.2 將數據庫文件導出到本地
將數據庫文件導出到本地,思路也很多,我的方案是,將android手機作爲ftp服務器(Servers Ultimate Pro),在本機(PC)使用FileZilla軟件連接手機的ftp服務器,直接將文件下載到本地。
ps:
- Servers Ultimate Pro是一款集成了ssh、ftp、http等數十種協議的服務器app,可以輕鬆的將android手機變爲服務器使用,收費軟件,價格不美麗。
- 本博文使用的是VirtualApp進行XPosed測試,需要將Servers Ultimate Pro服務器程序也安裝在VirtualApp中,這樣以來,微信和服務器程序就處於同一用戶權限了,所以PC上的FileZilla客戶端就可以訪問微信的數據文件了。
1.3 打開加密的數據庫文件
實用開源項目SQLiteStudio,在github上下載最新的軟件即可,該軟件跨平臺(Mac、Windows已經測試通過)、支持多種加密方式(這裏選擇SQLCipher選項),使用方法如下圖所示:
選擇數據庫軟件的過程經歷了很多次嘗試,嘗試過程請參考另一篇文章:【程序員日記】2020-02-19__踩坑微信加密後的Android數據庫,
2. 將頭像拼接成照片牆
這裏不詳細介紹了,參考下面資料即可
- 使用 Python + Pillow 完成圖片牆拼圖
- 用python的PIL庫輕鬆拼接一百張照片
- 提取微信/QQ聊天記錄並生成詞雲
- https://github.com/yangxuanxc/wechat_friends
聲明
本文章僅供用於技術研究用途,請勿利用文章內容操作用於違反法律的事情。
關於作者
歡迎各位關注公衆號和QQ羣進行技術交流,關注有福利喔。
微信公衆號:
qq羣:IT技術控/953949723