@jshookmcp/jshook 0.1.5 → 0.1.6

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 (81) hide show
  1. package/LICENSE +661 -661
  2. package/README.md +72 -40
  3. package/README.zh.md +77 -40
  4. package/dist/constants.d.ts +1 -0
  5. package/dist/constants.js +13 -1
  6. package/dist/modules/analyzer/IntelligentAnalyzer.js +19 -11
  7. package/dist/modules/browser/BrowserModeManager.d.ts +5 -0
  8. package/dist/modules/browser/BrowserModeManager.js +96 -10
  9. package/dist/modules/browser/CamoufoxBrowserManager.d.ts +4 -0
  10. package/dist/modules/browser/CamoufoxBrowserManager.js +64 -3
  11. package/dist/modules/browser/TabRegistry.js +3 -2
  12. package/dist/modules/browser/UnifiedBrowserManager.d.ts +5 -0
  13. package/dist/modules/browser/UnifiedBrowserManager.js +62 -9
  14. package/dist/modules/captcha/AICaptchaDetector.js +185 -185
  15. package/dist/modules/debugger/DebuggerSessionManager.d.ts +4 -0
  16. package/dist/modules/debugger/DebuggerSessionManager.js +29 -19
  17. package/dist/modules/debugger/ScriptManager.impl.class.d.ts +4 -0
  18. package/dist/modules/debugger/ScriptManager.impl.class.js +46 -21
  19. package/dist/modules/emulator/EnvironmentEmulator.js +2 -2
  20. package/dist/modules/monitor/NetworkMonitor.impl.d.ts +1 -0
  21. package/dist/modules/monitor/NetworkMonitor.impl.js +22 -15
  22. package/dist/modules/monitor/PerformanceMonitor.js +64 -32
  23. package/dist/modules/process/LinuxProcessManager.d.ts +3 -1
  24. package/dist/modules/process/LinuxProcessManager.js +7 -3
  25. package/dist/modules/process/MacProcessManager.d.ts +3 -1
  26. package/dist/modules/process/MacProcessManager.js +32 -28
  27. package/dist/modules/process/ProcessManager.impl.d.ts +5 -1
  28. package/dist/modules/process/ProcessManager.impl.js +54 -13
  29. package/dist/modules/process/index.d.ts +3 -1
  30. package/dist/modules/process/index.js +2 -2
  31. package/dist/modules/process/memory/AuditTrail.d.ts +25 -0
  32. package/dist/modules/process/memory/AuditTrail.js +44 -0
  33. package/dist/modules/process/memory/availability.js +49 -49
  34. package/dist/modules/process/memory/injector.js +185 -185
  35. package/dist/modules/process/memory/linux/mapsParser.d.ts +16 -0
  36. package/dist/modules/process/memory/linux/mapsParser.js +28 -0
  37. package/dist/modules/process/memory/reader.js +50 -50
  38. package/dist/modules/process/memory/regions.enumerate.js +45 -1
  39. package/dist/modules/process/memory/regions.protection.js +48 -2
  40. package/dist/modules/process/memory/scanner.d.ts +4 -1
  41. package/dist/modules/process/memory/scanner.js +383 -182
  42. package/dist/modules/process/memory/writer.js +54 -54
  43. package/dist/native/NativeMemoryManager.impl.d.ts +4 -0
  44. package/dist/native/NativeMemoryManager.impl.js +72 -24
  45. package/dist/native/NativeMemoryManager.utils.d.ts +1 -0
  46. package/dist/native/NativeMemoryManager.utils.js +44 -1
  47. package/dist/native/scripts/linux/enum-windows.sh +12 -12
  48. package/dist/native/scripts/macos/enum-windows.applescript +22 -22
  49. package/dist/native/scripts/windows/enum-windows-by-class.ps1 +51 -51
  50. package/dist/native/scripts/windows/enum-windows.ps1 +44 -44
  51. package/dist/native/scripts/windows/inject-dll.ps1 +21 -21
  52. package/dist/server/MCPServer.search.d.ts +3 -0
  53. package/dist/server/MCPServer.search.js +21 -2
  54. package/dist/server/ToolCallContextGuard.d.ts +2 -0
  55. package/dist/server/ToolCallContextGuard.js +29 -14
  56. package/dist/server/ToolSearch.js +11 -5
  57. package/dist/server/domains/browser/definitions.tools.page-core.js +53 -53
  58. package/dist/server/domains/browser/definitions.tools.runtime.js +40 -40
  59. package/dist/server/domains/browser/definitions.tools.security.js +76 -76
  60. package/dist/server/domains/browser/handlers/tab-workflow.js +6 -4
  61. package/dist/server/domains/maintenance/handlers.extensions.js +46 -26
  62. package/dist/server/domains/process/definitions.js +20 -7
  63. package/dist/server/domains/process/handlers.impl.core.runtime.base.d.ts +35 -0
  64. package/dist/server/domains/process/handlers.impl.core.runtime.base.js +107 -1
  65. package/dist/server/domains/process/handlers.impl.core.runtime.inject.js +111 -2
  66. package/dist/server/domains/process/handlers.impl.core.runtime.memory.d.ts +9 -0
  67. package/dist/server/domains/process/handlers.impl.core.runtime.memory.js +282 -31
  68. package/dist/server/domains/process/manifest.js +1 -0
  69. package/dist/server/domains/transform/handlers.impl.transform-base.js +102 -102
  70. package/dist/server/domains/workflow/handlers.impl.workflow-api.js +14 -4
  71. package/dist/server/domains/workflow/handlers.impl.workflow-base.js +51 -51
  72. package/dist/server/registry/discovery.js +17 -12
  73. package/dist/server/registry/index.js +10 -2
  74. package/dist/utils/TokenBudgetManager.d.ts +1 -0
  75. package/dist/utils/TokenBudgetManager.js +22 -0
  76. package/package.json +5 -1
  77. package/src/native/scripts/linux/enum-windows.sh +12 -12
  78. package/src/native/scripts/macos/enum-windows.applescript +22 -22
  79. package/src/native/scripts/windows/enum-windows-by-class.ps1 +51 -51
  80. package/src/native/scripts/windows/enum-windows.ps1 +44 -44
  81. package/src/native/scripts/windows/inject-dll.ps1 +21 -21
@@ -1,104 +1,104 @@
1
1
  import { logger } from '../../../utils/logger.js';
2
2
  import { executePowerShellScript } from '../../process/memory/types.js';
3
3
  function buildDllInjectionScript(pid, dllPath) {
4
- return `
5
- Add-Type @"
6
- using System;
7
- using System.Runtime.InteropServices;
8
- using System.ComponentModel;
9
- using System.IO;
10
-
11
- public class DllInjector {
12
- [DllImport("kernel32.dll", SetLastError = true)]
13
- public static extern IntPtr OpenProcess(int access, bool inherit, int pid);
14
-
15
- [DllImport("kernel32.dll", SetLastError = true)]
16
- public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr addr, int size, int allocType, int protect);
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 IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr attr, int stackSize, IntPtr startAddr, IntPtr param, int flags, out int threadId);
23
-
24
- [DllImport("kernel32.dll", SetLastError = true)]
25
- public static extern IntPtr GetModuleHandle(string name);
26
-
27
- [DllImport("kernel32.dll", SetLastError = true)]
28
- public static extern IntPtr GetProcAddress(IntPtr hModule, string name);
29
-
30
- [DllImport("kernel32.dll", SetLastError = true)]
31
- public static extern bool CloseHandle(IntPtr handle);
32
-
33
- [DllImport("kernel32.dll", SetLastError = true)]
34
- public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr addr, int size, int freeType);
35
-
36
- const int PROCESS_CREATE_THREAD = 0x0002;
37
- const int PROCESS_QUERY_INFORMATION = 0x0400;
38
- const int PROCESS_VM_OPERATION = 0x0008;
39
- const int PROCESS_VM_WRITE = 0x0020;
40
- const int MEM_COMMIT = 0x1000;
41
- const int MEM_RESERVE = 0x2000;
42
- const int PAGE_READWRITE = 0x04;
43
- const int MEM_RELEASE = 0x8000;
44
-
45
- public static object Inject(int pid, string dllPath) {
46
- if (!File.Exists(dllPath)) {
47
- return new { success = false, error = "DLL not found: " + dllPath };
48
- }
49
-
50
- IntPtr hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, false, pid);
51
- if (hProcess == IntPtr.Zero) {
52
- int error = Marshal.GetLastWin32Error();
53
- throw new Win32Exception(error, "Failed to open process. Run as Administrator.");
54
- }
55
-
56
- try {
57
- byte[] dllBytes = System.Text.Encoding.ASCII.GetBytes(dllPath + "\\0");
58
- IntPtr remoteMem = VirtualAllocEx(hProcess, IntPtr.Zero, dllBytes.Length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
59
- if (remoteMem == IntPtr.Zero) {
60
- int error = Marshal.GetLastWin32Error();
61
- throw new Win32Exception(error, "Failed to allocate memory in target");
62
- }
63
-
64
- try {
65
- int written;
66
- if (!WriteProcessMemory(hProcess, remoteMem, dllBytes, dllBytes.Length, out written)) {
67
- int error = Marshal.GetLastWin32Error();
68
- throw new Win32Exception(error, "Failed to write DLL path to target");
69
- }
70
-
71
- IntPtr hKernel32 = GetModuleHandle("kernel32.dll");
72
- IntPtr loadLibraryAddr = GetProcAddress(hKernel32, "LoadLibraryA");
73
- if (loadLibraryAddr == IntPtr.Zero) {
74
- throw new Exception("Failed to get LoadLibraryA address");
75
- }
76
-
77
- int threadId;
78
- IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, loadLibraryAddr, remoteMem, 0, out threadId);
79
- if (hThread == IntPtr.Zero) {
80
- int error = Marshal.GetLastWin32Error();
81
- throw new Win32Exception(error, "Failed to create remote thread");
82
- }
83
-
84
- CloseHandle(hThread);
85
- return new { success = true, remoteThreadId = threadId };
86
- } finally {
87
- VirtualFreeEx(hProcess, remoteMem, 0, MEM_RELEASE);
88
- }
89
- } finally {
90
- CloseHandle(hProcess);
91
- }
92
- }
93
- }
94
- "@
95
-
96
- try {
97
- $result = [DllInjector]::Inject(${pid}, "${dllPath.replace(/\\/g, '\\\\').replace(/"/g, '`"').replace(/`/g, '``').replace(/\$/g, '`$')}")
98
- $result | ConvertTo-Json -Compress
99
- } catch {
100
- @{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
101
- }
4
+ return `
5
+ Add-Type @"
6
+ using System;
7
+ using System.Runtime.InteropServices;
8
+ using System.ComponentModel;
9
+ using System.IO;
10
+
11
+ public class DllInjector {
12
+ [DllImport("kernel32.dll", SetLastError = true)]
13
+ public static extern IntPtr OpenProcess(int access, bool inherit, int pid);
14
+
15
+ [DllImport("kernel32.dll", SetLastError = true)]
16
+ public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr addr, int size, int allocType, int protect);
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 IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr attr, int stackSize, IntPtr startAddr, IntPtr param, int flags, out int threadId);
23
+
24
+ [DllImport("kernel32.dll", SetLastError = true)]
25
+ public static extern IntPtr GetModuleHandle(string name);
26
+
27
+ [DllImport("kernel32.dll", SetLastError = true)]
28
+ public static extern IntPtr GetProcAddress(IntPtr hModule, string name);
29
+
30
+ [DllImport("kernel32.dll", SetLastError = true)]
31
+ public static extern bool CloseHandle(IntPtr handle);
32
+
33
+ [DllImport("kernel32.dll", SetLastError = true)]
34
+ public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr addr, int size, int freeType);
35
+
36
+ const int PROCESS_CREATE_THREAD = 0x0002;
37
+ const int PROCESS_QUERY_INFORMATION = 0x0400;
38
+ const int PROCESS_VM_OPERATION = 0x0008;
39
+ const int PROCESS_VM_WRITE = 0x0020;
40
+ const int MEM_COMMIT = 0x1000;
41
+ const int MEM_RESERVE = 0x2000;
42
+ const int PAGE_READWRITE = 0x04;
43
+ const int MEM_RELEASE = 0x8000;
44
+
45
+ public static object Inject(int pid, string dllPath) {
46
+ if (!File.Exists(dllPath)) {
47
+ return new { success = false, error = "DLL not found: " + dllPath };
48
+ }
49
+
50
+ IntPtr hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, false, pid);
51
+ if (hProcess == IntPtr.Zero) {
52
+ int error = Marshal.GetLastWin32Error();
53
+ throw new Win32Exception(error, "Failed to open process. Run as Administrator.");
54
+ }
55
+
56
+ try {
57
+ byte[] dllBytes = System.Text.Encoding.ASCII.GetBytes(dllPath + "\\0");
58
+ IntPtr remoteMem = VirtualAllocEx(hProcess, IntPtr.Zero, dllBytes.Length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
59
+ if (remoteMem == IntPtr.Zero) {
60
+ int error = Marshal.GetLastWin32Error();
61
+ throw new Win32Exception(error, "Failed to allocate memory in target");
62
+ }
63
+
64
+ try {
65
+ int written;
66
+ if (!WriteProcessMemory(hProcess, remoteMem, dllBytes, dllBytes.Length, out written)) {
67
+ int error = Marshal.GetLastWin32Error();
68
+ throw new Win32Exception(error, "Failed to write DLL path to target");
69
+ }
70
+
71
+ IntPtr hKernel32 = GetModuleHandle("kernel32.dll");
72
+ IntPtr loadLibraryAddr = GetProcAddress(hKernel32, "LoadLibraryA");
73
+ if (loadLibraryAddr == IntPtr.Zero) {
74
+ throw new Exception("Failed to get LoadLibraryA address");
75
+ }
76
+
77
+ int threadId;
78
+ IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, loadLibraryAddr, remoteMem, 0, out threadId);
79
+ if (hThread == IntPtr.Zero) {
80
+ int error = Marshal.GetLastWin32Error();
81
+ throw new Win32Exception(error, "Failed to create remote thread");
82
+ }
83
+
84
+ CloseHandle(hThread);
85
+ return new { success = true, remoteThreadId = threadId };
86
+ } finally {
87
+ VirtualFreeEx(hProcess, remoteMem, 0, MEM_RELEASE);
88
+ }
89
+ } finally {
90
+ CloseHandle(hProcess);
91
+ }
92
+ }
93
+ }
94
+ "@
95
+
96
+ try {
97
+ $result = [DllInjector]::Inject(${pid}, "${dllPath.replace(/\\/g, '\\\\').replace(/"/g, '`"').replace(/`/g, '``').replace(/\$/g, '`$')}")
98
+ $result | ConvertTo-Json -Compress
99
+ } catch {
100
+ @{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
101
+ }
102
102
  `.trim();
103
103
  }
104
104
  export async function injectDll(platform, pid, dllPath) {
@@ -127,93 +127,93 @@ export async function injectDll(platform, pid, dllPath) {
127
127
  }
128
128
  }
129
129
  function buildShellcodeInjectionScript(pid, shellcode) {
130
- return `
131
- Add-Type @"
132
- using System;
133
- using System.Runtime.InteropServices;
134
- using System.ComponentModel;
135
-
136
- public class ShellcodeInjector {
137
- [DllImport("kernel32.dll", SetLastError = true)]
138
- public static extern IntPtr OpenProcess(int access, bool inherit, int pid);
139
-
140
- [DllImport("kernel32.dll", SetLastError = true)]
141
- public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr addr, int size, int allocType, int protect);
142
-
143
- [DllImport("kernel32.dll", SetLastError = true)]
144
- public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr addr, byte[] buffer, int size, out int written);
145
-
146
- [DllImport("kernel32.dll", SetLastError = true)]
147
- public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr attr, int stackSize, IntPtr startAddr, IntPtr param, int flags, out int threadId);
148
-
149
- [DllImport("kernel32.dll", SetLastError = true)]
150
- public static extern bool CloseHandle(IntPtr handle);
151
-
152
- [DllImport("kernel32.dll", SetLastError = true)]
153
- public static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr addr, int size, int newProtect, out int oldProtect);
154
-
155
- const int PROCESS_CREATE_THREAD = 0x0002;
156
- const int PROCESS_QUERY_INFORMATION = 0x0400;
157
- const int PROCESS_VM_OPERATION = 0x0008;
158
- const int PROCESS_VM_WRITE = 0x0020;
159
- const int MEM_COMMIT = 0x1000;
160
- const int MEM_RESERVE = 0x2000;
161
- const int PAGE_READWRITE = 0x04;
162
- const int PAGE_EXECUTE_READWRITE = 0x40;
163
-
164
- public static object Inject(int pid, byte[] shellcode) {
165
- IntPtr hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, false, pid);
166
- if (hProcess == IntPtr.Zero) {
167
- int error = Marshal.GetLastWin32Error();
168
- throw new Win32Exception(error, "Failed to open process. Run as Administrator.");
169
- }
170
-
171
- try {
172
- IntPtr remoteMem = VirtualAllocEx(hProcess, IntPtr.Zero, shellcode.Length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
173
- if (remoteMem == IntPtr.Zero) {
174
- int error = Marshal.GetLastWin32Error();
175
- throw new Win32Exception(error, "Failed to allocate memory in target");
176
- }
177
-
178
- try {
179
- int written;
180
- if (!WriteProcessMemory(hProcess, remoteMem, shellcode, shellcode.Length, out written)) {
181
- int error = Marshal.GetLastWin32Error();
182
- throw new Win32Exception(error, "Failed to write shellcode to target");
183
- }
184
-
185
- int oldProtect;
186
- if (!VirtualProtectEx(hProcess, remoteMem, shellcode.Length, PAGE_EXECUTE_READWRITE, out oldProtect)) {
187
- int error = Marshal.GetLastWin32Error();
188
- throw new Win32Exception(error, "Failed to change memory protection to executable");
189
- }
190
-
191
- int threadId;
192
- IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, remoteMem, IntPtr.Zero, 0, out threadId);
193
- if (hThread == IntPtr.Zero) {
194
- int error = Marshal.GetLastWin32Error();
195
- throw new Win32Exception(error, "Failed to create remote thread");
196
- }
197
-
198
- CloseHandle(hThread);
199
- return new { success = true, remoteThreadId = threadId };
200
- } finally {
201
- // Note: Memory is not freed to allow shellcode to execute
202
- }
203
- } finally {
204
- CloseHandle(hProcess);
205
- }
206
- }
207
- }
208
- "@
209
-
210
- try {
211
- $shellcode = @(${Array.from(shellcode).join(',')})
212
- $result = [ShellcodeInjector]::Inject(${pid}, $shellcode)
213
- $result | ConvertTo-Json -Compress
214
- } catch {
215
- @{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
216
- }
130
+ return `
131
+ Add-Type @"
132
+ using System;
133
+ using System.Runtime.InteropServices;
134
+ using System.ComponentModel;
135
+
136
+ public class ShellcodeInjector {
137
+ [DllImport("kernel32.dll", SetLastError = true)]
138
+ public static extern IntPtr OpenProcess(int access, bool inherit, int pid);
139
+
140
+ [DllImport("kernel32.dll", SetLastError = true)]
141
+ public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr addr, int size, int allocType, int protect);
142
+
143
+ [DllImport("kernel32.dll", SetLastError = true)]
144
+ public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr addr, byte[] buffer, int size, out int written);
145
+
146
+ [DllImport("kernel32.dll", SetLastError = true)]
147
+ public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr attr, int stackSize, IntPtr startAddr, IntPtr param, int flags, out int threadId);
148
+
149
+ [DllImport("kernel32.dll", SetLastError = true)]
150
+ public static extern bool CloseHandle(IntPtr handle);
151
+
152
+ [DllImport("kernel32.dll", SetLastError = true)]
153
+ public static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr addr, int size, int newProtect, out int oldProtect);
154
+
155
+ const int PROCESS_CREATE_THREAD = 0x0002;
156
+ const int PROCESS_QUERY_INFORMATION = 0x0400;
157
+ const int PROCESS_VM_OPERATION = 0x0008;
158
+ const int PROCESS_VM_WRITE = 0x0020;
159
+ const int MEM_COMMIT = 0x1000;
160
+ const int MEM_RESERVE = 0x2000;
161
+ const int PAGE_READWRITE = 0x04;
162
+ const int PAGE_EXECUTE_READWRITE = 0x40;
163
+
164
+ public static object Inject(int pid, byte[] shellcode) {
165
+ IntPtr hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, false, pid);
166
+ if (hProcess == IntPtr.Zero) {
167
+ int error = Marshal.GetLastWin32Error();
168
+ throw new Win32Exception(error, "Failed to open process. Run as Administrator.");
169
+ }
170
+
171
+ try {
172
+ IntPtr remoteMem = VirtualAllocEx(hProcess, IntPtr.Zero, shellcode.Length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
173
+ if (remoteMem == IntPtr.Zero) {
174
+ int error = Marshal.GetLastWin32Error();
175
+ throw new Win32Exception(error, "Failed to allocate memory in target");
176
+ }
177
+
178
+ try {
179
+ int written;
180
+ if (!WriteProcessMemory(hProcess, remoteMem, shellcode, shellcode.Length, out written)) {
181
+ int error = Marshal.GetLastWin32Error();
182
+ throw new Win32Exception(error, "Failed to write shellcode to target");
183
+ }
184
+
185
+ int oldProtect;
186
+ if (!VirtualProtectEx(hProcess, remoteMem, shellcode.Length, PAGE_EXECUTE_READWRITE, out oldProtect)) {
187
+ int error = Marshal.GetLastWin32Error();
188
+ throw new Win32Exception(error, "Failed to change memory protection to executable");
189
+ }
190
+
191
+ int threadId;
192
+ IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, remoteMem, IntPtr.Zero, 0, out threadId);
193
+ if (hThread == IntPtr.Zero) {
194
+ int error = Marshal.GetLastWin32Error();
195
+ throw new Win32Exception(error, "Failed to create remote thread");
196
+ }
197
+
198
+ CloseHandle(hThread);
199
+ return new { success = true, remoteThreadId = threadId };
200
+ } finally {
201
+ // Note: Memory is not freed to allow shellcode to execute
202
+ }
203
+ } finally {
204
+ CloseHandle(hProcess);
205
+ }
206
+ }
207
+ }
208
+ "@
209
+
210
+ try {
211
+ $shellcode = @(${Array.from(shellcode).join(',')})
212
+ $result = [ShellcodeInjector]::Inject(${pid}, $shellcode)
213
+ $result | ConvertTo-Json -Compress
214
+ } catch {
215
+ @{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
216
+ }
217
217
  `.trim();
218
218
  }
219
219
  export async function injectShellcode(platform, pid, shellcode, encoding = 'hex') {
@@ -0,0 +1,16 @@
1
+ export interface LinuxMemoryRegion {
2
+ start: bigint;
3
+ end: bigint;
4
+ permissions: {
5
+ read: boolean;
6
+ write: boolean;
7
+ exec: boolean;
8
+ private: boolean;
9
+ };
10
+ offset: bigint;
11
+ dev: string;
12
+ inode: number;
13
+ pathname: string;
14
+ }
15
+ export declare function parseProcMaps(content: string): LinuxMemoryRegion[];
16
+ export declare function formatLinuxProtection(perms: LinuxMemoryRegion['permissions']): string;
@@ -0,0 +1,28 @@
1
+ const PROC_MAPS_LINE_RE = /^([0-9a-f]+)-([0-9a-f]+)\s+([r-][w-][x-][ps])\s+([0-9a-f]+)\s+(\S+)\s+(\d+)\s*(.*)$/i;
2
+ export function parseProcMaps(content) {
3
+ const regions = [];
4
+ for (const line of content.split(/\r?\n/)) {
5
+ const match = line.trimEnd().match(PROC_MAPS_LINE_RE);
6
+ if (!match)
7
+ continue;
8
+ const perms = match[3];
9
+ regions.push({
10
+ start: BigInt(`0x${match[1]}`),
11
+ end: BigInt(`0x${match[2]}`),
12
+ permissions: {
13
+ read: perms[0] === 'r',
14
+ write: perms[1] === 'w',
15
+ exec: perms[2] === 'x',
16
+ private: perms[3] === 'p',
17
+ },
18
+ offset: BigInt(`0x${match[4]}`),
19
+ dev: match[5],
20
+ inode: parseInt(match[6], 10),
21
+ pathname: match[7]?.trim() ?? '',
22
+ });
23
+ }
24
+ return regions;
25
+ }
26
+ export function formatLinuxProtection(perms) {
27
+ return `${perms.read ? 'r' : '-'}${perms.write ? 'w' : '-'}${perms.exec ? 'x' : '-'}`;
28
+ }
@@ -5,56 +5,56 @@ import { isKoffiAvailable } from '../../../native/Win32API.js';
5
5
  import { execAsync, executePowerShellScript, } from '../../process/memory/types.js';
6
6
  async function readMemoryWindows(pid, address, size) {
7
7
  try {
8
- const psScript = `
9
- Add-Type @"
10
- using System;
11
- using System.Runtime.InteropServices;
12
- using System.ComponentModel;
13
-
14
- public class MemoryReader {
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 ReadProcessMemory(IntPtr hProcess, IntPtr addr, byte[] buffer, int size, out int read);
20
-
21
- [DllImport("kernel32.dll", SetLastError = true)]
22
- public static extern bool CloseHandle(IntPtr handle);
23
-
24
- const int PROCESS_VM_READ = 0x0010;
25
- const int PROCESS_QUERY_INFORMATION = 0x0400;
26
-
27
- public static string ReadMemory(int pid, long address, int size) {
28
- IntPtr hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, 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[size];
36
- int bytesRead;
37
- bool success = ReadProcessMemory(hProcess, (IntPtr)address, buffer, size, out bytesRead);
38
-
39
- if (!success) {
40
- int error = Marshal.GetLastWin32Error();
41
- throw new Win32Exception(error, "Failed to read memory");
42
- }
43
-
44
- return BitConverter.ToString(buffer, 0, bytesRead).Replace("-", " ");
45
- } finally {
46
- CloseHandle(hProcess);
47
- }
48
- }
49
- }
50
- "@
51
-
52
- try {
53
- $result = [MemoryReader]::ReadMemory(${pid}, ${address}, ${size})
54
- @{ success = $true; data = $result } | ConvertTo-Json -Compress
55
- } catch {
56
- @{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
57
- }
8
+ const psScript = `
9
+ Add-Type @"
10
+ using System;
11
+ using System.Runtime.InteropServices;
12
+ using System.ComponentModel;
13
+
14
+ public class MemoryReader {
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 ReadProcessMemory(IntPtr hProcess, IntPtr addr, byte[] buffer, int size, out int read);
20
+
21
+ [DllImport("kernel32.dll", SetLastError = true)]
22
+ public static extern bool CloseHandle(IntPtr handle);
23
+
24
+ const int PROCESS_VM_READ = 0x0010;
25
+ const int PROCESS_QUERY_INFORMATION = 0x0400;
26
+
27
+ public static string ReadMemory(int pid, long address, int size) {
28
+ IntPtr hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, 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[size];
36
+ int bytesRead;
37
+ bool success = ReadProcessMemory(hProcess, (IntPtr)address, buffer, size, out bytesRead);
38
+
39
+ if (!success) {
40
+ int error = Marshal.GetLastWin32Error();
41
+ throw new Win32Exception(error, "Failed to read memory");
42
+ }
43
+
44
+ return BitConverter.ToString(buffer, 0, bytesRead).Replace("-", " ");
45
+ } finally {
46
+ CloseHandle(hProcess);
47
+ }
48
+ }
49
+ }
50
+ "@
51
+
52
+ try {
53
+ $result = [MemoryReader]::ReadMemory(${pid}, ${address}, ${size})
54
+ @{ success = $true; data = $result } | ConvertTo-Json -Compress
55
+ } catch {
56
+ @{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
57
+ }
58
58
  `;
59
59
  const { stdout } = await executePowerShellScript(psScript, { maxBuffer: 1024 * 1024 * 10 });
60
60
  const _trimmed = stdout.trim();
@@ -1,5 +1,9 @@
1
+ import { readFileSync } from 'fs';
1
2
  import { logger } from '../../../utils/logger.js';
2
3
  import { execAsync, executePowerShellScript } from '../../process/memory/types.js';
4
+ import { parseProcMaps, formatLinuxProtection } from './linux/mapsParser.js';
5
+ import { nativeMemoryManager } from '../../../native/NativeMemoryManager.js';
6
+ import { isKoffiAvailable } from '../../../native/NativeMemoryManager.utils.js';
3
7
  function buildEnumerateRegionsScript(pid) {
4
8
  return `
5
9
  Add-Type @"
@@ -111,8 +115,28 @@ try {
111
115
  `.trim();
112
116
  }
113
117
  export async function enumerateRegions(platform, pid) {
118
+ if (platform === 'linux') {
119
+ try {
120
+ const mapsContent = readFileSync(`/proc/${pid}/maps`, 'utf-8');
121
+ const readableRegions = parseProcMaps(mapsContent).filter(region => region.permissions.read);
122
+ const regions = readableRegions
123
+ .map(region => ({
124
+ baseAddress: `0x${region.start.toString(16)}`,
125
+ size: Number(region.end - region.start),
126
+ state: 'COMMIT',
127
+ protection: formatLinuxProtection(region.permissions),
128
+ isReadable: true,
129
+ type: region.pathname || 'anonymous',
130
+ }));
131
+ return { success: true, regions };
132
+ }
133
+ catch (error) {
134
+ logger.error('Linux region enumeration failed:', error);
135
+ return { success: false, error: error instanceof Error ? error.message : String(error) };
136
+ }
137
+ }
114
138
  if (platform !== 'win32' && platform !== 'darwin') {
115
- return { success: false, error: 'Region enumeration currently only implemented for Windows and macOS' };
139
+ return { success: false, error: 'Region enumeration currently only implemented for Windows, Linux, and macOS' };
116
140
  }
117
141
  if (platform === 'darwin') {
118
142
  try {
@@ -148,6 +172,26 @@ export async function enumerateRegions(platform, pid) {
148
172
  return { success: false, error: error instanceof Error ? error.message : String(error) };
149
173
  }
150
174
  }
175
+ if (isKoffiAvailable()) {
176
+ try {
177
+ const nativeResult = await nativeMemoryManager.enumerateRegions(pid);
178
+ if (nativeResult.success) {
179
+ return nativeResult;
180
+ }
181
+ logger.warn('Native Windows region enumeration failed, falling back to PowerShell', {
182
+ pid,
183
+ error: nativeResult.error,
184
+ nativeAvailable: isKoffiAvailable(),
185
+ });
186
+ }
187
+ catch (error) {
188
+ logger.warn('Native Windows region enumeration threw, falling back to PowerShell', {
189
+ pid,
190
+ error: error instanceof Error ? error.message : String(error),
191
+ nativeAvailable: isKoffiAvailable(),
192
+ });
193
+ }
194
+ }
151
195
  try {
152
196
  const psScript = buildEnumerateRegionsScript(pid);
153
197
  const { stdout } = await executePowerShellScript(psScript, {