Android逆向分析实例(三)-解密微信EnMicroMsg.db数据库
1.簡介
首先介紹下EnMicroMsg.db數據庫:這個數據庫是存放在Android手機本地的用來保存微信聊天記錄的一個數據庫,是一個Sqlite數據庫,且手機必須要有root權限才能獲取到,而且是被加密過的,必須先找到密鑰才能打開。我們現在要做的就是找到這個密鑰。
網上關于該數據庫的解密方法幾乎都一樣:首先通過微信的 system_config_prefs.xml 文件獲取uin值,然后獲取手機的IMEI值,最后 (IMEI值+uin值)取MD5的前七位就是數據庫的密碼。
說下這個方法的缺陷:
下面將介紹通過frida hook方法獲取數據庫密鑰。
實驗準備:
2.實驗
首先將EnMicroMsg.db文件從模擬器(手機)復制到電腦上(手機或者模擬器要登陸微信):
adb pull /data/data/com.tencent.mm/MicroMsg/8e1435ec4ddf157ca48ec73b4fc108ac/EnMicroMsg.db C:\Users\lxh\Desktop\WeiXin\EnMicroMsg #8e1435ec4ddf157ca48ec73b4fc108ac這個文件夾名稱可能不一樣,要注意一下。然后可以這樣想:微信在啟動時,肯定會連接到這個數據庫,連接后需要一個函數以及密碼來打開數據庫讀取其中的內容,我們要做的就是找到這個打開數據庫的函數,然后用frida hook 這個函數,打印出密碼。
將微信.apk拖入jadx,打開騰訊微信官方api文檔:https://tencent.github.io/wcdb/references/android/reference/com/tencent/wcdb/database/SQLiteDatabase.html
因為涉及到數據庫的操作函數肯定帶有database字段,所以我們直接在頁面搜索"database“,經過搜索與分析后可以發現一個openOrCreateDatabase函數:(可以看到第一個參數file應該就是需要打開的數據庫文件,第二個參數password就是打開數據庫的密碼)
于是在jadx中搜索"openOrCreateDatabase",可以得到如下結果:
點進去:
可以看到這個y就是數據庫文件名,而str2就是打開數據庫的密碼,這兩個參數傳給了openOrCreateDatabase函數,接下來查看"openOrCreateDatabase"函數的調用:
可以看到這個函數是個重載函數,其中有一個調用了openDatabase函數,查看其調用
這里的大概意思是:如果str3字符串以"EnMicroMsg.db"結尾,也就是說如果數據庫名為EnMicroMsg.db,則調用openDatabase(str3, bytes,sQLiteCipherSpec, null, i, fVar, 8)打開這個數據庫。接著查找該函數的聲明:
到這里我們就可以直接用frida來hook這個函數了,并打印前兩個參數(數據庫名和密碼):
hook.js:
import frida import sys jscode = """Java.perform(function(){ var utils = Java.use("com.tencent.wcdb.database.SQLiteDatabase"); // 類的加載路徑utils.openDatabase.overload('java.lang.String', '[B', 'com.tencent.wcdb.database.SQLiteCipherSpec', 'com.tencent.wcdb.database.SQLiteDatabase$CursorFactory', 'int', 'com.tencent.wcdb.DatabaseErrorHandler', 'int').implementation = function(a,b,c,d,e,f,g){ console.log("Hook start......");var JavaString = Java.use("java.lang.String");var database = this.openDatabase(a,b,c,d,e,f,g);send(a);console.log(JavaString.$new(b));send("Hook ending......");return database;};}); """def on_message(message,data): #js中執行send函數后要回調的函數if message["type"] == "send":print("[*] {0}".format(message["payload"]))else:print(message)process = frida.get_remote_device() pid = process.spawn(['com.tencent.mm']) #spawn函數:進程啟動的瞬間就會調用該函數 session = process.attach(pid) # 加載進程號 script = session.create_script(jscode) #創建js腳本 script.on('message',on_message) #加載回調函數,也就是js中執行send函數規定要執行的python函數 script.load() #加載腳本 process.resume(pid) # 重啟app sys.stdin.read()執行代碼可以得到如下結果:
這個95af940就是我EnMicroMsg.db數據庫的密碼,用sqlcipher.exe打開EnMIcroMsg.db,輸入密碼:
成功打開了數據庫,然后可以在message表中看到所有的聊天記錄。
3.總結
本次實例的難點就是找那個打開EnMicroMsg.db數據庫的函數,以及js中重載函數部分代碼的編寫,只要函數找對了,找出密碼也就近在咫尺了。
關注公眾號[人人皆是程序猿],回復sqlcipher獲取工具下載鏈接。
曾經發生過的事情不可能忘記,只不過是想不起而已。
——《千與千尋》總結
以上是生活随笔為你收集整理的Android逆向分析实例(三)-解密微信EnMicroMsg.db数据库的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 鞋带打结不散
- 下一篇: 【eoeAndroid社区索引】andr