两种进程遍历方式

版权声明:本文为博主原创文章, 未经博主允许, 可随意转载. https://blog.csdn.net/cqu20124793/article/details/82590837

通过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;
}

note

通过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本质上也是这个方式:
1
2

猜你喜欢

转载自blog.csdn.net/cqu20124793/article/details/82590837