#include "nt_help.h"
#include "pe_image.h"
typedef NTSTATUS (NTAPI * PFN_RtlGetVersion)(OUT PRTL_OSVERSIONINFOW lpVersionInformation);
PVOID
GetSectionHeaderFreeSpace(
IN PVOID ModuleBase,
IN ULONG NeedSize,
IN OUT PULONG RetFreeSize
)
{
PIMAGE_DOS_HEADER imgModule = (PIMAGE_DOS_HEADER)ModuleBase;
PIMAGE_NT_HEADERS imgNtHeader = NULL;
PIMAGE_SECTION_HEADER imgSecHdr = NULL;
ULONG i;
ASSERT(ModuleBase && RetFreeSize);
imgNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)ModuleBase + imgModule->e_lfanew);
imgSecHdr = (PIMAGE_SECTION_HEADER)((PBYTE)imgNtHeader + 0x18 + imgNtHeader->FileHeader.SizeOfOptionalHeader);
/*
//获取PE头空隙
*RetFreeSize = (ULONG)ModuleBase + imgNtHeader->OptionalHeader.SectionAlignment -
(ULONG)(imgSecHdr + imgNtHeader->FileHeader.NumberOfSections);
return (PVOID)(imgSecHdr + imgNtHeader->FileHeader.NumberOfSections);
*/
for (i=0; i<imgNtHeader->FileHeader.NumberOfSections; i++, imgSecHdr++)
{
ULONG freeSize = imgSecHdr->SizeOfRawData - imgSecHdr->Misc.VirtualSize;
KdPrint(("free space at %s: %d free %d need\n", imgSecHdr->Name, freeSize, NeedSize));
if ((freeSize > 0) &&
(NeedSize <= freeSize) &&
(imgSecHdr->Characteristics & IMAGE_SCN_CNT_CODE))
{
KdPrint(("free space at %s:%08x %d free %d need\n", imgSecHdr->Name,
(PCHAR)ModuleBase + imgSecHdr->VirtualAddress + imgSecHdr->Misc.VirtualSize,
freeSize, NeedSize));
*RetFreeSize = freeSize;
return (PCHAR)ModuleBase + imgSecHdr->VirtualAddress + imgSecHdr->Misc.VirtualSize;
}
}
return NULL;
}
//
//通过搜索PE文件导出表,获取指定模块的函数地址
//注意返回EAT地址
PVOID
GetModuleFunction(
IN PVOID ModuleBase,
IN PUCHAR FunctionName,
IN ULONG Length
)
{
PIMAGE_DOS_HEADER imgModule = (PIMAGE_DOS_HEADER)ModuleBase;
PIMAGE_OPTIONAL_HEADER imgOptHeader = NULL;
PIMAGE_EXPORT_DIRECTORY imgExportDirectory = NULL;
PULONG arrayOfFunctionAddresses;
PULONG arrayOfFunctionNames;
WORD* arrayOfFunctionOrdinals;
ULONG i;
ASSERT(ModuleBase && FunctionName);//MZ
imgOptHeader = (PIMAGE_OPTIONAL_HEADER)((PBYTE)ModuleBase + imgModule->e_lfanew + 24);
imgExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((PBYTE)ModuleBase + imgOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
arrayOfFunctionAddresses = (PULONG)((PBYTE)ModuleBase + imgExportDirectory->AddressOfFunctions);
arrayOfFunctionNames = (PULONG)((PBYTE)ModuleBase + imgExportDirectory->AddressOfNames);
arrayOfFunctionOrdinals = (WORD*)((PBYTE)ModuleBase + imgExportDirectory->AddressOfNameOrdinals);
//AddressOfFunctions 函数偏移地址列表
//AddressOfNames 函数名的偏移地址列表
//AddressOfNameOrdinals 函数名对应AddressOfFunctions列表索引
for (i=0; i<imgExportDirectory->NumberOfNames; i++)
{
PCHAR name = (PCHAR)((PBYTE)ModuleBase + arrayOfFunctionNames[i]);
ULONG index = arrayOfFunctionOrdinals[i] + imgExportDirectory->Base - 1;
//KdPrint(("%s ? %s\n", name, FunctionName));
if (strncmp(name, FunctionName, Length) == 0)
{
return arrayOfFunctionAddresses + index;
//return (PVOID)((ULONG)ModuleBase + arrayOfFunctionAddresses[index]);
}
}
return NULL;
}
/*
* 枚举系统进程列表
* 返回值:枚举进程分配的内存首地址【由调用者ExFreePool】
*/
PVOID HelpQueryProcess(
IN PWCHAR ProcessName,
IN OUT PSYSTEM_PROCESS_INFORMATION* ProcessInfo
)
{
ULONG cbBuffer = 0x8000;
PSYSTEM_PROCESS_INFORMATION sysProcessList = NULL;
PVOID pBuffer = NULL;
NTSTATUS rc;
ASSERT(ProcessName && ProcessInfo);
for(;;) {
pBuffer = ExAllocatePoolWithTag(PagedPool, cbBuffer, 'hlpm'); // pBuffer为非分页内存
if (pBuffer == NULL)
return FALSE;
//
//注意测试表明NtQuerySystemInformation直接返回STATUS_ACCESS_VIOLATION,要使用ZwQuerySystemInformation
//
rc = ZwQuerySystemInformation(SystemProcessInformation, pBuffer, cbBuffer, NULL);
if ( rc == STATUS_INFO_LENGTH_MISMATCH){
ExFreePool(pBuffer); //缓冲区不足
cbBuffer *= 2; //直到有充足的缓冲区
continue;
}else if (NT_SUCCESS(rc))
break;
KdPrint(("ZwQuerySystemInformation failed %08x\n!", rc));
ExFreePool(pBuffer);
return FALSE;
}
sysProcessList = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
if (sysProcessList){
PSYSTEM_PROCESS_INFORMATION processItem = sysProcessList;
while (processItem->NextEntryDelta) {
processItem = (PSYSTEM_PROCESS_INFORMATION)((PBYTE)processItem + processItem->NextEntryDelta);
if (_wcsnicmp(ProcessName, processItem->ProcessName.Buffer, processItem->ProcessName.Length) == 0){
//KdPrint(("%wZ %d\n", &processItem->ProcessName, processItem->ProcessId));
*ProcessInfo = processItem;
return pBuffer;
}
}
ExFreePool(sysProcessList);
}
return NULL;
}
PPEB
GetCurrentProcessPeb()
{
PROCESS_BASIC_INFORMATION pbi;
NTSTATUS status;
PPEB result = NULL;
status = ZwQueryInformationProcess((HANDLE)-1, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL);
if (NT_SUCCESS(status)) {
result = pbi.PebBaseAddress;
}
return result;
}
PVOID
HelpGetProcAddress(
PVOID ModuleBase,
PCHAR pFunctionName)
{
PVOID pFunctionAddress = NULL;
ULONG size = 0, addr, max_name, max_func, i, ord;
PIMAGE_EXPORT_DIRECTORY exports;
PULONG functions, names;
PSHORT ordinals;
exports = (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(ModuleBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size);
addr = (ULONG)exports - (ULONG)ModuleBase;
functions = (PULONG)((ULONG)ModuleBase + exports->AddressOfFunctions);
ordinals = (PSHORT)((ULONG)ModuleBase + exports->AddressOfNameOrdinals);
names = (PULONG)((ULONG)ModuleBase + exports->AddressOfNames);
max_name = exports->NumberOfNames;
max_func = exports->NumberOfFunctions;
for (i = 0; i < max_name; i++) {
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)) {
pFunctionAddress = (PVOID)((PCHAR)ModuleBase + functions[ord]);
break;
}
}
}
return pFunctionAddress;
}
//
//通过NtQuerySystemInformation枚举系统模块列表
//
BOOLEAN
EnumSysModule(