RE: API Hooking Differing across APIs? (NtQuerySystemInformation Hook) 09-26-2012, 11:08 PM
#11
I am on a 32 bit OS so I cannot be writing to a 64 bit process. My current OS is Windows 7 Professional 32-bit. And I am not sure. I just recently started using VC++. I will look more into it. Here is the full DLL source code
Code:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#define STATUS_SUCCESS (NTSTATUS)0x000000000L
typedef struct __SYSTEM_PROCESS_INFORMATION
{
ULONG NextEntryOffset;
ULONG NumThreads;
LARGE_INTEGER Reserved[3];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
ULONG BasePriority;
HANDLE ProcessId;
HANDLE InheritedFromProcessId;
} __SYSTEM_PROCESS_INFORMATION,*__PSYSTEM_PROCESS_INFORMATION;
typedef NTSTATUS (WINAPI* NTQSI_Type)(__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
__inout PVOID SystemInformation,
__in ULONG SystemInformationLength,
__out_opt PULONG ReturnLength);
NTQSI_Type oNtQuerySystemInformation;
_declspec(dllexport) NTSTATUS WINAPI hNtQuerySystemInformation(__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
__inout PVOID SystemInformation,
__in ULONG SystemInformationLength,
__out_opt PULONG ReturnLength)
{
NTSTATUS status = oNtQuerySystemInformation(SystemInformationClass,SystemInformation,SystemInformationLength,ReturnLength);
if (SystemInformationClass == SystemProcessInformation && status == STATUS_SUCCESS)
{
__PSYSTEM_PROCESS_INFORMATION piCur = NULL;
__PSYSTEM_PROCESS_INFORMATION piNext = (__PSYSTEM_PROCESS_INFORMATION)SystemInformation;
do
{
piCur = piNext;
piNext = (__PSYSTEM_PROCESS_INFORMATION)SystemInformation;
if (!wcsncmp(piNext->ImageName.Buffer, L"chrome.exe", piNext->ImageName.Length))
{
if (piNext->NextEntryOffset == 0)
piCur->NextEntryOffset = 0;
else
piCur->NextEntryOffset += piNext->NextEntryOffset;
piNext = piCur;
}
}
while(piCur->NextEntryOffset != 0);
}
return status;
}
_declspec(dllexport) DWORD WINAPI Hook(LPVOID);
_declspec(dllexport) void Unhook();
BYTE oldBytes[5] = {0};
BYTE JMP[5] = {0};
DWORD oldProtect;
_declspec(dllexport) DWORD WINAPI Hook(LPVOID func)
{
oNtQuerySystemInformation = (NTQSI_Type)GetProcAddress(GetModuleHandle(L"ntdll.dll"),"NtQuerySystemInformation");
if (oNtQuerySystemInformation != NULL)
{
MessageBox(NULL,L"Correct",L"",MB_OK);
BYTE tmpJMP[5] = {0xE9,0x90,0x90,0x90,0x90}; //jmp,A,D,D,R
memcpy(JMP,tmpJMP,5);
if (VirtualProtect((LPVOID)oNtQuerySystemInformation,5,PAGE_EXECUTE_READWRITE,&oldProtect) == FALSE)
MessageBox(NULL,L"Error unprotecting memory",L"",MB_OK);
DWORD Addr = (DWORD)func - (DWORD)oNtQuerySystemInformation - 5;
for (int i=0;i<4;++i)
JMP[i+1] = ((BYTE*)&Addr)[i];
memcpy(oldBytes,(LPVOID)oNtQuerySystemInformation,5);
if (!WriteProcessMemory(GetCurrentProcess(),(LPVOID)oNtQuerySystemInformation,(LPCVOID)JMP,5,NULL))
MessageBox(NULL,L"Unable to write to process memory space",L"",MB_OK);
VirtualProtect((LPVOID)oNtQuerySystemInformation,5,oldProtect,NULL);
FlushInstructionCache(GetCurrentProcess(),NULL,NULL);
return 0;
}
return 1;
}
_declspec(dllexport) void Unhook()
{
memcpy((LPVOID)oNtQuerySystemInformation,oldBytes,5);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
Hook(&hNtQuerySystemInformation);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
Unhook();
break;
}
return TRUE;
}