能力值:
( LV9,RANK:250 )
|
-
-
2 楼
本帖没看懂lz啥意思
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
我也想学习,密切关注楼主的帖子。。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
QQ的Msg保存是一COM Storage 方式,使用VC 工具读出分析,肯定是加过密的
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
可以逆一下从MSG.10到MSG2.0的过程。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
支持~关注一下~腾讯又换格式真是麻烦啊~
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
非常观注。。。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
你可以用7z解包...
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
然后解密吧,不会了..
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
7z解包?怎么解,改成什么扩展名?
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
听说文件貌似是加密了.
具体怎么加密不太清楚.
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
不会用密码加密的 一旦更换密码 那不是聊天记录就会丢失么 现在网上也有读2009聊天记录的软件
|
能力值:
( LV3,RANK:30 )
|
-
-
13 楼
改成EXE,用UNIEXTRACT抽文件,可以
|
能力值:
( LV2,RANK:10 )
|
-
-
14 楼
沒試過,等大牛來解吧
|
能力值:
( LV4,RANK:50 )
|
-
-
15 楼
是lz77 压缩?
|
能力值:
( LV2,RANK:10 )
|
-
-
16 楼
装好7z以后直接右键7z,解压到文件夹就可以解出来了,解出来是分开文件夹存放的。进一步如何读取请教高人了。另外解开以后大小都比原来小,不知是何原因
|
能力值:
( LV2,RANK:10 )
|
-
-
17 楼
7ZIP打开就能解出来
|
能力值:
( LV2,RANK:10 )
|
-
-
18 楼
是用QQ密码加密的,改了密码也能读
|
能力值:
( LV2,RANK:10 )
|
-
-
19 楼
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");
}
}
|
能力值:
( LV2,RANK:10 )
|
-
-
20 楼
真的能破?
比较怀疑,我测试看看~~
测试结果,失败~~~~~
|
能力值:
( LV2,RANK:15 )
|
-
-
21 楼
TC会用7Z不会吧。。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
22 楼
19楼的方法俺没试成功.有成功的吗?
关注中......
|
能力值:
( LV2,RANK:10 )
|
-
-
23 楼
是7-zip解压,能看到里面的结构包括buddy,discuss,group,mobile,system这5个文件夹,以及lastmsginfo.dat ,Matrix.dat,seqbase.dat 这3个加密的dat文件,聊天记录存在buddy中,与2008相比每个QQ号码文件夹中多了info.dat文件,我想关键是这个文件了。
|
能力值:
( LV2,RANK:10 )
|
-
-
24 楼
19楼的帖子在网上有,这个不是用来破解的,功能只是打开了QQ的msg2.0的存储结构,并没有涉及到里面的解密,另外java方法也只是适用于LoginUinList(QQ2008)文件,对于msg2.0中的dat文件并没有用,因为QQ2009中的dat文件也加密了
|
能力值:
( LV2,RANK:10 )
|
-
-
25 楼
不知有没有试过,就算用DEC压缩后替换为自己的QQ号,在陌生人或黑名单中也找不到数据
|