通过performance counter
病毒样本MD5: 642A393A5C65D202180DF5AF06F29C5A
#include <windows.h>
#include <stdio.h>
//通过HKEY_PERFORMANCE_DATA遍历进程. ----- 从nimda病毒中发现的这种方式.
//https://docs.microsoft.com/en-us/windows/desktop/perfctrs/using-the-registry-functions-to-consume-counter-data
int main()
{
BYTE data[0x40000] = { 0 };
DWORD cb = 0x40000, type = 0;;
RegQueryValueExA(HKEY_PERFORMANCE_DATA, "230 232", NULL, &type, data, &cb);
//
PPERF_DATA_BLOCK ppdb = (PPERF_DATA_BLOCK)data;
PPERF_OBJECT_TYPE ppbt = (PPERF_OBJECT_TYPE)((BYTE*)data + ppdb->HeaderLength);
int count_obj = 0;
while (ppbt->ObjectNameTitleIndex != 230) //process
{
ppbt = (PPERF_OBJECT_TYPE)(ppbt->TotalByteLength + (BYTE*)ppbt);
if (++count_obj >= ppdb->NumObjectTypes)
{
printf("error, no process objects found\n");
return 0;
}
}
PPERF_COUNTER_DEFINITION ppcd = (PPERF_COUNTER_DEFINITION)(ppbt->HeaderLength + (BYTE*)ppbt);
int count_counter = 0;
while (ppcd->CounterNameTitleIndex != 784) //pid
{
ppcd = (PPERF_COUNTER_DEFINITION)(ppcd->ByteLength + (BYTE*)ppcd);
if (++count_counter >= ppbt->NumCounters)
{
printf("error, no pid counter found\n");
return 0;
}
}
PERF_INSTANCE_DEFINITION *ppid = (PPERF_INSTANCE_DEFINITION)(ppbt->DefinitionLength + (BYTE*)ppbt);
int count_instance = 0;
while (ppid && ppid->ByteLength) //因为看了下ppbt->numofinstance是0, 不能用于作结尾标志,所以就这样了..
{
wprintf(L"%s %d\n", ppid->NameOffset + (BYTE*)ppid, *(DWORD*)(ppid->ByteLength + (BYTE*)ppid + ppcd->CounterOffset));
ppid = (PERF_INSTANCE_DEFINITION*)(*(DWORD*)(ppid->ByteLength + (BYTE*)ppid) + ppid->ByteLength + (BYTE*)ppid);
}
return 0;
}
通过ZwQuerySystemInformation
这个比较常见
#include <windows.h>
#include <stdio.h>
typedef NTSTATUS
(_stdcall *pfnZwQuerySystemInformation)(
int SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
ULONG *ReturnLength);
int main()
{
HMODULE hMod = LoadLibraryA("ntdll.dll");
pfnZwQuerySystemInformation ZwQuerySystemInformation = (pfnZwQuerySystemInformation)GetProcAddress(hMod, "ZwQuerySystemInformation");
BYTE *data = (BYTE*)VirtualAlloc(NULL,0x100000,0x3000,0x4);
DWORD cb = 0;
ZwQuerySystemInformation(5, data, 0x100000, &cb);
while (*(DWORD*)data)
{
wprintf(L"%s %d\n", *(DWORD*)(data + 0x3c), *(DWORD*)(data + 0x44));
data = (BYTE*)(data + *(DWORD*)data);
}
VirtualFree(data, 0x100000, 0x10000);
return 0;
}
Numeric Value | Symbolic Name |
---|---|
0x05 | SystemProcessInformation |
Offset(x86) | Offset(x64) | Definition |
---|---|---|
0x00 | 0x00 | ULONG NextEntryOffset |
0x38 | 0x38 | UNICODE_STRING ImageName |
0x44 | 0x50 | UniqueProcessId |
另外, 调用CreateToolhelp32Snapshot本质上也是这个方式: