QQ2009聊天记录破解思路
步骤简短,看不懂的,本人不提供支持。本人原创。纯研究,用于黑客或商业用途,请别联系我。----Alex msg2.0.db,这个东西真麻烦,不象之前的msgex那么容易破解。下面简短陈述。看的懂得拿走,看不懂的自己想。 如果你连msg2.0.db是什么都不知道,那就别往下看了。你肯定看不懂。更浪费时间。 1.需要:7-zip,DBcompresser或者Paradox (Paradox用起来麻烦需要library,推荐DBC) 2 用7—zip释放你需要破解得msg2.0.db。 得到buddy,discuss,group,mobile,system这5个文件夹。以及lastmsginfo.dat , Matrix.dat,seqbase.dat 这3个加密的dat文件。 3 需要你自己的msg2.0 并且释放。得到buddy,discuss,group,mobile,system这5个文件夹。以及lastmsginfo.dat , Matrix.dat,seqbase.dat 这3个加密的dat文件。注:buddy是重点,其余的文件夹缺失,没有关系。 4 打开需破解的buddy文件夹,里面就是很多qq号码组成的文件夹。再任意打开其中一个看到content.dat,index.dat,info.dat 三个dat文件。 将自己的info.dat 复制到需破解buddy文件夹下。根据号码复制自己需要的。当然,你也可以全部复制。 5 把7-zip 释放的3个你自己的dat文件,既lastmsginfo.dat , Matrix.dat,seqbase.dat 覆盖到需破解的msq2.0文件夹中。(却一不可) 6 用DBcompresse组合文件,重命名为msg2.0.db,默认储存路径为C:\gainover 。放入user\XXXX里面。(DOS可以直接combine,这个我没研究,看到有人研究过) 7 用复制合成的msg2.0 登陆自己的号码,就能直接看到其中记录。目标人一般在你的黑名单或已删除联系人中。 8 破解完毕。享受吧。该哭的哭,该笑的笑。
感谢朋友DiLi,提供 qq2009 msg2.0.db VB结构。 以下是msq2.0.db 分析图。如果需要查看内容的话,用IStorage::OpenStream函数就可以打开,这里不多说。 // ClassTest.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "objidl.h" #include "comdef.h" void PrintDB(IEnumSTATSTG *pEnum,IStorage *pStore,int Depth) { STATSTG statstg;
while(NOERROR == pEnum->Next(1,&statstg,NULL)) { for(int i=0;i<Depth;i++)printf("\t|"); wprintf(_T("---%s\n"),statstg.pwcsName); if(statstg.type == STGTY_STORAGE) { IStorage *pStore1=NULL; HRESULT hr; hr=pStore->OpenStorage(statstg.pwcsName,NULL, STGM_READ|STGM_DIRECT|STGM_SHARE_EXCLUSIVE, NULL, 0,&pStore1); if(hr != S_OK || pStore1==NULL) { wprintf(_T("open %s error\n"),statstg.pwcsName); continue; } IEnumSTATSTG *pEnum1=NULL; pStore1->EnumElements(0,NULL,0,&pEnum1); PrintDB(pEnum1,pStore1,Depth+1); pEnum1->Release(); pStore1->Release(); } } } int _tmain(int argc, _TCHAR* argv[]) { wchar_t szFileName[]=_T("E:\\下载保存\\XXXX\\msg2.0.db"//换成你的QQ); ::CoInitialize(NULL); IStorage *pStore=NULL; IStream *pStream=NULL; HRESULT hr=E_FAIL; hr=::StgOpenStorage(_bstr_t(szFileName),NULL,STGM_READ|STGM_DIRECT|STGM_SHARE_EXCLUSIVE,NULL,0,&pStore); if(hr != S_OK || pStore==NULL) { printf("open failed\n"); return 0; } IEnumSTATSTG *pEnum=NULL; hr = pStore->EnumElements(0,NULL,0,&pEnum ); if(hr != S_OK || pStore==NULL) { printf("enumerate failed\n"); return 0; } PrintDB(pEnum,pStore,0); pEnum-> Release(); pStore->Release(); return 0; } 输出结果 ---buddy |---8362xx | |---info.dat | |---index.dat | |---content.dat |---169329xx | |---info.dat | |---index.dat | |---content.dat ---group |---2048838xx | |---info.dat | |---index.dat | |---content.dat |---2049667xx | |---info.dat | |---index.dat | |---content.dat ---mobile ---system |---1 | |---index.dat | |---content.dat |---3 | |---index.dat | |---content.dat |---4 | |---index.dat | |---content.dat ---discuss ---Matrix.dat ---seqbase.dat ---lastmsginfo.dat
以下是JAVA。 package com; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /** * Decry LoginUinList.dat * @author rmb * 2008-08-07 */ public class LoginUinListDecry { FileOutputStream fw = null; FileInputStream fr = null; boolean isFileEnd = false; int[] ascii = ; /** * init Decry,Encry file handle * @return */ public int initFile(){ int result = -1; try { fw = new FileOutputStream((new File("LoginUinList_Decry.txt"))); fr = new FileInputStream((new File("LoginUinList.dat"))); result = 1; } catch (FileNotFoundException e) { result = -1; e.printStackTrace(); } return result; } /** * Judge file effectiveness * @return */ public int isEffectHead(){ int result = -1; try{ if(fr!=null){ byte[] byte_head = new byte[13]; fr.read(byte_head); if(byte_head[0] == 0x51 && byte_head[1] == 0x41 ){ //&& byte_head[4] == 0x0E result = 1; } if(result>0){ fr.read(new byte[6]); } } } catch(Exception e){ result = -1; e.printStackTrace(); } return result; } /** * decry LoginUinList data * @param key * @param orig_Data * @return */ public byte[] decryData(byte key,byte[] encry_Data){ /* mov dl, byte ptr [ecx+esi] * not dl * xor dl, al * mov byte ptr [ecx+esi], dl */ byte single_Data; for(int i=0;i<encry_Data.length;i++){ single_Data = encry_Data[i]; single_Data = (byte)(~single_Data); single_Data = (byte)(single_Data^key); encry_Data[i] = single_Data; } return encry_Data; } public byte[] getEncryData(byte encryDataLength){ byte[] encryData = new byte[encryDataLength]; int read_num = 0; try { read_num = fr.read(encryData); if(read_num!=encryData.length){ isFileEnd = true; } return encryData; } catch (IOException e) { e.printStackTrace(); } return null; } public byte[] getKeyField(int length){ int read_num = 0; if(fr!=null){ byte[] keyField = new byte[length]; try { read_num = fr.read(keyField); if(read_num!=keyField.length){ isFileEnd = true; } return keyField; } catch (IOException e) { e.printStackTrace(); return null; }
} return null; } public byte getKey(byte[] KeyField){ byte key; key = KeyField[1]; return key; } public byte getKeyDataValue(byte[] KeyField){ byte key; key = KeyField[0]; return key; } public boolean isNeedDecry(byte key){ int int_key = (int)key; if(int_key<5){ return false; } return true; } public boolean isNeedJump(byte[] KeyField){ if(KeyField[0]==0x09){ return true; } return false; } public byte[] trunAround(byte[] DateValue){ byte[] temp = new byte[DateValue.length]; for(int i=0;i<temp.length;i++){ temp[i] = DateValue[DateValue.length-i-1]; } return temp; } public int writeData(byte[] decryData){ try{ fw.write(decryData); return 1; } catch(Exception e){ e.printStackTrace(); } return -1; } public int writeDataString(byte[] decryData){ try{ int height = 0; int down = 0; for(int i=0;i<decryData.length;i++){ height = ((decryData[i]&240)>>4); if(height<0){ height = 0; } down = (decryData[i]&15); if(down<0){ down = 0; } fw.write(ascii[height]); fw.write(ascii[down]); } return 1; } catch(Exception e){ e.printStackTrace(); } return -1; } public void fileFlush(){ try { fw.flush(); } catch (IOException e) { e.printStackTrace(); } } public void jump(){ try { fr.read(new byte[8]); } catch (IOException e) { e.printStackTrace(); } } public int run(){ int result = -1; byte[] keyField; byte key; byte[] decryData; byte[] encryData; if(initFile()>0){ if(isEffectHead()>0){ while(!isFileEnd){ result=-1; keyField = getKeyField(3); if(keyField==null) break; if(isNeedJump(keyField)){ jump(); writeData(new byte[]);//block line continue; } key = getKey(keyField); encryData = getEncryData(key); if(encryData==null) break; decryData = decryData(key,encryData); writeData(decryData); writeData(new byte[]);//:
keyField = getKeyField(4); if(keyField==null) break; key = getKeyDataValue(keyField); encryData = getEncryData(key); if(encryData==null) break; if(isNeedDecry(key)){ decryData = decryData(key,encryData); decryData = trunAround(decryData); } else{ decryData = trunAround(encryData); } writeDataString(decryData); writeData(new byte[]);//break line fileFlush(); result=1; } } destroy(); } return result; } /** * destroy * @return */ public int destroy(){ int result = -1; try{ if(fw!=null){ fw.close(); } if(fr!=null){ fr.close(); } result = 1; } catch(Exception e){ result = -1; e.printStackTrace(); } return result; } public static void main(String[] args) { LoginUinListDecry ListDecry = new LoginUinListDecry(); if(ListDecry.run()>0){ System.out.println("Decry LoginUinList.dat Success"); } else{ System.out.println("Decry LoginUinList.dat Fail"); } }
7-zip 请去官网下载。 下载地址 : http://www.7-zip.org/
DB压缩器 : 下载地址 : http://www.rayfile.com/zh-cn/files/41470597-ee3f-11de-884b-0014221b798a/ |