- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
可选引擎:
nthookengine //支持x64 开源
mhook //支持x64 开源
Detour//x64收费
方法:
本进程HOOK,直接调用HOOK函数;
否则,写成一个DLL,在DLL里HOOK每个函数
然后将该DLL注入到目标进程,达到HOOK目标进程中的函数的目的
MHOOK
//需要直接获取原始函数地址
#include mhook.h
typedef 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);[/code]
测试使用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 hook
if (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 hook
Mhook_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;
}
[/code]
NTHookEngine导出函数(对比的进程HOOK 推荐使用这个)
BOOL (__cdecl *HookFunction)(ULONG_PTR OriginalFunction, ULONG_PTR NewFunction);
VOID (__cdecl *UnhookFunction)(ULONG_PTR Function);
ULONG_PTR (__cdecl *GetOriginalFunction)(ULONG_PTR Hook);
[/code]
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"));
[/code]
// 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);
}
[/code]
实例:
使用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 variable
HOOKDLL_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 definition
Chookdll::Chookdll()
{
return;
}
[/code]
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 address
OldCreateProcessW = (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;
}
[/code]
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:oDataExchange(CDataExchange* pDX)
{
CDialog:oDataExchange(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:oDataExchange(CDataExchange* pDX)
{
CDialog:oDataExchange(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_MAP
ON_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();
}
[/code]
需要注意的时,此时应将NtHookEngine编译出来的NtHookEngine.dll放置目标运行目录下(或者使用全路径,推荐使用全路径,因为如果只是文件名的话,程序会先去系统变量path里面找有没有这个镜像的目录,如果有就加载,这样很容易被劫持)
效果如下:
未HOOK前:
正常MessageBox 和 创建一个cmd
HOOK后:
标题被改了,创建进程的时候要询问了 |
|