惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
A
About on SuperTechFans
博客园 - Franky
Engineering at Meta
Engineering at Meta
Recent Announcements
Recent Announcements
云风的 BLOG
云风的 BLOG
B
Blog
Microsoft Security Blog
Microsoft Security Blog
L
LangChain Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
U
Unit 42
Martin Fowler
Martin Fowler
Y
Y Combinator Blog
Stack Overflow Blog
Stack Overflow Blog
博客园 - 叶小钗
Vercel News
Vercel News
Apple Machine Learning Research
Apple Machine Learning Research
The Cloudflare Blog
Last Week in AI
Last Week in AI
腾讯CDC
Microsoft Azure Blog
Microsoft Azure Blog
爱范儿
爱范儿
V
V2EX
G
Google Developers Blog

博客园 - rex.ying

ASP.NET+Win2003虚拟主机安全设置 Windows2003服务器安全配置详细篇 - rex.ying - 博客园 mssql 日期格式化函数 devexpress报表控件的使用 关闭wscript.shell VS2005网站和SQL一起打包部署安装心得【转载】 怎样制作VS2008.NET应用程序的安装包 Developer Express XtraGrid使用技巧 UltraGrid文章收集 用独立的DLL来存储图片(资源文件) InstallShield集成.net Framework的安装包制作 导出EXCEL后去除单元格前置的单引号 从SQL Server中导入/导出 Excel 的基本方法 通过远程桌面操作程序出现hook cannot be created(SendKeys语句错误)的解决 ASP.NET自定义控件事件响应 C# 获取任意窗体选中文字 屏幕取词 在 ASP.NET 中执行 URL 重写 仿Google的输入下拉提示框 xtrareport的使用心得(转)
QQ2009聊天记录破解思路
rex.ying · 2010-03-13 · via 博客园 - rex.ying

步骤简短,看不懂的,本人不提供支持。本人原创。纯研究,用于黑客或商业用途,请别联系我。----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 破解完毕。享受吧。该哭的哭,该笑的笑。


如果你懂java.可以直接破解dat,算法已有。还有,别以为这些buddy里面的dat很容易破解。Passware Kit 没有破出来,想破壳的人...绕道吧...

感谢朋友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/