Hello, everyone, I meet a very strange problem, maybe some one will not believe my word:
If I delete a DbgPrint in code below, the function will not work.
"Not work" means this function cannot enumerate process modules, without any exceptions or BSOD. Why?
If I delete a DbgPrint in code below, the function will not work.
"Not work" means this function cannot enumerate process modules, without any exceptions or BSOD. Why?
Code: Select all
typedef enum _MEMORY_INFORMATION_CLASS
{
MemoryBasicInformation,
MemoryWorkingSetList,
MemorySectionName,
MemoryBasicVlmInformation
} MEMORY_INFORMATION_CLASS;
typedef struct _MEMORY_BASIC_INFORMATION {
PVOID BaseAddress;
PVOID AllocationBase;
DWORD AllocationProtect;
SIZE_T RegionSize;
DWORD State;
DWORD Protect;
DWORD Type;
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
typedef struct _MEMORY_SECTION_NAME // Information Class 2
{
UNICODE_STRING SectionFileName;
} MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME;
NTKERNELAPI NTSTATUS __fastcall ZwQueryVirtualMemory
(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
OUT PVOID MemoryInformation,
IN ULONG MemoryInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
VOID EnumModuleByQueryVM(PEPROCESS Process)
{
KAPC_STATE ks;
NTSTATUS Status=0;
HANDLE hProcess=(HANDLE)(-1);
PVOID MemBase=NULL;
SIZE_T MemSize=0;
MEMORY_BASIC_INFORMATION MemBasicInfo={0};
PMEMORY_SECTION_NAME MemSectionName=NULL;
ULONG MemSectionNameLength=0;
ULONG ReturnLength=0,i=0,PmCnt=0;
//Init data array
PmCnt=0;
memset(ModuleInfo2,0,512 * sizeof(MODULE_INFO));
//Enum modules
KeStackAttachProcess(Process, &ks);
__try
{
while (MemBase<(PVOID)0x7FFFFFFFFFFF)
{
//Query Basic Information
Status=ZwQueryVirtualMemory(hProcess,
MemBase,
MemoryBasicInformation,
&MemBasicInfo,
sizeof(MemBasicInfo),
&ReturnLength);
if (Status==0)
{
MemSize=MemBasicInfo.RegionSize;
//
//IF DELETE THIS DbgPrint, THIS FUNCTION CANNOT ENUMERATE PROCESS MODULES!!! WHY???
//
DbgPrint("BaseAddress:0x%p\tAllocationBase:0x%p\tAllocationProtect:0x%x\tRegionSize:0x%x\tState:0x%x\tProtect:0x%x\tType:0x%x\n",
MemBasicInfo.BaseAddress,
MemBasicInfo.AllocationBase,
MemBasicInfo.AllocationProtect,
MemBasicInfo.RegionSize,
MemBasicInfo.State,
MemBasicInfo.Protect,
MemBasicInfo.Type);
//Query Image Name
Status=ZwQueryVirtualMemory(hProcess,
MemBase,
MemorySectionName,
NULL,
0,
&ReturnLength);
MemSectionNameLength=ReturnLength;
MemSectionName=(PMEMORY_SECTION_NAME)kmalloc(MemSectionNameLength); //LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,MemSectionNameLength);
memset(MemSectionName,0,MemSectionNameLength);
MemSectionName->SectionFileName.Buffer=(PWCHAR)((PCHAR)MemSectionName + sizeof (MEMORY_SECTION_NAME));
MemSectionName->SectionFileName.MaximumLength=(USHORT)(MemSectionNameLength -sizeof sizeof (MEMORY_SECTION_NAME));
//
//IF DELETE DbgPrint ABOVE, THIS ZwQueryVirtualMemory WILL NEVER RETURN STATUS_SUCCESS
//
Status=ZwQueryVirtualMemory(hProcess,
MemBase,
MemorySectionName,
MemSectionName,
MemSectionNameLength,
&ReturnLength);
DbgPrint("ZwQueryVirtualMemory~MemorySectionName status: %x\n",Status);
if (NT_SUCCESS(Status))
{
PmCnt++;
DbgPrint("[QVM_EM]%p\t%wZ",MemBasicInfo.AllocationBase,&(MemSectionName->SectionFileName));
}
kfree(MemSectionName);
MemBase=(PCHAR)MemBase+MemSize;
}
else
{
DbgPrint("Enum memory finished: %x\tCount: %ld\n",Status,PmCnt);
break;
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("[QVM_EM]EXCEPTION_EXECUTE_HANDLER\n");
}
KeUnstackDetachProcess(&ks);
}