Windows Practice_Dll&Hook_封装IAT Hook
来源:互联网 发布:网络打印被挂起 编辑:程序博客网 时间:2024/06/16 16:59
进程保护器的实现
本程序实现了一个简单的暴力的进程保护器,其原理也很简单,就是修改导入表,挂钩TerminateProcess函数,因为这个函数可以远程无条件的结束其它进程,所以我们要挂钩这个函数。
因为每一个程序都有可能结束要保护的程序,所以我们必须以Dll的形式注入到每一个进程中,这就涉及到注入的问题了,而Windows给我们提供了一个简单的全局挂钩的函数,即SetWindowsHook函数。
本工程主要有三个程序,分别是ProcessProtectorDll、ProcessProtectorExe以及TerminateProcessExe,从这三个程序的名字相信大家也都知道这些程序的作用了,就不再多做解释了。
下面我们一一将它们的源代码附上并稍作解释。
ProcessProtectorDll动态链接库程序
该程序主要是用来被其它的可执行程序调用,从而达到全局挂钩并保护相应进程的目的。代码如下:
// IATHook.h文件#pragma once#include <string>namespace PoEdu{ class CIATHook { public: // 初始化即Hook // 挂哪个Dll的哪个函数的钩 // 新的函数的地址 // 现有的所有Module CIATHook(const std::string &dll_name, const std::string &func_name, void *new_func_addr); HMODULE WINAPI LoadLibraryA(_In_ LPCSTR lpFileName); HMODULE WINAPI LoadLibraryW(_In_ LPCWSTR lpFileName); HMODULE WINAPI LoadLibraryExA(_In_ LPCSTR lpFileName, _Reserved_ HANDLE hFile, _In_ DWORD dwFlags); HMODULE WINAPI LoadLibraryExW(_In_ LPCWSTR lpFileName, _Reserved_ HANDLE hFile, _In_ DWORD dwFlags); FARPROC WINAPI GetProcAddress(_In_ HMODULE hModule, _In_ LPCSTR lpProcName ) const; private: void HookAllModule() const; void HookOneModule(HMODULE hModule) const; private: std::string dll_name_; void *new_func_addr_; void *old_func_addr_; };}
//IATHook.cpp文件#include "stdafx.h"#include "IATHook.h"#include <TlHelp32.h>#include <DbgHelp.h>#include <winbase.h>#pragma comment(lib, "DbgHelp.lib")// 这个类还有有些不足// 在启用新进程的时候还是挂不上namespace PoEdu{ CIATHook::CIATHook(const std::string& dll_name, const std::string& func_name, void* new_func_addr) : dll_name_(dll_name), new_func_addr_(new_func_addr) { old_func_addr_ = GetProcAddress(GetModuleHandleA(dll_name.c_str()), func_name.c_str()); // 开始挂钩 // 每个Module都有自己的IAT,所以需要遍历所有的Module HookAllModule(); } HMODULE CIATHook::LoadLibraryA(LPCSTR lpFileName) { HMODULE hModule = ::LoadLibraryA(lpFileName); HookOneModule(hModule); return hModule; } HMODULE CIATHook::LoadLibraryW(LPCWSTR lpFileName) { HMODULE hModule = ::LoadLibraryW(lpFileName); HookOneModule(hModule); return hModule; } HMODULE CIATHook::LoadLibraryExA(LPCSTR lpFileName, HANDLE hFile, DWORD dwFlags) { HMODULE hModule = ::LoadLibraryExA(lpFileName, hFile, dwFlags); HookOneModule(hModule); return hModule; } HMODULE CIATHook::LoadLibraryExW(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags) { HMODULE hModule = ::LoadLibraryExW(lpFileName, hFile, dwFlags); HookOneModule(hModule); return hModule; } FARPROC CIATHook::GetProcAddress(HMODULE hModule, LPCSTR lpProcName) const { FARPROC pAddr = ::GetProcAddress(hModule, lpProcName); if (pAddr == old_func_addr_) { return static_cast<FARPROC>(new_func_addr_); } else { return pAddr; } } void CIATHook::HookAllModule() const { HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()); MODULEENTRY32 me32 = { sizeof(MODULEENTRY32) }; BOOL bNext = ::Module32FirstW(hSnap, &me32); while (bNext) { // 给每个Module挂钩 HookOneModule(me32.hModule); bNext = Module32NextW(hSnap, &me32); } CloseHandle(hSnap); } void CIATHook::HookOneModule(HMODULE hModule) const { ULONG ulSize = 0; PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor = static_cast<PIMAGE_IMPORT_DESCRIPTOR>(ImageDirectoryEntryToData(hModule, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize)); if (!pImageImportDescriptor) { return; } while (pImageImportDescriptor->Name) { char *pDllName = reinterpret_cast<char *>(reinterpret_cast<BYTE *>(hModule) + pImageImportDescriptor->Name); if (dll_name_.compare(pDllName) == 0) { break; } ++pImageImportDescriptor; } if (pImageImportDescriptor->Name) { PIMAGE_THUNK_DATA pImageThunkData = reinterpret_cast<PIMAGE_THUNK_DATA>(reinterpret_cast<BYTE *>(hModule) + pImageImportDescriptor->FirstThunk); while (pImageThunkData->u1.Function) { DWORD *pDwAddr = &(pImageThunkData->u1.Function); if (*pDwAddr == reinterpret_cast<DWORD>(old_func_addr_)) { MEMORY_BASIC_INFORMATION mbi; VirtualQuery(pDwAddr, &mbi, sizeof(MEMORY_BASIC_INFORMATION)); DWORD dwOldProtection = 0; VirtualProtect(pDwAddr, sizeof(DWORD_PTR), PAGE_READWRITE, &dwOldProtection); // 为了安全起见,可以使用WriteProcessMemory函数进行远进程写入,这样即使权限不够,也不会报异常 if (!WriteProcessMemory(GetCurrentProcess(), pDwAddr, &new_func_addr_, sizeof(DWORD_PTR), nullptr)) { MessageBoxW(nullptr, L"WriteProcessMemory", L"WriteProcessMemory", MB_OK); } VirtualProtect(pDwAddr, sizeof(DWORD_PTR), dwOldProtection, nullptr); break; } ++pImageThunkData; } } }}
// dllmain.cpp : 定义 DLL 应用程序的入口点。#include "stdafx.h"#include "IATHook.h"// 找到当前注入后的 IAT 表 Hook TerminateProcess//PoEdu::CIATHook g_MyHook;DWORD g_dwPID = 0;HHOOK g_hHook = nullptr;BOOL WINAPI MyTerminateProcess(_In_ HANDLE hProcess, _In_ UINT uExitCode){ return FALSE;// DWORD dwPID = GetProcessId(hProcess);// if (g_dwPID == dwPID)// {// MessageBoxW(nullptr, L"这是我要保护的进程,请不要无条件终止它!", L"警告", MB_OK);// return TRUE;// } //return TerminateProcess(hProcess, uExitCode);}PoEdu::CIATHook g_MyHook("KERNEL32.dll", "TerminateProcess", MyTerminateProcess);BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; default: break; } return TRUE;}HMODULE GetFuncModule(void * pFuncAddr){ HMODULE hRet = nullptr; MEMORY_BASIC_INFORMATION mbi; if (VirtualQuery(pFuncAddr, &mbi, sizeof(MEMORY_BASIC_INFORMATION)) != 0) { hRet = static_cast<HMODULE>(mbi.AllocationBase); } return hRet;}LRESULT CALLBACK GetMsgProc(_In_ int code, _In_ WPARAM wParam, _In_ LPARAM lParam){ //MessageBoxW(nullptr, L"GetMsgProc", L"GetMsgProc", MB_OK); return CallNextHookEx(g_hHook, code, wParam, lParam);}// 用SetWindowsHook做的注入extern "C" _declspec(dllexport) BOOL StartProtecting(DWORD dwPID)//extern "C" _declspec(dllexport) BOOL StartProtecting(){ BOOL bRet = FALSE; if (g_hHook == nullptr) { g_hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, GetFuncModule(GetMsgProc), 0); if (g_hHook != nullptr) { g_dwPID = dwPID; bRet = TRUE; } } return bRet;}extern "C" _declspec(dllexport) BOOL EndProtecting(){ BOOL bRet = FALSE; if (g_hHook != nullptr) { if (UnhookWindowsHookEx(g_hHook)) { bRet = TRUE; } } return bRet;}
上面主要有问题的是MyTerminateProcess函数,从这个函数的实现可以看出,我们屏蔽的是所有的TerminateProcess,因为每一个进程在调用ProcessProtectorDll动态链接库的时候都是重新复制一份,所以没法简单的在挂钩的时候传递一个要保护的进程ID,因为在新的进程调用该动态链接库的时候,一切都是初始化状态,并没有要保护的进程ID,只能通过共享空间实现所有进程的数据共享,这里我们没有实现,感兴趣的朋友可以实现一下。。。
ProcessProtectorExe程序源码
该程序主要是加载ProcessProtectorDll动态链接库从而达到保护进程不被远程无条件结束的目的。
// ProcessProtectorExe.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <Windows.h>#include <clocale>// 选择需要保护的进程// 启动Hooktypedef BOOL(*FUNC)(DWORD dwPID);void PrintErrorMessage(DWORD dwErrorCode){ setlocale(LC_ALL, "chs"); TCHAR strErrorMessage[MAXBYTE] = { 0 }; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, dwErrorCode, 0, strErrorMessage, MAXBYTE, nullptr); wprintf(L"错误代码是:%d %s\r\n", dwErrorCode, strErrorMessage);}int main(){ HMODULE hDllModule = nullptr; FUNC StartProtecting = nullptr; FARPROC EndProtecting = nullptr; do { // 查找窗口 char strProcessName[MAXBYTE] = "计算器"; HWND hWnd = FindWindowA(nullptr, strProcessName); if (hWnd == nullptr) { printf("the handle of window do not found!\r\n"); break; } // 根据窗口句柄查找进程ID DWORD dwProcessId = 0; GetWindowThreadProcessId(hWnd, &dwProcessId); if (dwProcessId == NULL) { printf("process Id do not found!\r\n"); break; } // 打开进程 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); if (hProcess == nullptr) { printf("open the process failed!\r\n"); break; } // LoadLibray hDllModule = LoadLibrary(L"ProcessProtectorDll.dll"); if (hDllModule == nullptr) { PrintErrorMessage(GetLastError()); break; } // SetHook StartProtecting = reinterpret_cast<FUNC>(GetProcAddress(hDllModule, "StartProtecting")); if (StartProtecting == nullptr) { PrintErrorMessage(GetLastError()); break; } if (!StartProtecting(dwProcessId)) { PrintErrorMessage(GetLastError()); break; } printf("进程保护成功!\r\n"); MSG msg; BOOL ret; while ((ret = GetMessage(&msg, nullptr, 0, 0))) { if (ret == -1) break; TranslateMessage(&msg); DispatchMessage(&msg); } // UnHook EndProtecting = GetProcAddress(hDllModule, "EndProtecting"); if (EndProtecting == nullptr) { PrintErrorMessage(GetLastError()); break; } if (!EndProtecting()) { PrintErrorMessage(GetLastError()); break; } } while (false); if (hDllModule) { FreeLibrary(hDllModule); } system("pause"); return 0;}
由于动态链接库是被所有进程调用的,所以这里保护的是所有的进程不被远程无条件结束掉,而不只是计算器这个程序,这个需要注意一下。
**
// TerminateProcessExe.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <Windows.h>int main(){ do { // 查找窗口 char strProcessName[MAXBYTE] = "计算器"; HWND hWnd = FindWindowA(nullptr, strProcessName); if (hWnd == nullptr) { printf("the handle of window do not found!\r\n"); break; } // 根据窗口句柄查找进程ID DWORD dwProcessId = 0; GetWindowThreadProcessId(hWnd, &dwProcessId); if (dwProcessId == NULL) { printf("process Id do not found!\r\n"); break; } // 打开进程 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); if (hProcess == nullptr) { printf("open the process failed!\r\n"); break; } MessageBoxW(nullptr, L"", L"", MB_OK); if (TerminateProcess(hProcess, 1)) { printf("已经被终止运行!\r\n"); } else { printf("没有被终止运行!\r\n"); } } while (false); system("pause"); return 0;}
本程序就是尝试远程结束计算器程序,当开启了我们的进程保护器后,我们是无法终止计算器的,这也就达到了要保护的目的。
当然了,这种全局挂钩的方式是存在问题的,它会使我们的系统变得非常的慢。我们的这个进程保护器目的只是让大家了解一下什么是IAT Hook,它的原理是什么,实际上基本上不会用这种方式来实现进程保护器的。
- Windows Practice_Dll&Hook_封装IAT Hook
- Windows Practice_Dll&Hook_消息钩子
- Windows Practice_Dll&Hook_IAT Hook
- windows hook 之IAT篇
- IAT HOOK
- IAT HOOK
- HOOK IAT
- IAT HOOK
- IAT HOOK
- IAT HOOK
- IAT HOOK
- IAT HOOK
- IAT HOOK
- Windows Practice_Dll&Hook_Hook是什么?
- Windows Practice_Dll&Hook_DetourHook库
- IAT HOOK及遍历IAT
- 利用IAT hook实现windows通用密码后门
- 利用IAT hook实现windows通用密码后门
- HDU 6206 Apple(外心)
- 单链表
- centOS安装搜索工具locate报错
- java Class 的加载时机
- Dynamic Programming:121. Best Time to Buy and Sell Stock
- Windows Practice_Dll&Hook_封装IAT Hook
- Guava 指南 之「通用 Object 方法」
- Pseudo-terminal will not be allocated because stdin is not a terminal
- 数组中的最大递增子序列(Longest Increasing Subsequence<LIS>)
- Java 基础集合遍历删除 for与foreach区别
- 算法第三周Reverse Integer[easy]
- LeetCode#670 Maximum Swap题解(C++版)
- JSON基本使用
- Python Computer Vision Programming学习笔记(一)——Python以及各Package安装