使用库
libMinHook.lib,安装方式Visual Studio 工具栏->工具->NuGet 包管理->管理解决方案->搜索MinHook
hook程序
#include "pch.h"
#include <Windows.h>
#include <MinHook.h>
#pragma comment(lib,"libMinHook.lib")
//定义约定调用方式 ,以及传参结构 和 出参结构
typedef BOOL(WINAPI* OldSetWindowTextA)(HWND, LPCSTR);
typedef BOOL(WINAPI* OldEnableWindow)(HWND ,BOOL );
OldSetWindowTextA fpSetWindowTextA = NULL;
OldEnableWindow fpOldEnableWindow = NULL;
BOOL WINAPI MyEnableWindow(HWND hWnd, BOOL bEnable)
{
BOOL ret = fpOldEnableWindow(hWnd, true);
return ret;
}
BOOL WINAPI MySetWindowTextA(HWND hWnd, LPCSTR lpString)
{
BOOL ret = fpSetWindowTextA(hWnd, "");
return ret;
}
void SetHook()
{
if (MH_Initialize() == MB_OK)
{
//先拦截 ,然后在调用原来的函数
MH_CreateHook(&EnableWindow, &MyEnableWindow, reinterpret_cast<void**>(&fpOldEnableWindow));
MH_EnableHook(&EnableWindow);
}
//if (MH_Initialize() == MB_OK)
//{
// //先拦截 ,然后在调用原来的函数
// MH_CreateHook(&SetWindowTextA, &MySetWindowTextA, reinterpret_cast<void**>(&fpSetWindowTextA));
// MH_EnableHook(&SetWindowTextA);
//}
}
void UnHook()
{
if (MH_DisableHook(&EnableWindow) == MB_OK)
{
MH_Uninitialize();
}
/*if (MH_DisableHook(&SetWindowTextA) == MB_OK)
{
MH_Uninitialize();
}*/
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
SetHook();
break;
case DLL_PROCESS_DETACH:
UnHook();
break;
}
return TRUE;
}
建立导出dll
#pragma once
// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 LIBMATH_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// LIBMATH_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifdef LIBMATH_EXPORTS
#define LIBMATH_API __declspec(dllexport)
#else
#define LIBMATH_API __declspec(dllimport)
#endif
// 此类是从 dll 导出的
class LIBMATH_API ClibMath {
public:
ClibMath();
int Add(int a, int b);
int Sub(int a, int b);
};
// 由于需要给C#调用,为了方便导出类,添加了函数进行导出,并且需要加extern "C"
extern "C" {
LIBMATH_API ClibMath* CreateMyClass();
LIBMATH_API void DeleteMyClass(ClibMath* obj);
LIBMATH_API int CallAdd(ClibMath* obj, int num1, int num2);
LIBMATH_API int CallSub(ClibMath* obj, int num1, int num2);
}
#include "pch.h"
#include "ClibMathC.h"
#include "string"
#include <windows.h>
#include <iostream>
#include <Tlhelp32.h>
#include <stdio.h>
#include <tchar.h>
using namespace std;
// 这是已导出类的构造函数。
ClibMath::ClibMath()
{
return;
}
int ClibMath::Add(int a, int b)
{
const char* DllFullPath = "cc";
int pid = 0;
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if (hProc == 0) return -1;
int pathSize = (strlen(DllFullPath) + 1) * sizeof(wchar_t);
LPVOID buffer = VirtualAllocEx(hProc, 0, pathSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (buffer == 0) return -2;
if (!WriteProcessMemory(hProc, buffer, DllFullPath, pathSize, NULL)) return -3;
LPVOID pFunc = GetProcAddress(GetModuleHandleA("Kernel32.dll"), "LoadLibraryA");
CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)pFunc, buffer, 0, 0);
return a + b;
}
int ClibMath::Sub(int a, int b)
{
return a - b;
}
ClibMath* CreateMyClass() {
return new ClibMath();
}
void DeleteMyClass(ClibMath* obj) {
delete obj;
}
int CallAdd(ClibMath* obj, int num1, int num2) {
return obj->Add(num1, num2);
}
int CallSub(ClibMath* obj, int num1, int num2) {
return obj->Sub(num1, num2);
}
C# 调用导出C++
[DllImport("kernel32.dll")] //声明API函数
public static extern int VirtualAllocEx(IntPtr hwnd, int lpaddress, int size, int type, int tect);
[DllImport("kernel32.dll")]
public static extern int WriteProcessMemory(IntPtr hwnd, int baseaddress, string buffer, int nsize, int filewriten);
[DllImport("kernel32.dll")]
public static extern int GetProcAddress(int hwnd, string lpname);
[DllImport("kernel32.dll")]
public static extern int GetModuleHandleA(string name);
[DllImport("kernel32.dll")]
public static extern int CreateRemoteThread(IntPtr hwnd, int attrib, int size, int address, int par, int flags, int threadid);
int ok1;
int baseaddress;
int temp = 0;
int hack;
int yan;
string dllname;
dllname = "Dllhook.dll";
int dlllength;
dlllength = dllname.Length + 1;
Process[] pname = Process.GetProcesses(); //取得所有进程
foreach (Process name in pname) //遍历进程
{
//MessageBox.Show(name.ProcessName.ToLower());
if (name.ProcessName.Equals("") ) //所示记事本,那么下面开始注入
{
baseaddress = VirtualAllocEx(name.Handle, 0, dlllength, 0x00001000 | 0x00002000, 0x40); //申请内存空间
if (baseaddress == 0) //返回0则操作失败,下面都是
{
MessageBox.Show("申请内存空间失败!!");
Application.Exit();
}
ok1 = WriteProcessMemory(name.Handle, baseaddress, dllname, dlllength, temp); //写内存
if (ok1 == 0)
{
MessageBox.Show("写内存失败!!");
Application.Exit();
}
hack = GetProcAddress(GetModuleHandleA("Kernel32"), "LoadLibraryA"); //取得loadlibarary在kernek32.dll地址
if (hack == 0)
{
MessageBox.Show("无法取得函数的入口点!!");
Application.Exit();
}
yan = CreateRemoteThread(name.Handle, 0, 0, hack, baseaddress, 0, temp); //创建远程线程。
if (yan == 0)
{
MessageBox.Show("创建远程线程失败!!");
Application.Exit();
}
else
{
MessageBox.Show("已成功注入dll!!");
}
}
}