作者: cooldiyer
一晚上的战绩, 希望尊重版权, 写一个ring3下的例子,ring0下就不写了,很简单
复制内容到剪贴板
代码:
#include <stdio.h>
#include "InlineHook.h"
typedef void (__stdcall *__Sleep)(DWORD);
__Sleep realSleep = NULL;
VOID
__stdcall
MySleep(
IN DWORD dwMilliseconds
)
{
printf("Sleep(%d) Called/n", dwMilliseconds);
return realSleep(dwMilliseconds);
}
int main(int argc, char* argv[])
{
InlineHook(Sleep, MySleep, &realSleep);
Sleep(10);
UnInlineHook(Sleep, realSleep);
return 0;
}
主文件代码如下
[Copy to clipboard] [ - ]CODE:
/*++
Copyright (c) 2008/08/27 By CoolDiyer
Abstract:
Ring3 & Ring0 all-purpose inline hook module
--*/
#if !defined(AFX_INLINEHOOK_H_INCLUDED)
#define AFX_INLINEHOOK_H_INCLUDED
#ifdef WIN32
#include <windows.h>
#define JMP_SIZE 5
#else
#include <windef.h>
#define JMP_SIZE 7
#endif
#include "LDasm.h"
BOOL
GetPatchSize(
IN void *Proc, /* 需要Hook的函数地址 */
IN DWORD dwNeedSize, /* Hook函数头部占用的字节大小 */
OUT LPDWORD lpPatchSize /* 返回根据函数头分析需要修补的大小 */
)
/*++
计算函数头需要Patch的大小
--*/
{
DWORD Length;
PUCHAR pOpcode;
DWORD PatchSize = 0;
if (!Proc || !lpPatchSize)
{
return FALSE;
}
do
{
Length = SizeOfCode(Proc, &pOpcode);
if ((Length == 1) && (*pOpcode == 0xC3)) break;
if ((Length == 3) && (*pOpcode == 0xC2)) break;
Proc = (PVOID)((DWORD)Proc + Length);
PatchSize += Length;
if (PatchSize >= dwNeedSize)
{
break;
}
} while (Length);
*lpPatchSize = PatchSize;
return TRUE;
}
BOOL
InlineHook(
IN void *OrgProc, /* 需要Hook的函数地址 */
IN void *NewProc, /* 代替被Hook函数的地址 */
OUT void **RealProc /* 返回原始函数的入口地址 */
)
/*++
对函数进行Inline Hook
--*/
{
DWORD dwPatchSize; // 得到需要patch的字节大小
DWORD dwOldProtect;
LPVOID lpHookFunc; // 分配的Hook函数的内存
DWORD dwBytesNeed; // 分配的Hook函数的大小
LPBYTE MappedProc = NULL;
#ifndef WIN32
PMDL pMdlSystemCall = NULL;
#endif
if (!OrgProc || !NewProc || !RealProc)
{
return FALSE;
}
// 得到需要patch的字节大小
if (!GetPatchSize(OrgProc, JMP_SIZE, &dwPatchSize))
{
return FALSE;
}
/*
0x00000800 0x00000800 sizeof(DWORD) // dwPatchSize
JMP / FAR 0xAABBCCDD E9 DDCCBBAA JMP_SIZE
... ... dwPatchSize // Backup instruction
JMP / FAR 0xAABBCCDD E9 DDCCBBAA JMP_SIZE
*/
dwBytesNeed = sizeof(DWORD) + JMP_SIZE + dwPatchSize + JMP_SIZE;
#ifdef WIN32
MappedProc = OrgProc;
// 使前几个字节的内存可写
VirtualProtect(MappedProc, dwPatchSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
lpHookFunc = VirtualAlloc(NULL, dwBytesNeed, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else
pMdlSystemCall = IoAllocateMdl(
OrgProc,
dwPatchSize,
0,
0,
NULL
);
if(!pMdlSystemCall)
return FALSE;
MmBuildMdlForNonPagedPool(pMdlSystemCall);
MappedProc = (LPBYTE)MmMapLockedPages(pMdlSystemCall, KernelMode);
lpHookFunc = ExAllocatePool(NonPagedPool, dwBytesNeed);
#endif
*(DWORD *)lpHookFunc = dwPatchSize;
// 跳过开头的4个字节
lpHookFunc = (LPVOID)((DWORD)lpHookFunc + sizeof(DWORD));
// 开始Patch函数开头的字节
// 备份dwPatchSize到lpHookFunc
memcpy((BYTE *)lpHookFunc + JMP_SIZE, OrgProc, dwPatchSize);
// NOP填充
memset(MappedProc, 0x90, dwPatchSize);
#ifdef WIN32
// jmp
*(BYTE *)MappedProc = 0xE9;
// 注意计算长度的时候得用OrgProc
*(DWORD*)(MappedProc + 1) = (DWORD)lpHookFunc - (DWORD)OrgProc - JMP_SIZE;
// jmp到Hook
*(BYTE *)lpHookFunc = 0xE9;
*(DWORD*)((DWORD)lpHookFunc + 1) = (DWORD)NewProc - (DWORD)lpHookFunc - JMP_SIZE;
// 跳回原始
*(BYTE *)((DWORD)lpHookFunc + 5 + dwPatchSize) = 0xE9;
*(DWORD*)((DWORD)lpHookFunc + 5 + dwPatchSize + 1) = ((DWORD)OrgProc + dwPatchSize) - ((DWORD)lpHookFunc + JMP_SIZE + dwPatchSize) - JMP_SIZE;
#else
// jmp far
*(BYTE *)MappedProc = 0xEA;
// 注意计算长度的时候得用OrgProc
*(DWORD*)(MappedProc + 1) = (DWORD)lpHookFunc;
*(WORD*)(MappedProc + 5) = 0x08;
// jmp到Hook
*(BYTE *)lpHookFunc = 0xEA;
*(DWORD*)((DWORD)lpHookFunc + 1) = (DWORD)NewProc;
*(WORD*)((DWORD)lpHookFunc + 5) = 0x08;
// 跳回原始
*(BYTE *)((DWORD)lpHookFunc + JMP_SIZE + dwPatchSize) = 0xEA;
*(DWORD*)((DWORD)lpHookFunc + JMP_SIZE + dwPatchSize + 1) = ((DWORD)OrgProc + dwPatchSize);
*(WORD*)((DWORD)lpHookFunc + JMP_SIZE + dwPatchSize + 5) = 0x08;
#endif
#ifdef WIN32
// 恢复对内存的设置
VirtualProtect(MappedProc, dwPatchSize, dwOldProtect, &dwOldProtect);
#else
MmUnmapLockedPages(MappedProc, pMdlSystemCall);
IoFreeMdl(pMdlSystemCall);
#endif
*RealProc = (DWORD)lpHookFunc + JMP_SIZE;
return TRUE;
}
void UnInlineHook(
void *OrgProc, /* 需要恢复Hook的函数地址 */
void *RealProc /* 原始函数的入口地址 */
)
/*++
恢复对函数进行的Inline Hook
--*/
{
DWORD dwPatchSize;
DWORD dwOldProtect;
LPBYTE lpBuffer;
LPBYTE MappedProc = NULL;
#ifndef WIN32
PMDL pMdlSystemCall = NULL;
#endif
// 找到分配的空间
lpBuffer = (DWORD)RealProc - (sizeof(DWORD) + JMP_SIZE);
// 得到dwPatchSize
dwPatchSize = *(DWORD *)lpBuffer;
#ifdef WIN32
MappedProc = OrgProc;
VirtualProtect(MappedProc, dwPatchSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
// 恢复函数头
memcpy(MappedProc, RealProc, dwPatchSize);
VirtualProtect(MappedProc, dwPatchSize, dwOldProtect, &dwOldProtect);
// 释放分配的空间
VirtualFree(lpBuffer, 0, MEM_RELEASE);
#else
pMdlSystemCall = IoAllocateMdl(
OrgProc,
dwPatchSize,
0,
0,
NULL
);
if(!pMdlSystemCall)
return FALSE;
MmBuildMdlForNonPagedPool(pMdlSystemCall);
MappedProc = (LPBYTE)MmMapLockedPages(pMdlSystemCall, KernelMode);
memcpy(MappedProc, RealProc, dwPatchSize);
MmUnmapLockedPages(MappedProc, pMdlSystemCall);
IoFreeMdl(pMdlSystemCall);
ExFreePool(lpBuffer);
#endif
}
#endif // !defined(AFX_INLINEHOOK_H_INCLUDED)