@jshookmcp/jshook 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/LICENSE +661 -661
  2. package/dist/index.js +0 -0
  3. package/dist/modules/captcha/AICaptchaDetector.js +185 -185
  4. package/dist/modules/process/MacProcessManager.js +25 -25
  5. package/dist/modules/process/memory/availability.js +49 -49
  6. package/dist/modules/process/memory/injector.js +185 -185
  7. package/dist/modules/process/memory/reader.js +50 -50
  8. package/dist/modules/process/memory/scanner.js +165 -165
  9. package/dist/modules/process/memory/writer.js +54 -54
  10. package/dist/native/scripts/linux/enum-windows.sh +12 -12
  11. package/dist/native/scripts/macos/enum-windows.applescript +22 -22
  12. package/dist/native/scripts/windows/enum-windows-by-class.ps1 +51 -51
  13. package/dist/native/scripts/windows/enum-windows.ps1 +44 -44
  14. package/dist/native/scripts/windows/inject-dll.ps1 +21 -21
  15. package/dist/server/domains/browser/definitions.tools.page-core.js +53 -53
  16. package/dist/server/domains/browser/definitions.tools.runtime.js +40 -40
  17. package/dist/server/domains/browser/definitions.tools.security.js +76 -76
  18. package/dist/server/domains/transform/handlers.impl.transform-base.js +102 -102
  19. package/dist/server/domains/workflow/handlers.impl.workflow-base.js +51 -51
  20. package/package.json +26 -43
  21. package/src/native/scripts/linux/enum-windows.sh +12 -12
  22. package/src/native/scripts/macos/enum-windows.applescript +22 -22
  23. package/src/native/scripts/windows/enum-windows-by-class.ps1 +51 -51
  24. package/src/native/scripts/windows/enum-windows.ps1 +44 -44
  25. package/src/native/scripts/windows/inject-dll.ps1 +21 -21
@@ -156,130 +156,130 @@ function buildMemoryScanScript(pid, pattern, patternType) {
156
156
  const { patternBytes, mask } = buildPatternBytesAndMask(pattern, patternType);
157
157
  const patternArray = patternBytes.join(',');
158
158
  const maskArray = mask.join(',');
159
- return `
160
- Add-Type @"
161
- using System;
162
- using System.Runtime.InteropServices;
163
- using System.Collections.Generic;
164
- using System.ComponentModel;
165
-
166
- public class MemoryScanner {
167
- [DllImport("kernel32.dll", SetLastError = true)]
168
- public static extern IntPtr OpenProcess(int access, bool inherit, int pid);
169
-
170
- [DllImport("kernel32.dll", SetLastError = true)]
171
- public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr addr, byte[] buffer, int size, out int read);
172
-
173
- [DllImport("kernel32.dll", SetLastError = true)]
174
- public static extern int VirtualQueryEx(IntPtr hProcess, IntPtr addr, out MEMORY_BASIC_INFORMATION info, int size);
175
-
176
- [DllImport("kernel32.dll", SetLastError = true)]
177
- public static extern bool CloseHandle(IntPtr handle);
178
-
179
- const int PROCESS_VM_READ = 0x0010;
180
- const int PROCESS_QUERY_INFORMATION = 0x0400;
181
-
182
- [StructLayout(LayoutKind.Sequential)]
183
- public struct MEMORY_BASIC_INFORMATION {
184
- public IntPtr BaseAddress;
185
- public IntPtr AllocationBase;
186
- public uint AllocationProtect;
187
- public IntPtr RegionSize;
188
- public uint State;
189
- public uint Protect;
190
- public uint Type;
191
- }
192
-
193
- const uint MEM_COMMIT = 0x1000;
194
- const uint PAGE_READONLY = 0x02;
195
- const uint PAGE_READWRITE = 0x04;
196
- const uint PAGE_WRITECOPY = 0x08;
197
- const uint PAGE_EXECUTE_READ = 0x20;
198
- const uint PAGE_EXECUTE_READWRITE = 0x40;
199
-
200
- public static List<string> ScanMemory(int pid, byte[] pattern, byte[] mask, int maxResults = 10000) {
201
- var results = new List<string>();
202
- IntPtr hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, false, pid);
203
- if (hProcess == IntPtr.Zero) {
204
- int error = Marshal.GetLastWin32Error();
205
- throw new Win32Exception(error, "Failed to open process. Run as Administrator.");
206
- }
207
-
208
- try {
209
- IntPtr addr = IntPtr.Zero;
210
- MEMORY_BASIC_INFORMATION info;
211
- int infoSize = Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION));
212
- int scannedRegions = 0;
213
-
214
- while (VirtualQueryEx(hProcess, addr, out info, infoSize) == infoSize) {
215
- scannedRegions++;
216
- bool isReadable = (info.State == MEM_COMMIT) &&
217
- ((info.Protect & PAGE_READONLY) != 0 ||
218
- (info.Protect & PAGE_READWRITE) != 0 ||
219
- (info.Protect & PAGE_WRITECOPY) != 0 ||
220
- (info.Protect & PAGE_EXECUTE_READ) != 0 ||
221
- (info.Protect & PAGE_EXECUTE_READWRITE) != 0);
222
-
223
- if (isReadable && info.RegionSize.ToInt64() > 0 && info.RegionSize.ToInt64() < 1073741824) {
224
- long regionSize = info.RegionSize.ToInt64();
225
- if (regionSize > 16777216) regionSize = 16777216; // bound scan window per region (16MB)
226
- byte[] buffer = new byte[(int)regionSize];
227
- int bytesRead;
228
-
229
- if (ReadProcessMemory(hProcess, info.BaseAddress, buffer, buffer.Length, out bytesRead)) {
230
- for (int i = 0; i <= bytesRead - pattern.Length; i++) {
231
- if (PatternMatch(buffer, i, pattern, mask)) {
232
- long foundAddr = info.BaseAddress.ToInt64() + i;
233
- results.Add("0x" + foundAddr.ToString("X"));
234
- if (results.Count >= maxResults) break;
235
- }
236
- }
237
- }
238
- }
239
-
240
- if (results.Count >= maxResults) break;
241
- if (scannedRegions >= 50000) break;
242
- long baseAddr = info.BaseAddress.ToInt64();
243
- long regionSizeRaw = info.RegionSize.ToInt64();
244
- if (regionSizeRaw <= 0) break;
245
- long nextAddr = baseAddr + regionSizeRaw;
246
- if (nextAddr <= baseAddr) break;
247
- addr = new IntPtr(nextAddr);
248
- if (addr.ToInt64() >= 0x7FFFFFFF0000) break;
249
- }
250
-
251
- return results;
252
- } finally {
253
- CloseHandle(hProcess);
254
- }
255
- }
256
-
257
- private static bool PatternMatch(byte[] buffer, int offset, byte[] pattern, byte[] mask) {
258
- for (int i = 0; i < pattern.Length; i++) {
259
- if (mask[i] == 1 && buffer[offset + i] != pattern[i]) {
260
- return false;
261
- }
262
- }
263
- return true;
264
- }
265
- }
266
- "@
267
-
268
- try {
269
- $patternBytes = @(${patternArray})
270
- $maskBytes = @(${maskArray})
271
- $results = [MemoryScanner]::ScanMemory(${pid}, $patternBytes, $maskBytes, 1000)
272
- @{
273
- success = $true;
274
- addresses = $results;
275
- stats = @{
276
- patternLength = $patternBytes.Length;
277
- resultsFound = $results.Count
278
- }
279
- } | ConvertTo-Json -Compress
280
- } catch {
281
- @{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
282
- }
159
+ return `
160
+ Add-Type @"
161
+ using System;
162
+ using System.Runtime.InteropServices;
163
+ using System.Collections.Generic;
164
+ using System.ComponentModel;
165
+
166
+ public class MemoryScanner {
167
+ [DllImport("kernel32.dll", SetLastError = true)]
168
+ public static extern IntPtr OpenProcess(int access, bool inherit, int pid);
169
+
170
+ [DllImport("kernel32.dll", SetLastError = true)]
171
+ public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr addr, byte[] buffer, int size, out int read);
172
+
173
+ [DllImport("kernel32.dll", SetLastError = true)]
174
+ public static extern int VirtualQueryEx(IntPtr hProcess, IntPtr addr, out MEMORY_BASIC_INFORMATION info, int size);
175
+
176
+ [DllImport("kernel32.dll", SetLastError = true)]
177
+ public static extern bool CloseHandle(IntPtr handle);
178
+
179
+ const int PROCESS_VM_READ = 0x0010;
180
+ const int PROCESS_QUERY_INFORMATION = 0x0400;
181
+
182
+ [StructLayout(LayoutKind.Sequential)]
183
+ public struct MEMORY_BASIC_INFORMATION {
184
+ public IntPtr BaseAddress;
185
+ public IntPtr AllocationBase;
186
+ public uint AllocationProtect;
187
+ public IntPtr RegionSize;
188
+ public uint State;
189
+ public uint Protect;
190
+ public uint Type;
191
+ }
192
+
193
+ const uint MEM_COMMIT = 0x1000;
194
+ const uint PAGE_READONLY = 0x02;
195
+ const uint PAGE_READWRITE = 0x04;
196
+ const uint PAGE_WRITECOPY = 0x08;
197
+ const uint PAGE_EXECUTE_READ = 0x20;
198
+ const uint PAGE_EXECUTE_READWRITE = 0x40;
199
+
200
+ public static List<string> ScanMemory(int pid, byte[] pattern, byte[] mask, int maxResults = 10000) {
201
+ var results = new List<string>();
202
+ IntPtr hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, false, pid);
203
+ if (hProcess == IntPtr.Zero) {
204
+ int error = Marshal.GetLastWin32Error();
205
+ throw new Win32Exception(error, "Failed to open process. Run as Administrator.");
206
+ }
207
+
208
+ try {
209
+ IntPtr addr = IntPtr.Zero;
210
+ MEMORY_BASIC_INFORMATION info;
211
+ int infoSize = Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION));
212
+ int scannedRegions = 0;
213
+
214
+ while (VirtualQueryEx(hProcess, addr, out info, infoSize) == infoSize) {
215
+ scannedRegions++;
216
+ bool isReadable = (info.State == MEM_COMMIT) &&
217
+ ((info.Protect & PAGE_READONLY) != 0 ||
218
+ (info.Protect & PAGE_READWRITE) != 0 ||
219
+ (info.Protect & PAGE_WRITECOPY) != 0 ||
220
+ (info.Protect & PAGE_EXECUTE_READ) != 0 ||
221
+ (info.Protect & PAGE_EXECUTE_READWRITE) != 0);
222
+
223
+ if (isReadable && info.RegionSize.ToInt64() > 0 && info.RegionSize.ToInt64() < 1073741824) {
224
+ long regionSize = info.RegionSize.ToInt64();
225
+ if (regionSize > 16777216) regionSize = 16777216; // bound scan window per region (16MB)
226
+ byte[] buffer = new byte[(int)regionSize];
227
+ int bytesRead;
228
+
229
+ if (ReadProcessMemory(hProcess, info.BaseAddress, buffer, buffer.Length, out bytesRead)) {
230
+ for (int i = 0; i <= bytesRead - pattern.Length; i++) {
231
+ if (PatternMatch(buffer, i, pattern, mask)) {
232
+ long foundAddr = info.BaseAddress.ToInt64() + i;
233
+ results.Add("0x" + foundAddr.ToString("X"));
234
+ if (results.Count >= maxResults) break;
235
+ }
236
+ }
237
+ }
238
+ }
239
+
240
+ if (results.Count >= maxResults) break;
241
+ if (scannedRegions >= 50000) break;
242
+ long baseAddr = info.BaseAddress.ToInt64();
243
+ long regionSizeRaw = info.RegionSize.ToInt64();
244
+ if (regionSizeRaw <= 0) break;
245
+ long nextAddr = baseAddr + regionSizeRaw;
246
+ if (nextAddr <= baseAddr) break;
247
+ addr = new IntPtr(nextAddr);
248
+ if (addr.ToInt64() >= 0x7FFFFFFF0000) break;
249
+ }
250
+
251
+ return results;
252
+ } finally {
253
+ CloseHandle(hProcess);
254
+ }
255
+ }
256
+
257
+ private static bool PatternMatch(byte[] buffer, int offset, byte[] pattern, byte[] mask) {
258
+ for (int i = 0; i < pattern.Length; i++) {
259
+ if (mask[i] == 1 && buffer[offset + i] != pattern[i]) {
260
+ return false;
261
+ }
262
+ }
263
+ return true;
264
+ }
265
+ }
266
+ "@
267
+
268
+ try {
269
+ $patternBytes = @(${patternArray})
270
+ $maskBytes = @(${maskArray})
271
+ $results = [MemoryScanner]::ScanMemory(${pid}, $patternBytes, $maskBytes, 1000)
272
+ @{
273
+ success = $true;
274
+ addresses = $results;
275
+ stats = @{
276
+ patternLength = $patternBytes.Length;
277
+ resultsFound = $results.Count
278
+ }
279
+ } | ConvertTo-Json -Compress
280
+ } catch {
281
+ @{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
282
+ }
283
283
  `.trim();
284
284
  }
285
285
  async function scanMemoryWindows(pid, pattern, patternType) {
@@ -497,47 +497,47 @@ async function scanMemoryMac(pid, pattern, patternType) {
497
497
  const tag = `${pid}_${Date.now()}`;
498
498
  const pyFile = `/tmp/lldb_scan_${tag}.py`;
499
499
  const cmdFile = `/tmp/lldb_scan_${tag}.txt`;
500
- const pyScript = `
501
- import lldb, json, sys
502
-
503
- def __lldb_init_module(debugger, internal_dict):
504
- proc = debugger.GetSelectedTarget().GetProcess()
505
- pat = bytes([${byteList}])
506
- mask = [${maskList}]
507
- results = []
508
- rl = proc.GetMemoryRegions()
509
- for i in range(rl.GetSize()):
510
- info = lldb.SBMemoryRegionInfo()
511
- rl.GetMemoryRegionAtIndex(i, info)
512
- if not info.IsReadable():
513
- continue
514
- s = info.GetRegionBase()
515
- sz = info.GetRegionEnd() - s
516
- if sz > 32 * 1024 * 1024:
517
- continue
518
- err = lldb.SBError()
519
- data = proc.ReadMemory(s, sz, err)
520
- if not err.Success():
521
- continue
522
- n = len(pat)
523
- for j in range(len(data) - n + 1):
524
- match = True
525
- for k in range(n):
526
- if mask[k] == 1 and data[j+k] != pat[k]:
527
- match = False
528
- break
529
- if match:
530
- results.append(hex(s + j))
531
- if len(results) >= 1000:
532
- break
533
- if len(results) >= 1000:
534
- break
535
- sys.stdout.write('SCAN_RESULT:' + json.dumps({
536
- 'success': True,
537
- 'addresses': results,
538
- 'stats': {'patternLength': len(pat), 'resultsFound': len(results)}
539
- }) + '\\n')
540
- sys.stdout.flush()
500
+ const pyScript = `
501
+ import lldb, json, sys
502
+
503
+ def __lldb_init_module(debugger, internal_dict):
504
+ proc = debugger.GetSelectedTarget().GetProcess()
505
+ pat = bytes([${byteList}])
506
+ mask = [${maskList}]
507
+ results = []
508
+ rl = proc.GetMemoryRegions()
509
+ for i in range(rl.GetSize()):
510
+ info = lldb.SBMemoryRegionInfo()
511
+ rl.GetMemoryRegionAtIndex(i, info)
512
+ if not info.IsReadable():
513
+ continue
514
+ s = info.GetRegionBase()
515
+ sz = info.GetRegionEnd() - s
516
+ if sz > 32 * 1024 * 1024:
517
+ continue
518
+ err = lldb.SBError()
519
+ data = proc.ReadMemory(s, sz, err)
520
+ if not err.Success():
521
+ continue
522
+ n = len(pat)
523
+ for j in range(len(data) - n + 1):
524
+ match = True
525
+ for k in range(n):
526
+ if mask[k] == 1 and data[j+k] != pat[k]:
527
+ match = False
528
+ break
529
+ if match:
530
+ results.append(hex(s + j))
531
+ if len(results) >= 1000:
532
+ break
533
+ if len(results) >= 1000:
534
+ break
535
+ sys.stdout.write('SCAN_RESULT:' + json.dumps({
536
+ 'success': True,
537
+ 'addresses': results,
538
+ 'stats': {'patternLength': len(pat), 'resultsFound': len(results)}
539
+ }) + '\\n')
540
+ sys.stdout.flush()
541
541
  `;
542
542
  await fs.writeFile(pyFile, pyScript, 'utf8');
543
543
  await fs.writeFile(cmdFile, `command script import ${pyFile}\nprocess detach\n`, 'utf8');
@@ -5,60 +5,60 @@ import { execAsync, executePowerShellScript, } from '../../process/memory/types.
5
5
  async function writeMemoryWindows(pid, address, data) {
6
6
  try {
7
7
  const hexData = data.toString('hex').toUpperCase();
8
- const psScript = `
9
- Add-Type @"
10
- using System;
11
- using System.Runtime.InteropServices;
12
- using System.ComponentModel;
13
-
14
- public class MemoryWriter {
15
- [DllImport("kernel32.dll", SetLastError = true)]
16
- public static extern IntPtr OpenProcess(int access, bool inherit, int pid);
17
-
18
- [DllImport("kernel32.dll", SetLastError = true)]
19
- public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr addr, byte[] buffer, int size, out int written);
20
-
21
- [DllImport("kernel32.dll", SetLastError = true)]
22
- public static extern bool CloseHandle(IntPtr handle);
23
-
24
- const int PROCESS_VM_WRITE = 0x0020;
25
- const int PROCESS_VM_OPERATION = 0x0008;
26
-
27
- public static int WriteMemory(int pid, long address, string hexData) {
28
- IntPtr hProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, false, pid);
29
- if (hProcess == IntPtr.Zero) {
30
- int error = Marshal.GetLastWin32Error();
31
- throw new Win32Exception(error, "Failed to open process. Run as Administrator.");
32
- }
33
-
34
- try {
35
- byte[] buffer = new byte[hexData.Length / 2];
36
- for (int i = 0; i < hexData.Length; i += 2) {
37
- buffer[i / 2] = Convert.ToByte(hexData.Substring(i, 2), 16);
38
- }
39
-
40
- int bytesWritten;
41
- bool success = WriteProcessMemory(hProcess, (IntPtr)address, buffer, buffer.Length, out bytesWritten);
42
-
43
- if (!success) {
44
- int error = Marshal.GetLastWin32Error();
45
- throw new Win32Exception(error, "Failed to write memory");
46
- }
47
-
48
- return bytesWritten;
49
- } finally {
50
- CloseHandle(hProcess);
51
- }
52
- }
53
- }
54
- "@
55
-
56
- try {
57
- $bytesWritten = [MemoryWriter]::WriteMemory(${pid}, ${address}, "${hexData}")
58
- @{ success = $true; bytesWritten = $bytesWritten } | ConvertTo-Json -Compress
59
- } catch {
60
- @{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
61
- }
8
+ const psScript = `
9
+ Add-Type @"
10
+ using System;
11
+ using System.Runtime.InteropServices;
12
+ using System.ComponentModel;
13
+
14
+ public class MemoryWriter {
15
+ [DllImport("kernel32.dll", SetLastError = true)]
16
+ public static extern IntPtr OpenProcess(int access, bool inherit, int pid);
17
+
18
+ [DllImport("kernel32.dll", SetLastError = true)]
19
+ public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr addr, byte[] buffer, int size, out int written);
20
+
21
+ [DllImport("kernel32.dll", SetLastError = true)]
22
+ public static extern bool CloseHandle(IntPtr handle);
23
+
24
+ const int PROCESS_VM_WRITE = 0x0020;
25
+ const int PROCESS_VM_OPERATION = 0x0008;
26
+
27
+ public static int WriteMemory(int pid, long address, string hexData) {
28
+ IntPtr hProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, false, pid);
29
+ if (hProcess == IntPtr.Zero) {
30
+ int error = Marshal.GetLastWin32Error();
31
+ throw new Win32Exception(error, "Failed to open process. Run as Administrator.");
32
+ }
33
+
34
+ try {
35
+ byte[] buffer = new byte[hexData.Length / 2];
36
+ for (int i = 0; i < hexData.Length; i += 2) {
37
+ buffer[i / 2] = Convert.ToByte(hexData.Substring(i, 2), 16);
38
+ }
39
+
40
+ int bytesWritten;
41
+ bool success = WriteProcessMemory(hProcess, (IntPtr)address, buffer, buffer.Length, out bytesWritten);
42
+
43
+ if (!success) {
44
+ int error = Marshal.GetLastWin32Error();
45
+ throw new Win32Exception(error, "Failed to write memory");
46
+ }
47
+
48
+ return bytesWritten;
49
+ } finally {
50
+ CloseHandle(hProcess);
51
+ }
52
+ }
53
+ }
54
+ "@
55
+
56
+ try {
57
+ $bytesWritten = [MemoryWriter]::WriteMemory(${pid}, ${address}, "${hexData}")
58
+ @{ success = $true; bytesWritten = $bytesWritten } | ConvertTo-Json -Compress
59
+ } catch {
60
+ @{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
61
+ }
62
62
  `;
63
63
  const { stdout } = await executePowerShellScript(psScript, { maxBuffer: 1024 * 1024 });
64
64
  const _trimmed = stdout.trim();
@@ -1,12 +1,12 @@
1
- #!/bin/bash
2
- # enum-windows.sh
3
- # Linux window enumeration script (placeholder)
4
-
5
- TARGET_PID=$1
6
-
7
- # Use xdotool or wmctrl for window enumeration
8
- # This is a placeholder for future implementation
9
-
10
- if command -v xdotool &> /dev/null; then
11
- xdotool search --pid "$TARGET_PID" --name "" get-window-name
12
- fi
1
+ #!/bin/bash
2
+ # enum-windows.sh
3
+ # Linux window enumeration script (placeholder)
4
+
5
+ TARGET_PID=$1
6
+
7
+ # Use xdotool or wmctrl for window enumeration
8
+ # This is a placeholder for future implementation
9
+
10
+ if command -v xdotool &> /dev/null; then
11
+ xdotool search --pid "$TARGET_PID" --name "" get-window-name
12
+ fi
@@ -1,22 +1,22 @@
1
- -- enum-windows.applescript
2
- -- macOS window enumeration script (placeholder)
3
-
4
- param TargetPid
5
-
6
- -- AppleScript implementation for window enumeration
7
- -- This is a placeholder for future implementation
8
-
9
- tell application "System Events"
10
- set windowList to {}
11
- repeat with proc in (every process whose unix id is TargetPid)
12
- repeat with win in windows of proc
13
- set end of windowList to {¬
14
- title: name of win, ¬
15
- position: position of win, ¬
16
- size: size of win ¬
17
- }
18
- end repeat
19
- end repeat
20
- end tell
21
-
22
- return windowList
1
+ -- enum-windows.applescript
2
+ -- macOS window enumeration script (placeholder)
3
+
4
+ param TargetPid
5
+
6
+ -- AppleScript implementation for window enumeration
7
+ -- This is a placeholder for future implementation
8
+
9
+ tell application "System Events"
10
+ set windowList to {}
11
+ repeat with proc in (every process whose unix id is TargetPid)
12
+ repeat with win in windows of proc
13
+ set end of windowList to {¬
14
+ title: name of win, ¬
15
+ position: position of win, ¬
16
+ size: size of win ¬
17
+ }
18
+ end repeat
19
+ end repeat
20
+ end tell
21
+
22
+ return windowList
@@ -1,51 +1,51 @@
1
- param(
2
- [string]$ClassPattern
3
- )
4
-
5
- Add-Type @"
6
- using System;
7
- using System.Runtime.InteropServices;
8
- public class Win32 {
9
- [DllImport("user32.dll")] public static extern IntPtr FindWindowEx(IntPtr parent, IntPtr childAfter, string className, string title);
10
- [DllImport("user32.dll")] public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int pid);
11
- [DllImport("user32.dll")] public static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder text, int count);
12
- [DllImport("user32.dll")] public static extern int GetClassName(IntPtr hWnd, System.Text.StringBuilder className, int maxCount);
13
- }
14
- "@
15
-
16
- $windows = @()
17
- $hwnd = [IntPtr]::Zero
18
- while ($true) {
19
- $hwnd = [Win32]::FindWindowEx([IntPtr]::Zero, $hwnd, $null, $null)
20
- if ($hwnd -eq [IntPtr]::Zero) { break }
21
-
22
- $className = New-Object System.Text.StringBuilder 256
23
- [Win32]::GetClassName($hwnd, $className, 256) | Out-Null
24
- $classNameStr = $className.ToString()
25
-
26
- # Support wildcard pattern matching
27
- $isMatch = $false
28
- if ($ClassPattern -eq $classNameStr) {
29
- $isMatch = $true
30
- } elseif ($ClassPattern.Contains('*')) {
31
- # Convert wildcard pattern to regex
32
- $regexPattern = [regex]::Escape($ClassPattern).Replace('\*', '.*')
33
- if ($classNameStr -match $regexPattern) {
34
- $isMatch = $true
35
- }
36
- }
37
-
38
- if ($isMatch) {
39
- $windowPid = 0
40
- [Win32]::GetWindowThreadProcessId($hwnd, [ref]$windowPid) | Out-Null
41
- $title = New-Object System.Text.StringBuilder 256
42
- [Win32]::GetWindowText($hwnd, $title, 256) | Out-Null
43
- $windows += @{
44
- Handle = $hwnd.ToString()
45
- Title = $title.ToString()
46
- ClassName = $classNameStr
47
- ProcessId = $windowPid
48
- }
49
- }
50
- }
51
- $windows | ConvertTo-Json -Compress
1
+ param(
2
+ [string]$ClassPattern
3
+ )
4
+
5
+ Add-Type @"
6
+ using System;
7
+ using System.Runtime.InteropServices;
8
+ public class Win32 {
9
+ [DllImport("user32.dll")] public static extern IntPtr FindWindowEx(IntPtr parent, IntPtr childAfter, string className, string title);
10
+ [DllImport("user32.dll")] public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int pid);
11
+ [DllImport("user32.dll")] public static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder text, int count);
12
+ [DllImport("user32.dll")] public static extern int GetClassName(IntPtr hWnd, System.Text.StringBuilder className, int maxCount);
13
+ }
14
+ "@
15
+
16
+ $windows = @()
17
+ $hwnd = [IntPtr]::Zero
18
+ while ($true) {
19
+ $hwnd = [Win32]::FindWindowEx([IntPtr]::Zero, $hwnd, $null, $null)
20
+ if ($hwnd -eq [IntPtr]::Zero) { break }
21
+
22
+ $className = New-Object System.Text.StringBuilder 256
23
+ [Win32]::GetClassName($hwnd, $className, 256) | Out-Null
24
+ $classNameStr = $className.ToString()
25
+
26
+ # Support wildcard pattern matching
27
+ $isMatch = $false
28
+ if ($ClassPattern -eq $classNameStr) {
29
+ $isMatch = $true
30
+ } elseif ($ClassPattern.Contains('*')) {
31
+ # Convert wildcard pattern to regex
32
+ $regexPattern = [regex]::Escape($ClassPattern).Replace('\*', '.*')
33
+ if ($classNameStr -match $regexPattern) {
34
+ $isMatch = $true
35
+ }
36
+ }
37
+
38
+ if ($isMatch) {
39
+ $windowPid = 0
40
+ [Win32]::GetWindowThreadProcessId($hwnd, [ref]$windowPid) | Out-Null
41
+ $title = New-Object System.Text.StringBuilder 256
42
+ [Win32]::GetWindowText($hwnd, $title, 256) | Out-Null
43
+ $windows += @{
44
+ Handle = $hwnd.ToString()
45
+ Title = $title.ToString()
46
+ ClassName = $classNameStr
47
+ ProcessId = $windowPid
48
+ }
49
+ }
50
+ }
51
+ $windows | ConvertTo-Json -Compress