来源《逆向工程核心原理》
运行notepad.exe可以劫持notepad.exe的键盘输入
HookMain.cpp

//HookMain.cpp

#include"stdio.h"
#include"conio.h"
#include"windows.h"
#define DEF_DLL_NAME "HookKey.dll"
#define DEF_HOOKSTART "HookStart"
#define DEF_HOOKSTOP "HookStop"

typedef void(*PFN_HOOKSTART)();
typedef void(*PFN_HOOKSTOP)();

void main()
{
	HMODULE hDll = NULL;
	PFN_HOOKSTART HookStart = NULL;
	PFN_HOOKSTOP HookStop = NULL;
	char ch = 0;

	//加载KeyHook.dll
	hDll = LoadLibraryA(DEF_DLL_NAME);
	if (hDll == NULL)
	{
		printf("dll load failed");
		exit(0);
	}
	//获取导出函数地址
	HookStart = (PFN_HOOKSTART)GetProcAddress(hDll, DEF_HOOKSTART);
	HookStart = (PFN_HOOKSTOP)GetProcAddress(hDll, DEF_HOOKSTOP);

	//开始钩取

	HookStart();
	//等待直到用户输入q
	printf("press 'q' to quit!\n");
	while (_getch() != 'q');
	HookStop();
	FreeLibrary(hDll);
}

HookKey.dll

#include"stdio.h"
#include"windows.h"
#define DEF_PROCESS_NAME "notepad.exe"
HINSTANCE g_hInstance = NULL;
HHOOK g_hHook = NULL;
HWND g_hWnd = NULL;
BOOL WINAPI DllMain(HINSTANCE hinstDLLL, DWORD dwReason, LPVOID lpvReserved)
{
	switch (dwReason)
	{
	case DLL_PROCESS_ATTACH:
		g_hInstance = hinstDLLL;
		break;
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	char szPath[MAX_PATH] = { 0, };
	char *p = NULL;
	if (nCode == 0)
	{
		if (!(lParam & 0x80000000))//释放键盘按键时
		{
			GetModuleFileNameA(NULL, szPath, MAX_PATH);
			p = strrchr(szPath, '\\');
			if (!_stricmp(p + 1, DEF_PROCESS_NAME))
				return 1;
		}
	}
	return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

#ifdef  __cplusplus
extern "C"{
#endif
	__declspec(dllexport) void HookStart()
	{
		g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstance, 0);
	}
	__declspec(dllexport)void HookStop()
	{
		if (g_hHook)
		{
			UnhookWindowsHookEx(g_hHook);
			g_hHook = NULL;
		}
	}
#ifdef __cplusplus
}
#endif

win10测试失败,介绍说win7和winXP成功


手动获取pid实现注入

InjectDll.cpp

//InjectDll.cpp
#include"windows.h"
#include"tchar.h"
BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
{
	HANDLE hProcess = NULL, hThread = NULL;
	HMODULE hMod = NULL;
	LPVOID pRemoteBuf = NULL;
	DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1)*sizeof(TCHAR);
	LPTHREAD_START_ROUTINE pThreadProc;

//使用dwpid获取目标进程句柄
	if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
	{
		_tprintf(L"OpenProcess(%d) failed!!![%d]\n", dwPID, GetLastError());
		return FALSE;
	}
	//在目标进程内存中分配szDllname大小的内存
	pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);//分配物理存储,可读可写
	//将myhack.dll路径写入分配的内存。
	WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL);
	//获取LoadLibraryW API的地址
	hMod = GetModuleHandle(L"Kernel32.dll");//获取已经加载模块的句柄
	pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");//获取函数地址

	//在目标进程中运行线程
	hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);//创建远程线程
	_tprintf(L"%d", GetLastError());
	WaitForSingleObject(hThread, INFINITE);
	CloseHandle(hProcess);
	return TRUE;
}
int _tmain(int argc, TCHAR *argv[])
{
	if (argc != 3)
	{
		_tprintf(L"USAGE: %s pid dll_path\n", argv[2]);
		return 1;
	}
//inject dll
	if (InjectDll((DWORD)_tstol(argv[1]), argv[2]))
		_tprintf(L"InjectDll(\"%s\")success!!\n", argv[2]);
	else
		_tprintf(L"InjectDll(\"%s\") failed!!\n", argv[2]);

	return 0;
}

调试参考https://blog.csdn.net/qq76536257/article/details/50590272

//myhack.cpp

#include"windows.h"
#include"tchar.h"
#pragma comment(lib,"urlmon.lib")

#define DEF_URL		(L"http://www.naver.com/index.html")
#define DEF_FILE_NAME (L"index.html")

HMODULE g_hMod = NULL;
DWORD WINAPI ThreadProc(LPVOID lParam)
{
	TCHAR szPath[_MAX_PATH] = { 0, };
	if (!GetModuleFileName(g_hMod, szPath, MAX_PATH))//获取当前文件加载路径,存放到szPath中
		return FALSE;
	TCHAR *p = _tcsrchr(szPath, '\\');//找出文件名
	if (!p)
		return FALSE;
	_tcscpy_s(p + 1, _MAX_PATH, DEF_FILE_NAME);
	URLDownloadToFile(NULL, DEF_URL, szPath, 0, NULL);
	return 0;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	HANDLE hThread = NULL;
	g_hMod = (HMODULE)hinstDLL;
	switch (fdwReason)
	{
	case DLL_PROCESS_ATTACH:
		OutputDebugString(L"myhack.dll Injection!!!!");
		hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
		CloseHandle(hThread);
		break;
	}
	return TRUE;
}

可以下载一个网页。
这一组还是失败了,在调用 CreateRemoteThread的时候返回0错误代码5


再贴上一个dll

//myhack.cpp

#include"windows.h"
#include"tchar.h"
#define DEF_CMD L"c:Program File\\Internet Explorer \\ieplore.exe"
#define DEF_ADDR L"http://www.naver.com"
#define DEF_DST_PROC L"notepad.exe"
BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
{
	TCHAR szCmd[MAX_PATH] = { 0, };
	TCHAR szPath[MAX_PATH] = { 0, };
	TCHAR *p = NULL;
	STARTUPINFO si = { 0, };
	PROCESS_INFORMATION pi = { 0, };
	si.cb = sizeof(STARTUPINFO);
	si.dwFlags = STARTF_USESHOWWINDOW;
	si.wShowWindow = SW_HIDE;
	switch (fdwReason)
	{
	case DLL_PROCESS_ATTACH:
		if (!GetModuleFileName(NULL, szPath, MAX_PATH))
			break;
		if (!(p = _tcsrchr(szPath, '\\')))
			break;
		if (_tcsicmp(p + 1, DEF_DST_PROC))
			break;
		wsprintf(szCmd, L"%s %s", DEF_CMD, DEF_ADDR);
		if (!CreateProcess(NULL, (LPTSTR)(LPTSTR)szCmd, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
			break;
		if (pi.hProcess != NULL)
			CloseHandle(pi.hProcess);
		break;
	}
	return TRUE;

}
10-03 22:17