@jshookmcp/jshook 0.2.8 → 0.3.0

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 (162) hide show
  1. package/README.md +36 -5
  2. package/README.zh.md +36 -5
  3. package/dist/{AntiCheatDetector-S8VRj-dD.mjs → AntiCheatDetector-CqGDXmfc.mjs} +160 -54
  4. package/dist/{CodeInjector-4Z3ngPoX.mjs → CodeInjector-BdjRfNx7.mjs} +5 -5
  5. package/dist/ConsoleMonitor-DykL3IAw.mjs +2269 -0
  6. package/dist/{DarwinAPI-B8hg_yhz.mjs → DarwinAPI-ETyy0xyo.mjs} +1 -1
  7. package/dist/DetailedDataManager-HT49OrvF.mjs +217 -0
  8. package/dist/EventBus-DFKvADm3.mjs +141 -0
  9. package/dist/EvidenceGraphBridge-318Oi0Lf.mjs +153 -0
  10. package/dist/{ExtensionManager-D5-bO9D8.mjs → ExtensionManager-BDMsY2Dz.mjs} +27 -13
  11. package/dist/{FingerprintManager-BVxFJL2-.mjs → FingerprintManager-BN4UQWnX.mjs} +1 -1
  12. package/dist/{HardwareBreakpoint-DK1yjWkV.mjs → HardwareBreakpoint-Cc2AFq1Y.mjs} +3 -3
  13. package/dist/{HeapAnalyzer-CEbo10xU.mjs → HeapAnalyzer-DruMgsgj.mjs} +21 -21
  14. package/dist/HookGeneratorBuilders.core.generators.storage-CTbB4Lcx.mjs +566 -0
  15. package/dist/InstrumentationSession-DLH0vd-z.mjs +244 -0
  16. package/dist/{MemoryController-DdtnBdD4.mjs → MemoryController-CMtviNW_.mjs} +3 -3
  17. package/dist/{MemoryScanSession-RMixN3bX.mjs → MemoryScanSession-ITgb_NMi.mjs} +81 -78
  18. package/dist/{MemoryScanner-QjK4ld0B.mjs → MemoryScanner-CiL7Z3ey.mjs} +50 -21
  19. package/dist/{NativeMemoryManager.impl-CB6gJ0NM.mjs → NativeMemoryManager.impl-D9Lkovvn.mjs} +20 -56
  20. package/dist/{NativeMemoryManager.utils-BML4q1ry.mjs → NativeMemoryManager.utils-BBlAixF5.mjs} +1 -1
  21. package/dist/{PEAnalyzer-CK0xe0Fs.mjs → PEAnalyzer-DMQ44gen.mjs} +16 -16
  22. package/dist/PageController-BPJNqqBN.mjs +431 -0
  23. package/dist/{PointerChainEngine-Cd73qu5b.mjs → PointerChainEngine-K7wN8Z-w.mjs} +10 -7
  24. package/dist/PrerequisiteError-TuyZIs6n.mjs +20 -0
  25. package/dist/ProcessRegistry-zGg12QbE.mjs +74 -0
  26. package/dist/ResponseBuilder-CJXWmWNw.mjs +143 -0
  27. package/dist/ReverseEvidenceGraph-C02-gXOh.mjs +269 -0
  28. package/dist/ScriptManager-ZuWD-0Jg.mjs +3003 -0
  29. package/dist/{Speedhack-CeF0XmEz.mjs → Speedhack-D-z0umeT.mjs} +2 -2
  30. package/dist/{StructureAnalyzer-D4GkMduU.mjs → StructureAnalyzer-Cav5AVSL.mjs} +9 -6
  31. package/dist/ToolCatalog-5OJdMiF0.mjs +582 -0
  32. package/dist/ToolError-jh9whhMd.mjs +15 -0
  33. package/dist/ToolProbe-DbCFGyrg.mjs +45 -0
  34. package/dist/ToolRegistry-B9krbTtI.mjs +180 -0
  35. package/dist/ToolRouter.policy-BGDAGyeH.mjs +344 -0
  36. package/dist/TraceRecorder-B41Z5XBj.mjs +1286 -0
  37. package/dist/{Win32API-Bc0QnQsN.mjs → Win32API-C2kjj0ze.mjs} +19 -13
  38. package/dist/{Win32Debug-DUHt9XUn.mjs → Win32Debug-CKrGOTpo.mjs} +3 -3
  39. package/dist/WorkflowEngine-DJ6M4opp.mjs +569 -0
  40. package/dist/analysis-BHeJW2Nb.mjs +1234 -0
  41. package/dist/antidebug-BRKeyt27.mjs +1081 -0
  42. package/dist/artifactRetention-CPXkUJXp.mjs +598 -0
  43. package/dist/artifacts-DkfosXH3.mjs +59 -0
  44. package/dist/authorization-schema-DRqyJMSk.mjs +31 -0
  45. package/dist/betterSqlite3-DLSBZodi.mjs +74 -0
  46. package/dist/binary-instrument--V3MAhJ4.mjs +971 -0
  47. package/dist/bind-helpers-ClV34xdn.mjs +42 -0
  48. package/dist/boringssl-inspector-Bo_LOLaS.mjs +180 -0
  49. package/dist/browser-Dx3_S2cG.mjs +4369 -0
  50. package/dist/capabilities-CcHlvWgK.mjs +33 -0
  51. package/dist/concurrency-Drev_Vz9.mjs +41 -0
  52. package/dist/{constants-CCvsN80K.mjs → constants-CDZLOoVv.mjs} +105 -48
  53. package/dist/coordination-DgItD9DL.mjs +259 -0
  54. package/dist/debugger-RS3RSAqs.mjs +1288 -0
  55. package/dist/definitions-BEoYofW5.mjs +47 -0
  56. package/dist/definitions-BRaefg3u.mjs +365 -0
  57. package/dist/definitions-BbkvZkiv.mjs +96 -0
  58. package/dist/definitions-BtWSHJ3o.mjs +17 -0
  59. package/dist/definitions-C1gCHO0i.mjs +43 -0
  60. package/dist/definitions-CDOg_b-l.mjs +138 -0
  61. package/dist/definitions-CVPD9hzZ.mjs +54 -0
  62. package/dist/definitions-Cea8Lgl7.mjs +94 -0
  63. package/dist/definitions-DAgIyjxM.mjs +10 -0
  64. package/dist/definitions-DJA27nsL.mjs +66 -0
  65. package/dist/definitions-DKPFU3LW.mjs +25 -0
  66. package/dist/definitions-DPRpZQ96.mjs +47 -0
  67. package/dist/definitions-DUE5gmdn.mjs +18 -0
  68. package/dist/definitions-DYVjOtxa.mjs +26 -0
  69. package/dist/definitions-DcYLVLCo.mjs +37 -0
  70. package/dist/definitions-Pp5LI2H4.mjs +27 -0
  71. package/dist/definitions-j9KdHVNR.mjs +14 -0
  72. package/dist/definitions-uzkjBwa7.mjs +258 -0
  73. package/dist/definitions-va-AnLuQ.mjs +28 -0
  74. package/dist/encoding-DJeqHmpd.mjs +1079 -0
  75. package/dist/evidence-graph-bridge-DcYizFk2.mjs +136 -0
  76. package/dist/{factory-CibqTNC8.mjs → factory-C90tBff6.mjs} +41 -56
  77. package/dist/flat-target-session-Dgax2Cy3.mjs +29 -0
  78. package/dist/graphql-CoHrhweh.mjs +1197 -0
  79. package/dist/handlers-4jmR0nMs.mjs +898 -0
  80. package/dist/handlers-BAHPxcch.mjs +789 -0
  81. package/dist/handlers-BOs9b907.mjs +2600 -0
  82. package/dist/handlers-BWXEy6ef.mjs +917 -0
  83. package/dist/handlers-Bndn6QvE.mjs +111 -0
  84. package/dist/handlers-BqC4bD4s.mjs +681 -0
  85. package/dist/handlers-BtYq60bM2.mjs +276 -0
  86. package/dist/handlers-BzgcB4iv.mjs +799 -0
  87. package/dist/handlers-CRyRWj2b.mjs +859 -0
  88. package/dist/handlers-CVv2H1uq.mjs +592 -0
  89. package/dist/handlers-Dl5a7JS4.mjs +572 -0
  90. package/dist/handlers-Dx2d7jt7.mjs +2537 -0
  91. package/dist/handlers-Dz9PYsCa.mjs +2805 -0
  92. package/dist/handlers-HujRKC3b.mjs +661 -0
  93. package/dist/handlers.impl-XWXkQfyi.mjs +807 -0
  94. package/dist/hooks-B1B8NRHL.mjs +898 -0
  95. package/dist/index.mjs +491 -259
  96. package/dist/{logger-BmWzC2lM.mjs → logger-Dh_xb7_2.mjs} +14 -6
  97. package/dist/maintenance-PRMkLVRW.mjs +835 -0
  98. package/dist/manifest-67Bok-Si.mjs +58 -0
  99. package/dist/manifest-6lNTMZAB2.mjs +87 -0
  100. package/dist/manifest-B2duEHiH.mjs +90 -0
  101. package/dist/manifest-B6EY9Vm8.mjs +57 -0
  102. package/dist/manifest-B6nKSbyY.mjs +95 -0
  103. package/dist/manifest-BL8AQNPF.mjs +106 -0
  104. package/dist/manifest-BSZvJJmV.mjs +47 -0
  105. package/dist/manifest-BU7qzUyX.mjs +418 -0
  106. package/dist/manifest-Bl62e8WK.mjs +49 -0
  107. package/dist/manifest-Bo5cXjdt.mjs +82 -0
  108. package/dist/manifest-BpS4gtUK.mjs +1347 -0
  109. package/dist/manifest-Bv65_e2W.mjs +101 -0
  110. package/dist/manifest-BytNIF4Z.mjs +117 -0
  111. package/dist/manifest-C-xtsjS3.mjs +81 -0
  112. package/dist/manifest-CDYl7OhA.mjs +66 -0
  113. package/dist/manifest-CRZ3xmkD.mjs +61 -0
  114. package/dist/manifest-CoW6u4Tp.mjs +132 -0
  115. package/dist/manifest-Cq5zN_8A.mjs +50 -0
  116. package/dist/manifest-D7YZM_2e.mjs +194 -0
  117. package/dist/manifest-DE_VrAeQ.mjs +314 -0
  118. package/dist/manifest-DGsXSCpT.mjs +39 -0
  119. package/dist/manifest-DJ2vfEuW.mjs +156 -0
  120. package/dist/manifest-DPXDYhEu.mjs +80 -0
  121. package/dist/manifest-Dd4fQb0a.mjs +322 -0
  122. package/dist/manifest-Deq6opGg.mjs +223 -0
  123. package/dist/manifest-DfJTafJK.mjs +37 -0
  124. package/dist/manifest-DgOdgN_j.mjs +50 -0
  125. package/dist/manifest-DlbMW4v4.mjs +47 -0
  126. package/dist/manifest-DmVfbH0w.mjs +374 -0
  127. package/dist/manifest-Dog6Ddjr.mjs +109 -0
  128. package/dist/manifest-DvgU5FWb.mjs +58 -0
  129. package/dist/manifest-HsfDBs7j.mjs +50 -0
  130. package/dist/manifest-I8oQHvCG.mjs +186 -0
  131. package/dist/manifest-NvH_a-av.mjs +786 -0
  132. package/dist/manifest-cEJU1v0Z.mjs +129 -0
  133. package/dist/manifest-wOl5XLB12.mjs +112 -0
  134. package/dist/modules-tZozf0LQ.mjs +10635 -0
  135. package/dist/mojo-ipc-DXNEXEqb.mjs +640 -0
  136. package/dist/network-CPVvwvFg.mjs +3852 -0
  137. package/dist/{artifacts-BbdOMET5.mjs → outputPaths-um7lCRY3.mjs} +219 -216
  138. package/dist/parse-args-B4cY5Vx5.mjs +39 -0
  139. package/dist/platform-CYeFoTWp.mjs +2161 -0
  140. package/dist/process-BTbgcVc6.mjs +1306 -0
  141. package/dist/proxy-r8YN6nP1.mjs +192 -0
  142. package/dist/registry-Bl8ZQW61.mjs +34 -0
  143. package/dist/response-CWhh2aLo.mjs +34 -0
  144. package/dist/server/plugin-api.mjs +2 -2
  145. package/dist/shared-state-board-BoZnSoj-.mjs +586 -0
  146. package/dist/sourcemap-BIDHUVXy.mjs +934 -0
  147. package/dist/ssrf-policy-Dsqd-DTX.mjs +166 -0
  148. package/dist/streaming-Dal6utPp.mjs +725 -0
  149. package/dist/tool-builder-BHJp32mV.mjs +186 -0
  150. package/dist/transform-DRVgGG90.mjs +1011 -0
  151. package/dist/types-Bx92KJfT.mjs +4 -0
  152. package/dist/wasm-BYx5UOeG.mjs +1044 -0
  153. package/dist/webcrack-Be0_FccV.mjs +747 -0
  154. package/dist/workflow-BpuKEtvn.mjs +725 -0
  155. package/package.json +82 -49
  156. package/dist/ExtensionManager-CPTJhHFg.mjs +0 -2
  157. package/dist/ToolCatalog-Bq4V2sbJ.mjs +0 -67201
  158. package/dist/{CacheAdapters-CzFNpD9a.mjs → CacheAdapters-jJFy20G-.mjs} +0 -0
  159. package/dist/{StealthVerifier-BzBCFiwx.mjs → StealthVerifier-BWmPgQsv.mjs} +0 -0
  160. package/dist/{VersionDetector-CNXcvD46.mjs → VersionDetector-K3V4vGsw.mjs} +0 -0
  161. package/dist/{formatAddress-ChCSIRWT.mjs → formatAddress-nnMvEohD.mjs} +0 -0
  162. package/dist/{types-BBjOqye-.mjs → types-DDBWs9UP.mjs} +1 -1
@@ -0,0 +1,244 @@
1
+ //#region src/server/instrumentation/InstrumentationSession.ts
2
+ let nextId = 0;
3
+ function uid(prefix) {
4
+ return `${prefix}-${Date.now().toString(36)}-${(++nextId).toString(36)}`;
5
+ }
6
+ function isRecord(value) {
7
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8
+ }
9
+ function parseToolPayload(response) {
10
+ const firstText = response.content.find((item) => item.type === "text" && typeof item.text === "string");
11
+ if (!firstText) throw new Error("Expected JSON text payload from wrapped tool response");
12
+ let parsed;
13
+ try {
14
+ parsed = JSON.parse(firstText.text);
15
+ } catch (error) {
16
+ throw new Error(
17
+ /* istanbul ignore next */
18
+ `Wrapped tool returned non-JSON text payload: ${error instanceof Error ? error.message : String(error)}`,
19
+ { cause: error }
20
+ );
21
+ }
22
+ if (!isRecord(parsed)) throw new Error("Wrapped tool returned JSON that is not an object");
23
+ return parsed;
24
+ }
25
+ function getStringArray(value) {
26
+ return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
27
+ }
28
+ var InstrumentationSessionManager = class {
29
+ /** All sessions (including destroyed). */
30
+ sessions = /* @__PURE__ */ new Map();
31
+ /** Session ID → operations. */
32
+ operations = /* @__PURE__ */ new Map();
33
+ /** Session ID → artifacts. */
34
+ artifacts = /* @__PURE__ */ new Map();
35
+ /** Operation ID → owning session ID (reverse index). */
36
+ operationIndex = /* @__PURE__ */ new Map();
37
+ /** Optional evidence graph bridge for auto-population (EVID-04). */
38
+ evidenceBridge;
39
+ /** Set the evidence graph bridge for auto-populating evidence nodes. */
40
+ setEvidenceBridge(bridge) {
41
+ this.evidenceBridge = bridge;
42
+ }
43
+ createSession(name) {
44
+ const id = uid("sess");
45
+ const info = {
46
+ id,
47
+ name,
48
+ createdAt: Date.now(),
49
+ operationCount: 0,
50
+ artifactCount: 0,
51
+ status: "active"
52
+ };
53
+ this.sessions.set(id, info);
54
+ this.operations.set(id, []);
55
+ this.artifacts.set(id, []);
56
+ return info;
57
+ }
58
+ destroySession(sessionId) {
59
+ const session = this.sessions.get(sessionId);
60
+ if (!session) throw new Error(`Session "${sessionId}" not found`);
61
+ session.status = "destroyed";
62
+ /* istanbul ignore next */
63
+ const ops = this.operations.get(sessionId) ?? [];
64
+ for (const op of ops) if (op.status === "active") op.status = "completed";
65
+ }
66
+ listSessions() {
67
+ return [...this.sessions.values()].filter((s) => s.status === "active");
68
+ }
69
+ getSession(sessionId) {
70
+ return this.sessions.get(sessionId);
71
+ }
72
+ registerOperation(sessionId, type, target, config) {
73
+ const session = this.sessions.get(sessionId);
74
+ if (!session) throw new Error(`Session "${sessionId}" not found`);
75
+ if (session.status === "destroyed") throw new Error(`Session "${sessionId}" is destroyed — cannot register new operations`);
76
+ const id = uid("op");
77
+ const op = {
78
+ id,
79
+ sessionId,
80
+ type,
81
+ target,
82
+ config,
83
+ createdAt: Date.now(),
84
+ status: "active"
85
+ };
86
+ const ops = this.operations.get(sessionId);
87
+ ops.push(op);
88
+ this.operationIndex.set(id, sessionId);
89
+ session.operationCount = ops.length;
90
+ this.evidenceBridge?.onOperation(op);
91
+ return op;
92
+ }
93
+ getSessionOperations(sessionId) {
94
+ /* istanbul ignore next */
95
+ return this.operations.get(sessionId) ?? [];
96
+ }
97
+ recordArtifact(operationId, data) {
98
+ const sessionId = this.operationIndex.get(operationId);
99
+ if (!sessionId) throw new Error(`Operation "${operationId}" not found`);
100
+ const op = (this.operations.get(sessionId) ?? []).find((o) => o.id === operationId);
101
+ if (!op) throw new Error(`Operation "${operationId}" metadata missing`);
102
+ const artifact = {
103
+ operationId,
104
+ sessionId,
105
+ type: op.type,
106
+ timestamp: Date.now(),
107
+ data
108
+ };
109
+ const sessionArtifacts = this.artifacts.get(sessionId);
110
+ sessionArtifacts.push(artifact);
111
+ const session = this.sessions.get(sessionId);
112
+ session.artifactCount = sessionArtifacts.length;
113
+ this.evidenceBridge?.onArtifact(artifact);
114
+ return artifact;
115
+ }
116
+ getArtifacts(sessionId, type) {
117
+ /* istanbul ignore next */
118
+ const all = this.artifacts.get(sessionId) ?? [];
119
+ if (!type) return all;
120
+ return all.filter((a) => a.type === type);
121
+ }
122
+ getSessionSnapshot(sessionId) {
123
+ const session = this.sessions.get(sessionId);
124
+ if (!session) return;
125
+ return {
126
+ session,
127
+ stats: this.getSessionStats(sessionId),
128
+ operations: [...this.getSessionOperations(sessionId)],
129
+ artifacts: [...this.getArtifacts(sessionId)]
130
+ };
131
+ }
132
+ listSessionSnapshots() {
133
+ return this.listSessions().map((session) => ({
134
+ session,
135
+ stats: this.getSessionStats(session.id),
136
+ operations: [...this.getSessionOperations(session.id)],
137
+ artifacts: [...this.getArtifacts(session.id)]
138
+ }));
139
+ }
140
+ async applyHookPreset(sessionId, presetInvoker, args) {
141
+ const presetNames = getStringArray(args["presets"]);
142
+ const target = (typeof args["preset"] === "string" ? args["preset"] : void 0) ?? (presetNames.length > 0 ? presetNames.join(", ") : "hook_preset");
143
+ return this.executeTrackedTool({
144
+ sessionId,
145
+ type: "runtime-hook",
146
+ target,
147
+ config: { ...args },
148
+ invoke: () => presetInvoker.handleHookPreset(args),
149
+ isSuccessful: (payload) => {
150
+ return getStringArray(payload.injected).length > 0;
151
+ },
152
+ buildArtifacts: (payload) => {
153
+ const injected = getStringArray(payload.injected);
154
+ return [{
155
+ presetIds: injected,
156
+ failedPresets: Array.isArray(payload.failed) ? payload.failed.filter((item) => isRecord(item) && typeof item["preset"] === "string" && typeof item["error"] === "string") : [],
157
+ injectionPoint: payload.method === "evaluateOnNewDocument" ? "before-load" : "runtime",
158
+ scriptContent: injected.join(", "),
159
+ body: payload
160
+ }];
161
+ }
162
+ });
163
+ }
164
+ async replayNetworkRequest(sessionId, replayInvoker, args) {
165
+ const requestId = typeof args["requestId"] === "string" ? args["requestId"] : "network_replay";
166
+ const urlOverride = typeof args["urlOverride"] === "string" ? args["urlOverride"] : void 0;
167
+ return this.executeTrackedTool({
168
+ sessionId,
169
+ type: "network-intercept",
170
+ target: requestId,
171
+ config: { ...args },
172
+ invoke: () => replayInvoker.handleNetworkReplayRequest(args),
173
+ buildArtifacts: (payload) => {
174
+ if (payload.dryRun === true && isRecord(payload.preview)) return [{
175
+ requestId,
176
+ url: typeof payload.preview["url"] === "string" ? payload.preview["url"] : urlOverride,
177
+ method: typeof payload.preview["method"] === "string" ? payload.preview["method"] : void 0,
178
+ headers: isRecord(payload.preview["headers"]) ? payload.preview["headers"] : void 0,
179
+ body: payload.preview["body"],
180
+ replayMode: "dry-run"
181
+ }];
182
+ return [{
183
+ requestId: typeof payload.requestId === "string" ? payload.requestId : requestId,
184
+ url: urlOverride,
185
+ method: typeof args["methodOverride"] === "string" ? args["methodOverride"] : void 0,
186
+ headers: isRecord(payload.headers) ? payload.headers : void 0,
187
+ body: payload.body,
188
+ statusCode: typeof payload.status === "number" ? payload.status : void 0,
189
+ statusText: typeof payload.statusText === "string" ? payload.statusText : void 0,
190
+ bodyTruncated: typeof payload.bodyTruncated === "boolean" ? payload.bodyTruncated : void 0,
191
+ replayMode: "live"
192
+ }];
193
+ }
194
+ });
195
+ }
196
+ getSessionStats(sessionId) {
197
+ const session = this.sessions.get(sessionId);
198
+ if (!session) return {
199
+ operationCount: 0,
200
+ artifactCount: 0
201
+ };
202
+ return {
203
+ operationCount: session.operationCount,
204
+ artifactCount: session.artifactCount
205
+ };
206
+ }
207
+ findOperation(operationId) {
208
+ const sessionId = this.operationIndex.get(operationId);
209
+ if (!sessionId) return;
210
+ /* istanbul ignore next */
211
+ return (this.operations.get(sessionId) ?? []).find((operation) => operation.id === operationId);
212
+ }
213
+ setOperationStatus(operationId, status) {
214
+ const operation = this.findOperation(operationId);
215
+ if (operation) operation.status = status;
216
+ }
217
+ async executeTrackedTool(spec) {
218
+ const operation = this.registerOperation(spec.sessionId, spec.type, spec.target, spec.config);
219
+ try {
220
+ const payload = parseToolPayload(await spec.invoke());
221
+ if (!(spec.isSuccessful ? spec.isSuccessful(payload) : payload["success"] !== false)) {
222
+ this.setOperationStatus(operation.id, "failed");
223
+ return {
224
+ operation,
225
+ artifacts: [],
226
+ payload
227
+ };
228
+ }
229
+ /* istanbul ignore next */
230
+ const artifacts = (spec.buildArtifacts?.(payload) ?? []).map((artifactData) => this.recordArtifact(operation.id, artifactData));
231
+ this.setOperationStatus(operation.id, "completed");
232
+ return {
233
+ operation,
234
+ artifacts,
235
+ payload
236
+ };
237
+ } catch (error) {
238
+ this.setOperationStatus(operation.id, "failed");
239
+ throw error;
240
+ }
241
+ }
242
+ };
243
+ //#endregion
244
+ export { InstrumentationSessionManager };
@@ -1,6 +1,6 @@
1
- import { cr as WRITE_HISTORY_MAX, q as FREEZE_DEFAULT_INTERVAL_MS } from "./constants-CCvsN80K.mjs";
2
- import { _ as WriteProcessMemory, b as openProcessForMemory, d as ReadProcessMemory, m as VirtualProtectEx, t as CloseHandle, u as PAGE } from "./Win32API-Bc0QnQsN.mjs";
3
- import { i as parsePattern } from "./NativeMemoryManager.utils-BML4q1ry.mjs";
1
+ import { Vr as WRITE_HISTORY_MAX, Z as FREEZE_DEFAULT_INTERVAL_MS } from "./constants-CDZLOoVv.mjs";
2
+ import { _ as WriteProcessMemory, b as openProcessForMemory, d as ReadProcessMemory, m as VirtualProtectEx, t as CloseHandle, u as PAGE } from "./Win32API-C2kjj0ze.mjs";
3
+ import { i as parsePattern } from "./NativeMemoryManager.utils-BBlAixF5.mjs";
4
4
  import { randomUUID } from "node:crypto";
5
5
  //#region src/native/MemoryController.ts
6
6
  /**
@@ -1,5 +1,5 @@
1
- import { Gt as SCAN_SESSION_MAX_COUNT, Kt as SCAN_SESSION_TTL_MS } from "./constants-CCvsN80K.mjs";
2
- import { n as parseAddress, t as formatAddress } from "./formatAddress-ChCSIRWT.mjs";
1
+ import { Sn as SCAN_SESSION_TTL_MS, xn as SCAN_SESSION_MAX_COUNT } from "./constants-CDZLOoVv.mjs";
2
+ import { n as parseAddress, t as formatAddress } from "./formatAddress-nnMvEohD.mjs";
3
3
  import { randomUUID } from "node:crypto";
4
4
  //#region src/native/ScanComparators.ts
5
5
  const FLOAT_EPSILON = 1e-6;
@@ -44,94 +44,97 @@ function getDefaultAlignment(type) {
44
44
  default: return 1;
45
45
  }
46
46
  }
47
- /**
48
- * Read a typed numeric value from a buffer at offset 0.
49
- */
50
- function readTypedValue(buf, type) {
47
+ function makeReader(type) {
51
48
  switch (type) {
52
- case "byte": return buf.readUInt8(0);
53
- case "int8": return buf.readInt8(0);
54
- case "int16": return buf.readInt16LE(0);
55
- case "uint16": return buf.readUInt16LE(0);
56
- case "int32": return buf.readInt32LE(0);
57
- case "uint32": return buf.readUInt32LE(0);
58
- case "int64": return buf.readBigInt64LE(0);
49
+ case "byte": return (buf) => buf.readUInt8(0);
50
+ case "int8": return (buf) => buf.readInt8(0);
51
+ case "int16": return (buf) => buf.readInt16LE(0);
52
+ case "uint16": return (buf) => buf.readUInt16LE(0);
53
+ case "int32": return (buf) => buf.readInt32LE(0);
54
+ case "uint32": return (buf) => buf.readUInt32LE(0);
55
+ case "int64": return (buf) => buf.readBigInt64LE(0);
59
56
  case "uint64":
60
- case "pointer": return buf.readBigUInt64LE(0);
61
- case "float": return buf.readFloatLE(0);
62
- case "double": return buf.readDoubleLE(0);
63
- default: return buf.readInt32LE(0);
57
+ case "pointer": return (buf) => buf.readBigUInt64LE(0);
58
+ case "float": return (buf) => buf.readFloatLE(0);
59
+ case "double": return (buf) => buf.readDoubleLE(0);
60
+ default: return (buf) => buf.readInt32LE(0);
64
61
  }
65
62
  }
66
- /**
67
- * Check if two numeric values are approximately equal, using epsilon for floats.
68
- */
69
- function approxEqual(a, b, type) {
70
- if (typeof a === "bigint" && typeof b === "bigint") return a === b;
71
- const na = Number(a);
72
- const nb = Number(b);
73
- if (type === "float") return Math.abs(na - nb) < FLOAT_EPSILON;
74
- if (type === "double") return Math.abs(na - nb) < DOUBLE_EPSILON;
75
- return na === nb;
63
+ function makeApproxEqual(type) {
64
+ if (type === "float") return (a, b) => Math.abs(Number(a) - Number(b)) < FLOAT_EPSILON;
65
+ if (type === "double") return (a, b) => Math.abs(Number(a) - Number(b)) < DOUBLE_EPSILON;
66
+ if (type === "int64" || type === "uint64" || type === "pointer") return (a, b) => a === b;
67
+ return (a, b) => Number(a) === Number(b);
76
68
  }
77
- /**
78
- * Compare a numeric value against another for ordering.
79
- * Returns negative if a < b, 0 if equal, positive if a > b.
80
- */
81
- function compareValues(a, b) {
82
- if (typeof a === "bigint" && typeof b === "bigint") {
83
- if (a < b) return -1;
84
- if (a > b) return 1;
85
- return 0;
69
+ function makeComparator(mode, type) {
70
+ const read = makeReader(type);
71
+ const approxEq = makeApproxEqual(type);
72
+ const compare = type === "int64" || type === "uint64" || type === "pointer" ? (a, b) => {
73
+ const ba = BigInt(a);
74
+ const bb = BigInt(b);
75
+ return ba < bb ? -1 : ba > bb ? 1 : 0;
76
+ } : (a, b) => Number(a) - Number(b);
77
+ switch (mode) {
78
+ case "exact": return (cur, _prev, tgt, _tgt2) => {
79
+ if (!tgt) return false;
80
+ return approxEq(read(cur), read(tgt));
81
+ };
82
+ case "unknown_initial": return () => true;
83
+ case "changed": return (cur, prev, _tgt, _tgt2) => {
84
+ if (!prev) return false;
85
+ return !approxEq(read(cur), read(prev));
86
+ };
87
+ case "unchanged": return (cur, prev, _tgt, _tgt2) => {
88
+ if (!prev) return true;
89
+ return approxEq(read(cur), read(prev));
90
+ };
91
+ case "increased": return (cur, prev, _tgt, _tgt2) => {
92
+ if (!prev) return false;
93
+ return compare(read(cur), read(prev)) > 0;
94
+ };
95
+ case "decreased": return (cur, prev, _tgt, _tgt2) => {
96
+ if (!prev) return false;
97
+ return compare(read(cur), read(prev)) < 0;
98
+ };
99
+ case "greater_than": return (cur, _prev, tgt, _tgt2) => {
100
+ if (!tgt) return false;
101
+ return compare(read(cur), read(tgt)) > 0;
102
+ };
103
+ case "less_than": return (cur, _prev, tgt, _tgt2) => {
104
+ if (!tgt) return false;
105
+ return compare(read(cur), read(tgt)) < 0;
106
+ };
107
+ case "between": return (cur, _prev, tgt, tgt2) => {
108
+ if (!tgt || !tgt2) return false;
109
+ return compare(read(cur), read(tgt)) >= 0 && compare(read(cur), read(tgt2)) <= 0;
110
+ };
111
+ case "not_equal": return (cur, _prev, tgt, _tgt2) => {
112
+ if (!tgt) return false;
113
+ return !approxEq(read(cur), read(tgt));
114
+ };
115
+ default: return () => false;
86
116
  }
87
- return Number(a) - Number(b);
117
+ }
118
+ const comparatorCache = /* @__PURE__ */ new Map();
119
+ function getComparator(mode, valueType) {
120
+ const key = `${mode}:${valueType}`;
121
+ let comp = comparatorCache.get(key);
122
+ if (!comp) {
123
+ comp = makeComparator(mode, valueType);
124
+ comparatorCache.set(key, comp);
125
+ }
126
+ return comp;
88
127
  }
89
128
  /**
90
129
  * Compare scan values according to the specified mode.
91
130
  *
92
- * @param current - Current value buffer read from memory
93
- * @param previous - Previous value buffer from last scan (null on first scan)
94
- * @param target - Target value buffer for exact/greater/less/not_equal comparisons
95
- * @param target2 - Second target value buffer for 'between' mode (upper bound)
96
- * @param mode - Comparison mode
97
- * @param valueType - Value type for proper reading
131
+ * Dispatches to a monomorphic specialist comparator that is cached per
132
+ * (mode, valueType) pair. This avoids per-call switch dispatch on valueType
133
+ * in the hot scan loop, allowing V8 TurboFan to inline and optimize the
134
+ * typed read + compare path.
98
135
  */
99
136
  function compareScanValues(current, previous, target, target2, mode, valueType) {
100
- const cur = readTypedValue(current, valueType);
101
- switch (mode) {
102
- case "exact":
103
- if (!target) return false;
104
- return approxEqual(cur, readTypedValue(target, valueType), valueType);
105
- case "unknown_initial": return true;
106
- case "changed":
107
- if (!previous) return false;
108
- return !approxEqual(cur, readTypedValue(previous, valueType), valueType);
109
- case "unchanged":
110
- if (!previous) return true;
111
- return approxEqual(cur, readTypedValue(previous, valueType), valueType);
112
- case "increased":
113
- if (!previous) return false;
114
- return compareValues(cur, readTypedValue(previous, valueType)) > 0;
115
- case "decreased":
116
- if (!previous) return false;
117
- return compareValues(cur, readTypedValue(previous, valueType)) < 0;
118
- case "greater_than":
119
- if (!target) return false;
120
- return compareValues(cur, readTypedValue(target, valueType)) > 0;
121
- case "less_than":
122
- if (!target) return false;
123
- return compareValues(cur, readTypedValue(target, valueType)) < 0;
124
- case "between": {
125
- if (!target || !target2) return false;
126
- const lo = readTypedValue(target, valueType);
127
- const hi = readTypedValue(target2, valueType);
128
- return compareValues(cur, lo) >= 0 && compareValues(cur, hi) <= 0;
129
- }
130
- case "not_equal":
131
- if (!target) return false;
132
- return !approxEqual(cur, readTypedValue(target, valueType), valueType);
133
- default: return false;
134
- }
137
+ return getComparator(mode, valueType)(current, previous, target, target2);
135
138
  }
136
139
  //#endregion
137
140
  //#region src/native/MemoryScanSession.ts
@@ -1,9 +1,9 @@
1
- import { Ht as SCAN_GROUP_MAX_PATTERN_SIZE, Ut as SCAN_MAX_RESULTS_PER_SCAN, Vt as SCAN_DISPLAY_RESULTS_LIMIT, Wt as SCAN_POINTER_MAX_RESULTS, qt as SCAN_UNKNOWN_INITIAL_MAX_ADDRESSES } from "./constants-CCvsN80K.mjs";
2
- import { t as nativeMemoryManager } from "./NativeMemoryManager.impl-CB6gJ0NM.mjs";
3
- import { t as createPlatformProvider } from "./factory-CibqTNC8.mjs";
4
- import { i as parsePattern } from "./NativeMemoryManager.utils-BML4q1ry.mjs";
5
- import { n as parseAddress, t as formatAddress } from "./formatAddress-ChCSIRWT.mjs";
6
- import { n as getDefaultAlignment, r as getValueSize, scanSessionManager, t as compareScanValues } from "./MemoryScanSession-RMixN3bX.mjs";
1
+ import { Cn as SCAN_UNKNOWN_INITIAL_MAX_ADDRESSES, _n as SCAN_DISPLAY_RESULTS_LIMIT, bn as SCAN_POINTER_MAX_RESULTS, vn as SCAN_GROUP_MAX_PATTERN_SIZE, yn as SCAN_MAX_RESULTS_PER_SCAN } from "./constants-CDZLOoVv.mjs";
2
+ import { t as createPlatformProvider } from "./factory-C90tBff6.mjs";
3
+ import { i as parsePattern } from "./NativeMemoryManager.utils-BBlAixF5.mjs";
4
+ import { t as nativeMemoryManager } from "./NativeMemoryManager.impl-D9Lkovvn.mjs";
5
+ import { n as parseAddress, t as formatAddress } from "./formatAddress-nnMvEohD.mjs";
6
+ import { n as getDefaultAlignment, r as getValueSize, scanSessionManager, t as compareScanValues } from "./MemoryScanSession-ITgb_NMi.mjs";
7
7
  //#region src/native/MemoryScanner.ts
8
8
  /**
9
9
  * Memory Scanner — orchestrates iterative scan workflows.
@@ -21,10 +21,13 @@ import { n as getDefaultAlignment, r as getValueSize, scanSessionManager, t as c
21
21
  */
22
22
  var MemoryScanner = class {
23
23
  nmm;
24
- _provider = null;
24
+ providerCache = null;
25
25
  get provider() {
26
- if (!this._provider) this._provider = createPlatformProvider();
27
- return this._provider;
26
+ if (!this.providerCache) this.providerCache = createPlatformProvider();
27
+ return this.providerCache;
28
+ }
29
+ set provider(value) {
30
+ this.providerCache = value;
28
31
  }
29
32
  constructor(nmm) {
30
33
  this.nmm = nmm;
@@ -67,14 +70,28 @@ var MemoryScanner = class {
67
70
  } catch {
68
71
  break;
69
72
  }
70
- const alignStep = alignment > 0 ? alignment : 1;
71
- const startOffset = alignment > 0 ? (alignStep - offset % alignStep) % alignStep : 0;
72
- for (let i = startOffset; i <= chunk.length - valueSize; i += alignStep) {
73
- const currentBuf = chunk.subarray(i, i + valueSize);
74
- if (compareScanValues(currentBuf, null, targetBuf, null, "exact", valueType)) {
73
+ if (alignment === valueSize && valueSize > 0) {
74
+ const alignStep = this.getAlignStep(alignment);
75
+ let searchFrom = this.getAlignedChunkStart(chunkAddr, alignStep);
76
+ while (searchFrom <= chunk.length - valueSize && addresses.length < maxResults) {
77
+ const hit = chunk.indexOf(targetBuf, searchFrom);
78
+ if (hit === -1) break;
79
+ if (!this.isAlignedAddress(chunkAddr + BigInt(hit), alignStep)) {
80
+ searchFrom = hit + 1;
81
+ continue;
82
+ }
83
+ const addr = chunkAddr + BigInt(hit);
84
+ addresses.push(addr);
85
+ values.set(addr, Buffer.from(chunk.subarray(hit, hit + valueSize)));
86
+ searchFrom = hit + alignStep;
87
+ }
88
+ } else {
89
+ const alignStep = this.getAlignStep(alignment);
90
+ const chunkStart = this.getAlignedChunkStart(chunkAddr, alignStep);
91
+ for (let i = chunkStart; i <= chunk.length - valueSize; i += alignStep) if (Buffer.compare(chunk.subarray(i, i + valueSize), targetBuf) === 0) {
75
92
  const addr = chunkAddr + BigInt(i);
76
93
  addresses.push(addr);
77
- values.set(addr, Buffer.from(currentBuf));
94
+ values.set(addr, Buffer.from(chunk.subarray(i, i + valueSize)));
78
95
  if (addresses.length >= maxResults) break;
79
96
  }
80
97
  }
@@ -183,12 +200,12 @@ var MemoryScanner = class {
183
200
  } catch {
184
201
  break;
185
202
  }
186
- const alignStep = alignment > 0 ? alignment : 1;
187
- for (let i = 0; i <= chunk.length - valueSize; i += alignStep) {
203
+ const alignStep = this.getAlignStep(alignment);
204
+ const chunkStart = this.getAlignedChunkStart(chunkAddr, alignStep);
205
+ for (let i = chunkStart; i <= chunk.length - valueSize; i += alignStep) {
188
206
  const addr = chunkAddr + BigInt(i);
189
- const currentBuf = chunk.subarray(i, i + valueSize);
190
207
  addresses.push(addr);
191
- values.set(addr, Buffer.from(currentBuf));
208
+ values.set(addr, Buffer.from(chunk.subarray(i, i + valueSize)));
192
209
  if (addresses.length >= maxAddresses) break;
193
210
  }
194
211
  }
@@ -312,8 +329,9 @@ var MemoryScanner = class {
312
329
  } catch {
313
330
  break;
314
331
  }
315
- const alignStep = alignment > 0 ? alignment : 1;
316
- for (let i = 0; i <= chunk.length - maxOffset; i += alignStep) {
332
+ const alignStep = this.getAlignStep(alignment);
333
+ const chunkStart = this.getAlignedChunkStart(chunkAddr, alignStep);
334
+ for (let i = chunkStart; i <= chunk.length - maxOffset; i += alignStep) {
317
335
  let match = true;
318
336
  for (let j = 0; j < maxOffset; j++) if (compositeMask[j] === 1 && chunk[i + j] !== compositePattern[j]) {
319
337
  match = false;
@@ -342,6 +360,17 @@ var MemoryScanner = class {
342
360
  elapsed
343
361
  };
344
362
  }
363
+ getAlignStep(alignment) {
364
+ return alignment > 0 ? alignment : 1;
365
+ }
366
+ getAlignedChunkStart(chunkAddr, alignStep) {
367
+ const align = BigInt(alignStep);
368
+ const remainder = chunkAddr % align;
369
+ return remainder === 0n ? 0 : Number(align - remainder);
370
+ }
371
+ isAlignedAddress(address, alignStep) {
372
+ return address % BigInt(alignStep) === 0n;
373
+ }
345
374
  /**
346
375
  * Pattern-based first scan for variable-length types (hex/string).
347
376
  * Delegates to existing NativeMemoryManager.scanMemory.