#include "downloader.h"
#include <QDebug>
#include <QEventLoop>
void Downloader::downloadFileFromURL(const QString &url, const QString &filePath)
{
if (!m_isReady)
return;
m_isReady = false;
const QString fileName = filePath + url.right(url.size() - url.lastIndexOf("/"));
qDebug() << fileName;
m_file = new QFile();
m_file->setFileName(fileName);
m_file->open(QIODevice::WriteOnly);
if (!m_file->isOpen()) {
m_isReady = true;
return;
}
QNetworkAccessManager *manager = new QNetworkAccessManager;
QNetworkRequest request;
request.setUrl(QUrl(url));
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(onDownloadFileComplete(QNetworkReply *)));
manager->get(request);
}
void Downloader::onDownloadFileComplete(QNetworkReply *reply)
{
if (!m_file->isWritable()) {
m_isReady = true;
return;
}
m_file->write(reply->readAll());
m_file->close();
m_isReady = true;
}
bool downloadURL(const QString &url, const QString &fileName)
{
QNetworkAccessManager manager;
QNetworkRequest request;
request.setUrl(url);
QNetworkReply *reply = manager.get(request);
QEventLoop loop;
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
if (reply->error() != QNetworkReply::NoError)
{
return false;
}
QFile f(fileName);
qDebug() << fileName;
if(!f.open(QIODevice::WriteOnly))
return false;
f.write(reply->readAll());
f.close();
delete reply;
return true;
}
#ifndef DOWNLOADER_H
#define DOWNLOADER_H
#include <QFile>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QObject>
#include <QUrl>
class Downloader : public QObject {
Q_OBJECT
QFile *m_file;
bool m_isReady;
public:
explicit Downloader(QObject *parent = 0) : QObject(parent) {m_isReady = true;}
virtual ~Downloader() {}
void downloadFileFromURL(const QString &url, const QString &filePath);
private slots:
void onDownloadFileComplete(QNetworkReply *reply);
};
bool downloadURL(const QString &url, const QString &fileName);
#endif // DOWNLOADER_H
bool GetCfgFiles( string path, vector<string>& vecDbFile, vector<string>& vecUniFile, string &strKeyPrefsFile,
string& strDengtaMetaFile)
{
//文件句柄
long hFile ;
//文件信息
struct _finddata_t fileinfo;
string p;
if((hFile = _findfirst(p.assign(path).append("\\*").c_str(),&fileinfo)) != 0)
{
do
{
//如果是目录,迭代之
//如果不是,加入列表
if((fileinfo.attrib & _A_SUBDIR))
{
if(strcmp(fileinfo.name,".") != 0 && strcmp(fileinfo.name,"..") != 0)
{
GetCfgFiles(p.assign(path).append("\\").append(fileinfo.name), vecDbFile,
vecUniFile,
strKeyPrefsFile,
strDengtaMetaFile);
}
}
else
{
string strFile = p.assign(path).append("\\").append(fileinfo.name);
string strFileName(fileinfo.name);
QString qstrFileName = QString::fromLocal8Bit(fileinfo.name);
QString qstrFullName = QString::fromLocal8Bit(strFile.c_str());
if (qstrFileName == "auth_info_key_prefs.xml")
{
strKeyPrefsFile = strFile;
}
if (qstrFileName == "DENGTA_META.xml")
{
strDengtaMetaFile = strFile;
}
if (qstrFileName == "EnMicroMsg.db")
{
vecDbFile.push_back(strFile);
}
if (qstrFileName.startsWith("ReportConfig_20971520_"))
{
vecUniFile.push_back(strFileName);
}
}
}while(_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
return true;
}
QString GetMd5(QString pwd="867071047680551184993731")
{
QString md5;
QByteArray ba,bb;
QCryptographicHash md(QCryptographicHash::Md5);
ba.append(pwd);
md.addData(ba);
bb = md.result();
md5.append(bb.toHex());
md5 = md5.mid(0, 7);
return md5;
}
#include <map>
class VxAccount
{
public:
QString m_qstrTel;
QString m_qstrVxId;
QString m_qstrNickName;
QString m_qstrImgPath;
QString m_qstrDbPath;
QString m_qstrDbPwd;
QString m_qstrVxNo; //对外显示的微信号
//QString m_qstr;
};
class CInstance
{
private:
static CInstance* m_spInstance;
CInstance(){}
public:
static CInstance* getInstance()
{
return m_spInstance;
}
map<QString, VxAccount> m_mapAccount;
};
CInstance* CInstance::m_spInstance = new CInstance();
bool getUserInfo(std::string strDbPath, const char* key, VxAccount &vxAccount)
{
QString qstrPath = QCoreApplication::applicationDirPath ();
sqlite3 *db;
if (sqlite3_open(strDbPath.c_str(), &db) == SQLITE_OK)
{
int rc;
if (db == NULL) {
//ERROR(("sqlite3_open reported OK, but db is null, retrying open %s\n", sqlite3_errmsg(db)))
return false;
}
if (sqlite3_key(db, key, strlen(key)) != SQLITE_OK) {
//ERROR(("error setting key %s\n", sqlite3_errmsg(db)))
return false;
}
char szSql[256] = {'\0'};
sprintf(szSql, "PRAGMA key = '%s';", key);
rc = sqlite3_exec(db, szSql, NULL, NULL, NULL);
rc = sqlite3_exec(db, "PRAGMA cipher_use_hmac = off;", NULL, NULL, NULL);
rc = sqlite3_exec(db, "PRAGMA cipher_page_size = 1024;", NULL, NULL, NULL);
rc = sqlite3_exec(db, "PRAGMA kdf_iter = 4000;", NULL, NULL, NULL);
//SQLlite 操作代码...
const char* sqlstatement = "select id, value from userinfo where id in(2,4, 6, 42);";
sqlite3_stmt *stmt = NULL; // stmt语句句柄
int result = sqlite3_prepare_v2(db, sqlstatement, -1, &stmt, NULL);
if (result == SQLITE_OK)
{
// 每调一次sqlite3_step()函数,stmt语句句柄就会指向下一条记录
while (sqlite3_step(stmt) == SQLITE_ROW)
{
// 取出第0列字段的值
const unsigned char *key = sqlite3_column_text(stmt, 0);
// 取出第1列字段的值
const unsigned char *value = sqlite3_column_text(stmt, 1);
string strKey = string((char*)key);
string strValue = string((char*)value);
//输出相关查询的数据
cout << "name = " << key <<", value = "<< value << endl;
if ("2" == strKey)
{
vxAccount.m_qstrVxId = QString::fromStdString(strValue);
}
if ("4" == strKey)
{
vxAccount.m_qstrNickName = QString::fromStdString(strValue);
}
if ("6" == strKey)
{
vxAccount.m_qstrTel = QString::fromStdString(strValue);
}
if ("42" == strKey)
{
vxAccount.m_qstrVxNo = QString::fromStdString(strValue);
}
}
}
else
{
cout << "查询语句有问题" << endl;
sqlite3_close(db);
return false;
}
sqlite3_close(db);
return true;
}
return false;
}
bool getImgPath(std::string strDbPath, const char* key, VxAccount &vxAccount)
{
QString qstrPath = QCoreApplication::applicationDirPath ();
sqlite3 *db;
if (sqlite3_open(strDbPath.c_str(), &db) == SQLITE_OK)
{
int rc;
if (db == NULL) {
//ERROR(("sqlite3_open reported OK, but db is null, retrying open %s\n", sqlite3_errmsg(db)))
return false;
}
if (sqlite3_key(db, key, strlen(key)) != SQLITE_OK) {
//ERROR(("error setting key %s\n", sqlite3_errmsg(db)))
return false;
}
char szSql[256] = {'\0'};
sprintf(szSql, "PRAGMA key = '%s';", key);
rc = sqlite3_exec(db, szSql, NULL, NULL, NULL);
rc = sqlite3_exec(db, "PRAGMA cipher_use_hmac = off;", NULL, NULL, NULL);
rc = sqlite3_exec(db, "PRAGMA cipher_page_size = 1024;", NULL, NULL, NULL);
rc = sqlite3_exec(db, "PRAGMA kdf_iter = 4000;", NULL, NULL, NULL);
//SQLlite 操作代码...
const char* sqlstatement = "select reserved2 from img_flag where username = wxid_ypk5cle17j9u22 ;";
sqlite3_stmt *stmt = NULL; // stmt语句句柄
int result = sqlite3_prepare_v2(db, sqlstatement, -1, &stmt, NULL);
if (result == SQLITE_OK)
{
// 每调一次sqlite3_step()函数,stmt语句句柄就会指向下一条记录
while (sqlite3_step(stmt) == SQLITE_ROW)
{
// 取出第0列字段的值
const unsigned char *key = sqlite3_column_text(stmt, 0);
// 取出第1列字段的值
const unsigned char *value = sqlite3_column_text(stmt, 1);
string strKey = string((char*)key);
string strValue = string((char*)value);
//输出相关查询的数据
cout << "name = " << key <<", value = "<< value << endl;
if ("2" == strKey)
{
vxAccount.m_qstrVxId = QString::fromStdString(strValue);
}
if ("4" == strKey)
{
vxAccount.m_qstrNickName = QString::fromStdString(strValue);
}
if ("6" == strKey)
{
vxAccount.m_qstrTel = QString::fromStdString(strValue);
}
if ("42" == strKey)
{
vxAccount.m_qstrVxNo = QString::fromStdString(strValue);
}
}
}
else
{
cout << "查询语句有问题" << endl;
sqlite3_close(db);
return false;
}
sqlite3_close(db);
return true;
}
return false;
}
QString GetMd5(QString pwd="867071047680551184993731")
{
QString md5;
QByteArray ba,bb;
QCryptographicHash md(QCryptographicHash::Md5);
ba.append(pwd);
md.addData(ba);
bb = md.result();
md5.append(bb.toHex());
md5 = md5.mid(0, 7);
return md5;
}
vector<string> vecDbFile;
vector<string> vecUniFile;
string strKeyPrefsFile;
string strDengtaMetaFile;
GetCfgFiles("E:\\huawei", vecDbFile, vecUniFile, strKeyPrefsFile, strDengtaMetaFile);
PrefsDomParser domParser;
QString qstrAuthUni;
domParser.getAuthUin(QString::fromStdString(strKeyPrefsFile), qstrAuthUni);
cout << "qstrAuthUni " << qstrAuthUni.toStdString() << endl;
DengtaDomParser DengtaParser;
QString qstrDengta;
DengtaParser.getAuthUin(QString::fromStdString(strDengtaMetaFile), qstrDengta);
cout << "qstrDengta " << qstrDengta.toStdString() << endl;
int iPreLen = strlen("ReportConfig_20971520_");
for (int i = 0; i < (int)vecUniFile.size(); i++)
{
vecUniFile[i] = vecUniFile[i].substr(iPreLen, vecUniFile[i].length() - 4 - iPreLen);
QString qstrDbPwd = GetMd5(qstrDengta + QString::fromStdString(vecUniFile[i])); //"867071047680551184993731"
//qstrDbPwd = qstrDbPwd.mid(0, 7);
vecUniFile[i] = qstrDbPwd.toStdString();
cout << "pwd: " << vecUniFile[i] << endl;
}
qstrAuthUni = "1234567890ABCDEF" + qstrAuthUni;
qstrAuthUni = GetMd5(qstrAuthUni);
vecUniFile.push_back(qstrAuthUni.toStdString());
//cout << "strDengtaMetaFile " << qstrDengta.toStdString() << endl;
for (int i = 0; i < (int)vecUniFile.size(); i++)
{
for (int j = 0; j < (int)vecDbFile.size(); j++)
{
VxAccount vxAccount;
if (true == getUserInfo(vecDbFile[j], vecUniFile[i].c_str(), vxAccount))
{
vxAccount.m_qstrDbPwd = QString::fromStdString(vecUniFile[i]);
vxAccount.m_qstrDbPath = QString::fromStdString(vecDbFile[j]);
CInstance::getInstance()->m_mapAccount.insert(
pair<QString, VxAccount>(vxAccount.m_qstrVxId, vxAccount)
);
cout << "open db success " << vxAccount.m_qstrTel.toStdString() << endl;
}
}
}
for (auto itor = CInstance::getInstance()->m_mapAccount.begin();
itor != CInstance::getInstance()->m_mapAccount.end();
itor++)
{
string strDbPath = itor->second.m_qstrDbPath.toStdString();
string strPwd = itor->second.m_qstrDbPwd.toStdString();
getImgPath(strDbPath, strPwd.c_str(), itor->second);
}
string strDbPath = "E:\\huawei\\fulmz\\apps\\com.tencent.mm\\r\\MicroMsg\\e3b4a2f52515036bece3f285a0e10e3a\\EnMicroMsg.db";
一文教会你导出微信聊天记录_司小远的博客-优快云博客