HOOK Engine (nthookengine.mhook)

来源:互联网 发布:苹果怎么打开php文件 编辑:程序博客网 时间:2024/06/01 03:58
可选引擎:
nthookengine //支持x64 开源
mhook //支持x64 开源

Detour//x64收费

方法:
本进程HOOK,直接调用HOOK函数;
否则,写成一个DLL,在DLL里HOOK每个函数

然后将该DLL注入到目标进程,达到HOOK目标进程中的函数的目的


MHOOK

//需要直接获取原始函数地址

#include mhook.htypedef ULONG (WINAPI* _NtOpenProcess)(OUT PHANDLE ProcessHandle,      IN ACCESS_MASK AccessMask, IN PVOID ObjectAttributes,  IN PCLIENT_ID ClientId ); _NtOpenProcess TrueNtOpenProcess = (_NtOpenProcess)GetProcAddress(GetModuleHandle(L"ntdll"), "NtOpenProcess");ULONG WINAPI HookNtOpenProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK AccessMask, IN PVOID ObjectAttributes, IN PCLIENT_ID ClientId){return TrueNtOpenProcess(ProcessHandle, AccessMask, ObjectAttributes, ClientId);}Mhook_SetHook((PVOID*)&TrueNtOpenProcess, HookNtOpenProcess);Mhook_Unhook((PVOID*)&TrueNtOpenProcess);

测试使用mhook-2.1 Hook本进程的OpenProcess

#include "stdafx.h"#include "mhook-lib/mhook.h"//=========================================================================// Define _NtOpenProcess so we can dynamically bind to the function//typedef struct _CLIENT_ID {DWORD_PTR UniqueProcess;DWORD_PTR UniqueThread;} CLIENT_ID, *PCLIENT_ID;typedef ULONG (WINAPI* _NtOpenProcess)(OUT PHANDLE ProcessHandle,      IN ACCESS_MASK AccessMask, IN PVOID ObjectAttributes,  IN PCLIENT_ID ClientId ); //=========================================================================// Get the current (original) address to the function to be hooked//_NtOpenProcess TrueNtOpenProcess = (_NtOpenProcess)GetProcAddress(GetModuleHandle(L"ntdll"), "NtOpenProcess");//=========================================================================// This is the function that will replace NtOpenProcess once the hook // is in place//ULONG WINAPI HookNtOpenProcess(OUT PHANDLE ProcessHandle,    IN ACCESS_MASK AccessMask,    IN PVOID ObjectAttributes,    IN PCLIENT_ID ClientId){printf("***** Call to open process %d\n", ClientId->UniqueProcess);return TrueNtOpenProcess(ProcessHandle, AccessMask, ObjectAttributes, ClientId);}//=========================================================================// This is where the work gets done.//int wmain(int argc, WCHAR* argv[]){HANDLE hProc = NULL;// Set the hookif (Mhook_SetHook((PVOID*)&TrueNtOpenProcess, HookNtOpenProcess)) {// Now call OpenProcess and observe NtOpenProcess being redirected// under the hood.hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());if (hProc) {printf("Successfully opened self: %p\n", hProc);CloseHandle(hProc);} else {printf("Could not open self: %d\n", GetLastError());}// Remove the hookMhook_Unhook((PVOID*)&TrueNtOpenProcess);}// Call OpenProces again - this time there won't be a redirection as// the hook has bee removed.hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());if (hProc) {printf("Successfully opened self: %p\n", hProc);CloseHandle(hProc);} else {printf("Could not open self: %d\n", GetLastError());}return 0;}


NTHookEngine导出函数(对比的进程HOOK 推荐使用这个)

BOOL (__cdecl *HookFunction)(ULONG_PTR OriginalFunction, ULONG_PTR NewFunction);VOID (__cdecl *UnhookFunction)(ULONG_PTR Function);ULONG_PTR (__cdecl *GetOriginalFunction)(ULONG_PTR Hook);

NTHookEngineHOOK实现

int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,WORD wLanguageId, DWORD dwMilliseconds){int (WINAPI *pMessageBoxW)(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwMilliseconds);pMessageBoxW = (int (WINAPI *)(HWND, LPCWSTR, LPCWSTR, UINT, WORD, DWORD))GetOriginalFunction((ULONG_PTR) MyMessageBoxW);return pMessageBoxW(hWnd, lpText, L"Hooked MessageBox",uType, wLanguageId, dwMilliseconds);}HookFunction((ULONG_PTR) GetProcAddress(LoadLibrary(_T("User32.dll")),"MessageBoxTimeoutW"), (ULONG_PTR) &MyMessageBoxW);UnhookFunction((ULONG_PTR) GetProcAddress(LoadLibrary(_T("User32.dll")), "MessageBoxTimeoutW"));


// NtHookEngine_Test.cpp : Defines the entry point for the application.//#include "stdafx.h"#include "NtHookEngine_Test.h"BOOL (__cdecl *HookFunction)(ULONG_PTR OriginalFunction, ULONG_PTR NewFunction);VOID (__cdecl *UnhookFunction)(ULONG_PTR Function);ULONG_PTR (__cdecl *GetOriginalFunction)(ULONG_PTR Hook);int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwMilliseconds);int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,   LPTSTR lpCmdLine, int nCmdShow){//// Retrive hook functions// HMODULE hHookEngineDll = LoadLibrary(_T("NtHookEngine.dll"));HookFunction = (BOOL (__cdecl *)(ULONG_PTR, ULONG_PTR))GetProcAddress(hHookEngineDll, "HookFunction");UnhookFunction = (VOID (__cdecl *)(ULONG_PTR))GetProcAddress(hHookEngineDll, "UnhookFunction");GetOriginalFunction = (ULONG_PTR (__cdecl *)(ULONG_PTR))GetProcAddress(hHookEngineDll, "GetOriginalFunction");if (HookFunction == NULL || UnhookFunction == NULL || GetOriginalFunction == NULL)return 0;//// Hook MessageBoxTimeoutW//HookFunction((ULONG_PTR) GetProcAddress(LoadLibrary(_T("User32.dll")),"MessageBoxTimeoutW"), (ULONG_PTR) &MyMessageBoxW);MessageBox(0, _T("Hi, this is a message box!"), _T("This is the title."), MB_ICONINFORMATION);//// Unhook MessageBoxTimeoutW//UnhookFunction((ULONG_PTR) GetProcAddress(LoadLibrary(_T("User32.dll")), "MessageBoxTimeoutW"));MessageBox(0, _T("Hi, this is a message box!"), _T("This is the title."), MB_ICONINFORMATION);return 0;}int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwMilliseconds){int (WINAPI *pMessageBoxW)(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwMilliseconds);pMessageBoxW = (int (WINAPI *)(HWND, LPCWSTR, LPCWSTR, UINT, WORD, DWORD))GetOriginalFunction((ULONG_PTR) MyMessageBoxW);return pMessageBoxW(hWnd, lpText, L"Hooked MessageBox",uType, wLanguageId, dwMilliseconds);}

实例:

使用nthookengine Hook目标进程的MessageBox和CreateProcess

被Hook进程 就是普通的进程 里面调用了MessageBox 和 CreateProcess

HOOK DLL代码:

hook.h

// hookdll.cpp : Defines the exported functions for the DLL application.//#include "stdafx.h"#include "hookdll.h"// This is an example of an exported variableHOOKDLL_API int nhookdll=0;// This is an example of an exported function.HOOKDLL_API int fnhookdll(void){return 42;}// This is the constructor of a class that has been exported.// see hookdll.h for the class definitionChookdll::Chookdll(){return;}

hook.cpp

// dllmain.cpp : Defines the entry point for the DLL application.#include "stdafx.h"#include <tchar.h>#include <stdio.h>BOOL (__cdecl *HookFunction)(ULONG_PTR OriginalFunction, ULONG_PTR NewFunction);VOID (__cdecl *UnhookFunction)(ULONG_PTR Function);ULONG_PTR (__cdecl *GetOriginalFunction)(ULONG_PTR Hook);int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwMilliseconds);typedef DWORD (WINAPI *CREATPROCESSW)(  LPCWSTR lpApplicationName,  LPWSTR lpCommandLine,   LPSECURITY_ATTRIBUTES lpProcessAttributes,  LPSECURITY_ATTRIBUTES lpThreadAttributes,  BOOL bInheritHandles,  DWORD dwCreationFlags,  LPVOID lpEnvironment,  LPCWSTR lpCurrentDirectory,  LPSTARTUPINFOW lpStartupInfo,  LPPROCESS_INFORMATION lpProcessInformation  );typedef DWORD (WINAPI *CREATPROCESSA)(  LPCSTR lpApplicationName,  LPSTR lpCommandLine,   LPSECURITY_ATTRIBUTES lpProcessAttributes,  LPSECURITY_ATTRIBUTES lpThreadAttributes,  BOOL bInheritHandles,  DWORD dwCreationFlags,  LPVOID lpEnvironment,  LPCSTR lpCurrentDirectory,  LPSTARTUPINFO lpStartupInfo,  LPPROCESS_INFORMATION lpProcessInformation  );typedef int (WINAPI *MESSAGEBOXW)(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwMilliseconds);CREATPROCESSW OldCreateProcessW = NULL;CREATPROCESSA OldCreateProcessA = NULL;MESSAGEBOXW OldMessageBoxW = NULL;int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwMilliseconds){return OldMessageBoxW(hWnd, lpText, L"Hooked MessageBox",uType, wLanguageId, dwMilliseconds);}DWORD WINAPI myCreateProcessW(LPCWSTR lpApplicationName,LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,BOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCWSTR lpCurrentDirectory,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation){WCHAR wszInfo[2*MAX_PATH] = {0};_stprintf_s(wszInfo,sizeof(wszInfo)/sizeof(WCHAR),  _T("将要创建进程:%s,阻止吗?"), lpApplicationName);if (MessageBoxW(NULL, wszInfo, lpApplicationName, MB_YESNO)==IDYES){return FALSE;}return OldCreateProcessW(lpApplicationName,lpCommandLine, lpProcessAttributes,lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,lpCurrentDirectory, lpStartupInfo, lpProcessInformation);}DWORD WINAPI myCreateProcessA(LPCSTR lpApplicationName,LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,BOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCSTR lpCurrentDirectory,LPSTARTUPINFO lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation){CHAR szInfo[2*MAX_PATH] = {0};sprintf_s(szInfo, sizeof(szInfo), ("将要创建进程:%s,阻止吗?"), lpApplicationName);if (MessageBoxA(NULL, lpApplicationName, lpApplicationName, MB_YESNO)==IDYES){return FALSE;}return OldCreateProcessA(lpApplicationName, lpCommandLine, lpProcessAttributes,lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,lpCurrentDirectory, lpStartupInfo, lpProcessInformation);}VOID HookIt(VOID){HMODULE hHookEngineDll = LoadLibrary(_T("NtHookEngine.dll"));HookFunction = (BOOL (__cdecl *)(ULONG_PTR, ULONG_PTR))GetProcAddress(hHookEngineDll, "HookFunction");UnhookFunction = (VOID (__cdecl *)(ULONG_PTR))GetProcAddress(hHookEngineDll, "UnhookFunction");GetOriginalFunction = (ULONG_PTR (__cdecl *)(ULONG_PTR))GetProcAddress(hHookEngineDll, "GetOriginalFunction");if (HookFunction == NULL || UnhookFunction == NULL || GetOriginalFunction == NULL)return;//// Hook ALL the apis you want here//HookFunction((ULONG_PTR) GetProcAddress(LoadLibrary(_T("User32.dll")),"MessageBoxTimeoutW"), (ULONG_PTR) &MyMessageBoxW);HookFunction((ULONG_PTR) GetProcAddress(LoadLibrary(_T("KERNEL32.DLL")),"CreateProcessA"), (ULONG_PTR) &myCreateProcessA);HookFunction((ULONG_PTR) GetProcAddress(LoadLibrary(_T("KERNEL32.DLL")),"CreateProcessW"), (ULONG_PTR) &myCreateProcessW);// save the original api addressOldCreateProcessW = (CREATPROCESSW) GetOriginalFunction((ULONG_PTR) myCreateProcessW);OldCreateProcessA = (CREATPROCESSA) GetOriginalFunction((ULONG_PTR) myCreateProcessA);OldMessageBoxW = (MESSAGEBOXW)GetOriginalFunction((ULONG_PTR) MyMessageBoxW);}VOID UnHook(){UnhookFunction((ULONG_PTR) GetProcAddress(LoadLibrary(_T("User32.dll")), "MessageBoxTimeoutW"));UnhookFunction((ULONG_PTR) GetProcAddress(LoadLibrary(_T("KERNEL32.DLL")), "myCreateProcessA"));UnhookFunction((ULONG_PTR) GetProcAddress(LoadLibrary(_T("KERNEL32.DLL")), "myCreateProcessW"));}BOOL APIENTRY DllMain( HMODULE hModule,                       DWORD  ul_reason_for_call,                       LPVOID lpReserved ){switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:HookIt();break;case DLL_THREAD_ATTACH:break;case DLL_THREAD_DETACH:break;case DLL_PROCESS_DETACH://UnHook();break;}return TRUE;}

HooKer的功能就是将dll注入目标进程

// hookerDlg.cpp : 实现文件//#include "stdafx.h"#include "hooker.h"#include "hookerDlg.h"#include <tchar.h>#ifdef _DEBUG#define new DEBUG_NEW#endif// 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialog{public:CAboutDlg();// 对话框数据enum { IDD = IDD_ABOUTBOX };protected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持// 实现protected:DECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD){}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)END_MESSAGE_MAP()// ChookerDlg 对话框ChookerDlg::ChookerDlg(CWnd* pParent /*=NULL*/): CDialog(ChookerDlg::IDD, pParent), m_dwPid(0){m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void ChookerDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);DDX_Text(pDX, IDC_EDIT_PID, m_dwPid);}BEGIN_MESSAGE_MAP(ChookerDlg, CDialog)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()//}}AFX_MSG_MAPON_BN_CLICKED(IDOK, &ChookerDlg::OnBnClickedOk)END_MESSAGE_MAP()// ChookerDlg 消息处理程序BOOL ChookerDlg::OnInitDialog(){CDialog::OnInitDialog();// 将“关于...”菜单项添加到系统菜单中。// IDM_ABOUTBOX 必须在系统命令范围内。ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动//  执行此操作SetIcon(m_hIcon, TRUE);// 设置大图标SetIcon(m_hIcon, FALSE);// 设置小图标// TODO: 在此添加额外的初始化代码return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE}void ChookerDlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialog::OnSysCommand(nID, lParam);}}// 如果向对话框添加最小化按钮,则需要下面的代码//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,//  这将由框架自动完成。void ChookerDlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// 使图标在工作区矩形中居中int cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// 绘制图标dc.DrawIcon(x, y, m_hIcon);}else{CDialog::OnPaint();}}//当用户拖动最小化窗口时系统调用此函数取得光标//显示。HCURSOR ChookerDlg::OnQueryDragIcon(){return static_cast<HCURSOR>(m_hIcon);}BOOL AddDebugPrivilege(void){TOKEN_PRIVILEGES tp;LUID luid;HANDLE hToken;if(!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid)){return FALSE;}tp.PrivilegeCount = 1;tp.Privileges[0].Luid=luid;tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken)){return FALSE;}if(!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,(PDWORD)NULL)){return FALSE;}return TRUE;} int InjectDll( HANDLE hProcess, TCHAR* szLibPath){HANDLE hThread;void*  pLibRemote = 0;DWORD  hLibModule = 0;HMODULE hKernel32 = ::GetModuleHandle(_T("Kernel32"));LPTHREAD_START_ROUTINE pLoadFunc = NULL;pLoadFunc = (LPTHREAD_START_ROUTINE) ::GetProcAddress(hKernel32,"LoadLibraryW");if (szLibPath == NULL ||hProcess == NULL ||pLoadFunc == NULL){return FALSE;}pLibRemote = ::VirtualAllocEx( hProcess, NULL, (_tcslen(szLibPath) + 1)*sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE );if( pLibRemote == NULL )return false;::WriteProcessMemory(hProcess, pLibRemote, (void*)szLibPath,(_tcslen(szLibPath) + 1)*sizeof(TCHAR),NULL);hThread = ::CreateRemoteThread( hProcess, NULL, 0,(LPTHREAD_START_ROUTINE)pLoadFunc, pLibRemote, 0, NULL );if( hThread == NULL )goto JUMP;DWORD dwError = GetLastError();::WaitForSingleObject( hThread, INFINITE );dwError = GetLastError();::GetExitCodeThread( hThread, &hLibModule );::CloseHandle( hThread );JUMP:::VirtualFreeEx( hProcess, pLibRemote, sizeof(szLibPath), MEM_RELEASE );if( hLibModule == NULL )return false;return hLibModule;}void ChookerDlg::OnBnClickedOk(){//LoadLibraryW(_T("hookdll.dll"));AddDebugPrivilege();UpdateData(TRUE);//MessageBox(_T("Failed"));HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE  | PROCESS_VM_READ,FALSE, m_dwPid);if (hProcess == NULL){MessageBox(_T("Failed"));return;}InjectDll(hProcess, _T("hookdll.dll"));//(CButton*)GetDlgItem(IDOK)->EnableWindow(FALSE);//OnOK();}

需要注意的时,此时应将NtHookEngine编译出来的NtHookEngine.dll放置目标运行目录下(或者使用全路径,推荐使用全路径,因为如果只是文件名的话,程序会先去系统变量path里面找有没有这个镜像的目录,如果有就加载,这样很容易被劫持)

效果如下:

未HOOK前:

正常MessageBox 和 创建一个cmd


HOOK后:

标题被改了,创建进程的时候要询问了




0 0