当前位置 博文首页 > KOOKNUT的博客:InlineHook--Ring3
实现思路:
使用GetProcAddress得到函数地址,将函数入口点的前5字节进行替换,使用e9指令进行跳转到Fake函数的地址,然后去执行挂钩函数。
在程序的实现过程中注意的问题有两个:
//e9指令后面的数据计算,就是跳转到当前地址加5字节偏移,加e9后面的偏移地址
//例如:00DB15E6 E9 A5 3B 00 00 jmp Sub_1 (0DB5190h)
//00DB15E6(当前地址) + 5 + 00003BA5 = 0DB5190h(目标地址)
测试时候,使用远程线程注入的方式,在目标进程中启动远程线程去加载dll,然后去实现Hook。
附上关键代码实现:
#include"Dll.h"
#include"HookApi_Jmp.h"
CHookApi_Jmp MyHook;
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
ExampleJmp();
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
int WINAPI JmpMessageBoxA(HWND hWnd, LPCTSTR lpText, LPCSTR lpCaption, UINT uType)
{
int ReturnValue = 0;
MyHook.SetHookOff();//恢复之后,显示该弹窗消息
ReturnValue = MessageBoxA(hWnd, "Hooking MessageBox by Jmp", lpCaption, uType);
MyHook.SetHookOn();//继续hook
return ReturnValue;
}
void WINAPI ExampleJmp()
{
//HookOneAPI保存挂钩函数的地址,替换E9指令
MyHook.HookOneAPI(_T("user32.dll"), "MessageBoxA", (FARPROC)JmpMessageBoxA);
//SetHookOn实现内存修改
MyHook.SetHookOn();
}
void CHookApi_Jmp::SetHookOn()
{
DWORD OldFlag;
WriteProcessMemory(m_ProcessHandle, (void *)m_HookFunctionAddress,
(void *)m_NewJmp, 5, &OldFlag);
}
void CHookApi_Jmp::SetHookOff()
{
DWORD OldFlag;
WriteProcessMemory(m_ProcessHandle, (void *)m_HookFunctionAddress,
(void *)m_OldCode, 5, &OldFlag);
}
void CHookApi_Jmp::HookOneAPI(LPCTSTR ModuleName,
LPCSTR ApiName, FARPROC FunctionAddress)
{
m_HookFunctionAddress = GetProcAddress(GetModuleHandle(ModuleName), ApiName);
//m_HookFunctionAddress = user32.dll!0x755eea11 (加载符号以获取其他信息)
m_ProcessHandle = GetCurrentProcess();
m_NewJmp[0] = 0xe9;
memcpy(m_OldCode, (char *)m_HookFunctionAddress, 5);
//m_OldCode 0x0F91C2A0 8b ff 55 8b ec旧指令 前五字节
/*
8B FF mov edi,edi
55 push ebp
8B EC mov ebp,esp
*/
//jmp指令后面的数据计算,就是跳转到当前地址加5字节偏移,加jmp后面的偏移地址
//例如:00DB15E6 E9 A5 3B 00 00 jmp Sub_1 (0DB5190h)
//00DB15E6 + 5 + 00003BA5 = 0DB5190h
DWORD* NewFunctionAddress;
NewFunctionAddress = (DWORD*)&m_NewJmp[1];
*NewFunctionAddress = (DWORD)FunctionAddress - (DWORD)m_HookFunctionAddress - 5;
//FunctionAddress = 0x0f91128a {Dll.dll!JmpMessageBoxA(struct HWND__ *, wchar_t const *, char const *, unsigned int)}
//m_HookFunctionAddress = user32.dll!0x755eea11 (加载符号以获取其他信息)
//*NewFunctionAddress = 0x9a322874;
//0x0F91C2A8 e9 74 28 32 9a
}
void _tmain()
{
ULONG_PTR ProcessId = GetActiveProcessId("Test.exe");
CHAR DllFullPath[MAX_PATH] = { 0 };
if (ProcessId)
{
//打开目标进程,获得目标进程句柄
HANDLE ProcessHandle = KtOpenProcess(PROCESS_ALL_ACCESS, false, ProcessId);
if (ProcessHandle == NULL)
{
KtCloseHandle(ProcessHandle);
}
GetCurrentDirectory(MAX_PATH, DllFullPath);
strcat(DllFullPath, "\\Dll.dll");
StartHook(ProcessHandle, DllFullPath);
}
getchar();
}
BOOL StartHook(HANDLE ProcessHandle, CHAR* DllFullPath)
{
BOOL IsOk = FALSE;
ULONG DllFullPathLength = 0;
DllFullPathLength = (strlen(DllFullPath) + 1);// '/0'
//目标进程空间中申请内存
LPVOID VirtualAddress = VirtualAllocEx(ProcessHandle, NULL,
DllFullPathLength, MEM_COMMIT, PAGE_READWRITE);
int LastError = GetLastError();
if (VirtualAddress == NULL)
{
KtCloseHandle(ProcessHandle);
return IsOk;
}
//目标进程空间中写入数据
if (KtProcessMemoryWriteSafe(ProcessHandle, VirtualAddress, DllFullPath,
DllFullPathLength, 0) == FALSE)
{
KtCloseHandle(ProcessHandle);
return IsOk;
}
HANDLE ThreadHandle = CreateRemoteThread(ProcessHandle,
NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary, //当前模块中导入函数
VirtualAddress, 0, NULL);
if (ThreadHandle == NULL)
{
VirtualFreeEx(ProcessHandle, VirtualAddress, DllFullPathLength, MEM_RELEASE);
return IsOk;
}
//等待远程线程结束
WaitForSingleObject(ThreadHandle, INFINITE);
if (VirtualAddress != NULL)
{
VirtualFreeEx(ProcessHandle, VirtualAddress, DllFullPathLength, MEM_RELEASE);
}
if (ProcessHandle)
{
KtCloseHandle(ProcessHandle);
}
IsOk = TRUE;
return IsOk;
}
测试程序:
void _tmain()
{
_tsetlocale(LC_ALL, _T("Chinese"));
MessageBoxA(NULL, "World", "Hello", 0);
printf("Print Anykey to confirme Hook\r\n");
getchar();
MessageBoxA(NULL, "World", "Hello", 0);
}
迟来的更新。。。最近确实有一些事情,没在家好好学习,也没有更新我的博客。青山不改,绿水长流。
“When all the clouds darken up the skyway, there’s a rainbow highway to be found.
当乌云密布,彩虹会为你铺就一条道路。”
参考书籍:
《Windows应用程序捆绑核心》