#include "stdafx.h"
#include <atlstr.h>
//很多人在vs2010找不到dllmain的文件,都倍封装好了,其实就在新建项目--win32--win32项目完后选择dll
#define WM_HOOKDLL WM_USER+2013
#pragma data_seg(".Share")
HWND g_hMainWnd=NULL;//主窗口句柄;
HHOOK hhkHook=NULL; //鼠标钩子句柄;
HINSTANCE hInstDll=NULL;//本dll实例句柄;
DWORD g_dwHookPid=-1;//要HOOK的进程的PID
BOOL g_bIsFirstLoad=TRUE;//判断是否是第一次加载本dll
#pragma data_seg()
#pragma comment(linker, "/section:.Share,rws")
struct ProcessWindow
{
DWORD dwProcessId;
HWND hwndWindow;
DWORD dwThreadID;
};
BOOL CALLBACK EnumWindowCallBack(HWND hWnd, LPARAM lParam) ;
BOOL CheckPid()
{
if (g_bIsFirstLoad)
{
return TRUE;//这里第一次直接返回不运行下面的,当starthook执行后 吧这个dll加载到别的指定进程中 又会再一次执行下面的不执行这里了 因为已经true了
}
DWORD pid=GetCurrentProcessId();
if (pid==g_dwHookPid)
{
return TRUE;
}
else
{
return FALSE;
}
}
//鼠标钩子过程,目的是加载本dll到使用鼠标的程序
//鼠标钩子的作用:当鼠标在某程序窗口中时,其就会加载我们这个dll
LRESULT CALLBACK MouseProc(
int nCode, // hook code
WPARAM wParam, // message identifier
LPARAM lParam // mouse coordinates
)
{
return CallNextHookEx(hhkHook,nCode,wParam,lParam);
}
//安装钩子
BOOL WINAPI StartHook(HWND hWnd,DWORD dwPid)
{
g_hMainWnd=hWnd; //保存主窗口句柄
//g_dwHookPid=dwPid;//要HOOK的进程的PID
/*hhkHook=::SetWindowsHookEx(WH_MOUSE,MouseProc,hInstDll,0);
if (hhkHook==NULL)
{
CString err;
err.Format(_T("设置钩子失败 error code=%d"),GetLastError());
MessageBox(g_hMainWnd,err.GetString(),L"err",0);
return FALSE;
}
else
{
return TRUE;
} */
ProcessWindow procwin;
procwin.dwProcessId = dwPid;
procwin.hwndWindow = NULL;
procwin.dwThreadID = NULL;
EnumWindows(EnumWindowCallBack, (LPARAM)&procwin);
g_dwHookPid = procwin.dwThreadID;
if(g_dwHookPid == NULL)
{
CString err;
err.Format(_T("设置钩子失败 error code=%d"),GetLastError());
MessageBox(g_hMainWnd,err.GetString(),L"err",0);
return FALSE;
}
else
return TRUE;
}
BOOL CALLBACK EnumWindowCallBack(HWND hWnd, LPARAM lParam)
{
ProcessWindow *pProcessWindow = (ProcessWindow *)lParam;
DWORD dwProcessId;
GetWindowThreadProcessId(hWnd, &dwProcessId);
// 判断是否是指定进程的主窗口
if (pProcessWindow->dwProcessId == dwProcessId && IsWindowVisible(hWnd) && GetParent(hWnd) == NULL)
{
DWORD proId;
pProcessWindow->hwndWindow = hWnd;
pProcessWindow->dwThreadID = GetWindowThreadProcessId(hWnd,&proId);
return FALSE;
}
return TRUE;
}
//卸载钩子
VOID WINAPI StopHook()
{
//HookOff();//记得恢复原API入口哈
//主程序调用该函数时,恢复的只是主程序原API的入口,
//其它程序的API入口还没有被恢复,所以我们必须处理
//dll退出过程,即在函数ExitInstance()中,调用恢复
//API入口的函数HookOff(),只有这样,其它程序再次调用
//原API时,才不会发生错误喔。
//当我们HOOK所有程序的某个系统API时,千万要注意在
//ExitInstance()中调用HookOff(),血的教训哈。
if (hhkHook!=NULL)
{
UnhookWindowsHookEx(hhkHook);
FreeLibrary(hInstDll);
}
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
if (!CheckPid())
{
return FALSE;
}
hInstDll=GetModuleHandle(0);//这行不能少
g_bIsFirstLoad = FALSE;
MessageBox(NULL,L"注入成功",L"信息",MB_ICONINFORMATION);
break;
}
case DLL_THREAD_ATTACH:
/*{
MessageBox(NULL,L"注入线程成功!",L"通知",MB_ICONINFORMATION);
break;
}*/
case DLL_THREAD_DETACH:
//{
// //MessageBox(NULL,L"注入线程卸载成功!",L"通知",MB_ICONINFORMATION);
// //break;
//}
case DLL_PROCESS_DETACH:
{
SendMessage(g_hMainWnd,WM_HOOKDLL,8,0);
break;
}
}
return TRUE;
}
// TestDlg.h : 头文件
//
#pragma once
#include "afxcmn.h"
#include "DlgProcess.h"
//#define WM_HOOKDLL WM_USER+2013
#define WM_HOOKDLL WM_USER+2013
typedef struct
{
CString strProcessName;
DWORD dwPid;
}PROCESSINFO;
// CTestDlg 对话框
class CTestDlg : public CDialogEx
{
// 构造
public:
CTestDlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
enum { IDD = IDD_DIALOG1 };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg LRESULT OnHookDll(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
public:
// afx_msg void OnBnClickedButton1();
// CString m_ShowHwnd;
private:
// 窗口是否在显示
// BOOL m_visible;
public:
afx_msg void OnDestroy();
// CString m_ProcessId;
// afx_msg void OnBnClickedButton2();
// HWND hwnd;
// CString m_ProcessHandle;
// afx_msg void OnBnClickedButton3();
// DWORD process_Id;
// DWORD processID;
private:
HWND gameHwnd;
DWORD processID;
INT gameAdress;
public:
//afx_msg void OnBnClickedButton1();
CString m_SNumber;
private:
HANDLE processHandle;
public:
//afx_msg void OnTimer(UINT_PTR nIDEvent);
//
//CString m_threadHandle;
//CString m_threadID;
//afx_msg void OnBnClickedButton2();
//BOOL EnumThreadInfo(DWORD proID);
private:
CDWordArray dwArray;
DWORD threadId;
public:
//afx_msg void OnBnClickedButton3();
private:
HANDLE threadHandle;
public:
//afx_msg void OnBnClickedButton4();
// CListCtrl m_List;
PROCESSINFO m_ProcessInfo;
afx_msg void OnBnClickedButton2();
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton3();
CString m_wndTitle;
void EnableDebugPriv(void);
CListCtrl m_List;
afx_msg void OnClose();
};
// TestDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "Test.h"
#include "TestDlg.h"
#include "afxdialogex.h"
#include <tlhelp32.h>
#include<iostream>
using namespace std;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CTestDlg 对话框
CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CTestDlg::IDD, pParent)
, processID(0)
,gameHwnd(NULL)
, gameAdress(0)
, threadId(0)
, threadHandle(0)
, m_wndTitle(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
// m_ShowHwnd = _T("");
// m_ProcessId = _T("");
// m_ProcessHandle = _T("");
m_SNumber = _T("");
/*m_threadHandle = _T("");
m_threadID = _T("");*/
m_ProcessInfo.dwPid=-1;
m_ProcessInfo.strProcessName=_T("未选择任何进程");
}
void CTestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
// DDX_Text(pDX, IDC_EDIT2, m_ShowHwnd);
// DDX_Text(pDX, IDC_EDIT3, m_ProcessId);
// DDX_Text(pDX, IDC_EDIT4, m_ProcessHandle);
/*DDX_Text(pDX, IDC_EDIT1, m_SNumber);
DDX_Text(pDX, IDC_EDIT2, m_threadHandle);
DDX_Text(pDX, IDC_EDIT3, m_threadID);*/
DDX_Control(pDX, IDC_LIST1, m_List);
}
BEGIN_MESSAGE_MAP(CTestDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_HOTKEY()
ON_WM_DESTROY()
/*ON_BN_CLICKED(IDC_BUTTON1, &CTestDlg::OnBnClickedButton1)*/
ON_WM_TIMER()
/*ON_BN_CLICKED(IDC_BUTTON2, &CTestDlg::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON3, &CTestDlg::OnBnClickedButton3)
ON_BN_CLICKED(IDC_BUTTON4, &CTestDlg::OnBnClickedButton4)*/
ON_BN_CLICKED(IDC_BUTTON2, &CTestDlg::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON1, &CTestDlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON3, &CTestDlg::OnBnClickedButton3)
ON_MESSAGE(WM_HOOKDLL,OnHookDll)
ON_WM_CLOSE()
END_MESSAGE_MAP()
// CTestDlg 消息处理程序
BOOL CTestDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
gameHwnd = ::FindWindow(L"TXGuiFoundation",L"QQ");
::GetWindowThreadProcessId(gameHwnd,&processID);
GetWindowText(m_wndTitle);
GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON3)->EnableWindow(FALSE);
m_List.InsertColumn(0,_T("窗口"));
m_List.SetColumnWidth(0,300);
m_List.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
EnableDebugPriv();//提升权限
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CTestDlg::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
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CTestDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
//void CTestDlg::OnBnClickedButton1()
//{
// // TODO: 在此添加控件通知处理程序代码
// if(m_ShowHwnd == CString(L""))
// {
//
// CString str;
// hwnd = ::FindWindow(_T("TXGuiFoundation"),L"QQ");
// str.Format(L"窗口句柄是:%x",hwnd);
// m_ShowHwnd = str;
// UpdateData(FALSE);
// }
//
//}
void CTestDlg::OnDestroy()
{
CDialogEx::OnDestroy();
//KillTimer(1001);
// TODO: 在此处添加消息处理程序代码
}
//void CTestDlg::OnBnClickedButton2()
//{
// // TODO: 在此添加控件通知处理程序代码
// if(m_ProcessId == L"")
// {
//
// DWORD dw = GetWindowThreadProcessId(hwnd,&process_Id);
// TRACE(L"the hwnd is:%x",hwnd);
// CString str;
// str.Format(L"进程ID是:%x",process_Id);
// m_ProcessId = str;
// UpdateData(FALSE);
//
// }
//
//}
//void CTestDlg::OnBnClickedButton3()
//{
// // TODO: 在此添加控件通知处理程序代码
// if(m_ProcessHandle == L"")
// {
//
//
// HANDLE handle = ::OpenProcess(PROCESS_ALL_ACCESS,FALSE,process_Id);
// CString str;
// str.Format(L"进程句柄是:%x",handle);
// m_ProcessHandle = str;
// UpdateData(FALSE);
// }
//}
//
//void CTestDlg::OnBnClickedButton1()
//{
// // TODO: 在此添加控件通知处理程序代码
// gameHwnd = ::FindWindow(L"#32770",L"对对碰角色版");
// if(gameHwnd == NULL)
// {
// SetWindowText(L"程序未运行!");
// }
// else
// {
// SetWindowText(L"程序运行中!");
// SetTimer(1001,1000,NULL);
//
// }
//}
//
//
//void CTestDlg::OnTimer(UINT_PTR nIDEvent)
//{
// // TODO: 在此添加消息处理程序代码和/或调用默认值
// switch (nIDEvent)
// {
// case 1001:
// {
//
// LPCVOID addr = (LPCVOID)0x48F128;
// LPVOID gameBuffer =new LPVOID;
// DWORD bt;
// CString str;
// /*gameHwnd = ::FindWindow(L"#32770 (对话框)",L"对对碰角色版");*/
// ::GetWindowThreadProcessId(gameHwnd,&processID);
// processHandle = OpenProcess(PROCESS_ALL_ACCESS,FALSE,processID);
// ReadProcessMemory(processHandle,addr,&gameBuffer,4,&bt);
// str.Format(L"%d",(DWORD *)gameBuffer);
// m_SNumber = str;
// UpdateData(FALSE);
// delete gameBuffer;
// }
// }
// CDialogEx::OnTimer(nIDEvent);
//}
//
//
//
//
//void CTestDlg::OnBnClickedButton2()
//{
// // TODO: 在此添加控件通知处理程序代码
// if(threadId == NULL)
// {
// MessageBox(L"请先获取线程id!");
// return;
// }
// threadHandle = OpenThread(THREAD_ALL_ACCESS,FALSE,threadId);
//
// CString str;
// str.Format(L"%d",threadHandle);
// m_threadHandle = str;
// UpdateData(FALSE);
//}
//
//
//BOOL CTestDlg::EnumThreadInfo(DWORD proID)
//{
// // 定义线程信息结构
// THREADENTRY32 te32 = {sizeof(THREADENTRY32)} ;
//
// //创建系统线程快照
// HANDLE hThreadSnap = CreateToolhelp32Snapshot ( TH32CS_SNAPTHREAD, 0 ) ;
// if ( hThreadSnap == INVALID_HANDLE_VALUE )
// return FALSE ;
//
// // 输出线程信息到文件
//
//
// // 循环枚举线程信息
// if ( Thread32First ( hThreadSnap, &te32 ) )
// {
// do{
//
// if(te32.th32OwnerProcessID == proID)
// {
// cout << '\t' << "OwnerProcessID : " << te32.th32OwnerProcessID << endl ;
// cout << '\t' << "Usage : " << te32.cntUsage << endl ;
// cout << '\t' << "Delta Priority : " << te32.tpDeltaPri << endl ;
// cout << '\t' << "Base Priority : " << te32.tpBasePri << endl ;
// dwArray.SetSize(100,100);
// INT index = 0;
// dwArray.SetAt(index,te32.th32ThreadID);
// index++;
// }
// }while ( Thread32Next ( hThreadSnap, &te32 ) ) ;
// }
//
//
// CloseHandle ( hThreadSnap ) ;
// return TRUE ;
//}
//
//
//void CTestDlg::OnBnClickedButton3()
//{
// // TODO: 在此添加控件通知处理程序代码
//
// if(!EnumThreadInfo(processID))
// MessageBox(L"查找进程出现未知错误");
// INT index = 0;
// threadId = dwArray.GetAt(index++);
// CString str;
// str.Format(L"%ld",threadId);
//
// m_threadID = str;
// UpdateData(FALSE);
//}
//
//
//void CTestDlg::OnBnClickedButton4()
//{
// // TODO: 在此添加控件通知处理程序代码
//}
HINSTANCE g_hInstDll=NULL;
void CTestDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
g_hInstDll=LoadLibrary(_T("hook2.dll"));
if (g_hInstDll==NULL)
{
CString err;
err.Format(_T("加载dll失败 error code=%d"),GetLastError());
AfxMessageBox(err);
return;
}
typedef BOOL (WINAPI *StartHook)(HWND hWnd,DWORD dwPid) ;
StartHook Hook=NULL;
Hook=(StartHook)::GetProcAddress(g_hInstDll,"StartHook");
if (Hook==NULL)
{
AfxMessageBox(_T("获取dll函数失败"));
return;
}
//开始注入
if (Hook(m_hWnd,m_ProcessInfo.dwPid))
{
AfxMessageBox(_T("hook sucess"));
}
else
{
AfxMessageBox(_T("hook failed"));
return;
}
GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON3)->EnableWindow(TRUE);
FreeLibrary(g_hInstDll);
const DWORD dwThreadSize = 5 * 1024;
DWORD dwWriteBytes;
// 提升进程访问权限
EnableDebugPriv();
// 等待输入进程名称,注意大小写匹配
//std::cout << "Please input the name of target process !" << std::endl;
//char szExeName[MAX_PATH] = { 0 };
//std::cin >> szExeName;
DWORD dwProcessId =m_ProcessInfo.dwPid;
if( dwProcessId == 0 )
{
MessageBox(
L"The target process have not been found !",L"Notice",MB_ICONINFORMATION|MB_OK);
return ;
}
// 根据进程ID得到进程句柄
HANDLE hTargetProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if( !hTargetProcess )
{
MessageBox(
L"Open target process failed !",
L"Notice",
MB_ICONINFORMATION | MB_OK
);
return ;
}
// 在宿主进程中为线程体开辟一块存储区域
// 在这里需要注意MEM_COMMIT内存非配类型以及PAGE_EXECUTE_READWRITE内存保护类型
// 其具体含义请参考MSDN中关于VirtualAllocEx函数的说明。
void* pRemoteThread = VirtualAllocEx( hTargetProcess,
0,
dwThreadSize,
MEM_COMMIT , PAGE_EXECUTE_READWRITE);
if( !pRemoteThread )
{
MessageBox( L"Alloc memory in target process failed !",
L"notice",
MB_ICONINFORMATION | MB_OK
);
return;
}
// 设置需要注入的DLL名称
char szDll[256];
memset(szDll, 0, 256);
strcpy(szDll, "D:\\My Documents\\Visual Studio 2010\\Projects\\Test\\Debug\\hook2.dll");
// 拷贝注入DLL内容到宿主空间
if( !WriteProcessMemory( hTargetProcess,
pRemoteThread,
(LPVOID)szDll,
dwThreadSize,
0) )
{
MessageBox( L"Write data to target process failed !",
L"Notice",
MB_ICONINFORMATION | MB_OK
);
return ;
}
LPVOID pFunc = LoadLibraryA;
//在宿主进程中创建线程
HANDLE hRemoteThread = CreateRemoteThread( hTargetProcess,
NULL,
0,
(LPTHREAD_START_ROUTINE)pFunc,
pRemoteThread,
0,
&dwWriteBytes);
if( !hRemoteThread )
{
MessageBox( L"Create remote thread failed !",
L"Notice",
MB_ICONINFORMATION | MB_OK
);
return ;
}
// 等待LoadLibraryA加载完毕
WaitForSingleObject(hRemoteThread, INFINITE );
VirtualFreeEx(hTargetProcess, pRemoteThread, dwThreadSize, MEM_COMMIT);
CloseHandle( hRemoteThread );
CloseHandle( hTargetProcess );
return ;
}
void CTestDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
CDlgProcess dlg;
dlg.DoModal();
//显示获取到的进程信息
CString s,tmp;
s=_T(" Hook进程:");
s.Append(m_ProcessInfo.strProcessName);
s.Append(_T(" PID="));
tmp.Format(_T("%d"),m_ProcessInfo.dwPid);
s.Append(tmp);
SetWindowText(m_wndTitle+s);
if (m_ProcessInfo.dwPid<0||m_ProcessInfo.strProcessName.Find(_T(".exe"))<0)
{
return;
}
GetDlgItem(IDC_BUTTON2)->EnableWindow(TRUE);
}
void CTestDlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
if (g_hInstDll==NULL)
{
return;
}
typedef VOID (WINAPI *StopHook)();
StopHook Hook=NULL;
Hook=(StopHook)::GetProcAddress(g_hInstDll,"StopHook");
if (Hook==NULL)
{
AfxMessageBox(_T("获取dll函数失败"));
FreeLibrary(g_hInstDll);
g_hInstDll=NULL;
return;
}
Hook();//Stop Hook
FreeLibrary(g_hInstDll);
g_hInstDll=NULL;
AfxMessageBox(_T("Stop Hook Ok"));
GetDlgItem(IDC_BUTTON2)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON3)->EnableWindow(FALSE);
}
void CTestDlg::EnableDebugPriv(void)
{
HANDLE hToken;
LUID sedebugnameValue;
TOKEN_PRIVILEGES tkp;
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
return;
}
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) {
CloseHandle(hToken);
return;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) {
CloseHandle(hToken);
return;
}
}
LRESULT CTestDlg::OnHookDll(WPARAM wParam, LPARAM lParam)
{
CString str;
str.Format(L"结果是%d",(int)wParam);
AfxMessageBox(str);
return 1;
}
void CTestDlg::OnClose()
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
OnBnClickedButton3();
CDialogEx::OnClose();
}