@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
|
@@ -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) {
|
|
@@ -130,93 +130,93 @@ export async function injectDll(platform, pid, dllPath) {
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
function buildShellcodeInjectionScript(pid, shellcode) {
|
|
133
|
-
return `
|
|
134
|
-
Add-Type @"
|
|
135
|
-
using System;
|
|
136
|
-
using System.Runtime.InteropServices;
|
|
137
|
-
using System.ComponentModel;
|
|
138
|
-
|
|
139
|
-
public class ShellcodeInjector {
|
|
140
|
-
[DllImport("kernel32.dll", SetLastError = true)]
|
|
141
|
-
public static extern IntPtr OpenProcess(int access, bool inherit, int pid);
|
|
142
|
-
|
|
143
|
-
[DllImport("kernel32.dll", SetLastError = true)]
|
|
144
|
-
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr addr, int size, int allocType, int protect);
|
|
145
|
-
|
|
146
|
-
[DllImport("kernel32.dll", SetLastError = true)]
|
|
147
|
-
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr addr, byte[] buffer, int size, out int written);
|
|
148
|
-
|
|
149
|
-
[DllImport("kernel32.dll", SetLastError = true)]
|
|
150
|
-
public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr attr, int stackSize, IntPtr startAddr, IntPtr param, int flags, out int threadId);
|
|
151
|
-
|
|
152
|
-
[DllImport("kernel32.dll", SetLastError = true)]
|
|
153
|
-
public static extern bool CloseHandle(IntPtr handle);
|
|
154
|
-
|
|
155
|
-
[DllImport("kernel32.dll", SetLastError = true)]
|
|
156
|
-
public static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr addr, int size, int newProtect, out int oldProtect);
|
|
157
|
-
|
|
158
|
-
const int PROCESS_CREATE_THREAD = 0x0002;
|
|
159
|
-
const int PROCESS_QUERY_INFORMATION = 0x0400;
|
|
160
|
-
const int PROCESS_VM_OPERATION = 0x0008;
|
|
161
|
-
const int PROCESS_VM_WRITE = 0x0020;
|
|
162
|
-
const int MEM_COMMIT = 0x1000;
|
|
163
|
-
const int MEM_RESERVE = 0x2000;
|
|
164
|
-
const int PAGE_READWRITE = 0x04;
|
|
165
|
-
const int PAGE_EXECUTE_READWRITE = 0x40;
|
|
166
|
-
|
|
167
|
-
public static object Inject(int pid, byte[] shellcode) {
|
|
168
|
-
IntPtr hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, false, pid);
|
|
169
|
-
if (hProcess == IntPtr.Zero) {
|
|
170
|
-
int error = Marshal.GetLastWin32Error();
|
|
171
|
-
throw new Win32Exception(error, "Failed to open process. Run as Administrator.");
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
try {
|
|
175
|
-
IntPtr remoteMem = VirtualAllocEx(hProcess, IntPtr.Zero, shellcode.Length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
|
176
|
-
if (remoteMem == IntPtr.Zero) {
|
|
177
|
-
int error = Marshal.GetLastWin32Error();
|
|
178
|
-
throw new Win32Exception(error, "Failed to allocate memory in target");
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
try {
|
|
182
|
-
int written;
|
|
183
|
-
if (!WriteProcessMemory(hProcess, remoteMem, shellcode, shellcode.Length, out written)) {
|
|
184
|
-
int error = Marshal.GetLastWin32Error();
|
|
185
|
-
throw new Win32Exception(error, "Failed to write shellcode to target");
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
int oldProtect;
|
|
189
|
-
if (!VirtualProtectEx(hProcess, remoteMem, shellcode.Length, PAGE_EXECUTE_READWRITE, out oldProtect)) {
|
|
190
|
-
int error = Marshal.GetLastWin32Error();
|
|
191
|
-
throw new Win32Exception(error, "Failed to change memory protection to executable");
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
int threadId;
|
|
195
|
-
IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, remoteMem, IntPtr.Zero, 0, out threadId);
|
|
196
|
-
if (hThread == IntPtr.Zero) {
|
|
197
|
-
int error = Marshal.GetLastWin32Error();
|
|
198
|
-
throw new Win32Exception(error, "Failed to create remote thread");
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
CloseHandle(hThread);
|
|
202
|
-
return new { success = true, remoteThreadId = threadId };
|
|
203
|
-
} finally {
|
|
204
|
-
// Note: Memory is not freed to allow shellcode to execute
|
|
205
|
-
}
|
|
206
|
-
} finally {
|
|
207
|
-
CloseHandle(hProcess);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
"@
|
|
212
|
-
|
|
213
|
-
try {
|
|
214
|
-
$shellcode = @(${Array.from(shellcode).join(',')})
|
|
215
|
-
$result = [ShellcodeInjector]::Inject(${pid}, $shellcode)
|
|
216
|
-
$result | ConvertTo-Json -Compress
|
|
217
|
-
} catch {
|
|
218
|
-
@{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
|
|
219
|
-
}
|
|
133
|
+
return `
|
|
134
|
+
Add-Type @"
|
|
135
|
+
using System;
|
|
136
|
+
using System.Runtime.InteropServices;
|
|
137
|
+
using System.ComponentModel;
|
|
138
|
+
|
|
139
|
+
public class ShellcodeInjector {
|
|
140
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
141
|
+
public static extern IntPtr OpenProcess(int access, bool inherit, int pid);
|
|
142
|
+
|
|
143
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
144
|
+
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr addr, int size, int allocType, int protect);
|
|
145
|
+
|
|
146
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
147
|
+
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr addr, byte[] buffer, int size, out int written);
|
|
148
|
+
|
|
149
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
150
|
+
public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr attr, int stackSize, IntPtr startAddr, IntPtr param, int flags, out int threadId);
|
|
151
|
+
|
|
152
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
153
|
+
public static extern bool CloseHandle(IntPtr handle);
|
|
154
|
+
|
|
155
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
156
|
+
public static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr addr, int size, int newProtect, out int oldProtect);
|
|
157
|
+
|
|
158
|
+
const int PROCESS_CREATE_THREAD = 0x0002;
|
|
159
|
+
const int PROCESS_QUERY_INFORMATION = 0x0400;
|
|
160
|
+
const int PROCESS_VM_OPERATION = 0x0008;
|
|
161
|
+
const int PROCESS_VM_WRITE = 0x0020;
|
|
162
|
+
const int MEM_COMMIT = 0x1000;
|
|
163
|
+
const int MEM_RESERVE = 0x2000;
|
|
164
|
+
const int PAGE_READWRITE = 0x04;
|
|
165
|
+
const int PAGE_EXECUTE_READWRITE = 0x40;
|
|
166
|
+
|
|
167
|
+
public static object Inject(int pid, byte[] shellcode) {
|
|
168
|
+
IntPtr hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, false, pid);
|
|
169
|
+
if (hProcess == IntPtr.Zero) {
|
|
170
|
+
int error = Marshal.GetLastWin32Error();
|
|
171
|
+
throw new Win32Exception(error, "Failed to open process. Run as Administrator.");
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
IntPtr remoteMem = VirtualAllocEx(hProcess, IntPtr.Zero, shellcode.Length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
|
176
|
+
if (remoteMem == IntPtr.Zero) {
|
|
177
|
+
int error = Marshal.GetLastWin32Error();
|
|
178
|
+
throw new Win32Exception(error, "Failed to allocate memory in target");
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
try {
|
|
182
|
+
int written;
|
|
183
|
+
if (!WriteProcessMemory(hProcess, remoteMem, shellcode, shellcode.Length, out written)) {
|
|
184
|
+
int error = Marshal.GetLastWin32Error();
|
|
185
|
+
throw new Win32Exception(error, "Failed to write shellcode to target");
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
int oldProtect;
|
|
189
|
+
if (!VirtualProtectEx(hProcess, remoteMem, shellcode.Length, PAGE_EXECUTE_READWRITE, out oldProtect)) {
|
|
190
|
+
int error = Marshal.GetLastWin32Error();
|
|
191
|
+
throw new Win32Exception(error, "Failed to change memory protection to executable");
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
int threadId;
|
|
195
|
+
IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, remoteMem, IntPtr.Zero, 0, out threadId);
|
|
196
|
+
if (hThread == IntPtr.Zero) {
|
|
197
|
+
int error = Marshal.GetLastWin32Error();
|
|
198
|
+
throw new Win32Exception(error, "Failed to create remote thread");
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
CloseHandle(hThread);
|
|
202
|
+
return new { success = true, remoteThreadId = threadId };
|
|
203
|
+
} finally {
|
|
204
|
+
// Note: Memory is not freed to allow shellcode to execute
|
|
205
|
+
}
|
|
206
|
+
} finally {
|
|
207
|
+
CloseHandle(hProcess);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
"@
|
|
212
|
+
|
|
213
|
+
try {
|
|
214
|
+
$shellcode = @(${Array.from(shellcode).join(',')})
|
|
215
|
+
$result = [ShellcodeInjector]::Inject(${pid}, $shellcode)
|
|
216
|
+
$result | ConvertTo-Json -Compress
|
|
217
|
+
} catch {
|
|
218
|
+
@{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
|
|
219
|
+
}
|
|
220
220
|
`.trim();
|
|
221
221
|
}
|
|
222
222
|
export async function injectShellcode(platform, pid, shellcode, encoding = 'hex') {
|
|
@@ -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,57 +1,57 @@
|
|
|
1
1
|
import { logger } from '../../../utils/logger.js';
|
|
2
2
|
import { execFileAsync, executePowerShellScript, } from '../../process/memory/types.js';
|
|
3
3
|
function buildMemoryDumpScript(pid, address, size, outputPath) {
|
|
4
|
-
return `
|
|
5
|
-
Add-Type @"
|
|
6
|
-
using System;
|
|
7
|
-
using System.Runtime.InteropServices;
|
|
8
|
-
using System.IO;
|
|
9
|
-
using System.ComponentModel;
|
|
10
|
-
|
|
11
|
-
public class MemoryDumper {
|
|
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 bool ReadProcessMemory(IntPtr hProcess, IntPtr addr, byte[] buffer, int size, out int read);
|
|
17
|
-
|
|
18
|
-
[DllImport("kernel32.dll", SetLastError = true)]
|
|
19
|
-
public static extern bool CloseHandle(IntPtr handle);
|
|
20
|
-
|
|
21
|
-
const int PROCESS_VM_READ = 0x0010;
|
|
22
|
-
const int PROCESS_QUERY_INFORMATION = 0x0400;
|
|
23
|
-
|
|
24
|
-
public static string DumpMemory(int pid, long address, int size, string outputPath) {
|
|
25
|
-
IntPtr hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, false, pid);
|
|
26
|
-
if (hProcess == IntPtr.Zero) {
|
|
27
|
-
int error = Marshal.GetLastWin32Error();
|
|
28
|
-
throw new Win32Exception(error, "Failed to open process. Run as Administrator.");
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
byte[] buffer = new byte[size];
|
|
33
|
-
int bytesRead;
|
|
34
|
-
|
|
35
|
-
if (!ReadProcessMemory(hProcess, (IntPtr)address, buffer, size, out bytesRead)) {
|
|
36
|
-
int error = Marshal.GetLastWin32Error();
|
|
37
|
-
throw new Win32Exception(error, "Failed to read memory");
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
File.WriteAllBytes(outputPath, buffer);
|
|
41
|
-
return "Dumped " + bytesRead + " bytes to " + outputPath;
|
|
42
|
-
} finally {
|
|
43
|
-
CloseHandle(hProcess);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
"@
|
|
48
|
-
|
|
49
|
-
try {
|
|
50
|
-
$result = [MemoryDumper]::DumpMemory(${pid}, ${address}, ${size}, "${outputPath.replace(/\\/g, '\\\\').replace(/"/g, '`"').replace(/\$/g, '`$')}")
|
|
51
|
-
@{ success = $true; message = $result } | ConvertTo-Json -Compress
|
|
52
|
-
} catch {
|
|
53
|
-
@{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
|
|
54
|
-
}
|
|
4
|
+
return `
|
|
5
|
+
Add-Type @"
|
|
6
|
+
using System;
|
|
7
|
+
using System.Runtime.InteropServices;
|
|
8
|
+
using System.IO;
|
|
9
|
+
using System.ComponentModel;
|
|
10
|
+
|
|
11
|
+
public class MemoryDumper {
|
|
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 bool ReadProcessMemory(IntPtr hProcess, IntPtr addr, byte[] buffer, int size, out int read);
|
|
17
|
+
|
|
18
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
19
|
+
public static extern bool CloseHandle(IntPtr handle);
|
|
20
|
+
|
|
21
|
+
const int PROCESS_VM_READ = 0x0010;
|
|
22
|
+
const int PROCESS_QUERY_INFORMATION = 0x0400;
|
|
23
|
+
|
|
24
|
+
public static string DumpMemory(int pid, long address, int size, string outputPath) {
|
|
25
|
+
IntPtr hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, false, pid);
|
|
26
|
+
if (hProcess == IntPtr.Zero) {
|
|
27
|
+
int error = Marshal.GetLastWin32Error();
|
|
28
|
+
throw new Win32Exception(error, "Failed to open process. Run as Administrator.");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
byte[] buffer = new byte[size];
|
|
33
|
+
int bytesRead;
|
|
34
|
+
|
|
35
|
+
if (!ReadProcessMemory(hProcess, (IntPtr)address, buffer, size, out bytesRead)) {
|
|
36
|
+
int error = Marshal.GetLastWin32Error();
|
|
37
|
+
throw new Win32Exception(error, "Failed to read memory");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
File.WriteAllBytes(outputPath, buffer);
|
|
41
|
+
return "Dumped " + bytesRead + " bytes to " + outputPath;
|
|
42
|
+
} finally {
|
|
43
|
+
CloseHandle(hProcess);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
"@
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
$result = [MemoryDumper]::DumpMemory(${pid}, ${address}, ${size}, "${outputPath.replace(/\\/g, '\\\\').replace(/"/g, '`"').replace(/\$/g, '`$')}")
|
|
51
|
+
@{ success = $true; message = $result } | ConvertTo-Json -Compress
|
|
52
|
+
} catch {
|
|
53
|
+
@{ success = $false; error = $_.Exception.Message } | ConvertTo-Json -Compress
|
|
54
|
+
}
|
|
55
55
|
`.trim();
|
|
56
56
|
}
|
|
57
57
|
export async function dumpMemoryRegion(platform, pid, startAddress, size, outputPath) {
|