win原理Day006.zip
TestDll
// dllmain.cpp : 定义 DLL 应用程序的入口点。#include "stdafx.h"#include <windows.h>BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: MessageBox(0, L"注入成功", L"good", 0); case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE;}
消息钩子
消息钩子DLL
// dllmain.cpp : 定义 DLL 应用程序的入口点。#include "stdafx.h"#include <windows.h>#include <stdlib.h>#include <stdio.h>HHOOK g_hook;HMODULE g_mod;LRESULT CALLBACK KeyboardProc( _In_ int code, _In_ WPARAM wParam, _In_ LPARAM lParam ){ // 判断是否wParam与lParam都有键盘消息,是的话则执行打印操作 if (code == HC_ACTION){ // 将256个虚拟键的状态拷贝到指定的缓冲区中,如果成功则继续 BYTE KeyState[256] = { 0 }; if (GetKeyboardState(KeyState)) { // 得到第16–23位,键盘虚拟码 LONG KeyInfo = lParam; UINT keyCode = (KeyInfo >> 16) & 0x00ff; WCHAR wKeyCode = 0; ToAscii((UINT)wParam, keyCode, KeyState, (LPWORD)&wKeyCode, 0); // 将其打印出来 CHAR szInfo[10] = { 0 }; sprintf_s(szInfo, _countof(szInfo), "Hook_%c", wKeyCode); OutputDebugStringA(szInfo); return 0; } }// char str[10] = {};// str[0] = wParam;// OutputDebugStringA(str); return CallNextHookEx(g_hook, code, wParam, lParam);}void OnHook(){ g_hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_mod, 0);// if ()// {// }}void UnHook(){ if (!g_hook) { UnhookWindowsHookEx(g_hook); }}BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: MessageBoxW(0, 0, 0, 0); g_mod = hModule;//模块句柄 OnHook(); //case DLL_THREAD_ATTACH: //case DLL_THREAD_DETACH: //case DLL_PROCESS_DETACH: //UnHook(); break; } return TRUE;}
内联HOOK
// 内联HOOK.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <windows.h>void UnHook();void OnHook();char g_OldCode[5];char g_NewCode[5] = { 0xE9 };int WINAPI MyMessageBoxW(_In_opt_ HWND hWnd,_In_opt_ LPCWSTR lpText,_In_opt_ LPCWSTR lpCaption,_In_ UINT uType){ lpText = L"你被HOOK\n"; lpCaption = L"嘿嘿"; //先卸载 UnHook(); //调用MessageBoxW int nRet = MessageBoxW(hWnd, lpText, lpCaption, uType); //再次挂上钩子 OnHook(); return nRet;}void OnHook(){ //1.保存原函数被修改的代码 memcpy(g_OldCode, MessageBoxW, 5); //2.计算偏移量 DWORD dwOffset = (DWORD)MyMessageBoxW - (DWORD)MessageBoxW - 5; //3.写入指令 memcpy(g_NewCode + 1, &dwOffset, 4); //修改内存属性(代码段没有可写属性) DWORD dwOld; VirtualProtect(MessageBoxW, 5, PAGE_EXECUTE_READWRITE, &dwOld); memcpy(MessageBoxW, g_NewCode, 5); VirtualProtect(MessageBoxW, 5, dwOld, &dwOld);}void UnHook(){ DWORD dwOld; VirtualProtect(MessageBoxW, 5, PAGE_EXECUTE_READWRITE, &dwOld); memcpy(MessageBoxW, g_OldCode, 5); VirtualProtect(MessageBoxW, 5, dwOld, &dwOld);}int _tmain(int argc, _TCHAR* argv[]){ MessageBoxW(0, 0, 0, 0); OnHook(); MessageBoxW(0, 0, 0, 0); return 0;}
内联HOOK_DLL
// dllmain.cpp : 定义 DLL 应用程序的入口点。#include "stdafx.h"#include <windows.h>void UnHook();void OnHook();char g_OldCode[5];char g_NewCode[5] = { 0xE9 };int WINAPI MyMessageBoxW( _In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType){ lpText = L"你被HOOK\n"; lpCaption = L"嘿嘿"; //先卸载 UnHook(); //调用MessageBoxW int nRet = MessageBoxW(hWnd, lpText, lpCaption, uType); //再次挂上钩子 OnHook(); return nRet;}void OnHook(){ //1.保存原函数被修改的代码 memcpy(g_OldCode, MessageBoxW, 5); //2.计算偏移量 DWORD dwOffset = (DWORD)MyMessageBoxW - (DWORD)MessageBoxW - 5; //3.写入指令 memcpy(g_NewCode + 1, &dwOffset, 4); //修改内存属性(代码段没有可写属性) DWORD dwOld; VirtualProtect(MessageBoxW, 5, PAGE_EXECUTE_READWRITE, &dwOld); memcpy(MessageBoxW, g_NewCode, 5); VirtualProtect(MessageBoxW, 5, dwOld, &dwOld);}void UnHook(){ DWORD dwOld; VirtualProtect(MessageBoxW, 5, PAGE_EXECUTE_READWRITE, &dwOld); memcpy(MessageBoxW, g_OldCode, 5); VirtualProtect(MessageBoxW, 5, dwOld, &dwOld);}BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: OnHook(); //case DLL_THREAD_ATTACH: //case DLL_THREAD_DETACH: //case DLL_PROCESS_DETACH: // UnHook(); break; } return TRUE;}
IAT_HOOK
// dllmain.cpp : 定义 DLL 应用程序的入口点。#include "stdafx.h"#include <windows.h>DWORD g_IatAddr;DWORD g_FunOldAddr;typedef int (WINAPI* FP_MessageBoxW)( _In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType);int WINAPI MyMessageBoxW( _In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType){ lpText = L"你被HOOK\n"; lpCaption = L"嘿嘿"; FP_MessageBoxW FpMsg = (FP_MessageBoxW)g_FunOldAddr; return FpMsg(hWnd, lpText, lpCaption, uType);}void OnHook(char* pFunName, char* pDllName){ //遍历导入表(INT) HMODULE hMod = GetModuleHandle(NULL); PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)hMod; PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + (DWORD)hMod); DWORD dwImportRVA = pNt->OptionalHeader.DataDirectory[1].VirtualAddress; PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR) (dwImportRVA + (DWORD)hMod); while (pImport->Name) { char* pDll = (char*)(pImport->Name + (DWORD)hMod); if (!_stricmp(pDll,pDllName)) { //遍历INT IMAGE_THUNK_DATA* pInt = (IMAGE_THUNK_DATA*) (pImport->OriginalFirstThunk + (DWORD)hMod); IMAGE_THUNK_DATA* pIat = (IMAGE_THUNK_DATA*) (pImport->FirstThunk + (DWORD)hMod); while (pInt->u1.AddressOfData) { if (!IMAGE_SNAP_BY_ORDINAL(pInt->u1.AddressOfData)) { PIMAGE_IMPORT_BY_NAME pName = (PIMAGE_IMPORT_BY_NAME)(pInt->u1.AddressOfData + (DWORD)hMod); if (!_stricmp(pName->Name,pFunName)) { //函数地址 g_FunOldAddr = pIat->u1.Function; g_IatAddr = (DWORD)pIat; //修改地址 //修改内存属性 DWORD dwOld; VirtualProtect(pIat, 4, PAGE_READWRITE, &dwOld); *(DWORD*)pIat = (DWORD)MyMessageBoxW; VirtualProtect(pIat, 4, dwOld, &dwOld); return; } } //下一个函数 pInt++; pIat++; } } //下一个模块 pImport++; }}void UnHook(){ DWORD dwOld; VirtualProtect((LPVOID)g_IatAddr, 4, PAGE_READWRITE, &dwOld); *(DWORD*)g_IatAddr = g_FunOldAddr; VirtualProtect((LPVOID)g_IatAddr, 4, dwOld, &dwOld);}BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: OnHook("MessageBoxW", "user32.dll"); case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE;}
注入工具代码
// win原理Day006.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <windows.h>#define DLL_MESSAGE "D:\\ProgramVS\\win原理Day006\\Debug\\消息钩子DLL.dll"#define DLL_PATH "D:\\ProgramVS\\win原理Day006\\Debug\\TestDll.dll"#define DLL_INLINE "D:\\ProgramVS\\win原理Day006\\Debug\\内联HOOK_DLL.dll"#define DLL_IAT "D:\\ProgramVS\\win原理Day006\\Debug\\IAT_HOOK.dll"//远程线程注入void Inject(char* pDllPath, DWORD dwPid){ //1.打开进程获取句柄 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid); if (!hProcess) { printf("句柄打开失败\n"); return; } //2. 再目标进程中申请足够大的内存,存储DLL的全路径 LPVOID lpBuf = VirtualAllocEx(hProcess, NULL, strlen(pDllPath), MEM_COMMIT, PAGE_READWRITE); if (!lpBuf) { printf("内存申请失败\n"); CloseHandle(hProcess); return; } //3.把DLL全路径写入进去 DWORD dwWrite; WriteProcessMemory(hProcess, lpBuf, pDllPath, strlen(pDllPath), &dwWrite); //4.创建远程线程 HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibraryA, lpBuf, NULL, NULL); //5.等待线程结束 WaitForSingleObject(hThread, -1); //6.释放内存 VirtualFreeEx(hProcess, lpBuf, 0, MEM_RELEASE); CloseHandle(hProcess);}//注入代码void InjectCode(char* pCode, DWORD dwSize,DWORD dwPid){ //1.打开进程获取句柄 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid); if (!hProcess) { printf("句柄打开失败\n"); return; } //2. 再目标进程中申请足够大的内存,存储DLL的全路径 LPVOID lpBuf = VirtualAllocEx(hProcess, NULL, strlen(pCode), MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!lpBuf) { printf("内存申请失败\n"); CloseHandle(hProcess); return; } //3.把DLL全路径写入进去 DWORD dwWrite; WriteProcessMemory(hProcess, lpBuf, pCode, dwSize, &dwWrite); //4.创建远程线程 HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)lpBuf, NULL, NULL, NULL); //5.等待线程结束 WaitForSingleObject(hThread, -1); //6.释放内存 VirtualFreeEx(hProcess, lpBuf, 0, MEM_RELEASE); CloseHandle(hProcess);}int _tmain(int argc, _TCHAR* argv[]){ //HMODULE hMod = LoadLibraryA(DLL_MESSAGE); int nPid; printf("输入PID:"); scanf_s("%d", &nPid); Inject(DLL_IAT, nPid); //DWORD dwAddr;// __asm// {// push 0;// push 0;// push 0;// push 0;// mov eax, 0x99999999;// call eax;// }// // char pCode[] = "\x6A\x00\x6A\x00\x6A\x00\x6A\x00\xB8\x99\x99\x99\x99\xFF\xD0";// DWORD dwAddr;// scanf_s("%x", &dwAddr);// *(int*)(pCode + 9) = dwAddr;// DWORD dwPid;// scanf_s("%d", &dwPid);// InjectCode(pCode, sizeof(pCode),dwPid);//测试// printf("MessageBoxW:0x%08X\n", (DWORD)MessageBoxW); system("pause"); return 0;}