Using only the ctypes
library, I would like to iterate through Windows processes and obtain the name of each process for comparison checks.
Right now, I am getting weird errors like this:
Failed to open process 0. Error: (87, 'The parameter is incorrect.')
Failed to enumerate process modules for 4. Error: (299, 'Only part of a ReadProcessMemory or WriteProcessMemory request was completed.')
Failed to enumerate process modules for 196. Error: (299, 'Only part of a ReadProcessMemory or WriteProcessMemory request was completed.')
Failed to enumerate process modules for 708. Error: (5, 'Access is denied.')
Failed to open process 956. Error: (5, 'Access is denied.')
Failed to enumerate process modules for 884. Error: (5, 'Access is denied.')
Failed to open process 868. Error: (5, 'Access is denied.')
Failed to enumerate process modules for 960. Error: (5, 'Access is denied.')
Failed to enumerate process modules for 1028. Error: (5, 'Access is denied.')
Failed to enumerate process modules for 1136. Error: (5, 'Access is denied.')
Every Windows process is throwing an error. I've tried running the script with Admin privileges and ensuring that it Python is 64-bit.
Current code:
import ctypes
import ctypes.wintypes
# Library initializations
psapi = ctypes.windll.psapi
kernel32 = ctypes.windll.kernel32
FORMAT_MESSAGE_FROM_SYSTEM = 0x1000
PROCESS_QUERY_INFORMATION = 0x1000
MAX_PROCESS_NAME_LENGTH = 512
MAX_PROCESS_COUNT = 4096
FLAGGED_PROCESSES = ["test.exe"]
def get_last_error():
"""Retrieve the last error code and its description."""
error_code = ctypes.GetLastError()
buffer = ctypes.create_unicode_buffer(256)
kernel32.FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, None, error_code, 0, buffer, len(buffer), None)
return error_code, buffer.value.strip()
def _get_process_name(process_id):
h_process = kernel32.OpenProcess(PROCESS_QUERY_INFORMATION, False, process_id)
if not h_process:
print(f"Failed to open process {process_id}. Error: {get_last_error()}")
return None
try:
module_handle = ctypes.wintypes.HMODULE()
cb_needed = ctypes.wintypes.DWORD()
if not psapi.EnumProcessModules(h_process, ctypes.byref(module_handle), ctypes.sizeof(module_handle), ctypes.byref(cb_needed)):
print(f"Failed to enumerate process modules for {process_id}. Error: {get_last_error()}")
return None
exe_name = ctypes.create_unicode_buffer(MAX_PROCESS_NAME_LENGTH)
if not psapi.GetModuleBaseNameW(h_process, module_handle, exe_name, ctypes.sizeof(exe_name) // 2):
print(f"Failed to get module base name for {process_id}. Error: {get_last_error()}")
return None
return exe_name.value
finally:
kernel32.CloseHandle(h_process)
def is_flagged_process_running():
DWORD = ctypes.wintypes.DWORD
DWORD_ARRAY = DWORD * MAX_PROCESS_COUNT
process_ids = DWORD_ARRAY()
bytes_returned = DWORD()
if not psapi.EnumProcesses(ctypes.byref(process_ids), ctypes.sizeof(process_ids), ctypes.byref(bytes_returned)):
print(f"Failed to enumerate processes. Error: {get_last_error()}")
return False
number_of_processes = bytes_returned.value // ctypes.sizeof(DWORD)
for index in range(number_of_processes):
process_name = _get_process_name(process_ids[index])
if process_name and process_name.lower() in FLAGGED_PROCESSES:
return True
return False
print(is_flagged_process_running())