来源《逆向工程核心原理》
运行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;
}