Skip to content

Instantly share code, notes, and snippets.

@Wohlstand
Created September 24, 2019 20:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Wohlstand/ce309fff0a70d94e1c31524bb16fad59 to your computer and use it in GitHub Desktop.
Save Wohlstand/ce309fff0a70d94e1c31524bb16fad59 to your computer and use it in GitHub Desktop.
C WinAPI Example of PIDs retrieving by absolute executable file path matching
#include <windows.h>
#include <psapi.h>
#include <stdio.h>
#include <wchar.h>
#ifdef _WIN64
/* This call is available since Windows Vista. It's useless on 32-bit builds. */
typedef BOOL (*call_EnumProcessModulesEx)(HANDLE, HMODULE*, DWORD, LPDWORD, DWORD);
static call_EnumProcessModulesEx g_EnumProcessModulesEx = NULL;
static void initCalls()
{
HINSTANCE lib = LoadLibraryW(L"kernel32.dll");
g_EnumProcessModulesEx = (call_EnumProcessModulesEx)GetProcAddress(lib, "EnumProcessModulesEx");
FreeLibrary(lib);
}
#endif
static BOOL checkProc(DWORD procId, const wchar_t *proc_name_wanted);
static DWORD getPidsByPath(const wchar_t *process_path, DWORD *found_pids, DWORD found_pids_max_size);
/* Checks matching of single process with full path string by PID */
static BOOL checkProc(DWORD procId, const wchar_t *proc_name_wanted)
{
wchar_t proc_name[MAX_PATH + 1] = L"<unknown>";
HMODULE h_mod = 0;
DWORD cbNeeded;
DWORD proc_name_len;
HANDLE h_process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, procId);
if(NULL == h_process)
return FALSE;
#ifdef _WIN64
if(g_EnumProcessModulesEx)
{
if(!g_EnumProcessModulesEx(h_process, &h_mod, sizeof(h_mod), &cbNeeded, LIST_MODULES_ALL))
return FALSE;
}
else
#endif
if(!EnumProcessModules(h_process, &h_mod, sizeof(h_mod), &cbNeeded))
return FALSE;
proc_name_len = GetModuleFileNameExW(h_process, h_mod, proc_name, MAX_PATH);
proc_name[proc_name_len] = '\0';
if(proc_name_len == 0)
{
proc_name_len = GetModuleBaseNameW(h_process, h_mod, proc_name, MAX_PATH);
proc_name[proc_name_len] = '\0';
}
wprintf(L"%s (PID: %u)\n", proc_name, procId);
CloseHandle(h_process);
return (lstrcmpiW(proc_name, proc_name_wanted) == 0);
}
/* Get all PIDs are matching given full path */
static DWORD getPidsByPath(const wchar_t *process_path, DWORD *found_pids, DWORD found_pids_max_size)
{
DWORD proc_id[1024];
DWORD ret_bytes = 0;
FILE *proc_file = NULL;
DWORD proc_count = 0;
unsigned int i;
DWORD found_pids_count = 0;
if(!EnumProcesses(proc_id, sizeof(proc_id), &ret_bytes))
{
wprintf(L"ERROR: Can not execute EnumProcesses()...\n");
return 0;
}
proc_count = ret_bytes / sizeof(DWORD);
for(i = 0; i < proc_count; i++)
{
if(proc_id[i] != 0)
{
if(checkProc(proc_id[i], process_path))
{
found_pids[found_pids_count++] = proc_id[i];
if(found_pids_count >= found_pids_max_size)
break;
}
}
}
return found_pids_count;
}
/* Usage example */
int main()
{
DWORD proc_id[1024];
DWORD proc_count = 0;
unsigned int i;
const wchar_t *path_to_find = L"C:\\Windows\\system32\\cmd.exe";
#ifdef _WIN64
initCalls();
#endif
wprintf(L"Getting PIDs...\n");
proc_count = getPidsByPath(path_to_find, proc_id, 1024);
wprintf(L"\n\n");
if(proc_count > 0)
{
wprintf(L"Found matching PIDs for %s:\n", path_to_find);
for(i = 0; i < proc_count; i++)
{
wprintf(L"%u\n", proc_id[i]);
}
}
else
wprintf(L"No matching PIDs found for %s:\n", path_to_find);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment