基於 Android 讀取微信本地 DB 資料 | 思維原理及技術分析

AlicFeng發表於2019-02-14

No matter where I am, I will reply you immediately when I see the email.My Email: echo "YUBzYW1lZ28uY29tCg==" | base64 -d

apk原始碼傳送門github dev分支

前言

該移動端軟體基於Android開發,是一個解析微信資料資訊(包括微信個人資料、聯絡人、聊天記錄等)並重灌報文同步至服務端的一款應用。其實實屬公司業務需要而開發的一個小玩意,Android嘛~笑O(∩_∩)O哈哈~。

應用的原理思維分析:首先拿到微信應用的本地SQLite資料庫檔案( 無網路的情況下可以顯示之前的聊天記錄,因而本地必有快取資料的載體、G一下 額 是本地資料 ),分析到本地快取以及找到檔案的路徑知識第一步,第二部需要秘鑰進一步開啟db檔案,找到密碼是很簡單的事情( 再此感謝前人貢獻 ) ,可以透過相關的資訊計算得到,肯定會有人問:萬一微信將其改了那此方案此不是作廢了嗎?,?既然微信憑其技術實力改變了,那也沒辦法呀,但是我相信騰訊不會輕而易舉的去做這一改動的,為何呢?這樣一改動的話,容易造成對之前版本不相容。既然db檔案找到了以及秘鑰也有了,最後一步就是理解與猜測資料表的結構與關係去做業務的開發。

核心技術

  • uin理解與獲取

    uin簡單而言就是微信登入的識別號,裝置必須有登入的歷史才有。uin是如何獲取的呢?

    # uid在aunt_info_key_prefs.xml檔案裡面
    # 具體的路徑為
    "/data/data/com.tencent.mm/shared_prefs/auth_info_key_prefs.xml"
    
    # uin的值為_auth_uin標籤的值,如下是例項檔案,可藉助jsoup依賴庫即可解析值
  • imei碼

    移動裝置的唯一編碼,雙卡雙待的會有兩個。與資料庫秘鑰息息相關。

    public static String imei(Context context) {
      try {
        //例項化TelephonyManager物件
        TelephonyManager telephonyManager = (TelephonyManager)  context.getSystemService(Context.TELEPHONY_SERVICE);
        String imei = telephonyManager.getDeviceId();
        if (imei == null) {
            imei = "";
        }
        return imei;
      } catch (Exception e) {
        e.printStackTrace();
      }
      return null;
    }
  • 資料庫路徑

    # 路徑為
    "/data/data/com.tencent.mm/MicroMsg/" + md5("mm" + uin) + "/EnMicroMsg.db";
  • 資料庫的密碼

    秘鑰為emei+uinmd5擷取前七位再轉大寫即可獲取。

    md5(imei + uin))).substring(0, 7).toLowerCase()
  • 資料庫讀寫操作

    import net.sqlcipher.Cursor;
    import net.sqlcipher.SQLException;
    import net.sqlcipher.database.SQLiteDatabase;
    import net.sqlcipher.database.SQLiteDatabaseHook;
    
    SQLiteDatabase.loadLibs(context);
    SQLiteDatabaseHook hook = new SQLiteDatabaseHook() {
    @Override
      public void preKey(SQLiteDatabase database) {
    
      }
    
      @Override
      public void postKey(SQLiteDatabase database) {
          database.rawExecSQL("PRAGMA cipher_migrate;"); // 相容2.0的資料庫
      }
    };
    String file = "資料庫備份後的檔案路徑;
    String password = "秘鑰";
    SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(file, password, null, hook);
    ... ...
  • 監控渲染圖

    目的為了大資料分析、精準營銷、自動化方案推送~笑?
    效果圖

本作品採用《CC 協議》,轉載必須註明作者和本文連結
價值源於技術,貢獻源於分享 | 筆記分享歸檔 No matter where I am, I will reply you immediately when I see the email. My Email: echo "YUBzYW1lZ28uY29tCg==" | base64 -d 個人比較喜歡分享,若有不對的地方非常感謝指出 相互學習、共同進步~

相關文章