Windows Python / Detecting Window with FindWindow API
Author | Jean-Pierre LESUEUR (DarkCoderSc) |
Platform | Windows |
Language | Python |
Technique | Detecting Window with FindWindow API |
Description:
Feel free to edit both fw_debuggers
and contains_in_title
to extend the search of known debuggers.
Code
import ctypes
import os
from ctypes.wintypes import BOOL, HWND, LPARAM,\
LPWSTR, INT, MAX_PATH,\
LPDWORD, DWORD, HANDLE,\
HMODULE
def found(description, hwnd):
"""
When a Window handle is found it will output to console several information about spotted process.
:param description: Description of found object.
:param hwnd: Handle of found object.
"""
lpdwProcessId = ctypes.c_ulong()
output = "-" * 60 + "\r\n"
output += description + "\r\n"
output += "-" * 60 + "\r\n"
output += f"Handle: {hwnd}\r\n"
_GetWindowThreadProcessId(hwnd, ctypes.byref(lpdwProcessId))
if (lpdwProcessId is not None) and (lpdwProcessId.value > 0):
PROCESS_QUERY_INFORMATION = 0x0400
PROCESS_VM_READ = 0x0010
procHandle = ctypes.windll.kernel32.OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
False,
lpdwProcessId.value
)
if procHandle > 0:
output += f"Process Id: {lpdwProcessId.value}\r\n"
lpFilename = ctypes.create_unicode_buffer(MAX_PATH)
if _GetModuleFileNameEx(procHandle, 0, lpFilename, MAX_PATH) > 0:
path, process_name = os.path.split(lpFilename.value)
output += f"Process Name: {process_name}\r\n"
output += f"Image Path: {path}\r\n"
ctypes.windll.kernel32.CloseHandle(procHandle)
output += "-" * 60 + "\r\n\r\n"
print(output)
def enum_window_proc(hwnd, lparam):
"""
EnumWindows API CallBack
:param hwnd: Current Window Handle
:param lparam: Not used in our case
:return: Always True in our case
"""
if hwnd > 0:
nMaxCount = ctypes.windll.user32.GetWindowTextLengthW(hwnd)+1
if nMaxCount > 0:
lpWindowName = ctypes.create_unicode_buffer(nMaxCount)
if _GetWindowText(hwnd, lpWindowName, nMaxCount) > 0:
for description, in_title in contains_in_title:
if in_title in lpWindowName.value:
found(description, hwnd)
return True
if __name__ == '__main__':
'''
Description | Window Class Name (lpClassName) | Window Title (lpWindowName)
'''
fw_debuggers = [
("OllyDbg", "OLLYDBG", None),
("x64dbg (x64)", None, "x64dbg"),
("x32dbg (x32)", None, "x32dbg"),
# ......... #
]
'''
Description | Text contained in debugger title.
'''
contains_in_title = [
("Immunity Debugger", "Immunity Debugger"),
# ......... #
]
# Define GetWindowThreadProcessId API
_GetWindowThreadProcessId = ctypes.windll.user32.GetWindowThreadProcessId
_GetWindowThreadProcessId.argtypes = HWND, LPDWORD
_GetWindowThreadProcessId.restype = DWORD
# Define GetModuleFileNameEx API
_GetModuleFileNameEx = ctypes.windll.psapi.GetModuleFileNameExW
_GetModuleFileNameEx.argtypes = HANDLE, HMODULE, LPWSTR, DWORD
_GetModuleFileNameEx.restype = DWORD
'''
Search for Debuggers using the FindWindowW API with ClassName /+ WindowName
'''
for description, lpClassName, lpWindowName in fw_debuggers:
handle = ctypes.windll.user32.FindWindowW(lpClassName, lpWindowName)
if handle > 0:
found(description, handle)
'''
Search for Debuggers using EnumWindows API.
We first list all Windows titles then search for a debugger title pattern.
This is useful against debuggers or tools without specific title / classname.
'''
# Define EnumWindows API
lpEnumFunc = ctypes.WINFUNCTYPE(
BOOL,
HWND,
LPARAM
)
_EnumWindows = ctypes.windll.user32.EnumWindows
_EnumWindows.argtypes = [
lpEnumFunc,
LPARAM
]
# Define GetWindowTextW API
_GetWindowText = ctypes.windll.user32.GetWindowTextW
_GetWindowText.argtypes = HWND, LPWSTR, INT
_GetWindowText.restype = INT
# Enumerate Windows through Windows API
_EnumWindows(lpEnumFunc(enum_window_proc), 0)
Created
September 2, 2020
Last Revised
April 22, 2024