Всем привет. Подскажите, как получить имя процесса, используя EnumProcesses, и соответственно имея только ID процессов? Process32First / Next, я знаю, просто интересно как добраться до имени процесса, с другого направления. МСДН перерыл, ничего не нашел Хотя мне кажется, что это возможно
из пеба 100 раз уже писали, напишем в 101-й Код (Text): int GetModuleNameByPid( IN HANDLE ProcessId, IN WCHAR** pwszFullPath) // // get name form PEB // return ZERO if fails // // remark: memory pointed by wszFullPath must be free when it unneeded, // wszFullPath -- always NULL-termintated // { NTSTATUS status; PEB_LDR_DATA Ldr; LDR_DATA_TABLE_ENTRY LdrData; PEB peb; PROCESS_BASIC_INFORMATION ProcBasicInfo; HANDLE hProcess; CLIENT_ID clid; OBJECT_ATTRIBUTES oa; SIZE_T rw; PVOID ptr; //temp //char str[256]; RtlZeroMemory(&oa, sizeof(oa)); oa.Length = sizeof(oa); clid.UniqueProcess = ProcessId; clid.UniqueThread = 0; status = NtOpenProcess( &hProcess, PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, &oa, &clid); if (status) return 0; status = NtQueryInformationProcess( hProcess, ProcessBasicInformation, &ProcBasicInfo, sizeof(ProcBasicInfo), 0); if (!ProcBasicInfo.PebBaseAddress && !status) { wsprintf(str, "ZERO PEB pid = 0x%04X\n", ProcBasicInfo.UniqueProcessId); print(str); } if (status || !ProcBasicInfo.PebBaseAddress) { exit: CloseHandle(hProcess); return 0; } RtlZeroMemory(&peb, sizeof(peb)); if (NtReadVirtualMemory(hProcess, ProcBasicInfo.PebBaseAddress, &peb, sizeof(peb), &rw)) goto exit; if (NtReadVirtualMemory(hProcess, peb.Ldr, &Ldr, sizeof(Ldr), &rw)) goto exit; if (NtReadVirtualMemory(hProcess, Ldr.InLoadOrderModuleList.Flink, &LdrData, sizeof(LdrData), &rw)) goto exit; ptr = GlobalAlloc(GMEM_FIXED, LdrData.BaseDllName.Length + 2); if (!ptr) goto exit; RtlZeroMemory(ptr, LdrData.BaseDllName.Length + 2); if (NtReadVirtualMemory(hProcess, LdrData.BaseDllName.Buffer, ptr, LdrData.BaseDllName.Length, &rw)){ GlobalFree(ptr); goto exit; } CloseHandle(hProcess); *pwszFullPath = ptr; //wsprintf(str, "name retrieved successful pid = 0x%04X, name = %ws\n", ProcBasicInfo.UniqueProcessId, ptr); //print(str); return 1; }
можно легче, но менее документированным способом Код (Text): name db 500 dup (?) oa OBJECT_ATTRIBUTES clid CLIENT_ID hProcess dd ? shit dd ? ..... mov [clid.UniqueProcess],PID invoke NtOpenProcess,hProcess,PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,oa,clid invoke NtQueryInformationProcess,[hProcess],27,name,500,shit в name получим UNICODE_STRING
Самый толковый способ прочитать память процесса, где командная строка лежит. Но жаль, что нет функций типа GetProcessFileName и GetProcessCommandLine