想了中新的HOOK API的方法,不过仅仅用于NtXxxxxxx和XP平台:)
原理:
ZwQuerySystemInformation: ; NtQuerySystemInformation
.text:7C92E1AA mov eax, 0ADh ; RtlGetNativeSystemInformation
.text:7C92E1AF mov edx, 7FFE0300h ;7FFE0300h好象存着好东西
.text:7C92E1B4 call dword ptr [edx]
.text:7C92E1B6 retn 10h
ZwQuerySystemTime: ; NtQuerySystemTime
.text:7C92E1BF mov eax, 0AEh
.text:7C92E1C4 mov edx, 7FFE0300h ;又是这
.text:7C92E1C9 call dword ptr [edx]
.text:7C92E1CB retn 4
FT,eax肯定是功能号,7FFE0300处存着全部需要进入Ring0的都要调用的过程的地址
原来7FFE0300放着KiFastSystemCall的地址7C92EB8B:)
KiFastSystemCall:
.text:7C92EB8B mov edx, esp
.text:7C92EB8D sysenter
.text:7C92EB94 retn
然后就是找到你要HOOK的NtXxxx,把7FFE0300改掉,改成存放你的myNtXxxx入口的变量地址
BYTE GetNtApiEP(char* ntApiName)
{
HMODULE lib;
PBYTE destApiEP;
lib = GetModuleHandle("ntdll.dll");
destApiEP = (PBYTE)GetProcAddress(lib , ntApiName);
if(!destApiEP)
{
return FALSE;
}
return destApiEP;
}
BOOL MakeMemRWE(PVOID mem,int size)
{
DWORD oldProtect;
if(!VirtualProtect(mem , size,PAGE_EXECUTE_READWRITE,&oldProtect))
{
return FALSE;
}
return TRUE;
}
BOOL isNtApi(PBYTE ntApiEP)
{
if(*ntApiEP != 0xB8)
{
return FALSE;
}
return TRUE;
}
BOOL Change0x77FE3000(PBYTE ntApiEP,PVOID value)
{
if(!value) return FALSE;
ntApiEP+=6;
*(DWORD*)ntApiEP = value;
return TRUE;
}
BOOL _stdcall HookNtXxx(PVOID destApiEP,PVOID pMonitorFuncAddr)
{
MessageBox(0,"I'm Hooking!","Message",0);
if(!MakeMemRWE(destApiEP,0x1000)) return FALSE;
if(!isNtApi(destApiEP)) return FALSE;
if(!Change0x77FE3000(destApiEP,pMonitorFuncAddr)) return FALSE;
return TRUE;
}
BOOL _stdcall UnHookNtXxx(PVOID destApiEP)
{
if(!MakeMemRWE(destApiEP,0x1000)) return FALSE;
if(!isNtApi(destApiEP)) return FALSE;
if(!Change0x77FE3000(destApiEP,0x7FFE0300)) return FALSE;
return TRUE;
}