📄 hookproc.c
字号:
*
* Returns:
* TRUE to indicate success, FALSE if failed.
*/
BOOLEAN
HookSystemServiceByName(PCHAR ServiceName, PULONG_PTR HookFunction)
{
int i;
for (i = 0; i < ZwCallsNumber; i++)
{
if (strlen(ServiceName) == ZwCalls[i].ZwNameLength && _stricmp(ServiceName, ZwCalls[i].ZwName + 2) == 0)
{
// LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_DEBUG, ("HookSystemServiceByName: Matched rule: %x\n", ZwCalls[i].ServiceIDNumber));
// hijack the syscall if not hijacked already
if (ZwCalls[i].Hijacked == FALSE && ZwCalls[i].ServiceIDNumber != -1)
{
if ((ZwCalls[i].OriginalFunction = HookSystemServiceByIndex(ZwCalls[i].ServiceIDNumber,
HookFunction ? HookFunction : ZwCalls[i].HookFunction)) != NULL)
{
ZwCalls[i].Hijacked = TRUE;
}
}
return TRUE;
}
}
return FALSE;
}
#if 0
/*
* FindSystemServiceIndex()
*
* Description:
* Find a system service index for a specified service name.
*
* Parameters:
* ServiceName - Name of a Zw* system service to find.
*
* Returns:
* System service index if found, -1 otherwise.
*/
ULONG
FindSystemServiceIndex(PCHAR ServiceName)
{
int i;
for (i = 0; i < ZwCallsNumber; i++)
{
if (strlen(ServiceName) == ZwCalls[i].ZwNameLength && _stricmp(ServiceName, ZwCalls[i].ZwName + 2) == 0)
{
// LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_DEBUG, ("FindSystemServiceByName: Matched rule: %x\n", ZwCalls[i].ServiceIDNumber));
return ZwCalls[i].ServiceIDNumber;
}
}
return -1;
}
#endif
/*
* FindSystemServiceNumber()
*
* Description:
* Find a system service number for a specified service name.
*
* Parameters:
* ServiceName - Name of a Zw* system service to find.
*
* Returns:
* System service number if found, -1 otherwise.
*/
ULONG
FindSystemServiceNumber(PCHAR ServiceName)
{
int i;
for (i = 0; i < ZwCallsNumber; i++)
{
if (strlen(ServiceName) == ZwCalls[i].ZwNameLength && _stricmp(ServiceName, ZwCalls[i].ZwName + 2) == 0)
{
// LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_DEBUG, ("FindSystemServiceByName: Matched rule: %x\n", ZwCalls[i].ServiceIDNumber));
return i;
}
}
return -1;
}
/*
* Find_NTDLL_Base()
*
* Description:
* Returns the base address of mapped ntdll.dll in a "System" process context.
*
* NOTE: Based on "Windows NT/2000 Native API Reference" implementation.
*
* Parameters:
* None.
*
* Returns:
* ntdll.dll base address (NULL if not found).
*/
PVOID
Find_NTDLL_Base()
{
ULONG size, i;
PVOID ntdll = NULL;
PULONG SystemInfo;
PSYSTEM_MODULE_INFORMATION pSMI;
NTSTATUS status;
/*
* The data returned to the SystemInformation buffer is a ULONG count of the number of
* modules followed immediately by an array of SYSTEM_MODULE_INFORMATION.
*
* The system modules are the Portable Executable (PE) format files loaded into the
* kernel address space (ntoskrnl.exe, hal.dll, device drivers, and so on) and ntdll.dll.
*/
/* first, find out the total amount of module information to be returned */
status = ZwQuerySystemInformation(SystemModuleInformation, &size, 0, &size);
if (size == 0 || size > 1024*1024)
{
LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_DEBUG, ("Find_NTDLL_Base: ZwQuerySystemInformation failed. status=%x size=%d\n", status, size));
return NULL;
}
/* second, allocate the required amount of memory */
SystemInfo = ExAllocatePoolWithTag(PagedPool, size + 4, _POOL_TAG);
if (SystemInfo == NULL)
{
LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_DEBUG, ("Find_NTDLL_Base: out of memory (requested %d bytes)\n", size + 4));
return NULL;
}
/* third, request the module information */
ZwQuerySystemInformation(SystemModuleInformation, SystemInfo, size, &i);
if (size != ((*SystemInfo * sizeof(SYSTEM_MODULE_INFORMATION)) + 4))
{
LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_DEBUG, ("Find_NTDLL_Base: inconsistent size (%d != %d * %d + 4)\n", size, *SystemInfo, sizeof(SYSTEM_MODULE_INFORMATION)));
return NULL;
}
pSMI = (PSYSTEM_MODULE_INFORMATION) (SystemInfo + 1);
for (i = 0; i < *SystemInfo; i++)
{
// LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_DEBUG, ("comparing '%s' (base 0x%x)\n", pSMI[i].ImageName + pSMI[i].ModuleNameOffset, pSMI[i].Base));
if (_stricmp(pSMI[i].ImageName + pSMI[i].ModuleNameOffset, "ntdll.dll") == 0)
{
LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_VERBOSE, ("Find_NTDLL_Base: ntdll.dll base address is %x\n", pSMI[i].Base));
ntdll = pSMI[i].Base;
break;
}
}
ExFreePoolWithTag(SystemInfo, _POOL_TAG);
return ntdll;
}
#if 0
PVOID
Find_Kernel32_Base2()
{
PVOID Kernel32 = NULL;
NTSTATUS status;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK isb;
HANDLE FileHandle;
UNICODE_STRING usName;
PVOID BaseAddress = NULL;
SIZE_T Size;
CHAR buffer[256];
// RtlInitUnicodeString(&usName, L"\\SystemRoot\\System32\\kernel32.dll");
RtlInitUnicodeString(&usName, L"\\??\\c:\\windows\\system32\\kernel32.dll");
InitializeObjectAttributes(&ObjectAttributes, &usName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
status = ZwCreateFile(&FileHandle, GENERIC_READ, &ObjectAttributes, &isb, NULL, 0, 0, 0, 0, NULL, 0);
if (!NT_SUCCESS(status))
{
LOG(LOG_SS_MISC, LOG_PRIORITY_DEBUG, ("Find_Kernel32_Base: Failed to open file %S (%x)\n", usName.Buffer, status));
return FALSE;
}
status = ZwReadFile(FileHandle, NULL, NULL, NULL, &isb, (PVOID) buffer, sizeof(buffer) - 1, 0, NULL);
if (! NT_SUCCESS(status))
{
if (status != STATUS_END_OF_FILE)
{
LOG(LOG_SS_POLICY, LOG_PRIORITY_DEBUG, ("LoadSecurityPolicy: ZwReadFile failed rc=%x\n", status));
}
}
ZwClose(FileHandle);
return Kernel32;
}
PVOID
Find_Kernel32_Base()
{
PVOID Kernel32 = NULL;
NTSTATUS status;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE SectionHandle;
UNICODE_STRING usName;
PVOID BaseAddress = NULL;
SIZE_T Size;
NTSTATUS q;
RtlInitUnicodeString(&usName, L"\\KnownDlls\\kernel32.dll");
InitializeObjectAttributes(&ObjectAttributes, &usName, OBJ_KERNEL_HANDLE, NULL, NULL);
if (NT_SUCCESS( ZwOpenSection(&SectionHandle, SECTION_MAP_READ, &ObjectAttributes) ))
{
q = ZwMapViewOfSection(SectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &Size, ViewShare, MEM_RESERVE, PAGE_READWRITE);
if (NT_SUCCESS(q))
{
KdPrint(("XXX mapped kernel32.dll at BaseAddress %x\n", BaseAddress));
if (!NT_SUCCESS( ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress) ))
{
KdPrint(("ZwUnmapViewOfSection failed"));
}
ZwClose(SectionHandle);
}
else
{
KdPrint(("ZwMapViewOfSection failed with status %x", q));
}
}
else
{
KdPrint(("ZwOpenSection failed"));
}
return Kernel32;
}
#endif
/*
* FindFunctionBase()
*
* Description:
* Finds the address where a function is mapped at.
*
* NOTE: Based on "Windows NT/2000 Native API Reference" implementation.
*
* Parameters:
* Base - Mapped address of a DLL exporting the function.
* Name - Function name.
*
* Returns:
* Address where a function is mapped at (NULL if not found).
*/
/* macro shortcut for bailing out of FindFunctionBase in case of an error */
#define ABORT_FindFunctionBase(msg) { \
LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_DEBUG, ("Error occured in FindFunctionBase():")); \
LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_DEBUG, msg); \
return NULL; \
}
PVOID
FindFunctionBase(PCHAR ImageBase, PCSTR Name)
{
PIMAGE_DOS_HEADER DosHeader;
PIMAGE_NT_HEADERS PeHeader;
PIMAGE_DATA_DIRECTORY ImageExportDirectoryEntry;
ULONG ExportDirectorySize, ExportDirectoryOffset, i;
PIMAGE_EXPORT_DIRECTORY ExportDirectory;
PULONG ExportAddressTable;
PSHORT ExportOrdinalTable;
PULONG ExportNameTable;
if ( (DosHeader = (PIMAGE_DOS_HEADER) ImageBase) == NULL)
ABORT_FindFunctionBase(("Base pointer is NULL (name = %s)\n", Name));
if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
ABORT_FindFunctionBase(("DOS Signature not found! (%x %x)\n", DosHeader, DosHeader->e_magic));
if (DosHeader->e_lfanew > 1024*1024)
ABORT_FindFunctionBase(("Invalid e_lfanew value %x\n", DosHeader->e_lfanew));
if ( (PeHeader = (PIMAGE_NT_HEADERS) (ImageBase + DosHeader->e_lfanew)) == NULL)
ABORT_FindFunctionBase(("NT header pointer is NULL (name = %s)\n", Name));
if (PeHeader->Signature != IMAGE_PE_SIGNATURE)
ABORT_FindFunctionBase(("PE Signature not found! (%x %x)\n", PeHeader, PeHeader->Signature));
if ( (ImageExportDirectoryEntry = PeHeader->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT) == NULL)
ABORT_FindFunctionBase(("Export directory pointer is NULL (name = %s)\n", Name));
ExportDirectorySize = ImageExportDirectoryEntry->Size;
ExportDirectoryOffset = ImageExportDirectoryEntry->VirtualAddress;
if ( (ExportDirectory = (PIMAGE_EXPORT_DIRECTORY) (ImageBase + ExportDirectoryOffset)) == NULL)
ABORT_FindFunctionBase(("Exports pointer is NULL (name = %s)\n", Name));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -