@jshookmcp/jshook 0.2.2 → 0.2.3
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.
- package/LICENSE +661 -661
- package/README.md +4 -4
- package/README.zh.md +3 -3
- package/dist/native/scripts/linux/enum-windows.sh +12 -12
- package/dist/native/scripts/macos/enum-windows.applescript +22 -22
- package/dist/native/scripts/windows/enum-windows-by-class.ps1 +51 -51
- package/dist/native/scripts/windows/enum-windows.ps1 +44 -44
- package/dist/native/scripts/windows/inject-dll.ps1 +21 -21
- package/dist/src/modules/analyzer/CodeAnalyzer.d.ts +1 -1
- package/dist/src/modules/analyzer/CodeAnalyzer.js +1 -1
- package/dist/src/modules/browser/BrowserDiscovery.d.ts +6 -5
- package/dist/src/modules/browser/BrowserDiscovery.js +1 -1
- package/dist/src/modules/browser/BrowserModeManager.d.ts +1 -1
- package/dist/src/modules/browser/BrowserModeManager.js +1 -1
- package/dist/src/modules/browser/UnifiedBrowserManager.js +1 -1
- package/dist/src/modules/captcha/AICaptchaDetector.d.ts +22 -22
- package/dist/src/modules/captcha/AICaptchaDetector.js +75 -75
- package/dist/src/modules/captcha/CaptchaDetector.d.ts +31 -17
- package/dist/src/modules/captcha/CaptchaDetector.js +1 -1
- package/dist/src/modules/collector/CodeCache.d.ts +2 -2
- package/dist/src/modules/collector/CodeCollector.d.ts +12 -9
- package/dist/src/modules/collector/CodeCollector.js +1 -1
- package/dist/src/modules/collector/DOMInspector.d.ts +3 -2
- package/dist/src/modules/collector/DOMInspector.js +1 -1
- package/dist/src/modules/crypto/CryptoDetector.d.ts +1 -1
- package/dist/src/modules/crypto/CryptoDetector.js +1 -1
- package/dist/src/modules/debugger/ScriptManager.impl.extract-function-tree.js +1 -1
- package/dist/src/modules/deobfuscator/Deobfuscator.d.ts +1 -1
- package/dist/src/modules/deobfuscator/Deobfuscator.js +1 -1
- package/dist/src/modules/deobfuscator/JSVMPDeobfuscator.restore.d.ts +1 -1
- package/dist/src/modules/deobfuscator/JSVMPDeobfuscator.restore.js +2 -2
- package/dist/src/modules/deobfuscator/PackerDeobfuscator.js +1 -1
- package/dist/src/modules/deobfuscator/VMDeobfuscator.d.ts +1 -1
- package/dist/src/modules/deobfuscator/VMDeobfuscator.js +82 -82
- package/dist/src/modules/emulator/AIEnvironmentAnalyzer.js +1 -1
- package/dist/src/modules/external/ExternalToolRunner.d.ts +1 -1
- package/dist/src/modules/external/ExternalToolRunner.js +1 -1
- package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.compose.js +5 -5
- package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.network.js +311 -311
- package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.runtime.js +410 -410
- package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.storage.js +122 -122
- package/dist/src/modules/monitor/ConsoleMonitor.impl.core.dynamic.js +194 -194
- package/dist/src/modules/monitor/PlaywrightNetworkMonitor.js +62 -62
- package/dist/src/modules/process/LinuxProcessManager.js +2 -2
- package/dist/src/modules/process/MacProcessManager.js +26 -26
- package/dist/src/modules/process/ProcessManager.impl.js +1 -1
- package/dist/src/modules/process/memory/availability.js +49 -49
- package/dist/src/modules/process/memory/injector.js +185 -185
- package/dist/src/modules/process/memory/reader.js +50 -50
- package/dist/src/modules/process/memory/regions.dump.js +51 -51
- package/dist/src/modules/process/memory/regions.enumerate.js +107 -107
- package/dist/src/modules/process/memory/regions.modules.js +80 -80
- package/dist/src/modules/process/memory/regions.protection.js +106 -106
- package/dist/src/modules/process/memory/scanner.darwin.js +41 -41
- package/dist/src/modules/process/memory/scanner.windows.js +124 -124
- package/dist/src/modules/process/memory/writer.js +54 -54
- package/dist/src/modules/security/ExecutionSandbox.js +44 -44
- package/dist/src/modules/stealth/StealthScripts.d.ts +3 -2
- package/dist/src/modules/stealth/StealthScripts.js +35 -1
- package/dist/src/modules/stealth/StealthVerifier.d.ts +1 -1
- package/dist/src/modules/stealth/StealthVerifier.js +1 -1
- package/dist/src/modules/trace/TraceDB.js +63 -63
- package/dist/src/native/CodeInjector.js +1 -1
- package/dist/src/native/HardwareBreakpoint.js +1 -1
- package/dist/src/server/MCPServer.js +1 -0
- package/dist/src/server/MCPServer.search.helpers.js +1 -1
- package/dist/src/server/MCPServer.tools.js +1 -1
- package/dist/src/server/ToolCallContextGuard.d.ts +5 -0
- package/dist/src/server/ToolCallContextGuard.js +77 -0
- package/dist/src/server/ToolRouter.d.ts +1 -1
- package/dist/src/server/ToolRouter.js +2 -2
- package/dist/src/server/domains/analysis/handlers.impl.d.ts +8 -8
- package/dist/src/server/domains/analysis/handlers.impl.js +8 -8
- package/dist/src/server/domains/analysis/handlers.web-tools.js +2 -2
- package/dist/src/server/domains/browser/definitions.tools.page-core.js +59 -59
- package/dist/src/server/domains/browser/definitions.tools.runtime.js +41 -41
- package/dist/src/server/domains/browser/definitions.tools.security.js +114 -114
- package/dist/src/server/domains/browser/handlers/facade-initializer.d.ts +3 -3
- package/dist/src/server/domains/browser/handlers/facade-initializer.js +3 -3
- package/dist/src/server/domains/browser/handlers/framework-state.js +210 -0
- package/dist/src/server/domains/browser/handlers/stealth-injection.js +8 -2
- package/dist/src/server/domains/browser/handlers.impl.d.ts +15 -11
- package/dist/src/server/domains/browser/handlers.impl.js +4 -4
- package/dist/src/server/domains/coordination/definitions.js +67 -0
- package/dist/src/server/domains/coordination/index.d.ts +18 -0
- package/dist/src/server/domains/coordination/index.js +132 -0
- package/dist/src/server/domains/coordination/manifest.js +15 -0
- package/dist/src/server/domains/graphql/handlers.impl.core.runtime.replay.js +2 -2
- package/dist/src/server/domains/graphql/handlers.impl.core.runtime.shared.js +77 -77
- package/dist/src/server/domains/hooks/ai-handlers.js +3 -3
- package/dist/src/server/domains/maintenance/handlers.d.ts +2 -2
- package/dist/src/server/domains/maintenance/handlers.js +2 -2
- package/dist/src/server/domains/platform/handlers/bridge-handlers.d.ts +1 -1
- package/dist/src/server/domains/platform/handlers/bridge-handlers.js +1 -1
- package/dist/src/server/domains/platform/handlers/miniapp-handlers.d.ts +1 -1
- package/dist/src/server/domains/platform/handlers/miniapp-handlers.js +1 -1
- package/dist/src/server/domains/process/handlers.impl.core.runtime.inject.js +1 -1
- package/dist/src/server/domains/trace/TraceSummarizer.d.ts +60 -0
- package/dist/src/server/domains/trace/TraceSummarizer.js +109 -0
- package/dist/src/server/domains/trace/definitions.tools.js +101 -71
- package/dist/src/server/domains/trace/handlers.d.ts +2 -1
- package/dist/src/server/domains/trace/handlers.js +59 -4
- package/dist/src/server/domains/trace/manifest.js +3 -1
- package/dist/src/server/domains/transform/handlers.impl.transform-base.js +103 -103
- package/dist/src/server/domains/wasm/handlers.js +2 -2
- package/dist/src/server/domains/workflow/handlers.impl.workflow-account-bundle.js +1 -1
- package/dist/src/server/domains/workflow/handlers.impl.workflow-api.js +51 -51
- package/dist/src/server/domains/workflow/handlers.impl.workflow-base.js +51 -51
- package/dist/src/server/extensions/ExtensionManager.roots.js +15 -5
- package/dist/src/server/http/HttpMiddleware.js +1 -1
- package/dist/src/server/registry/contracts.d.ts +6 -0
- package/dist/src/server/sandbox/MCPBridge.d.ts +9 -0
- package/dist/src/server/sandbox/MCPBridge.js +22 -0
- package/dist/src/server/sandbox/QuickJSSandbox.d.ts +4 -1
- package/dist/src/server/sandbox/QuickJSSandbox.js +149 -0
- package/dist/src/server/sandbox/SandboxHelpers.js +250 -250
- package/dist/src/server/sandbox/types.d.ts +13 -0
- package/dist/src/server/search/AffinityGraph.d.ts +7 -1
- package/dist/src/server/search/AffinityGraph.js +24 -3
- package/dist/src/services/LLMService.js +1 -1
- package/dist/src/utils/UnifiedCacheManager.d.ts +1 -1
- package/dist/src/utils/UnifiedCacheManager.js +2 -2
- package/dist/src/utils/cliFastPath.js +18 -4
- package/package.json +5 -3
- package/scripts/postinstall.cjs +37 -37
- package/src/native/scripts/linux/enum-windows.sh +12 -12
- package/src/native/scripts/macos/enum-windows.applescript +22 -22
- package/src/native/scripts/windows/enum-windows-by-class.ps1 +51 -51
- package/src/native/scripts/windows/enum-windows.ps1 +44 -44
- package/src/native/scripts/windows/inject-dll.ps1 +21 -21
|
@@ -5,113 +5,113 @@ import { parseProcMaps, formatLinuxProtection } from './linux/mapsParser.js';
|
|
|
5
5
|
import { nativeMemoryManager } from '../../../native/NativeMemoryManager.js';
|
|
6
6
|
import { isKoffiAvailable } from '../../../native/NativeMemoryManager.utils.js';
|
|
7
7
|
function buildEnumerateRegionsScript(pid) {
|
|
8
|
-
return `
|
|
9
|
-
Add-Type @"
|
|
10
|
-
using System;
|
|
11
|
-
using System.Runtime.InteropServices;
|
|
12
|
-
using System.Collections.Generic;
|
|
13
|
-
using System.ComponentModel;
|
|
14
|
-
|
|
15
|
-
public class RegionEnumerator {
|
|
16
|
-
[DllImport("kernel32.dll", SetLastError = true)]
|
|
17
|
-
public static extern IntPtr OpenProcess(int access, bool inherit, int pid);
|
|
18
|
-
|
|
19
|
-
[DllImport("kernel32.dll", SetLastError = true)]
|
|
20
|
-
public static extern int VirtualQueryEx(IntPtr hProcess, IntPtr addr, out MEMORY_BASIC_INFORMATION info, int size);
|
|
21
|
-
|
|
22
|
-
[DllImport("kernel32.dll", SetLastError = true)]
|
|
23
|
-
public static extern bool CloseHandle(IntPtr handle);
|
|
24
|
-
|
|
25
|
-
const int PROCESS_QUERY_INFORMATION = 0x0400;
|
|
26
|
-
|
|
27
|
-
[StructLayout(LayoutKind.Sequential)]
|
|
28
|
-
public struct MEMORY_BASIC_INFORMATION {
|
|
29
|
-
public IntPtr BaseAddress;
|
|
30
|
-
public IntPtr AllocationBase;
|
|
31
|
-
public uint AllocationProtect;
|
|
32
|
-
public IntPtr RegionSize;
|
|
33
|
-
public uint State;
|
|
34
|
-
public uint Protect;
|
|
35
|
-
public uint Type;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const uint MEM_COMMIT = 0x1000;
|
|
39
|
-
const uint MEM_FREE = 0x10000;
|
|
40
|
-
const uint MEM_RESERVE = 0x2000;
|
|
41
|
-
const uint PAGE_READONLY = 0x02;
|
|
42
|
-
const uint PAGE_READWRITE = 0x04;
|
|
43
|
-
const uint PAGE_WRITECOPY = 0x08;
|
|
44
|
-
const uint PAGE_EXECUTE = 0x10;
|
|
45
|
-
const uint PAGE_EXECUTE_READ = 0x20;
|
|
46
|
-
const uint PAGE_EXECUTE_READWRITE = 0x40;
|
|
47
|
-
|
|
48
|
-
public static List<object> EnumerateRegions(int pid) {
|
|
49
|
-
var regions = new List<object>();
|
|
50
|
-
IntPtr hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 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
|
-
IntPtr addr = IntPtr.Zero;
|
|
58
|
-
MEMORY_BASIC_INFORMATION info;
|
|
59
|
-
int infoSize = Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION));
|
|
60
|
-
int scannedRegions = 0;
|
|
61
|
-
|
|
62
|
-
while (VirtualQueryEx(hProcess, addr, out info, infoSize) == infoSize) {
|
|
63
|
-
scannedRegions++;
|
|
64
|
-
string state = info.State == MEM_COMMIT ? "COMMIT" : (info.State == MEM_RESERVE ? "RESERVE" : (info.State == MEM_FREE ? "FREE" : "UNKNOWN"));
|
|
65
|
-
string protect = GetProtectionString(info.Protect);
|
|
66
|
-
bool isReadable = (info.State == MEM_COMMIT) && ((info.Protect & (PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE)) != 0);
|
|
67
|
-
|
|
68
|
-
regions.Add(new {
|
|
69
|
-
baseAddress = "0x" + info.BaseAddress.ToInt64().ToString("X"),
|
|
70
|
-
size = info.RegionSize.ToInt64(),
|
|
71
|
-
state = state,
|
|
72
|
-
protection = protect,
|
|
73
|
-
isReadable = isReadable,
|
|
74
|
-
type = info.Type == 0x1000000 ? "IMAGE" : (info.Type == 0x40000 ? "MAPPED" : "PRIVATE")
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
if (regions.Count >= 10000 || scannedRegions >= 50000) break;
|
|
78
|
-
long baseAddr = info.BaseAddress.ToInt64();
|
|
79
|
-
long regionSize = info.RegionSize.ToInt64();
|
|
80
|
-
if (regionSize <= 0) break;
|
|
81
|
-
long nextAddr = baseAddr + regionSize;
|
|
82
|
-
if (nextAddr <= baseAddr) break;
|
|
83
|
-
addr = new IntPtr(nextAddr);
|
|
84
|
-
if (addr.ToInt64() >= 0x7FFFFFFF0000) break;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return regions;
|
|
88
|
-
} finally {
|
|
89
|
-
CloseHandle(hProcess);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
private static string GetProtectionString(uint protect) {
|
|
94
|
-
if (protect == 0) return "NOACCESS";
|
|
95
|
-
string s = "";
|
|
96
|
-
if ((protect & 0x100) != 0) s += "NOACCESS ";
|
|
97
|
-
if ((protect & PAGE_READONLY) != 0) s += "R ";
|
|
98
|
-
if ((protect & PAGE_READWRITE) != 0) s += "RW ";
|
|
99
|
-
if ((protect & PAGE_WRITECOPY) != 0) s += "W ";
|
|
100
|
-
if ((protect & PAGE_EXECUTE) != 0) s += "X ";
|
|
101
|
-
if ((protect & PAGE_EXECUTE_READ) != 0) s += "RX ";
|
|
102
|
-
if ((protect & PAGE_EXECUTE_READWRITE) != 0) s += "RWX ";
|
|
103
|
-
if ((protect & 0x100) != 0) s += "GUARD ";
|
|
104
|
-
return s.Trim();
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
"@
|
|
108
|
-
|
|
109
|
-
try {
|
|
110
|
-
$regions = [RegionEnumerator]::EnumerateRegions(${pid})
|
|
111
|
-
@{ success = $true; regions = $regions; count = $regions.Count } | ConvertTo-Json -Compress -Depth 10
|
|
112
|
-
} catch {
|
|
113
|
-
@{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
|
|
114
|
-
}
|
|
8
|
+
return `
|
|
9
|
+
Add-Type @"
|
|
10
|
+
using System;
|
|
11
|
+
using System.Runtime.InteropServices;
|
|
12
|
+
using System.Collections.Generic;
|
|
13
|
+
using System.ComponentModel;
|
|
14
|
+
|
|
15
|
+
public class RegionEnumerator {
|
|
16
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
17
|
+
public static extern IntPtr OpenProcess(int access, bool inherit, int pid);
|
|
18
|
+
|
|
19
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
20
|
+
public static extern int VirtualQueryEx(IntPtr hProcess, IntPtr addr, out MEMORY_BASIC_INFORMATION info, int size);
|
|
21
|
+
|
|
22
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
23
|
+
public static extern bool CloseHandle(IntPtr handle);
|
|
24
|
+
|
|
25
|
+
const int PROCESS_QUERY_INFORMATION = 0x0400;
|
|
26
|
+
|
|
27
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
28
|
+
public struct MEMORY_BASIC_INFORMATION {
|
|
29
|
+
public IntPtr BaseAddress;
|
|
30
|
+
public IntPtr AllocationBase;
|
|
31
|
+
public uint AllocationProtect;
|
|
32
|
+
public IntPtr RegionSize;
|
|
33
|
+
public uint State;
|
|
34
|
+
public uint Protect;
|
|
35
|
+
public uint Type;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const uint MEM_COMMIT = 0x1000;
|
|
39
|
+
const uint MEM_FREE = 0x10000;
|
|
40
|
+
const uint MEM_RESERVE = 0x2000;
|
|
41
|
+
const uint PAGE_READONLY = 0x02;
|
|
42
|
+
const uint PAGE_READWRITE = 0x04;
|
|
43
|
+
const uint PAGE_WRITECOPY = 0x08;
|
|
44
|
+
const uint PAGE_EXECUTE = 0x10;
|
|
45
|
+
const uint PAGE_EXECUTE_READ = 0x20;
|
|
46
|
+
const uint PAGE_EXECUTE_READWRITE = 0x40;
|
|
47
|
+
|
|
48
|
+
public static List<object> EnumerateRegions(int pid) {
|
|
49
|
+
var regions = new List<object>();
|
|
50
|
+
IntPtr hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 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
|
+
IntPtr addr = IntPtr.Zero;
|
|
58
|
+
MEMORY_BASIC_INFORMATION info;
|
|
59
|
+
int infoSize = Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION));
|
|
60
|
+
int scannedRegions = 0;
|
|
61
|
+
|
|
62
|
+
while (VirtualQueryEx(hProcess, addr, out info, infoSize) == infoSize) {
|
|
63
|
+
scannedRegions++;
|
|
64
|
+
string state = info.State == MEM_COMMIT ? "COMMIT" : (info.State == MEM_RESERVE ? "RESERVE" : (info.State == MEM_FREE ? "FREE" : "UNKNOWN"));
|
|
65
|
+
string protect = GetProtectionString(info.Protect);
|
|
66
|
+
bool isReadable = (info.State == MEM_COMMIT) && ((info.Protect & (PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE)) != 0);
|
|
67
|
+
|
|
68
|
+
regions.Add(new {
|
|
69
|
+
baseAddress = "0x" + info.BaseAddress.ToInt64().ToString("X"),
|
|
70
|
+
size = info.RegionSize.ToInt64(),
|
|
71
|
+
state = state,
|
|
72
|
+
protection = protect,
|
|
73
|
+
isReadable = isReadable,
|
|
74
|
+
type = info.Type == 0x1000000 ? "IMAGE" : (info.Type == 0x40000 ? "MAPPED" : "PRIVATE")
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
if (regions.Count >= 10000 || scannedRegions >= 50000) break;
|
|
78
|
+
long baseAddr = info.BaseAddress.ToInt64();
|
|
79
|
+
long regionSize = info.RegionSize.ToInt64();
|
|
80
|
+
if (regionSize <= 0) break;
|
|
81
|
+
long nextAddr = baseAddr + regionSize;
|
|
82
|
+
if (nextAddr <= baseAddr) break;
|
|
83
|
+
addr = new IntPtr(nextAddr);
|
|
84
|
+
if (addr.ToInt64() >= 0x7FFFFFFF0000) break;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return regions;
|
|
88
|
+
} finally {
|
|
89
|
+
CloseHandle(hProcess);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private static string GetProtectionString(uint protect) {
|
|
94
|
+
if (protect == 0) return "NOACCESS";
|
|
95
|
+
string s = "";
|
|
96
|
+
if ((protect & 0x100) != 0) s += "NOACCESS ";
|
|
97
|
+
if ((protect & PAGE_READONLY) != 0) s += "R ";
|
|
98
|
+
if ((protect & PAGE_READWRITE) != 0) s += "RW ";
|
|
99
|
+
if ((protect & PAGE_WRITECOPY) != 0) s += "W ";
|
|
100
|
+
if ((protect & PAGE_EXECUTE) != 0) s += "X ";
|
|
101
|
+
if ((protect & PAGE_EXECUTE_READ) != 0) s += "RX ";
|
|
102
|
+
if ((protect & PAGE_EXECUTE_READWRITE) != 0) s += "RWX ";
|
|
103
|
+
if ((protect & 0x100) != 0) s += "GUARD ";
|
|
104
|
+
return s.Trim();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
"@
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
$regions = [RegionEnumerator]::EnumerateRegions(${pid})
|
|
111
|
+
@{ success = $true; regions = $regions; count = $regions.Count } | ConvertTo-Json -Compress -Depth 10
|
|
112
|
+
} catch {
|
|
113
|
+
@{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
|
|
114
|
+
}
|
|
115
115
|
`.trim();
|
|
116
116
|
}
|
|
117
117
|
export async function enumerateRegions(platform, pid) {
|
|
@@ -5,86 +5,86 @@ export async function enumerateModules(platform, pid) {
|
|
|
5
5
|
return { success: false, error: 'Module enumeration currently only implemented for Windows' };
|
|
6
6
|
}
|
|
7
7
|
try {
|
|
8
|
-
const psScript = `
|
|
9
|
-
Add-Type @"
|
|
10
|
-
using System;
|
|
11
|
-
using System.Runtime.InteropServices;
|
|
12
|
-
using System.Collections.Generic;
|
|
13
|
-
using System.ComponentModel;
|
|
14
|
-
|
|
15
|
-
public class ModuleEnumerator {
|
|
16
|
-
[DllImport("psapi.dll", SetLastError = true)]
|
|
17
|
-
public static extern bool EnumProcessModules(IntPtr hProcess, [Out] IntPtr[] lphModule, int cb, out int lpcbNeeded);
|
|
18
|
-
|
|
19
|
-
[DllImport("psapi.dll", SetLastError = true)]
|
|
20
|
-
public static extern int GetModuleBaseName(IntPtr hProcess, IntPtr hModule, [Out] System.Text.StringBuilder lpBaseName, int nSize);
|
|
21
|
-
|
|
22
|
-
[DllImport("psapi.dll", SetLastError = true)]
|
|
23
|
-
public static extern bool GetModuleInformation(IntPtr hProcess, IntPtr hModule, out MODULEINFO lpmodinfo, int cb);
|
|
24
|
-
|
|
25
|
-
[DllImport("kernel32.dll", SetLastError = true)]
|
|
26
|
-
public static extern IntPtr OpenProcess(int access, bool inherit, int pid);
|
|
27
|
-
|
|
28
|
-
[DllImport("kernel32.dll", SetLastError = true)]
|
|
29
|
-
public static extern bool CloseHandle(IntPtr handle);
|
|
30
|
-
|
|
31
|
-
const int PROCESS_QUERY_INFORMATION = 0x0400;
|
|
32
|
-
const int PROCESS_VM_READ = 0x0010;
|
|
33
|
-
|
|
34
|
-
[StructLayout(LayoutKind.Sequential)]
|
|
35
|
-
public struct MODULEINFO {
|
|
36
|
-
public IntPtr lpBaseOfDll;
|
|
37
|
-
public int SizeOfImage;
|
|
38
|
-
public IntPtr EntryPoint;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
public static object Enumerate(int pid) {
|
|
42
|
-
IntPtr hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid);
|
|
43
|
-
if (hProcess == IntPtr.Zero) {
|
|
44
|
-
int error = Marshal.GetLastWin32Error();
|
|
45
|
-
throw new Win32Exception(error, "Failed to open process");
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
try {
|
|
49
|
-
IntPtr[] modules = new IntPtr[1024];
|
|
50
|
-
int cbNeeded;
|
|
51
|
-
|
|
52
|
-
if (!EnumProcessModules(hProcess, modules, modules.Length * IntPtr.Size, out cbNeeded)) {
|
|
53
|
-
int error = Marshal.GetLastWin32Error();
|
|
54
|
-
throw new Win32Exception(error, "EnumProcessModules failed");
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
int numModules = cbNeeded / IntPtr.Size;
|
|
58
|
-
var result = new List<object>();
|
|
59
|
-
|
|
60
|
-
for (int i = 0; i < numModules; i++) {
|
|
61
|
-
System.Text.StringBuilder baseName = new System.Text.StringBuilder(256);
|
|
62
|
-
if (GetModuleBaseName(hProcess, modules[i], baseName, baseName.Capacity) > 0) {
|
|
63
|
-
MODULEINFO modInfo;
|
|
64
|
-
if (GetModuleInformation(hProcess, modules[i], out modInfo, Marshal.SizeOf(typeof(MODULEINFO)))) {
|
|
65
|
-
result.Add(new {
|
|
66
|
-
name = baseName.ToString(),
|
|
67
|
-
baseAddress = "0x" + modInfo.lpBaseOfDll.ToInt64().ToString("X"),
|
|
68
|
-
size = modInfo.SizeOfImage
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return new { success = true, modules = result };
|
|
75
|
-
} finally {
|
|
76
|
-
CloseHandle(hProcess);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
"@
|
|
81
|
-
|
|
82
|
-
try {
|
|
83
|
-
$result = [ModuleEnumerator]::Enumerate(${pid})
|
|
84
|
-
$result | ConvertTo-Json -Compress -Depth 10
|
|
85
|
-
} catch {
|
|
86
|
-
@{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
|
|
87
|
-
}
|
|
8
|
+
const psScript = `
|
|
9
|
+
Add-Type @"
|
|
10
|
+
using System;
|
|
11
|
+
using System.Runtime.InteropServices;
|
|
12
|
+
using System.Collections.Generic;
|
|
13
|
+
using System.ComponentModel;
|
|
14
|
+
|
|
15
|
+
public class ModuleEnumerator {
|
|
16
|
+
[DllImport("psapi.dll", SetLastError = true)]
|
|
17
|
+
public static extern bool EnumProcessModules(IntPtr hProcess, [Out] IntPtr[] lphModule, int cb, out int lpcbNeeded);
|
|
18
|
+
|
|
19
|
+
[DllImport("psapi.dll", SetLastError = true)]
|
|
20
|
+
public static extern int GetModuleBaseName(IntPtr hProcess, IntPtr hModule, [Out] System.Text.StringBuilder lpBaseName, int nSize);
|
|
21
|
+
|
|
22
|
+
[DllImport("psapi.dll", SetLastError = true)]
|
|
23
|
+
public static extern bool GetModuleInformation(IntPtr hProcess, IntPtr hModule, out MODULEINFO lpmodinfo, int cb);
|
|
24
|
+
|
|
25
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
26
|
+
public static extern IntPtr OpenProcess(int access, bool inherit, int pid);
|
|
27
|
+
|
|
28
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
29
|
+
public static extern bool CloseHandle(IntPtr handle);
|
|
30
|
+
|
|
31
|
+
const int PROCESS_QUERY_INFORMATION = 0x0400;
|
|
32
|
+
const int PROCESS_VM_READ = 0x0010;
|
|
33
|
+
|
|
34
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
35
|
+
public struct MODULEINFO {
|
|
36
|
+
public IntPtr lpBaseOfDll;
|
|
37
|
+
public int SizeOfImage;
|
|
38
|
+
public IntPtr EntryPoint;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public static object Enumerate(int pid) {
|
|
42
|
+
IntPtr hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid);
|
|
43
|
+
if (hProcess == IntPtr.Zero) {
|
|
44
|
+
int error = Marshal.GetLastWin32Error();
|
|
45
|
+
throw new Win32Exception(error, "Failed to open process");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
IntPtr[] modules = new IntPtr[1024];
|
|
50
|
+
int cbNeeded;
|
|
51
|
+
|
|
52
|
+
if (!EnumProcessModules(hProcess, modules, modules.Length * IntPtr.Size, out cbNeeded)) {
|
|
53
|
+
int error = Marshal.GetLastWin32Error();
|
|
54
|
+
throw new Win32Exception(error, "EnumProcessModules failed");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
int numModules = cbNeeded / IntPtr.Size;
|
|
58
|
+
var result = new List<object>();
|
|
59
|
+
|
|
60
|
+
for (int i = 0; i < numModules; i++) {
|
|
61
|
+
System.Text.StringBuilder baseName = new System.Text.StringBuilder(256);
|
|
62
|
+
if (GetModuleBaseName(hProcess, modules[i], baseName, baseName.Capacity) > 0) {
|
|
63
|
+
MODULEINFO modInfo;
|
|
64
|
+
if (GetModuleInformation(hProcess, modules[i], out modInfo, Marshal.SizeOf(typeof(MODULEINFO)))) {
|
|
65
|
+
result.Add(new {
|
|
66
|
+
name = baseName.ToString(),
|
|
67
|
+
baseAddress = "0x" + modInfo.lpBaseOfDll.ToInt64().ToString("X"),
|
|
68
|
+
size = modInfo.SizeOfImage
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return new { success = true, modules = result };
|
|
75
|
+
} finally {
|
|
76
|
+
CloseHandle(hProcess);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
"@
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
$result = [ModuleEnumerator]::Enumerate(${pid})
|
|
84
|
+
$result | ConvertTo-Json -Compress -Depth 10
|
|
85
|
+
} catch {
|
|
86
|
+
@{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
|
|
87
|
+
}
|
|
88
88
|
`;
|
|
89
89
|
const { stdout } = await executePowerShellScript(psScript, {
|
|
90
90
|
maxBuffer: 1024 * 1024 * 10,
|
|
@@ -5,112 +5,112 @@ import { parseProcMaps, formatLinuxProtection } from './linux/mapsParser.js';
|
|
|
5
5
|
import { nativeMemoryManager } from '../../../native/NativeMemoryManager.js';
|
|
6
6
|
import { isKoffiAvailable } from '../../../native/NativeMemoryManager.utils.js';
|
|
7
7
|
function buildProtectionCheckScript(pid, address) {
|
|
8
|
-
return `
|
|
9
|
-
Add-Type @"
|
|
10
|
-
using System;
|
|
11
|
-
using System.Runtime.InteropServices;
|
|
12
|
-
using System.ComponentModel;
|
|
13
|
-
|
|
14
|
-
public class ProtectionChecker {
|
|
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 int VirtualQueryEx(IntPtr hProcess, IntPtr addr, out MEMORY_BASIC_INFORMATION info, int size);
|
|
20
|
-
|
|
21
|
-
[DllImport("kernel32.dll", SetLastError = true)]
|
|
22
|
-
public static extern bool CloseHandle(IntPtr handle);
|
|
23
|
-
|
|
24
|
-
const int PROCESS_QUERY_INFORMATION = 0x0400;
|
|
25
|
-
|
|
26
|
-
[StructLayout(LayoutKind.Sequential)]
|
|
27
|
-
public struct MEMORY_BASIC_INFORMATION {
|
|
28
|
-
public IntPtr BaseAddress;
|
|
29
|
-
public IntPtr AllocationBase;
|
|
30
|
-
public uint AllocationProtect;
|
|
31
|
-
public IntPtr RegionSize;
|
|
32
|
-
public uint State;
|
|
33
|
-
public uint Protect;
|
|
34
|
-
public uint Type;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const uint MEM_COMMIT = 0x1000;
|
|
38
|
-
const uint PAGE_NOACCESS = 0x01;
|
|
39
|
-
const uint PAGE_READONLY = 0x02;
|
|
40
|
-
const uint PAGE_READWRITE = 0x04;
|
|
41
|
-
const uint PAGE_WRITECOPY = 0x08;
|
|
42
|
-
const uint PAGE_EXECUTE = 0x10;
|
|
43
|
-
const uint PAGE_EXECUTE_READ = 0x20;
|
|
44
|
-
const uint PAGE_EXECUTE_READWRITE = 0x40;
|
|
45
|
-
const uint PAGE_EXECUTE_WRITECOPY = 0x80;
|
|
46
|
-
const uint PAGE_GUARD = 0x100;
|
|
47
|
-
|
|
48
|
-
public static object CheckProtection(int pid, long address) {
|
|
49
|
-
IntPtr hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, false, pid);
|
|
50
|
-
if (hProcess == IntPtr.Zero) {
|
|
51
|
-
int error = Marshal.GetLastWin32Error();
|
|
52
|
-
throw new Win32Exception(error, "Failed to open process. Run as Administrator.");
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
try {
|
|
56
|
-
MEMORY_BASIC_INFORMATION info;
|
|
57
|
-
int infoSize = Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION));
|
|
58
|
-
int result = VirtualQueryEx(hProcess, (IntPtr)address, out info, infoSize);
|
|
59
|
-
|
|
60
|
-
if (result != infoSize) {
|
|
61
|
-
return new { success = false, error = "Failed to query memory region" };
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (info.State != MEM_COMMIT) {
|
|
65
|
-
return new {
|
|
66
|
-
success = true,
|
|
67
|
-
protection = "NOT_COMMITTED",
|
|
68
|
-
isWritable = false,
|
|
69
|
-
isReadable = false,
|
|
70
|
-
isExecutable = false,
|
|
71
|
-
regionStart = "0x" + info.BaseAddress.ToInt64().ToString("X"),
|
|
72
|
-
regionSize = info.RegionSize.ToInt64()
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
uint protect = info.Protect;
|
|
77
|
-
string protectionStr = "";
|
|
78
|
-
bool isWritable = false;
|
|
79
|
-
bool isReadable = false;
|
|
80
|
-
bool isExecutable = false;
|
|
81
|
-
|
|
82
|
-
if ((protect & PAGE_NOACCESS) != 0) protectionStr += "NOACCESS ";
|
|
83
|
-
if ((protect & PAGE_READONLY) != 0) { protectionStr += "R "; isReadable = true; }
|
|
84
|
-
if ((protect & PAGE_READWRITE) != 0) { protectionStr += "RW "; isReadable = true; isWritable = true; }
|
|
85
|
-
if ((protect & PAGE_WRITECOPY) != 0) { protectionStr += "WC "; isReadable = true; isWritable = true; }
|
|
86
|
-
if ((protect & PAGE_EXECUTE) != 0) { protectionStr += "X "; isExecutable = true; }
|
|
87
|
-
if ((protect & PAGE_EXECUTE_READ) != 0) { protectionStr += "RX "; isReadable = true; isExecutable = true; }
|
|
88
|
-
if ((protect & PAGE_EXECUTE_READWRITE) != 0) { protectionStr += "RWX "; isReadable = true; isWritable = true; isExecutable = true; }
|
|
89
|
-
if ((protect & PAGE_EXECUTE_WRITECOPY) != 0) { protectionStr += "RWCX "; isReadable = true; isWritable = true; isExecutable = true; }
|
|
90
|
-
if ((protect & PAGE_GUARD) != 0) protectionStr += "GUARD ";
|
|
91
|
-
|
|
92
|
-
return new {
|
|
93
|
-
success = true,
|
|
94
|
-
protection = protectionStr.Trim(),
|
|
95
|
-
isWritable = isWritable,
|
|
96
|
-
isReadable = isReadable,
|
|
97
|
-
isExecutable = isExecutable,
|
|
98
|
-
regionStart = "0x" + info.BaseAddress.ToInt64().ToString("X"),
|
|
99
|
-
regionSize = info.RegionSize.ToInt64()
|
|
100
|
-
};
|
|
101
|
-
} finally {
|
|
102
|
-
CloseHandle(hProcess);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
"@
|
|
107
|
-
|
|
108
|
-
try {
|
|
109
|
-
$result = [ProtectionChecker]::CheckProtection(${pid}, ${address})
|
|
110
|
-
$result | ConvertTo-Json -Compress
|
|
111
|
-
} catch {
|
|
112
|
-
@{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
|
|
113
|
-
}
|
|
8
|
+
return `
|
|
9
|
+
Add-Type @"
|
|
10
|
+
using System;
|
|
11
|
+
using System.Runtime.InteropServices;
|
|
12
|
+
using System.ComponentModel;
|
|
13
|
+
|
|
14
|
+
public class ProtectionChecker {
|
|
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 int VirtualQueryEx(IntPtr hProcess, IntPtr addr, out MEMORY_BASIC_INFORMATION info, int size);
|
|
20
|
+
|
|
21
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
22
|
+
public static extern bool CloseHandle(IntPtr handle);
|
|
23
|
+
|
|
24
|
+
const int PROCESS_QUERY_INFORMATION = 0x0400;
|
|
25
|
+
|
|
26
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
27
|
+
public struct MEMORY_BASIC_INFORMATION {
|
|
28
|
+
public IntPtr BaseAddress;
|
|
29
|
+
public IntPtr AllocationBase;
|
|
30
|
+
public uint AllocationProtect;
|
|
31
|
+
public IntPtr RegionSize;
|
|
32
|
+
public uint State;
|
|
33
|
+
public uint Protect;
|
|
34
|
+
public uint Type;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const uint MEM_COMMIT = 0x1000;
|
|
38
|
+
const uint PAGE_NOACCESS = 0x01;
|
|
39
|
+
const uint PAGE_READONLY = 0x02;
|
|
40
|
+
const uint PAGE_READWRITE = 0x04;
|
|
41
|
+
const uint PAGE_WRITECOPY = 0x08;
|
|
42
|
+
const uint PAGE_EXECUTE = 0x10;
|
|
43
|
+
const uint PAGE_EXECUTE_READ = 0x20;
|
|
44
|
+
const uint PAGE_EXECUTE_READWRITE = 0x40;
|
|
45
|
+
const uint PAGE_EXECUTE_WRITECOPY = 0x80;
|
|
46
|
+
const uint PAGE_GUARD = 0x100;
|
|
47
|
+
|
|
48
|
+
public static object CheckProtection(int pid, long address) {
|
|
49
|
+
IntPtr hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, false, pid);
|
|
50
|
+
if (hProcess == IntPtr.Zero) {
|
|
51
|
+
int error = Marshal.GetLastWin32Error();
|
|
52
|
+
throw new Win32Exception(error, "Failed to open process. Run as Administrator.");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
MEMORY_BASIC_INFORMATION info;
|
|
57
|
+
int infoSize = Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION));
|
|
58
|
+
int result = VirtualQueryEx(hProcess, (IntPtr)address, out info, infoSize);
|
|
59
|
+
|
|
60
|
+
if (result != infoSize) {
|
|
61
|
+
return new { success = false, error = "Failed to query memory region" };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (info.State != MEM_COMMIT) {
|
|
65
|
+
return new {
|
|
66
|
+
success = true,
|
|
67
|
+
protection = "NOT_COMMITTED",
|
|
68
|
+
isWritable = false,
|
|
69
|
+
isReadable = false,
|
|
70
|
+
isExecutable = false,
|
|
71
|
+
regionStart = "0x" + info.BaseAddress.ToInt64().ToString("X"),
|
|
72
|
+
regionSize = info.RegionSize.ToInt64()
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
uint protect = info.Protect;
|
|
77
|
+
string protectionStr = "";
|
|
78
|
+
bool isWritable = false;
|
|
79
|
+
bool isReadable = false;
|
|
80
|
+
bool isExecutable = false;
|
|
81
|
+
|
|
82
|
+
if ((protect & PAGE_NOACCESS) != 0) protectionStr += "NOACCESS ";
|
|
83
|
+
if ((protect & PAGE_READONLY) != 0) { protectionStr += "R "; isReadable = true; }
|
|
84
|
+
if ((protect & PAGE_READWRITE) != 0) { protectionStr += "RW "; isReadable = true; isWritable = true; }
|
|
85
|
+
if ((protect & PAGE_WRITECOPY) != 0) { protectionStr += "WC "; isReadable = true; isWritable = true; }
|
|
86
|
+
if ((protect & PAGE_EXECUTE) != 0) { protectionStr += "X "; isExecutable = true; }
|
|
87
|
+
if ((protect & PAGE_EXECUTE_READ) != 0) { protectionStr += "RX "; isReadable = true; isExecutable = true; }
|
|
88
|
+
if ((protect & PAGE_EXECUTE_READWRITE) != 0) { protectionStr += "RWX "; isReadable = true; isWritable = true; isExecutable = true; }
|
|
89
|
+
if ((protect & PAGE_EXECUTE_WRITECOPY) != 0) { protectionStr += "RWCX "; isReadable = true; isWritable = true; isExecutable = true; }
|
|
90
|
+
if ((protect & PAGE_GUARD) != 0) protectionStr += "GUARD ";
|
|
91
|
+
|
|
92
|
+
return new {
|
|
93
|
+
success = true,
|
|
94
|
+
protection = protectionStr.Trim(),
|
|
95
|
+
isWritable = isWritable,
|
|
96
|
+
isReadable = isReadable,
|
|
97
|
+
isExecutable = isExecutable,
|
|
98
|
+
regionStart = "0x" + info.BaseAddress.ToInt64().ToString("X"),
|
|
99
|
+
regionSize = info.RegionSize.ToInt64()
|
|
100
|
+
};
|
|
101
|
+
} finally {
|
|
102
|
+
CloseHandle(hProcess);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
"@
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
$result = [ProtectionChecker]::CheckProtection(${pid}, ${address})
|
|
110
|
+
$result | ConvertTo-Json -Compress
|
|
111
|
+
} catch {
|
|
112
|
+
@{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
|
|
113
|
+
}
|
|
114
114
|
`.trim();
|
|
115
115
|
}
|
|
116
116
|
export async function checkMemoryProtection(platform, pid, address) {
|