-
Notifications
You must be signed in to change notification settings - Fork 5
/
FindWindow.py
141 lines (106 loc) · 4.05 KB
/
FindWindow.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
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)