<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          PC微信逆向:破解聊天記錄文件!

          共 7888字,需瀏覽 16分鐘

           ·

          2021-07-02 11:34


          作者:newx

          鏈接:https://bbs.pediy.com/thread-251303.htm

          在電子取證過(guò)程中,也會(huì)遇到提取PC版微信數(shù)據(jù)的情況,看雪、52破解和CSDN等網(wǎng)上的PC版微信數(shù)據(jù)庫(kù)破解文章實(shí)在是太簡(jiǎn)略了,大多數(shù)只有結(jié)果沒(méi)有過(guò)程。經(jīng)過(guò)反復(fù)試驗(yàn)終于成功解密了數(shù)據(jù)庫(kù),現(xiàn)在把詳細(xì)過(guò)程記錄下來(lái),希望大家不要繼續(xù)在已經(jīng)解決的問(wèn)題上過(guò)度浪費(fèi)時(shí)間,以便更投入地研究尚未解決的問(wèn)題。


          通過(guò)查閱資料得知,與安卓手機(jī)版微信的7位密碼不同,PC版微信的密碼是32字節(jié)(64位),加密算法沒(méi)有說(shuō)明,但是可以通過(guò)OllyDbg工具從內(nèi)存中獲取到這個(gè)密碼,然后通過(guò)一段C++代碼進(jìn)行解密。


           首先下載OllyDbg 2.01漢化版,我用的版本如下圖所示:



          運(yùn)行OllyDbg,然后運(yùn)行PC版微信(需要下載客戶(hù)端的,不是網(wǎng)頁(yè)版)。先不要點(diǎn)擊登錄按鈕。



          切換到Ollydbg界面:



          點(diǎn)擊文件菜單,選擇“附加”,在彈出的對(duì)話(huà)框中找到名稱(chēng)為WeChat的進(jìn)程,其窗口名稱(chēng)為“登錄”。然后點(diǎn)擊“附加”。



          附加成功后OllyDbg開(kāi)始加載,成功加載后可以看到最上面OllyDbg后面有WeChat.exe的字樣:



          在查看菜單中選擇“可執(zhí)行模塊”:



          找到名稱(chēng)為WeChatWin的模塊,雙擊選中。為了方便觀察,在窗口菜單中選擇水平平鋪。在CPU窗口標(biāo)題欄可以看到“模塊WeChatWin”字樣。



          在插件中選擇“StrFinder字符查找”中的“查找ASCII字符串”(注意如果下載的OllyDbg版本不對(duì),可能沒(méi)有相關(guān)插件,因此一定要找對(duì)版本),要稍微等一會(huì)兒,會(huì)出現(xiàn)搜索結(jié)果的窗口。



          在此窗口點(diǎn)擊鼠標(biāo)右鍵,選擇“Find”,在搜索框中輸入“DBFactory::encryptDB”。



          會(huì)自動(dòng)定位在第一處,但我們需要的是第二處,即“encryptDB %s DBKey can’t be null”下面這一處。可以用鼠標(biāo)點(diǎn)擊滾動(dòng)條向下,找到第二處,用鼠標(biāo)雙擊此處。



           在CPU窗口中可以看到已經(jīng)定位到了相應(yīng)的位置。用鼠標(biāo)點(diǎn)擊滾動(dòng)條向下翻。



          下面第六行應(yīng)該是TEST EDX,EDX,就是用來(lái)比對(duì)密碼的匯編語(yǔ)言代碼。在最前面地址位置(本文中是0F9712BA)雙擊設(shè)置斷點(diǎn)(設(shè)置斷點(diǎn)成功則地址會(huì)被標(biāo)紅,而且可以在斷點(diǎn)窗口中看到設(shè)置成功的斷點(diǎn))


          點(diǎn)擊“運(yùn)行”按鈕(或者在調(diào)試菜單中選擇“運(yùn)行”),這時(shí)寄存器窗口中的EDX的值應(yīng)該是00000000。


          切換到微信登錄頁(yè)面,點(diǎn)擊登錄,然后到手機(jī)端確認(rèn)登錄。這是OllyDbg界面中的數(shù)據(jù)不斷滾動(dòng),直到EDX不再為全0并且各個(gè)窗口內(nèi)容停止?jié)L動(dòng)為止。



          在EDX的值上面點(diǎn)擊鼠標(biāo)右鍵,在彈出的菜單里面選擇“數(shù)據(jù)窗口中跟隨”,則數(shù)據(jù)窗口中顯示的就是EDX的內(nèi)容。



          圖示中從0B946A80(這個(gè)數(shù)值是變化的,不但每臺(tái)電腦不同,每次調(diào)試也可能完全不同)到0B946A9F共32個(gè)字節(jié)就是微信的加密密碼,本圖中就是:

          “53E9BFB23B724195A2BC6EB5BFEB0610DC2164756B9B4279BA32157639A40BB1”

           

          一共32個(gè)字節(jié),共64位。


          得到這個(gè)之后,就可以關(guān)閉OllyDbg了,微信也會(huì)自動(dòng)被關(guān)閉。


          接下來(lái)就是解密過(guò)程。在看雪、52破解等多個(gè)論壇中都有相關(guān)的C++源碼,開(kāi)始企圖使用Dev-C++或者C-Free等輕量級(jí)IDE進(jìn)行編譯,也使用過(guò)Visual C++ 6.0綠色精簡(jiǎn)版,結(jié)果多次嘗試出現(xiàn)各種錯(cuò)誤,反復(fù)失敗,最終不得已使用Visual Studio,并對(duì)代碼進(jìn)行了一定的修正,終于調(diào)試成功。


          正好Visual Studio 2019剛剛發(fā)布直接到官方網(wǎng)站下載了社區(qū)版。


          根據(jù)查到的資料,需要先安裝openssl,為了省事直接下載了最新的Win64OpenSSL-1_1_1b,安裝后發(fā)現(xiàn)各種報(bào)錯(cuò),繼續(xù)查找資料發(fā)現(xiàn)原來(lái)sqlcipher使用的是低版本的openssl,之后找到了一個(gè)Win64OpenSSL-1_0_2r也報(bào)錯(cuò),最后發(fā)現(xiàn)還是官方這個(gè)直接解壓縮的版本靠譜:


          https://www.openssl.org/source/openssl-1.0.2r.tar.gz


          把壓縮包直接解壓到任意目錄,比如c:\openssl-1.0.2r


          啟動(dòng)Visual Studio 2019社區(qū)版(估計(jì)Visual Studio 2008以后的都應(yīng)該可以,懶得找就直接官網(wǎng)下載最新的吧)


          在啟動(dòng)界面右下方選擇“創(chuàng)建新項(xiàng)目”



          滾動(dòng)下拉條,在窗口中選擇C++控制臺(tái)應(yīng)用:



                 給項(xiàng)目隨便起個(gè)名字,選擇保存位置:



          然后點(diǎn)擊“創(chuàng)建”,即可完成新項(xiàng)目創(chuàng)建。生成默認(rèn)的Hello World代碼:



          先要做好項(xiàng)目的基礎(chǔ)配置,之前調(diào)試失敗主要問(wèn)題就出在這里了。


          在項(xiàng)目菜單中最下面選擇項(xiàng)目屬性“dewechat屬性”(這個(gè)跟設(shè)置的項(xiàng)目名稱(chēng)一致)


          對(duì)話(huà)框最左上角的配置后面,可以選擇配置的是Debug模式還是Release模式(Release模式不包含調(diào)試信息,編譯完成的exe文件更小一些,但如果是自己用,這兩個(gè)模式?jīng)]有區(qū)別,配置了哪個(gè),后面就要用哪個(gè)模式編譯,否則會(huì)報(bào)錯(cuò))


          先選擇C/C++下面的“常規(guī)”選項(xiàng):



          邊第一條是“附加包含目錄”,點(diǎn)擊右側(cè)空白處。在下拉框里選擇“編輯…”,在對(duì)話(huà)框中點(diǎn)擊四個(gè)圖標(biāo)按鈕最左側(cè)的“新行”按鈕,會(huì)生成一個(gè)空白行,點(diǎn)擊右側(cè)的“…”:


          在彈出的對(duì)話(huà)框里選擇剛剛安裝的openssl目錄(本文是c:\openssl-1.0.2r)中的include目錄。



          設(shè)置完成后如下:



          然后選擇左側(cè)“鏈接器”下面的“常規(guī)”:



          在中間位置,有一個(gè)“附加庫(kù)目錄”,點(diǎn)擊右側(cè)空白處,選擇openssl目錄下的lib目錄,設(shè)置完成后如下:



          最后點(diǎn)擊鏈接器下面的“輸入”:


          右側(cè)最上面有“附加依賴(lài)項(xiàng)”,默認(rèn)已經(jīng)有一些系統(tǒng)庫(kù),點(diǎn)擊右側(cè)內(nèi)容,選擇“編輯…”



          這個(gè)沒(méi)有增加新行的按鈕,只能手工錄入或者拷貝文件名進(jìn)去,需要增加上圖所示的兩個(gè)庫(kù)名稱(chēng)。


          設(shè)置完成后如下:



          現(xiàn)在所有的設(shè)置都OK了,可以把代碼放進(jìn)來(lái)編譯了。


          由于太多網(wǎng)站轉(zhuǎn)載,而且很多有錯(cuò)漏,已經(jīng)搞不清原始代碼是哪位大神寫(xiě)的了,其中有一些已經(jīng)被廢棄的代碼,根據(jù)系統(tǒng)報(bào)錯(cuò)提示進(jìn)行了替換,另外做了一個(gè)主要的變化就是之前的代碼是把數(shù)據(jù)庫(kù)名寫(xiě)在變量中,但由于需要解密很多庫(kù),為了靈活,改為輸入?yún)?shù)的方法,即在運(yùn)行時(shí)帶參數(shù)運(yùn)行或者根據(jù)提示輸入需要解密的數(shù)據(jù)庫(kù)文件名。


          using namespace std;#include <Windows.h>#include <iostream>#include <openssl/rand.h>#include <openssl/evp.h>#include <openssl/aes.h>#include <openssl/hmac.h>
          #undef _UNICODE#define SQLITE_FILE_HEADER "SQLite format 3" #define IV_SIZE 16#define HMAC_SHA1_SIZE 20#define KEY_SIZE 32
          #define SL3SIGNLEN 20
          #ifndef ANDROID_WECHAT#define DEFAULT_PAGESIZE 4096 //4048數(shù)據(jù) + 16IV + 20 HMAC + 12#define DEFAULT_ITER 64000#else#define NO_USE_HMAC_SHA1#define DEFAULT_PAGESIZE 1024#define DEFAULT_ITER 4000#endif//pc端密碼是經(jīng)過(guò)OllyDbg得到的32位pass。unsigned char pass[] = { 0x53,0xE9,0xBF,0xB2,0x3B,0x72,0x41,0x95,0xA2,0xBC,0x6E,0xB5,0xBF,0xEB,0x06,0x10,0xDC,0x21,0x64,0x75,0x6B,0x9B,0x42,0x79,0xBA,0x32,0x15,0x76,0x39,0xA4,0x0B,0xB1 };char dbfilename[50];int Decryptdb();int CheckKey();int CheckAESKey();int main(int argc, char* argv[]){ if (argc >= 2) //第二個(gè)參數(shù)argv[1]是文件名 strcpy_s(dbfilename, argv[1]); //復(fù)制 //沒(méi)有提供文件名,則提示用戶(hù)輸入 else { cout << "請(qǐng)輸入文件名:" << endl; cin >> dbfilename; } Decryptdb(); return 0;}
          int Decryptdb(){ FILE* fpdb; fopen_s(&fpdb, dbfilename, "rb+"); if (!fpdb) { printf("打開(kāi)文件錯(cuò)!"); getchar(); return 0; } fseek(fpdb, 0, SEEK_END); long nFileSize = ftell(fpdb); fseek(fpdb, 0, SEEK_SET); unsigned char* pDbBuffer = new unsigned char[nFileSize]; fread(pDbBuffer, 1, nFileSize, fpdb); fclose(fpdb);
          unsigned char salt[16] = { 0 }; memcpy(salt, pDbBuffer, 16);
          #ifndef NO_USE_HMAC_SHA1 unsigned char mac_salt[16] = { 0 }; memcpy(mac_salt, salt, 16); for (int i = 0; i < sizeof(salt); i++) { mac_salt[i] ^= 0x3a; }#endif
          int reserve = IV_SIZE; //校驗(yàn)碼長(zhǎng)度,PC端每4096字節(jié)有48字節(jié)#ifndef NO_USE_HMAC_SHA1 reserve += HMAC_SHA1_SIZE;#endif reserve = ((reserve % AES_BLOCK_SIZE) == 0) ? reserve : ((reserve / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
          unsigned char key[KEY_SIZE] = { 0 }; unsigned char mac_key[KEY_SIZE] = { 0 };
          OpenSSL_add_all_algorithms(); PKCS5_PBKDF2_HMAC_SHA1((const char*)pass, sizeof(pass), salt, sizeof(salt), DEFAULT_ITER, sizeof(key), key);#ifndef NO_USE_HMAC_SHA1 PKCS5_PBKDF2_HMAC_SHA1((const char*)key, sizeof(key), mac_salt, sizeof(mac_salt), 2, sizeof(mac_key), mac_key);#endif
          unsigned char* pTemp = pDbBuffer; unsigned char pDecryptPerPageBuffer[DEFAULT_PAGESIZE]; int nPage = 1; int offset = 16; while (pTemp < pDbBuffer + nFileSize) { printf("解密數(shù)據(jù)頁(yè):%d/%d \n", nPage, nFileSize / DEFAULT_PAGESIZE);
          #ifndef NO_USE_HMAC_SHA1 unsigned char hash_mac[HMAC_SHA1_SIZE] = { 0 }; unsigned int hash_len = 0; HMAC_CTX hctx; HMAC_CTX_init(&hctx); HMAC_Init_ex(&hctx, mac_key, sizeof(mac_key), EVP_sha1(), NULL); HMAC_Update(&hctx, pTemp + offset, DEFAULT_PAGESIZE - reserve - offset + IV_SIZE); HMAC_Update(&hctx, (const unsigned char*)& nPage, sizeof(nPage)); HMAC_Final(&hctx, hash_mac, &hash_len); HMAC_CTX_cleanup(&hctx); if (0 != memcmp(hash_mac, pTemp + DEFAULT_PAGESIZE - reserve + IV_SIZE, sizeof(hash_mac))) { printf("\n 哈希值錯(cuò)誤! \n"); getchar(); return 0; }#endif // if (nPage == 1) { memcpy(pDecryptPerPageBuffer, SQLITE_FILE_HEADER, offset); }
          EVP_CIPHER_CTX* ectx = EVP_CIPHER_CTX_new(); EVP_CipherInit_ex(ectx, EVP_get_cipherbyname("aes-256-cbc"), NULL, NULL, NULL, 0); EVP_CIPHER_CTX_set_padding(ectx, 0); EVP_CipherInit_ex(ectx, NULL, NULL, key, pTemp + (DEFAULT_PAGESIZE - reserve), 0);
          int nDecryptLen = 0; int nTotal = 0; EVP_CipherUpdate(ectx, pDecryptPerPageBuffer + offset, &nDecryptLen, pTemp + offset, DEFAULT_PAGESIZE - reserve - offset); nTotal = nDecryptLen; EVP_CipherFinal_ex(ectx, pDecryptPerPageBuffer + offset + nDecryptLen, &nDecryptLen); nTotal += nDecryptLen; EVP_CIPHER_CTX_free(ectx);
          memcpy(pDecryptPerPageBuffer + DEFAULT_PAGESIZE - reserve, pTemp + DEFAULT_PAGESIZE - reserve, reserve); char decFile[1024] = { 0 }; sprintf_s(decFile, "dec_%s", dbfilename); FILE * fp; fopen_s(&fp, decFile, "ab+"); { fwrite(pDecryptPerPageBuffer, 1, DEFAULT_PAGESIZE, fp); fclose(fp); }
          nPage++; offset = 0; pTemp += DEFAULT_PAGESIZE; } printf("\n 解密成功! \n"); return 0;}


          將之前默認(rèn)的代碼全部清除,將以上代碼拷貝進(jìn)去,保存。然后在工具條欄中選擇是Debug還是Release模式,是x86還是x64(需要跟之前配置匹配,如果選了沒(méi)配置的模式會(huì)報(bào)錯(cuò)。測(cè)試發(fā)現(xiàn)幾個(gè)選項(xiàng)沒(méi)有太大區(qū)別,建議默認(rèn)),之后點(diǎn)擊“本地windows調(diào)試器”(或者按F5鍵),如果前面的步驟操作都正確,應(yīng)該可以完成編譯并自動(dòng)運(yùn)行,彈出一個(gè)命令行窗口,提示需要輸入文件名:



          最下方顯示了生成的exe文件路徑,將這個(gè)文件拷貝到微信數(shù)據(jù)庫(kù)所在的目錄,一般是:

          C:\Users\Administrator\Documents\WeChat Files\********\Msg


          其中********位置為需要解密的微信id,目錄內(nèi)容如下:




          如果要解密ChatMsg.db,則在命令行窗口輸入指令dewechat ChatMsg.db回車(chē)即可。



          解密成功后,會(huì)在目錄中生成de_ChatMsg.db,用sqlite數(shù)據(jù)庫(kù)管理軟件打開(kāi)即可。


          本文主要是個(gè)驗(yàn)證過(guò)程,沒(méi)有做什么突破工作,目前的解密只能算是半自動(dòng)過(guò)程,密碼算法部分的獲得是下一步需要研究的內(nèi)容,希望大家共同努力!


          推薦閱讀:

          華為的數(shù)字化轉(zhuǎn)型與數(shù)據(jù)治理

          從0到1:華為政企數(shù)字化轉(zhuǎn)型項(xiàng)目實(shí)踐分享

          小米用戶(hù)畫(huà)像實(shí)戰(zhàn),48頁(yè)P(yáng)PT下載

          超詳細(xì)280頁(yè)Docker實(shí)戰(zhàn)文檔!開(kāi)放下載

          【干貨】如何從0到1構(gòu)建用戶(hù)畫(huà)像系統(tǒng)(附pdf下載鏈接)

          【中臺(tái)實(shí)踐】華為大數(shù)據(jù)中臺(tái)架構(gòu)分享.pdf

          華為大數(shù)據(jù)解決方案(PPT)


          瀏覽 38
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天澡天天狠天天天做 | 免费操B视频 | 国产成人无码免费视频 | 日本黄色电影大鸡巴 | 日本大香蕉网 |