Detours Loader實現對exe的API Hook
在前一篇http://www.dotblogs.com.tw/cmd4shell/archive/2011/10/26/46749.aspx中,主要介绍了一下Detours的一些基本编译,但是实际使用中,可能情况要比这个复杂一些。比如说,我们有一个不可控制程序HookTest.exe文件(事实上为了演示,这里的还是一个自己写的Messagebox程序,当然也只有这个功能)。
{
MessageBox(NULL, TEXT("Are you Hooked?"), TEXT("Hook Test"), MB_OK);
return 0;
}
这里演示的是使用Loader方式加载的API Hook,因此需要两个程序,一个Loader,一个Hook Dll。
先给一下HookDll的代码:
#include <windows.h>
#include <detours.h>
#pragma comment(lib, "detours.lib")
#define EXPORT_API extern "C" __declspec(dllexport)
EXPORT_API void InjectDll()
{
return;
}
static int(WINAPI *TrueMessageBox)(__in_opt HWND hWnd,
__in_opt LPCTSTR lpText,
__in_opt LPCTSTR lpCaption,
__in UINT uType) = MessageBox;
int WINAPI MyMessageBox(__in_opt HWND hWnd, __in_opt LPCTSTR lpText, __in_opt LPCTSTR lpCaption,__in UINT uType)
{
OutputDebugString("API Hooked!\n");
int rv = 0;
__try{
rv = TrueMessageBox(hWnd, TEXT("Hooked!"), lpCaption, uType);
}
__finally{
OutputDebugString("Call OrgMessageBox!\n");
}
return rv;
}
//dllmain.cpp
#include "stdafx.h"
#include "hookdll.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
//DetourAttach(&(PVOID&)TrueSleep, TimedSleep);
DetourAttach(&(PVOID&)TrueMessageBox, MyMessageBox);
DetourTransactionCommit();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
//DetourAttach(&(PVOID&)TrueSleep, TimedSleep);
DetourDetach(&(PVOID&)TrueMessageBox, MyMessageBox);
DetourTransactionCommit();
break;
}
return TRUE;
}
Loader的代码比较长,主要的代码给一下就好了:
{
BOOL fHasOrdinal1;
ULONG nExports;
};
static BOOL CALLBACK ExportCallback(PVOID pContext,
ULONG nOrdinal,
PCHAR pszSymbol,
PVOID pbTarget)
{
(void)pContext;
(void)pbTarget;
(void)pszSymbol;
ExportContext *pec = (ExportContext *)pContext;
if (nOrdinal == 1) {
pec->fHasOrdinal1 = TRUE;
}
pec->nExports++;
return TRUE;
}
//主函数:
ExportContext ec;
ec.fHasOrdinal1 = FALSE;
ec.nExports = 0;
DetourEnumerateExports(hDll, &ec, ExportCallback);
FreeLibrary(hDll);
if (!ec.fHasOrdinal1)
{
OutputDebugString("No ExportTable Found!\n");
return -1;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
CHAR szCommand[2048];
CHAR szExe[] = "HookTest.exe";
CHAR szFullExe[1024] = "\0";
PCHAR pszFileExe = NULL;
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);
szCommand[0] = '\0';
DWORD dwFlags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED;
SetLastError(0);
SearchPath(NULL, szExe, ".exe", ARRAYSIZE(szFullExe), szFullExe, &pszFileExe);
if (!DetourCreateProcessWithDll(szFullExe[0] ? szFullExe : NULL, szCommand,
NULL, NULL, TRUE, dwFlags, NULL, NULL,
&si, &pi, szDllPath, NULL))
{
OutputDebugString("CreateProcessFailed!\n");
return -1;
}
ResumeThread(pi.hThread);
WaitForSingleObject(pi.hProcess, INFINITE);
编译测试结果如图:
------------------------------
文章的授權使用CC BY-ND2.5協議。凡是標示“轉載”的文章,均來源於網絡並儘可能標註作者。如果有侵犯您的權益,請及時聯繫刪除或者署名、授權。
Gtalk/Email: cmd4shell [at] gmail.com