typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY {
ULONG Unknown1;
ULONG Unknown2;
#ifdef _WIN64
ULONG Unknown3;
ULONG Unknown4;
#endif
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT NameLength;
USHORT LoadCount;
USHORT PathLength;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;
typedef struct _SYSTEM_MODULE_INFORMATION {
ULONG Count;
SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
PVOID KernelGetModuleBase(PCHAR pModuleName)
{
PVOID pModuleBase = NULL;
PULONG pSystemInfoBuffer = NULL;
__try
{
NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES;
ULONG SystemInfoBufferSize = 0;
status = ZwQuerySystemInformation(SystemModuleInfo, &SystemInfoBufferSize, 0, &SystemInfoBufferSize);
if (!SystemInfoBufferSize) return NULL;
pSystemInfoBuffer = (PULONG)ExAllocatePool(NonPagedPool, SystemInfoBufferSize*2);
if (!pSystemInfoBuffer) return NULL;
memset(pSystemInfoBuffer, 0, SystemInfoBufferSize*2);
status = ZwQuerySystemInformation(SystemModuleInfo, pSystemInfoBuffer, SystemInfoBufferSize*2, &SystemInfoBufferSize);
if (NT_SUCCESS(status))
{
PSYSTEM_MODULE_ENTRY pSysModuleEntry = ((PSYSTEM_MODULE_INFORMATION)(pSystemInfoBuffer))->Module;
ULONG i;
for (i = 0; i <((PSYSTEM_MODULE_INFORMATION)(pSystemInfoBuffer))->Count; i++)
{
if (_stricmp(pSysModuleEntry[i].ModuleName + pSysModuleEntry[i].ModuleNameOffset, pModuleName) == 0)
{
pModuleBase = pSysModuleEntry[i].ModuleBaseAddress;
break;
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
pModuleBase = NULL;
}
if(pSystemInfoBuffer) ExFreePool(pSystemInfoBuffer);
return pModuleBase;
} // end KernelGetModuleBase()
PVOID KernelGetProcAddress( PVOID ModuleBase, PCHAR pFunctionName )
{
PVOID pFunctionAddress = NULL;
__try
{
#ifndef WIN9X_SUPPORT
ULONG size = 0;
PIMAGE_EXPORT_DIRECTORY exports =(PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(ModuleBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size);
ULONG addr = (PUCHAR)((ULONG)exports-(ULONG)ModuleBase);
#else
PIMAGE_DOS_HEADER dos =(PIMAGE_DOS_HEADER) ModuleBase;
PIMAGE_NT_HEADERS nt =(PIMAGE_NT_HEADERS)((ULONG) ModuleBase + dos->e_lfanew);
PIMAGE_DATA_DIRECTORY expdir = (PIMAGE_DATA_DIRECTORY)(nt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT);
ULONG addr = expdir->VirtualAddress;
PIMAGE_EXPORT_DIRECTORY exports =(PIMAGE_EXPORT_DIRECTORY)((ULONG) ModuleBase + addr);
#endif
PULONG functions = (PULONG)((ULONG) ModuleBase + exports->AddressOfFunctions);
PSHORT ordinals = (PSHORT)((ULONG) ModuleBase + exports->AddressOfNameOrdinals);
PULONG names = (PULONG)((ULONG) ModuleBase + exports->AddressOfNames);
ULONG max_name = exports->NumberOfNames;
ULONG max_func = exports->NumberOfFunctions;
ULONG i;
for (i = 0; i < max_name; i++)
{
ULONG ord = ordinals[i];
if(i >= max_name || ord >= max_func) return NULL;
if (functions[ord] < addr || functions[ord] >= addr + size)
{
if (strcmp((PCHAR) ModuleBase + names[i], pFunctionName) == 0)
{
pFunctionAddress =(PVOID)((PCHAR) ModuleBase + functions[ord]);
break;
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
pFunctionAddress = NULL;
}
return pFunctionAddress;
} // end KernelGetProcAddress()