2

それで、最近 Windows API をいじっていて、少し助けが必要な問題に遭遇しました。実は、正確には2つの問題があります。

最初にコードを示してから、私が経験している問題について説明します。

#pragma once
#pragma comment(lib, "Psapi.lib")   

#include <stdlib.h>
#include <stdio.h>
#include <Windows.h>
#include <TlHelp32.h>
#include <Psapi.h>

void ProcessError(DWORD error);

int main() {
    FILE* file = fopen("C:\\Users\\Administrator\\Desktop\\processes.txt", "w");
    DWORD count, i, modulesCount;
    WCHAR buffer[128] = {0};
    HMODULE modules[128] = {0};
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
    PROCESSENTRY32 pEntry;

    pEntry.dwSize = sizeof(PROCESSENTRY32);
    count = 0;

    if(snapshot != INVALID_HANDLE_VALUE) {
        if(!Process32First(snapshot, &pEntry)) {
            ProcessError(GetLastError());
            CloseHandle(snapshot);
            ExitProcess(EXIT_FAILURE);
        }

        do {
            HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pEntry.th32ProcessID);
            GetModuleFileNameEx(hProc, NULL, (LPWSTR)memset(buffer, 0, 128), 128);

            fwprintf(file, L"-------------------------------------------------------\n");
            fwprintf(file, L"%s\t pid: %d\n", pEntry.szExeFile, pEntry.th32ProcessID);
            fwprintf(file, L"%s\n", buffer);

            if(hProc != INVALID_HANDLE_VALUE) {
                if(EnumProcessModules(hProc, (HMODULE*)memset(modules, 0, 128), 128, &modulesCount)) {
                    modulesCount = modulesCount <= 128 ? modulesCount : 128;
                    for(i = 0; i < modulesCount; ++i) {
                        GetModuleFileName(modules[i], (LPWSTR)memset(buffer, 0, 128), 128);
                        if(wcslen(buffer) > 0) {
                            fwprintf(file, L"\t\t0x%X Module: %s\n", modules[i], buffer);
                        }
                    }
                }
                else {
                    ProcessError(GetLastError());
                }
                CloseHandle(hProc);
            }
            else {
                ProcessError(GetLastError());
            }

            count++;
        } while(Process32Next(snapshot, &pEntry));
        fwprintf(file, L"Process count: %d\n", count);

    }
    else {
        ProcessError(GetLastError());
        CloseHandle(snapshot);
        ExitProcess(EXIT_FAILURE);
    }

    fclose(file);
    CloseHandle(snapshot);
    ExitProcess(EXIT_SUCCESS);
}

void ProcessError(DWORD error) {
    printf("Error in thread 0x%X, code: 0x%X\n", GetThreadId(GetCurrentThread()), error);
}

したがって、最初の問題は次のことと関係があります。

if(EnumProcessModules(hProc, (HMODULE*)memset(modules, 0, 128), 128, &modulesCount))

ときどき INVALID_HANDLE エラーが発生しますが、その理由はよくわかりません。Process ハンドルは無効ではなく、関数に渡された他のパラメーターも無効ではありません。誰かが私に説明してくれるか、少なくとも何らかの方向性を示してくれれば (私は学ぶことにもっと興味があるので、より好ましい解決策です:D)、それは私にとって良いことです。

2 つ目は、何らかの理由で、プロセスのモジュールと GetModuleFileName() を列挙すると、現在のプロセスの場所も含まれていることです。

ファイルに書き込むと、次のようになります。

TuneUpUtilitiesApp32.exe   pid: 2744
D:\Program Files\TuneUp Utilities 2012\TuneUpUtilitiesApp32.exe
      0x76F60000 Module: C:\Windows\SYSTEM32\ntdll.dll
      0x75FE0000 Module: C:\Windows\system32\kernel32.dll
      0x75370000 Module: C:\Windows\system32\KERNELBASE.dll
      0x761A0000 Module: C:\Windows\system32\USER32.dll
      0x770D0000 Module: C:\Windows\system32\GDI32.dll
      0x77130000 Module: C:\Windows\system32\LPK.dll
      0x76EC0000 Module: C:\Windows\system32\USP10.dll
      0x75F20000 Module: C:\Windows\system32\msvcrt.dll
      0x755D0000 Module: C:\Windows\system32\ADVAPI32.dll
      0x75590000 Module: C:\Windows\SYSTEM32\sechost.dll
      0x757D0000 Module: C:\Windows\system32\RPCRT4.dll
      0x77120000 Module: C:\Windows\system32\PSAPI.DLL
      0x755B0000 Module: C:\Windows\system32\IMM32.DLL
      0x75670000 Module: C:\Windows\system32\MSCTF.dll
      0x10000000 Module: C:\Windows\system32\guard32.dll
      0x750D0000 Module: C:\Windows\system32\VERSION.dll
      0x750C0000 Module: C:\Windows\system32\fltlib.dll
      0x0 Module: C:\Users\Administrator\documents\visual studio 2010\Projects\FunWithWindowsAPI\Release\FunWithWindowsAPI.exe
      0x0 Module: C:\Users\Administrator\documents\visual studio 2010\Projects\FunWithWindowsAPI\Release\FunWithWindowsAPI.exe
      0x0 Module: C:\Users\Administrator\documents\visual studio 2010\Projects\FunWithWindowsAPI\Release\FunWithWindowsAPI.exe
      0x0 Module: C:\Users\Administrator\documents\visual studio 2010\Projects\FunWithWindowsAPI\Release\FunWithWindowsAPI.exe
      0x0 Module: C:\Users\Administrator\documents\visual studio 2010\Projects\FunWithWindowsAPI\Release\FunWithWindowsAPI.exe
      0x0 Module: C:\Users\Administrator\documents\visual studio 2010\Projects\FunWithWindowsAPI\Release\FunWithWindowsAPI.exe

モジュールを抽出できるすべてのプロセスに対して、文字通りそれを行います。どんな助けでも大歓迎です!

4

1 に答える 1

1

返された「modulesCount」を正しく使用していません。モジュールの数ではなく、バイト単位の配列のサイズです。モジュールの数を取得するには、sizeof(HMODULE) で割る必要があります。

2 つ目の問題は、プロセス エントリの繰り返しを開始するときに、pEntry.th32ProcessID がまだ有効であることを望んでいることです。それは無駄な希望です。反復中にプロセスが終了する可能性があります。これをチェックせず、OpenProcess() が有効なハンドルを返すかどうかを確認しません。プロセスにアクセスするための十分な権限がないために失敗することもあります。

CreateToolhelp32Snapshot() ができることに注目してください。Module32First/Next() もサポートしています。スナップショットを作成する関数の機能により、より信頼性が高くなります。

于 2012-12-22T01:39:52.390 に答える