第一次课(反馈,未讲评)

目标服务和目标进程

是两个概念,在计算机领域中有着不同的含义和用法。

目标服务(Target Service)指的是在分布式系统或网络中提供特定功能或服务的软件组件或模块。它通常以独立的方式运行,通过接收请求并提供相应的功能来满足服务需求。例如,Web服务器、数据库服务器、文件服务器等都可以被视为目标服务。

目标进程(Target Process)则是指操作系统中正在执行或运行的一个程序实例。进程是程序的执行实体,它负责分配和管理系统资源,并按照指令执行程序的逻辑。每个进程都有唯一的标识符(PID)和相关的资源集。一个进程可以包含多个线程,每个线程负责执行进程中的一部分工作。

因此,目标服务强调的是提供特定的功能和服务,而目标进程则关注的是程序的执行实体和资源管理。在某些情况下,一个目标服务可能由多个目标进程组成,这取决于实现的方式和要求。

作用:

1. CreateToolhelp32Snapshot(tlhelp32.h) :

该函数用于创建进程快照。它会创建当前系统中所有进程的快照,并返回一个句柄,可以用于后续的遍历操作。

cpp 复制代码
HANDLE CreateToolhelp32Snapshot(
  [in] DWORD dwFlags,
  [in] DWORD th32ProcessID
);




2. Process32First:

该函数用于从进程快照中获取第一个进程的信息。它接受一个进程快照句柄和一个进程信息结构体作为参数,并将第一个进程的信息填充到结构体中。

cpp 复制代码
BOOL Process32First(
  [in]      HANDLE           hSnapshot,
  [in, out] LPPROCESSENTRY32 lppe
);


PROCESSENTRY32

PROCESSENTRY32是Windows操作系统中的一个数据结构,用于描述进程的信息。它是在使用Toolhelp32快照函数获取进程快照时使用的数据结构。

PROCESSENTRY32结构定义如下:

c 复制代码
typedef struct tagPROCESSENTRY32 {
  DWORD     dwSize;
  DWORD     cntUsage;
  DWORD     th32ProcessID;
  ULONG_PTR th32DefaultHeapID;
  DWORD     th32ModuleID;
  DWORD     cntThreads;
  DWORD     th32ParentProcessID;
  LONG      pcPriClassBase;
  DWORD     dwFlags;
  TCHAR     szExeFile[MAX_PATH];
} PROCESSENTRY32;

这个结构包含了进程的各种信息,包括进程ID、父进程ID、线程计数、进程优先级等。其中,一些重要的成员包括:

  • dwSize:结构的大小。
  • th32ProcessID:进程的唯一标识符,用于在系统中唯一标识一个进程。
  • th32ParentProcessID:父进程的ID,用于表示该进程的父进程。
  • cntThreads:线程数量,表示进程中的线程数。
  • szExeFile:进程的可执行文件名。

通过使用Toolhelp32快照函数(如CreateToolhelp32Snapshot函数)获取进程快照,可以获得进程列表及其相关信息。使用PROCESSENTRY32结构可以逐个遍历进程列表,并获取每个进程的详细信息,以便进行进程管理、监控、调试等相关操作。

3. Process32Next:

该函数用于从进程快照中获取下一个进程的信息。它接受一个进程快照句柄和一个进程信息结构体作为参数,并将下一个进程的信息填充到结构体中。需要在调用 Process32First 后使用。

cpp 复制代码
BOOL Module32Next(
  [in]  HANDLE          hSnapshot,
  [out] LPMODULEENTRY32 lpme
);


LPMODULEENTRY32

LPMODULEENTRY32是Windows操作系统中的一个指向MODULEENTRY32结构类型的指针。MODULEENTRY32结构用于描述进程中的模块(DLL文件)的信息。

MODULEENTRY32结构定义如下:

c 复制代码
typedef struct tagMODULEENTRY32 {
  DWORD   dwSize;
  DWORD   th32ModuleID;
  DWORD   th32ProcessID;
  DWORD   GlblcntUsage;
  DWORD   ProccntUsage;
  BYTE    *modBaseAddr;
  DWORD   modBaseSize;
  HMODULE hModule;
  TCHAR   szModule[MAX_MODULE_NAME32 + 1];
  TCHAR   szExePath[MAX_PATH];
} MODULEENTRY32;

这个结构包含了模块的各种信息,包括模块在进程中的内存基地址、模块的大小、文件名以及文件路径等。其中,一些重要的成员包括:

  • dwSize:结构的大小。
  • th32ModuleID:模块的唯一标识符。
  • th32ProcessID:所属进程的ID。
  • modBaseAddr:模块在进程中的起始地址。
  • modBaseSize:模块的大小。
  • szModule:模块的名称。
  • szExePath:模块所在的文件路径。

通过使用Toolhelp32快照函数(如CreateToolhelp32Snapshot函数)获取进程快照,可以获得进程中加载的模块列表及其相关信息。使用LPMODULEENTRY32指针可以遍历模块列表,并获取每个模块的详细信息,如模块的地址、大小、名称等,以便进行模块分析、调试等相关操作。

4. EnumProcesses:

该函数用于获取当前系统中所有进程的ID列表。它接受一个进程ID数组和数组大小作为参数,并将进程ID填充到数组中。这个函数可以用来获取进程列表,但相比于前面三个API,它没有提供详细的进程信息。

这些API可以帮助开发人员遍历系统中的进程,获取进程的信息,以便进行进程管理、状态监控和其他相关操作。

cpp 复制代码
BOOL EnumProcesses(
  [out] DWORD   *lpidProcess,
  [in]  DWORD   cb,
  [out] LPDWORD lpcbNeeded
);


1. OpenSCManagerW:

  • 作用:打开服务控制管理器数据库,并返回一个句柄(SC_HANDLE)。这个句柄可以用于后续的操作,如创建、打开、关闭服务等。lpMachineName参数用于指定远程计算机名,若为NULL则表示本地计算机。lpDatabaseName参数用于指定服务控制管理器数据库的名称,默认为"Services"。
cpp 复制代码
SC_HANDLE OpenSCManagerW(
  [in, optional] LPCWSTR lpMachineName,
  [in, optional] LPCWSTR lpDatabaseName,
  [in]           DWORD   dwDesiredAccess
);


SERVICES_ACTIVE_DATABASE数据库

"SERVICES_ACTIVE_DATABASE"是Windows操作系统中的一个默认的服务控制管理器数据库名称。服务控制管理器(Service Control Manager)是Windows系统中负责管理系统服务的组件。

服务控制管理器数据库存储了系统中所有注册的服务的配置信息,包括服务的名称、描述、依赖关系、启动类型、二进制路径等。这个数据库作为服务控制管理器的核心部分,负责记录和管理系统中运行的服务。

"SERVICES_ACTIVE_DATABASE"是一个特定的标识符,用于表示系统当前正在运行的服务数据库。在调用OpenSCManager函数时,可以将这个标识符作为lpDatabaseName参数的值,以打开管理当前活动数据库的服务控制管理器。

需要注意的是,"SERVICES_ACTIVE_DATABASE"是Windows操作系统提供的默认数据库名称,用于表示当前活动的服务配置。在一些特殊情况下,例如使用数据库复制或移动服务配置时,可能会使用其他自定义的服务控制管理器数据库。

2. EnumServicesStatusExA:

  • 作用:枚举指定服务控制管理器数据库中满足指定条件的服务。hSCManager参数是调用OpenSCManager函数返回的句柄。dwInfoLevel参数指定返回的服务信息的详细程度。dwServiceType和dwServiceState参数用于指定服务类型和服务状态的过滤条件。lpServices参数接收枚举结果,cbBufSize表示接收缓冲区的大小,pcbBytesNeeded返回需要的缓冲区大小,lpServicesReturned返回实际枚举的服务数量,lpResumeHandle是用于继续枚举的句柄,pszGroupName是可选的服务组名。
cpp 复制代码
BOOL EnumServicesStatusExA(
  [in]                SC_HANDLE    hSCManager,
  [in]                SC_ENUM_TYPE InfoLevel,
  [in]                DWORD        dwServiceType,
  [in]                DWORD        dwServiceState,
  [out, optional]     LPBYTE       lpServices,
  [in]                DWORD        cbBufSize,
  [out]               LPDWORD      pcbBytesNeeded,
  [out]               LPDWORD      lpServicesReturned,
  [in, out, optional] LPDWORD      lpResumeHandle,
  [in, optional]      LPCSTR       pszGroupName
);



3. EnumServicesStatusExW:

  • 作用:与EnumServicesStatusExA函数相似,不同之处在于接受的参数和返回的结果都是宽字符字符串(Unicode)。

这些API函数提供了一些基本的服务管理操作,如打开服务控制管理器数据库、枚举服务列表等。通过使用这些函数,开发人员可以对Windows系统中的服务进行查询、操作和管理,以实现对服务的配置、监控和控制等功能。

cpp 复制代码
BOOL EnumServicesStatusExW(
  [in]                SC_HANDLE    hSCManager,
  [in]                SC_ENUM_TYPE InfoLevel,
  [in]                DWORD        dwServiceType,
  [in]                DWORD        dwServiceState,
  [out, optional]     LPBYTE       lpServices,
  [in]                DWORD        cbBufSize,
  [out]               LPDWORD      pcbBytesNeeded,
  [out]               LPDWORD      lpServicesReturned,
  [in, out, optional] LPDWORD      lpResumeHandle,
  [in, optional]      LPCWSTR      pszGroupName
);




这三个API函数都是Windows操作系统提供的用于处理模块(DLL文件)的函数。它们的作用如下:

1. Module32First:

  • 作用:从指定进程快照中获取第一个模块的信息,并存储在提供的MODULEENTRY32结构中。参数hSnapshot是通过CreateToolhelp32Snapshot函数创建的进程快照句柄,lpme是指向MODULEENTRY32结构的指针,用于存储第一个模块的信息。
cpp 复制代码
BOOL Module32First(
  [in]      HANDLE          hSnapshot,
  [in, out] LPMODULEENTRY32 lpme
);

MODULEENTRY32

cpp 复制代码
typedef struct tagMODULEENTRY32 {
  DWORD   dwSize;                   // 结构体大小
  DWORD   th32ModuleID;             // 模块ID
  DWORD   th32ProcessID;            // 进程ID
  DWORD   GlblcntUsage;             // 全局引用计数
  DWORD   ProccntUsage;             // 进程引用计数
  BYTE*   modBaseAddr;              // 模块基地址
  DWORD   modBaseSize;              // 模块大小
  HMODULE hModule;                  // 模块句柄
  TCHAR   szModule[MAX_MODULE_NAME32 + 1];   // 模块名称
  TCHAR   szExePath[MAX_PATH];                // 模块路径
} MODULEENTRY32;

MODULEENTRY32是Windows API中定义的一个结构体,用于存储模块(DLL文件)的相关信息

MODULEENTRY32结构体用于存储模块的相关信息,包括模块的ID、进程ID、全局引用计数、进程引用计数等。它还包含模块的基地址、大小、句柄、名称和路径等信息。

在使用Module32First和Module32Next函数获取模块信息时,可以通过提供一个指向MODULEENTRY32结构体的指针,将获取到的模块信息存储在该结构体中。可以通过访问结构体的成员来获取模块的各个属性,如模块的基地址、大小、名称和路径等。

请注意,为了正确使用这两个函数获取模块信息,需要首先初始化MODULEENTRY32结构体的dwSize成员,将其设为结构体的大小。这是因为操作系统会根据结构体的大小来判断传递的结构体是哪个版本,从而填充相应的数据。

2. Module32Next:

  • 作用:在指定进程快照中获取下一个模块的信息,并存储在提供的MODULEENTRY32结构中。该函数需要与Module32First函数结合使用,以遍历进程的模块列表。
cpp 复制代码
BOOL Module32Next(
  [in]  HANDLE          hSnapshot,
  [out] LPMODULEENTRY32 lpme
);


3. EnumProcessModules:

  • 作用:枚举指定进程中的所有模块。hProcess参数为目标进程的句柄,lphModule参数为输出,存储返回的模块句柄数组,cb参数指定模块句柄数组的大小,lpcbNeeded参数返回实际需要的模块句柄数组大小。

这些API函数提供了一些基本的模块处理操作,如获取进程的模块信息、遍历模块列表等。通过使用这些函数,开发人员可以获取进程加载的模块信息,包括模块的基地址、大小、文件名等。这对于进行模块分析、调试和安全监控等操作非常有用。

cpp 复制代码
BOOL EnumProcessModules(
  [in]  HANDLE  hProcess,
  [out] HMODULE *lphModule,
  [in]  DWORD   cb,
  [out] LPDWORD lpcbNeeded
);



使用WMIC 命令 实现当前系统进程信息遍历 使用WMIC 命令 实现枚举当前系统服务信息遍历

使用WMIC命令可以方便地遍历当前系统的进程信息和服务信息。以下是通过WMIC命令实现当前系统进程信息遍历和枚举当前系统服务信息的示例:

遍历当前系统进程信息:

cpp 复制代码
wmic process get Name, ProcessId, ParentProcessId

这个命令将返回当前系统中所有进程的名称(Name)、进程ID(ProcessId)和命令行参数(CommandLine)信息。

枚举当前系统服务信息:

cpp 复制代码
wmic service get Name, State

这个命令将返回当前系统中所有服务的名称(Name)、显示名称(DisplayName)和状态(State)信息。

解题代码:

微软给的样本

代码

cpp 复制代码
#include <windows.h>
#include <tlhelp32.h>
#include <tchar.h>
#include <psapi.h>
#include <stdio.h>

void PrintProcessNameAndID(DWORD processID)
{
    TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");

    // Get a handle to the process.

    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
        PROCESS_VM_READ,
        FALSE, processID);

    // Get the process name.

    if (NULL != hProcess)
    {
        HMODULE hMod;
        DWORD cbNeeded;

        if (EnumProcessModules(hProcess, &hMod, sizeof(hMod),
            &cbNeeded))
        {
            GetModuleBaseName(hProcess, hMod, szProcessName,
                sizeof(szProcessName) / sizeof(TCHAR));
        }
    }

    // Print the process name and identifier.

    _tprintf(TEXT("%s  (PID: %u)\n"), szProcessName, processID);

    // Release the handle to the process.

    CloseHandle(hProcess);
}
//  Forward declarations:
BOOL GetProcessList();
BOOL ListProcessModules(DWORD dwPID);
BOOL ListProcessThreads(DWORD dwOwnerPID);
void printError(const TCHAR* msg);

int main(void)
{
    GetProcessList();
    // Get the list of process identifiers.

    DWORD aProcesses[1024], cbNeeded, cProcesses;
    unsigned int i;

    if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
    {
        return 1;
    }


    // Calculate how many process identifiers were returned.

    cProcesses = cbNeeded / sizeof(DWORD);

    // Print the name and process identifier for each process.

    for (i = 0; i < cProcesses; i++)
    {
        if (aProcesses[i] != 0)
        {
            PrintProcessNameAndID(aProcesses[i]);
        }
    }

    return 0;
}

BOOL GetProcessList()
{
    HANDLE hProcessSnap;
    HANDLE hProcess;
    PROCESSENTRY32 pe32;
    DWORD dwPriorityClass;

    // Take a snapshot of all processes in the system.
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE)
    {
        printError(TEXT("CreateToolhelp32Snapshot (of processes)"));
        return(FALSE);
    }

    // Set the size of the structure before using it.
    pe32.dwSize = sizeof(PROCESSENTRY32);

    // Retrieve information about the first process,
    // and exit if unsuccessful
    if (!Process32First(hProcessSnap, &pe32))
    {
        printError(TEXT("Process32First")); // show cause of failure
        CloseHandle(hProcessSnap);          // clean the snapshot object
        return(FALSE);
    }

    // Now walk the snapshot of processes, and
    // display information about each process in turn
    do
    {
        _tprintf(TEXT("\n\n====================================================="));
        _tprintf(TEXT("\nPROCESS NAME:  %s"), pe32.szExeFile);
        _tprintf(TEXT("\n-------------------------------------------------------"));

        // Retrieve the priority class.
        dwPriorityClass = 0;
        hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
        if (hProcess == NULL)
            printError(TEXT("OpenProcess"));
        else
        {
            dwPriorityClass = GetPriorityClass(hProcess);
            if (!dwPriorityClass)
                printError(TEXT("GetPriorityClass"));
            CloseHandle(hProcess);
        }

        _tprintf(TEXT("\n  Process ID        = 0x%08X"), pe32.th32ProcessID);
        _tprintf(TEXT("\n  Thread count      = %d"), pe32.cntThreads);
        _tprintf(TEXT("\n  Parent process ID = 0x%08X"), pe32.th32ParentProcessID);
        _tprintf(TEXT("\n  Priority base     = %d"), pe32.pcPriClassBase);
        if (dwPriorityClass)
            _tprintf(TEXT("\n  Priority class    = %d"), dwPriorityClass);

        // List the modules and threads associated with this process
        ListProcessModules(pe32.th32ProcessID);
        ListProcessThreads(pe32.th32ProcessID);

    } while (Process32Next(hProcessSnap, &pe32));

    CloseHandle(hProcessSnap);
    return(TRUE);
}


BOOL ListProcessModules(DWORD dwPID)
{
    HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
    MODULEENTRY32 me32;

    // Take a snapshot of all modules in the specified process.
    hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
    if (hModuleSnap == INVALID_HANDLE_VALUE)
    {
        printError(TEXT("CreateToolhelp32Snapshot (of modules)"));
        return(FALSE);
    }

    // Set the size of the structure before using it.
    me32.dwSize = sizeof(MODULEENTRY32);

    // Retrieve information about the first module,
    // and exit if unsuccessful
    if (!Module32First(hModuleSnap, &me32))
    {
        printError(TEXT("Module32First"));  // show cause of failure
        CloseHandle(hModuleSnap);           // clean the snapshot object
        return(FALSE);
    }

    // Now walk the module list of the process,
    // and display information about each module
    do
    {
        _tprintf(TEXT("\n\n     MODULE NAME:     %s"), me32.szModule);
        _tprintf(TEXT("\n     Executable     = %s"), me32.szExePath);
        _tprintf(TEXT("\n     Process ID     = 0x%08X"), me32.th32ProcessID);
        _tprintf(TEXT("\n     Ref count (g)  = 0x%04X"), me32.GlblcntUsage);
        _tprintf(TEXT("\n     Ref count (p)  = 0x%04X"), me32.ProccntUsage);
        _tprintf(TEXT("\n     Base address   = 0x%08X"), (DWORD)me32.modBaseAddr);
        _tprintf(TEXT("\n     Base size      = %d"), me32.modBaseSize);

    } while (Module32Next(hModuleSnap, &me32));

    CloseHandle(hModuleSnap);
    return(TRUE);
}

BOOL ListProcessThreads(DWORD dwOwnerPID)
{
    HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
    THREADENTRY32 te32;

    // Take a snapshot of all running threads  
    hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    if (hThreadSnap == INVALID_HANDLE_VALUE)
        return(FALSE);

    // Fill in the size of the structure before using it. 
    te32.dwSize = sizeof(THREADENTRY32);

    // Retrieve information about the first thread,
    // and exit if unsuccessful
    if (!Thread32First(hThreadSnap, &te32))
    {
        printError(TEXT("Thread32First")); // show cause of failure
        CloseHandle(hThreadSnap);          // clean the snapshot object
        return(FALSE);
    }

    // Now walk the thread list of the system,
    // and display information about each thread
    // associated with the specified process
    do
    {
        if (te32.th32OwnerProcessID == dwOwnerPID)
        {
            _tprintf(TEXT("\n\n     THREAD ID      = 0x%08X"), te32.th32ThreadID);
            _tprintf(TEXT("\n     Base priority  = %d"), te32.tpBasePri);
            _tprintf(TEXT("\n     Delta priority = %d"), te32.tpDeltaPri);
            _tprintf(TEXT("\n"));
        }
    } while (Thread32Next(hThreadSnap, &te32));

    CloseHandle(hThreadSnap);
    return(TRUE);
}

void printError(const TCHAR* msg)
{
    DWORD eNum;
    TCHAR sysMsg[256];
    TCHAR* p;

    eNum = GetLastError();
    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL, eNum,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        sysMsg, 256, NULL);

    // Trim the end of the line and terminate it with a null
    p = sysMsg;
    while ((*p > 31) || (*p == 9))
        ++p;
    do { *p-- = 0; } while ((p >= sysMsg) &&
        ((*p == '.') || (*p < 33)));

    // Display the message
    _tprintf(TEXT("\n  WARNING: %s failed with error %d (%s)"), msg, eNum, sysMsg);
}

然后第二个版本的

cpp 复制代码
#include <Windows.h>
#include <TlHelp32.h>
#include <stdio.h>
#include <psapi.h>
#include <tchar.h>
#include <stdio.h>

// 获取指定进程的模块信息
void EnumerateProcessModules(DWORD processID) {
    HANDLE hProcess;
    MODULEENTRY32 me32;

    // 获取进程句柄
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
    if (hProcess == NULL) {
        printf("打开进程失败\n");
        return;
    }

    // 创建模块快照
    HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, processID);
    if (hModuleSnap == INVALID_HANDLE_VALUE) {
        printf("创建模块快照失败\n");
        CloseHandle(hProcess);
        return;
    }

    // 设置结构体大小并初始化
    me32.dwSize = sizeof(MODULEENTRY32);

    // 获取第一个模块信息
    if (Module32First(hModuleSnap, &me32)) {
        do {
            printf("模块路径:%ls\n", me32.szExePath);
        } while (Module32Next(hModuleSnap, &me32));
    }

    // 关闭模块快照句柄
    CloseHandle(hModuleSnap);

    // 关闭进程句柄
    CloseHandle(hProcess);
}
// 枚举系统服务
void EnumerateServices() {
    // 打开服务控制管理器
    SC_HANDLE hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
    if (hSCManager == NULL) {
        printf("打开服务控制管理器失败\n");
        return;
    }

    // 枚举服务状态
    DWORD dwBufferSize = 0;
    DWORD dwNumberOfServices = 0;
    DWORD dwResumeHandle = 0;
    DWORD dwBytesNeeded = 0;
    EnumServicesStatusExW(hSCManager, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &dwBytesNeeded,
        &dwNumberOfServices, &dwResumeHandle, NULL);
    if (GetLastError() != ERROR_MORE_DATA) {
        printf("获取服务状态失败\n");
        CloseServiceHandle(hSCManager);
        return;
    }

    dwBufferSize = dwBytesNeeded;
    LPENUM_SERVICE_STATUS_PROCESSW lpServices = (LPENUM_SERVICE_STATUS_PROCESSW)LocalAlloc(LPTR, dwBufferSize);
    if (!lpServices) {
        printf("内存分配失败\n");
        CloseServiceHandle(hSCManager);
        return;
    }

    if (!EnumServicesStatusExW(hSCManager, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL,
        (LPBYTE)lpServices, dwBufferSize, &dwBytesNeeded, &dwNumberOfServices, &dwResumeHandle, NULL)) {
        printf("获取服务状态失败\n");
        LocalFree(lpServices);
        CloseServiceHandle(hSCManager);
        return;
    }

    // 输出服务信息
    printf("服务列表:\n");
    for (DWORD i = 0; i < dwNumberOfServices; i++) {
        printf("服务名称:%ls\n", lpServices[i].lpServiceName);
        printf("服务状态:%u\n", lpServices[i].ServiceStatusProcess.dwCurrentState);
        printf("\n");
    }

    // 释放内存和关闭句柄
    LocalFree(lpServices);
    CloseServiceHandle(hSCManager);
}


int main() {
    HANDLE hSnapshot;
    PROCESSENTRY32 pe32;

    // 创建进程快照
    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        printf("创建进程快照失败\n");
        return 1;
    }

    // 设置结构体大小并初始化
    pe32.dwSize = sizeof(PROCESSENTRY32);

    // 获取第一个进程信息
    if (!Process32First(hSnapshot, &pe32)) {
        CloseHandle(hSnapshot);
        printf("获取第一个进程信息失败\n");
        return 1;
    }

    // 遍历进程并输出信息
    printf("进程列表:\n");
    do {
        printf("进程ID:%u,父进程ID:%u,进程名称:%ws\n",
            pe32.th32ProcessID, pe32.th32ParentProcessID, pe32.szExeFile);

        // 获取进程的模块信息
        EnumerateProcessModules(pe32.th32ProcessID);

        printf("\n");
    } while (Process32Next(hSnapshot, &pe32));

    // 关闭进程快照句柄
    CloseHandle(hSnapshot);

    // 枚举服务
    EnumerateServices();

    return 0;
}

最后版本

cpp 复制代码
#include <Windows.h>
#include <TlHelp32.h>
#include <stdio.h>
#include <psapi.h>
#include <tchar.h>
#include <stdio.h>
#include <winsvc.h>
#include <string>

// 检测进程是否正在运行
bool IsProcessRunning(const std::wstring& processName) {
    HANDLE hProcess;
    // 创建进程快照
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        return false;
    }

    // 遍历进程快照,查找目标进程
    PROCESSENTRY32W pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32W);
    MODULEENTRY32 me32;
    if (Process32First(hSnapshot, &pe32)) {
        do {
            if (_wcsicmp(pe32.szExeFile, processName.c_str()) == 0) {
                // 目标进程找到
                CloseHandle(hSnapshot);
                return true;
            }
        } while (Process32Next(hSnapshot, &pe32));
    }

    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, 0);
    if (hProcess == NULL) {
        printf("打开进程失败\n");
        return false;
    }
    HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32,0);
    if (hModuleSnap == INVALID_HANDLE_VALUE) {
        printf("创建模块快照失败\n");
        CloseHandle(hProcess);
        return false;
    }

    // 设置结构体大小并初始化
    me32.dwSize = sizeof(MODULEENTRY32);

    // 获取第一个模块信息
    if (Module32First(hModuleSnap, &me32)) {
        do {
            printf("模块路径:%ls\n", me32.szExePath);
        } while (Module32Next(hModuleSnap, &me32));
    }

    // 关闭模块快照句柄
    CloseHandle(hModuleSnap);

    // 目标进程未找到
    CloseHandle(hSnapshot);
    return false;
}

// 检测服务是否正在运行
bool IsServiceRunning(const std::wstring& serviceName) {
    // 打开服务控制管理器
    SC_HANDLE hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
    if (hSCManager == NULL) {
        return false;
    }

    // 枚举服务状态
    DWORD dwBufferSize = 0;
    DWORD dwNumberOfServices = 0;
    DWORD dwResumeHandle = 0;
    DWORD dwBytesNeeded = 0;
    EnumServicesStatusExW(hSCManager, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &dwBytesNeeded,
        &dwNumberOfServices, &dwResumeHandle, NULL);
    if (GetLastError() != ERROR_MORE_DATA) {
        CloseServiceHandle(hSCManager);
        return false;
    }

    dwBufferSize = dwBytesNeeded;
    LPENUM_SERVICE_STATUS_PROCESSW lpServices = (LPENUM_SERVICE_STATUS_PROCESSW)LocalAlloc(LPTR, dwBufferSize);
    if (!lpServices) {
        CloseServiceHandle(hSCManager);
        return false;
    }

    if (!EnumServicesStatusExW(hSCManager, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL,
        (LPBYTE)lpServices, dwBufferSize, &dwBytesNeeded, &dwNumberOfServices, &dwResumeHandle, NULL)) {
        LocalFree(lpServices);
        CloseServiceHandle(hSCManager);
        return false;
    }

    // 遍历服务列表,查找目标服务
    for (DWORD i = 0; i < dwNumberOfServices; i++) {
        if (_wcsicmp(lpServices[i].lpServiceName, serviceName.c_str()) == 0) {
            // 目标服务找到
            LocalFree(lpServices);
            CloseServiceHandle(hSCManager);
            return true;
        }
    }

    // 目标服务未找到
    LocalFree(lpServices);
    CloseServiceHandle(hSCManager);
    return false;
}

int main() {
    // 要检测的进程列表
    std::wstring processList[] = {
        L"ImmunityDebugger.exe",
        L"ollydbg.exe",
        L"ProcessHacker.exe",
        L"tcpview.exe",
        L"autoruns.exe",
        L"autorunsc.exe",
        L"filemon.exe",
        L"procmon.exe",
        L"regmon.exe",
        L"procexp.exe",
        L"idaq.exe",
        L"idaq64.exe",
        L"Wireshark.exe",
        L"dumpcap.exe",
        L"HookExplorer.exe",
        L"ImportREC.exe",
        L"PETools.exe",
        L"LordPE.exe",
        L"SysInspector.exe",
        L"proc_analyzer.exe",
        L"sysAnalyzer.exe",
        L"sniff_hit.exe",
        L"windbg.exe",
        L"joeboxcontrol.exe",
        L"joeboxserver.exe",
        L"ResourceHacker.exe",
        L"x32dbg.exe",
        L"x64dbg.exe",
        L"Fiddler.exe",
        L"httpdebugger.exe"
    };

    // 检查每个进程是否正在运行
    printf("进程检测结果:\n");
    for (const auto& processName : processList) {
        if (IsProcessRunning(processName)) {
            printf("%ls - 正在运行\n", processName.c_str());
        }
        else {
            printf("%ls - 未运行\n", processName.c_str());
        }
    }

    // 要检测的服务列表
    std::wstring serviceList[] = {
        L"VBoxWddm",
        L"VBoxSF",
        L"VBoxMouse",
        L"VBoxGuest",
        L"vmci",
        L"vmhgfs",
        L"vmmouse",
        L"vmmemctl",
        L"vmusb",
        L"vmusbmouse",
        L"vmx_svga",
        L"vmxnet",
        L"vmx86"
    };

    // 检查每个服务是否正在运行
    printf("\n服务检测结果:\n");
    for (const auto& serviceName : serviceList) {
        if (IsServiceRunning(serviceName)) {
            printf("%ls - 正在运行\n", serviceName.c_str());
        }
        else {
            printf("%ls - 未运行\n", serviceName.c_str());
        }
    }

    return 0;
}

最后这段代码是有点问题的,因为processID被我改成了0

使用WMIC 命令 实现当前系统进程信息遍历

使用WMIC 命令 实现枚举当前系统服务信息遍历

结果

对于进程:

调试工具和反调试工具:例如 ImmunityDebugger.exe、ollydbg.exe、ProcessHacker.exe、windbg.exe、x32dbg.exe、x64dbg.exe。

系统工具和配置工具:例如 autoruns.exe、autorunsc.exe、filemon.exe、procmon.exe、regmon.exe、procexp.exe、SysInspector.exe。

逆向工程和漏洞利用工具:例如 idaq.exe、idaq64.exe、ResourceHacker.exe、LordPE.exe、PETools.exe。

网络监控和分析工具:例如 tcpview.exe、Wireshark.exe、dumpcap.exe、Fiddler.exe、httpdebugger.exe。

其他工具:例如 HookExplorer.exe、ImportREC.exe、sniff_hit.exe、joeboxcontrol.exe。

对于服务:

虚拟化相关服务:例如 VBoxSF、VBoxMouse、VBoxGuest,这些服务与虚拟机软件(如VirtualBox)相关。

VMware相关服务:例如 vmci、vmhgfs、vmmouse、vmmemctl、vmusb、vmusbmouse、vmx_svga、vmxnet、vmx86,这些服务与VMware虚拟化软件相关。

相关推荐
西岸行者4 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意4 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码4 天前
嵌入式学习路线
学习
毛小茛4 天前
计算机系统概论——校验码
学习
babe小鑫4 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms4 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下4 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。4 天前
2026.2.25监控学习
学习
im_AMBER4 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J4 天前
从“Hello World“ 开始 C++
c语言·c++·学习