@bingine/cemem 0.0.0-stage → 0.1.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 (138) hide show
  1. package/PORT-SCOPE.md +169 -0
  2. package/README.md +451 -2
  3. package/dist/cjs/addr/expression.js +650 -0
  4. package/dist/cjs/addr/expression.js.map +1 -0
  5. package/dist/cjs/addresslist/memory-record.js +612 -0
  6. package/dist/cjs/addresslist/memory-record.js.map +1 -0
  7. package/dist/cjs/asm/assembler.js +354 -0
  8. package/dist/cjs/asm/assembler.js.map +1 -0
  9. package/dist/cjs/asm/autoassembler-directives.js +362 -0
  10. package/dist/cjs/asm/autoassembler-directives.js.map +1 -0
  11. package/dist/cjs/asm/autoassembler.js +2163 -0
  12. package/dist/cjs/asm/autoassembler.js.map +1 -0
  13. package/dist/cjs/asm/backend.js +394 -0
  14. package/dist/cjs/asm/backend.js.map +1 -0
  15. package/dist/cjs/asm/disassembler.js +715 -0
  16. package/dist/cjs/asm/disassembler.js.map +1 -0
  17. package/dist/cjs/backend/dbk-backend.js +683 -0
  18. package/dist/cjs/backend/dbk-backend.js.map +1 -0
  19. package/dist/cjs/backend/native-ce-backend.js +667 -0
  20. package/dist/cjs/backend/native-ce-backend.js.map +1 -0
  21. package/dist/cjs/backend/self-backend.js +449 -0
  22. package/dist/cjs/backend/self-backend.js.map +1 -0
  23. package/dist/cjs/backend/types.js +48 -0
  24. package/dist/cjs/backend/types.js.map +1 -0
  25. package/dist/cjs/cheattable/ct-format.js +533 -0
  26. package/dist/cjs/cheattable/ct-format.js.map +1 -0
  27. package/dist/cjs/index.js +219 -0
  28. package/dist/cjs/index.js.map +1 -0
  29. package/dist/cjs/lua/aa.js +230 -0
  30. package/dist/cjs/lua/aa.js.map +1 -0
  31. package/dist/cjs/lua/addressing.js +118 -0
  32. package/dist/cjs/lua/addressing.js.map +1 -0
  33. package/dist/cjs/lua/api.js +736 -0
  34. package/dist/cjs/lua/api.js.map +1 -0
  35. package/dist/cjs/lua/asm.js +220 -0
  36. package/dist/cjs/lua/asm.js.map +1 -0
  37. package/dist/cjs/lua/bridge.js +526 -0
  38. package/dist/cjs/lua/bridge.js.map +1 -0
  39. package/dist/cjs/lua/marshal.js +562 -0
  40. package/dist/cjs/lua/marshal.js.map +1 -0
  41. package/dist/cjs/lua/memory.js +213 -0
  42. package/dist/cjs/lua/memory.js.map +1 -0
  43. package/dist/cjs/lua/objects.js +1070 -0
  44. package/dist/cjs/lua/objects.js.map +1 -0
  45. package/dist/cjs/lua/scan.js +543 -0
  46. package/dist/cjs/lua/scan.js.map +1 -0
  47. package/dist/cjs/lua/types.js +103 -0
  48. package/dist/cjs/lua/types.js.map +1 -0
  49. package/dist/cjs/scanner/matcher.js +781 -0
  50. package/dist/cjs/scanner/matcher.js.map +1 -0
  51. package/dist/cjs/scanner/pointer-scan.js +546 -0
  52. package/dist/cjs/scanner/pointer-scan.js.map +1 -0
  53. package/dist/cjs/scanner/scanner.js +513 -0
  54. package/dist/cjs/scanner/scanner.js.map +1 -0
  55. package/dist/cjs/scanner/shared-layout.js +207 -0
  56. package/dist/cjs/scanner/shared-layout.js.map +1 -0
  57. package/dist/cjs/types.js +190 -0
  58. package/dist/cjs/types.js.map +1 -0
  59. package/dist/cjs/value-codec.js +515 -0
  60. package/dist/cjs/value-codec.js.map +1 -0
  61. package/dist/cjs/win/process.js +475 -0
  62. package/dist/cjs/win/process.js.map +1 -0
  63. package/dist/cjs/win/scan-worker.js +84 -0
  64. package/dist/cjs/win/scan-worker.js.map +1 -0
  65. package/dist/cjs/win/winapi.js +403 -0
  66. package/dist/cjs/win/winapi.js.map +1 -0
  67. package/dist/types/addr/expression.d.ts +98 -0
  68. package/dist/types/addr/expression.d.ts.map +1 -0
  69. package/dist/types/addresslist/memory-record.d.ts +218 -0
  70. package/dist/types/addresslist/memory-record.d.ts.map +1 -0
  71. package/dist/types/asm/assembler.d.ts +106 -0
  72. package/dist/types/asm/assembler.d.ts.map +1 -0
  73. package/dist/types/asm/autoassembler-directives.d.ts +118 -0
  74. package/dist/types/asm/autoassembler-directives.d.ts.map +1 -0
  75. package/dist/types/asm/autoassembler.d.ts +434 -0
  76. package/dist/types/asm/autoassembler.d.ts.map +1 -0
  77. package/dist/types/asm/backend.d.ts +167 -0
  78. package/dist/types/asm/backend.d.ts.map +1 -0
  79. package/dist/types/asm/disassembler.d.ts +194 -0
  80. package/dist/types/asm/disassembler.d.ts.map +1 -0
  81. package/dist/types/backend/dbk-backend.d.ts +353 -0
  82. package/dist/types/backend/dbk-backend.d.ts.map +1 -0
  83. package/dist/types/backend/native-ce-backend.d.ts +213 -0
  84. package/dist/types/backend/native-ce-backend.d.ts.map +1 -0
  85. package/dist/types/backend/self-backend.d.ts +64 -0
  86. package/dist/types/backend/self-backend.d.ts.map +1 -0
  87. package/dist/types/backend/types.d.ts +176 -0
  88. package/dist/types/backend/types.d.ts.map +1 -0
  89. package/dist/types/cheattable/ct-format.d.ts +100 -0
  90. package/dist/types/cheattable/ct-format.d.ts.map +1 -0
  91. package/dist/types/index.d.ts +54 -0
  92. package/dist/types/index.d.ts.map +1 -0
  93. package/dist/types/lua/aa.d.ts +107 -0
  94. package/dist/types/lua/aa.d.ts.map +1 -0
  95. package/dist/types/lua/addressing.d.ts +41 -0
  96. package/dist/types/lua/addressing.d.ts.map +1 -0
  97. package/dist/types/lua/api.d.ts +46 -0
  98. package/dist/types/lua/api.d.ts.map +1 -0
  99. package/dist/types/lua/asm.d.ts +42 -0
  100. package/dist/types/lua/asm.d.ts.map +1 -0
  101. package/dist/types/lua/bridge.d.ts +129 -0
  102. package/dist/types/lua/bridge.d.ts.map +1 -0
  103. package/dist/types/lua/marshal.d.ts +244 -0
  104. package/dist/types/lua/marshal.d.ts.map +1 -0
  105. package/dist/types/lua/memory.d.ts +61 -0
  106. package/dist/types/lua/memory.d.ts.map +1 -0
  107. package/dist/types/lua/objects.d.ts +210 -0
  108. package/dist/types/lua/objects.d.ts.map +1 -0
  109. package/dist/types/lua/scan.d.ts +106 -0
  110. package/dist/types/lua/scan.d.ts.map +1 -0
  111. package/dist/types/lua/types.d.ts +146 -0
  112. package/dist/types/lua/types.d.ts.map +1 -0
  113. package/dist/types/scanner/matcher.d.ts +122 -0
  114. package/dist/types/scanner/matcher.d.ts.map +1 -0
  115. package/dist/types/scanner/pointer-scan.d.ts +187 -0
  116. package/dist/types/scanner/pointer-scan.d.ts.map +1 -0
  117. package/dist/types/scanner/scanner.d.ts +150 -0
  118. package/dist/types/scanner/scanner.d.ts.map +1 -0
  119. package/dist/types/scanner/shared-layout.d.ts +96 -0
  120. package/dist/types/scanner/shared-layout.d.ts.map +1 -0
  121. package/dist/types/types.d.ts +239 -0
  122. package/dist/types/types.d.ts.map +1 -0
  123. package/dist/types/value-codec.d.ts +134 -0
  124. package/dist/types/value-codec.d.ts.map +1 -0
  125. package/dist/types/win/process.d.ts +190 -0
  126. package/dist/types/win/process.d.ts.map +1 -0
  127. package/dist/types/win/scan-worker.d.ts +51 -0
  128. package/dist/types/win/scan-worker.d.ts.map +1 -0
  129. package/dist/types/win/winapi.d.ts +144 -0
  130. package/dist/types/win/winapi.d.ts.map +1 -0
  131. package/docs/assembler.md +371 -0
  132. package/docs/autoassembler.md +423 -0
  133. package/docs/backend-dbk.md +305 -0
  134. package/docs/backends.md +273 -0
  135. package/docs/evidence/atomics-wait-io.js +20 -0
  136. package/docs/evidence/mini-repro.js +98 -0
  137. package/docs/lua-api.md +718 -0
  138. package/package.json +60 -4
@@ -0,0 +1,475 @@
1
+ "use strict";
2
+ /**
3
+ * 进程与内存访问层 —— 后端无关的门面。
4
+ *
5
+ * 本文件不再直接调用 Win32 API,而是委托给 `MemoryBackend`:
6
+ * - `SelfBackend` → 自研引擎(默认,本进程内直接调用 Win32)
7
+ * - `NativeCeBackend` → 原生 CE 兼容层(连接 ceserver 的 TCP 协议)
8
+ *
9
+ * 因此 `Process` 的用法在两种后端下完全一致:
10
+ * ```ts
11
+ * const p = Process.open(pid); // 默认自研后端
12
+ * const p2 = Process.open(pid, { backend: native }); // 走原生 CE
13
+ * ```
14
+ *
15
+ * 性能提示:CE 扫描时把整段内存拷进缓冲区再本地比较,本移植沿用同一思路,
16
+ * 因此后端只需要提供一个"按块读内存"的原语即可,比较逻辑全在上层。
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.DEFAULT_PROCESS_ACCESS = exports.MEM_PRIVATE = exports.MEM_MAPPED = exports.MEM_IMAGE = exports.MEM_COMMIT = exports.PAGE_GUARD = exports.MAX_ADDRESS = exports.Process = exports.ProcessOpenError = exports.isExecutable = exports.isWritable = exports.isReadable = void 0;
20
+ exports.getDefaultBackend = getDefaultBackend;
21
+ exports.setDefaultBackend = setDefaultBackend;
22
+ exports.listProcesses = listProcesses;
23
+ exports.findProcessesByName = findProcessesByName;
24
+ exports.listProcessesAsync = listProcessesAsync;
25
+ exports.findProcessesByNameAsync = findProcessesByNameAsync;
26
+ exports.enumerateRegions = enumerateRegions;
27
+ exports.selectScannableRegions = selectScannableRegions;
28
+ exports.openProcessAsync = openProcessAsync;
29
+ exports.openProcessByNameAsync = openProcessByNameAsync;
30
+ exports.regionTypeName = regionTypeName;
31
+ const types_1 = require("../types");
32
+ Object.defineProperty(exports, "DEFAULT_PROCESS_ACCESS", { enumerable: true, get: function () { return types_1.DEFAULT_PROCESS_ACCESS; } });
33
+ Object.defineProperty(exports, "MEM_COMMIT", { enumerable: true, get: function () { return types_1.MEM_COMMIT; } });
34
+ Object.defineProperty(exports, "MEM_IMAGE", { enumerable: true, get: function () { return types_1.MEM_IMAGE; } });
35
+ Object.defineProperty(exports, "MEM_MAPPED", { enumerable: true, get: function () { return types_1.MEM_MAPPED; } });
36
+ Object.defineProperty(exports, "MEM_PRIVATE", { enumerable: true, get: function () { return types_1.MEM_PRIVATE; } });
37
+ Object.defineProperty(exports, "PAGE_GUARD", { enumerable: true, get: function () { return types_1.PAGE_GUARD; } });
38
+ const self_backend_1 = require("../backend/self-backend");
39
+ var self_backend_2 = require("../backend/self-backend");
40
+ Object.defineProperty(exports, "isReadable", { enumerable: true, get: function () { return self_backend_2.isReadable; } });
41
+ Object.defineProperty(exports, "isWritable", { enumerable: true, get: function () { return self_backend_2.isWritable; } });
42
+ Object.defineProperty(exports, "isExecutable", { enumerable: true, get: function () { return self_backend_2.isExecutable; } });
43
+ /* ------------------------------------------------------------------ *
44
+ * 后端解析
45
+ * ------------------------------------------------------------------ */
46
+ let defaultBackend = null;
47
+ /** 取进程内共享的默认后端(自研引擎)。 */
48
+ function getDefaultBackend() {
49
+ if (!defaultBackend)
50
+ defaultBackend = new self_backend_1.SelfBackend();
51
+ return defaultBackend;
52
+ }
53
+ /** 替换默认后端(例如全局切到原生 CE)。传入 null 恢复自研后端。 */
54
+ function setDefaultBackend(backend) {
55
+ defaultBackend = backend;
56
+ }
57
+ function resolveBackend(options) {
58
+ if (options?.backend)
59
+ return options.backend;
60
+ if (options?.access !== undefined) {
61
+ return new self_backend_1.SelfBackend({ access: options.access });
62
+ }
63
+ return getDefaultBackend();
64
+ }
65
+ /**
66
+ * 断言后端是同步的,并把返回值收窄为 T。
67
+ *
68
+ * 用途:`Process` 的同步方法(`readMemory` 等)只能用于同步后端。
69
+ * 若换成了 `NativeCeBackend`(socket,异步),同步方法无法工作 ——
70
+ * 这时要给出**明确、可操作**的错误,而不是让调用方拿到一个 Promise 当 Buffer 用。
71
+ */
72
+ function syncResult(backend, value, operation) {
73
+ if (backend.capabilities.sync)
74
+ return value;
75
+ throw new Error(`后端 "${backend.name}" 是异步的,不能使用同步方法 ${operation}()。` +
76
+ `请改用异步变体(例如 readMemoryAsync())并 await,` +
77
+ `或改用同步后端 SelfBackend。`);
78
+ }
79
+ /** 枚举全部进程(使用默认后端;同步后端专用,异步后端请用 listProcessesAsync) */
80
+ function listProcesses(backend) {
81
+ const b = backend ?? getDefaultBackend();
82
+ const out = syncResult(b, b.listProcesses(), 'listProcesses').map((p) => ({
83
+ pid: p.pid,
84
+ name: p.name,
85
+ parentPid: p.parentPid,
86
+ threadCount: p.threadCount,
87
+ }));
88
+ // 标记同名进程,便于 CLI 提示用户选择
89
+ const counts = new Map();
90
+ for (const p of out) {
91
+ const k = p.name.toLowerCase();
92
+ counts.set(k, (counts.get(k) ?? 0) + 1);
93
+ }
94
+ for (const p of out) {
95
+ if ((counts.get(p.name.toLowerCase()) ?? 0) > 1)
96
+ p.duplicateName = true;
97
+ }
98
+ return out;
99
+ }
100
+ /** 按名字查进程(不区分大小写,包含匹配) */
101
+ function findProcessesByName(name, backend) {
102
+ const needle = name.toLowerCase();
103
+ return listProcesses(backend).filter((p) => p.name.toLowerCase() === needle || p.name.toLowerCase().includes(needle));
104
+ }
105
+ /* ------------------------------------------------------------------ *
106
+ * 异步变体(原生 CE 后端必须用这些)
107
+ * ------------------------------------------------------------------ */
108
+ /** 枚举全部进程(异步;对同步与异步后端都可用) */
109
+ async function listProcessesAsync(backend) {
110
+ const b = backend ?? getDefaultBackend();
111
+ const out = (await b.listProcesses()).map((p) => ({
112
+ pid: p.pid,
113
+ name: p.name,
114
+ parentPid: p.parentPid,
115
+ threadCount: p.threadCount,
116
+ }));
117
+ const counts = new Map();
118
+ for (const p of out) {
119
+ const k = p.name.toLowerCase();
120
+ counts.set(k, (counts.get(k) ?? 0) + 1);
121
+ }
122
+ for (const p of out) {
123
+ if ((counts.get(p.name.toLowerCase()) ?? 0) > 1)
124
+ p.duplicateName = true;
125
+ }
126
+ return out;
127
+ }
128
+ /** 按名字查进程(异步) */
129
+ async function findProcessesByNameAsync(name, backend) {
130
+ const needle = name.toLowerCase();
131
+ return (await listProcessesAsync(backend)).filter((p) => p.name.toLowerCase() === needle || p.name.toLowerCase().includes(needle));
132
+ }
133
+ /** 把后端区域转成对外暴露的 MemoryRegion */
134
+ function toMemoryRegion(r) {
135
+ return {
136
+ baseAddress: r.baseAddress,
137
+ memorySize: r.regionSize,
138
+ committed: r.state === types_1.MEM_COMMIT,
139
+ protect: r.protect,
140
+ type: r.type,
141
+ };
142
+ }
143
+ /**
144
+ * 枚举进程内存区域。
145
+ *
146
+ * 只接受 `Process` 实例(早期版本接受裸 Win32 句柄,那样无法支持原生 CE 后端,
147
+ * 因此移除;请用 `process.regions()`)。
148
+ */
149
+ function enumerateRegions(process, options = {}) {
150
+ if (!(process instanceof Process)) {
151
+ throw new TypeError('enumerateRegions 需要传入 Process 实例(裸 Win32 句柄已不再支持,请用 process.regions())');
152
+ }
153
+ return process.regions(options);
154
+ }
155
+ /** 选出"可扫描"的内存区域(对齐 CE 首次扫描的默认行为) */
156
+ function selectScannableRegions(process, filter = {}) {
157
+ return process.scannableRegions(filter);
158
+ }
159
+ /* ------------------------------------------------------------------ *
160
+ * Process
161
+ * ------------------------------------------------------------------ */
162
+ /** 打开进程失败时抛出的错误,带 pid 与 Win32 错误码(若后端提供)。 */
163
+ class ProcessOpenError extends Error {
164
+ pid;
165
+ win32Code;
166
+ constructor(pid, win32Code, message) {
167
+ super(message ?? `无法打开进程 ${pid}:Win32 错误 ${win32Code}`);
168
+ this.pid = pid;
169
+ this.win32Code = win32Code;
170
+ this.name = 'ProcessOpenError';
171
+ }
172
+ }
173
+ exports.ProcessOpenError = ProcessOpenError;
174
+ /**
175
+ * 一个已打开的目标进程。
176
+ *
177
+ * 生命周期:
178
+ * ```ts
179
+ * const p = Process.open(pid);
180
+ * try { ... } finally { p.close(); }
181
+ * ```
182
+ * 也支持 `using`(Symbol.dispose)。
183
+ */
184
+ class Process {
185
+ pid;
186
+ name;
187
+ backend;
188
+ handle;
189
+ closed = false;
190
+ constructor(pid, name, backend, handle) {
191
+ this.pid = pid;
192
+ this.name = name;
193
+ this.backend = backend;
194
+ this.handle = handle;
195
+ }
196
+ /** 按 pid 打开进程(同步后端专用;异步后端请用 openProcessAsync) */
197
+ static open(pid, options) {
198
+ const backend = resolveBackend(options);
199
+ let handle;
200
+ try {
201
+ handle = syncResult(backend, backend.openProcess(pid), 'openProcess');
202
+ }
203
+ catch (e) {
204
+ const err = e;
205
+ if (err.name === 'ProcessOpenError' || err.win32Code !== undefined) {
206
+ throw new ProcessOpenError(pid, err.win32Code ?? 0, err.message);
207
+ }
208
+ throw e;
209
+ }
210
+ const info = syncResult(backend, backend.listProcesses(), 'listProcesses').find((p) => p.pid === pid);
211
+ return new Process(pid, info?.name ?? `<pid ${pid}>`, backend, handle);
212
+ }
213
+ /** 按进程名打开;同名多进程时选第一个 */
214
+ static openByName(name, options) {
215
+ const backend = resolveBackend(options);
216
+ const matches = findProcessesByName(name, backend);
217
+ if (matches.length === 0)
218
+ throw new Error(`找不到进程:${name}`);
219
+ return Process.open(matches[0].pid, options);
220
+ }
221
+ /** 按进程名打开全部同名进程 */
222
+ static openByNameAll(name, options) {
223
+ const backend = resolveBackend(options);
224
+ return findProcessesByName(name, backend).map((p) => Process.open(p.pid, options));
225
+ }
226
+ /**
227
+ * 由"已打开的后端句柄"构造 Process —— 供异步打开路径使用。
228
+ * 一般业务代码请用 `Process.open` / `openProcessAsync`。
229
+ */
230
+ static fromHandle(pid, name, backend, handle) {
231
+ return new Process(pid, name, backend, handle);
232
+ }
233
+ get isOpen() {
234
+ return !this.closed;
235
+ }
236
+ /** 所属后端名称 */
237
+ get backendName() {
238
+ return this.backend.name;
239
+ }
240
+ /**
241
+ * 底层后端句柄 —— 供需要直接调用后端的扩展代码使用
242
+ * (例如 Lua 桥要把句柄转成整数传给脚本)。
243
+ * 一般业务代码应优先使用 Process 的高层方法。
244
+ */
245
+ get backendHandle() {
246
+ this.assertOpen();
247
+ return this.handle;
248
+ }
249
+ assertOpen() {
250
+ if (this.closed)
251
+ throw new Error(`进程 ${this.pid} 的句柄已关闭`);
252
+ }
253
+ /** 是否为 WOW64(32 位)进程 */
254
+ isWow64() {
255
+ this.assertOpen();
256
+ return syncResult(this.backend, this.backend.isWow64(this.handle), 'isWow64');
257
+ }
258
+ /** 列出全部内存区域 */
259
+ regions(options) {
260
+ this.assertOpen();
261
+ const list = syncResult(this.backend, this.backend.queryRegions(this.handle, {
262
+ includeFree: options?.includeFree ?? true,
263
+ maxAddress: options?.maxAddress,
264
+ }), 'regions');
265
+ return list.map(toMemoryRegion);
266
+ }
267
+ /** 列出可扫描区域 */
268
+ scannableRegions(filter) {
269
+ this.assertOpen();
270
+ const raw = syncResult(this.backend, this.backend.queryRegions(this.handle, filter ?? {}), 'scannableRegions');
271
+ return raw.map(toMemoryRegion);
272
+ }
273
+ /**
274
+ * 读取内存。整块读取失败时由后端做二分回退。
275
+ * @returns 实际读到的数据(长度可能小于请求)
276
+ */
277
+ readMemory(address, size) {
278
+ this.assertOpen();
279
+ return syncResult(this.backend, this.backend.readProcessMemory(this.handle, address, size), 'readMemory');
280
+ }
281
+ /** 读取失败时抛错的严格版本 */
282
+ readMemoryExact(address, size) {
283
+ const buf = this.readMemory(address, size);
284
+ if (buf.length !== size) {
285
+ throw new Error(`读取进程 ${this.pid} 内存失败:地址 0x${address.toString(16)},请求 ${size} 字节,实得 ${buf.length} 字节`);
286
+ }
287
+ return buf;
288
+ }
289
+ /**
290
+ * 写入内存。默认在写只读页前临时改保护(与 CE 的 writeprocessmemory 行为一致)。
291
+ * @returns 实际写入字节数
292
+ */
293
+ writeMemory(address, data, fixProtection = true) {
294
+ this.assertOpen();
295
+ return syncResult(this.backend, this.backend.writeProcessMemory(this.handle, address, data, fixProtection), 'writeMemory');
296
+ }
297
+ /** 在目标进程内分配内存 */
298
+ allocate(size, protect = 0x04, address = 0n) {
299
+ this.assertOpen();
300
+ return syncResult(this.backend, this.backend.allocate(this.handle, size, protect, address), 'allocate');
301
+ }
302
+ /** 释放由 allocate 分配的内存 */
303
+ free(address) {
304
+ this.assertOpen();
305
+ syncResult(this.backend, this.backend.free(this.handle, address), 'free');
306
+ }
307
+ /** 修改内存保护属性,返回旧保护值 */
308
+ protect(address, size, newProtect) {
309
+ this.assertOpen();
310
+ return syncResult(this.backend, this.backend.changeProtection(this.handle, address, size, newProtect), 'protect');
311
+ }
312
+ /** 列出进程模块 */
313
+ modules() {
314
+ this.assertOpen();
315
+ return syncResult(this.backend, this.backend.queryModules(this.handle), 'modules').map((m) => ({
316
+ name: m.name,
317
+ path: m.path,
318
+ baseAddress: m.baseAddress,
319
+ size: m.size,
320
+ }));
321
+ }
322
+ /** 列出线程 id */
323
+ threadIds() {
324
+ this.assertOpen();
325
+ return syncResult(this.backend, this.backend.queryThreads(this.handle), 'threadIds');
326
+ }
327
+ /**
328
+ * 挂起进程全部线程,返回可传给 resume() 的令牌。
329
+ * 仅自研后端支持(原生 CE 后端会抛错)。
330
+ */
331
+ suspend() {
332
+ this.assertOpen();
333
+ const b = this.backend;
334
+ if (typeof b.suspendAllThreads !== 'function') {
335
+ throw new Error(`后端 "${this.backend.name}" 不支持挂起线程(ceserver 的线程接口未实现)`);
336
+ }
337
+ return b.suspendAllThreads(this.handle);
338
+ }
339
+ /** 恢复之前挂起的线程 */
340
+ resume(token) {
341
+ const b = this.backend;
342
+ if (typeof b.resumeThreads !== 'function') {
343
+ throw new Error(`后端 "${this.backend.name}" 不支持恢复线程`);
344
+ }
345
+ b.resumeThreads(token);
346
+ }
347
+ /** 关闭句柄。可重复调用。 */
348
+ close() {
349
+ if (this.closed)
350
+ return;
351
+ this.closed = true;
352
+ void this.backend.closeProcess(this.handle);
353
+ }
354
+ /** 支持 `using` 语义 */
355
+ [Symbol.dispose]() {
356
+ this.close();
357
+ }
358
+ /* ---------------------------------------------------------------- *
359
+ * 异步变体
360
+ *
361
+ * 存在的理由:`NativeCeBackend`(原生 CE / ceserver)本质是 socket 通信,
362
+ * 只能是异步的;而 `SelfBackend` 是同步的。
363
+ * 下面这些 `*Async` 方法**对两种后端都可用** ——
364
+ * 同步后端会直接返回(`await` 一个非 Promise 值原样返回),
365
+ * 因此调用方可以统一写 `await`,无需分支判断。
366
+ * ---------------------------------------------------------------- */
367
+ /** 异步关闭句柄 */
368
+ async closeAsync() {
369
+ if (this.closed)
370
+ return;
371
+ this.closed = true;
372
+ await this.backend.closeProcess(this.handle);
373
+ }
374
+ /** 异步枚举全部内存区域 */
375
+ async regionsAsync(options) {
376
+ this.assertOpen();
377
+ const list = await this.backend.queryRegions(this.handle, {
378
+ includeFree: options?.includeFree ?? true,
379
+ maxAddress: options?.maxAddress,
380
+ });
381
+ return list.map(toMemoryRegion);
382
+ }
383
+ /** 异步枚举可扫描区域 */
384
+ async scannableRegionsAsync(filter) {
385
+ this.assertOpen();
386
+ const raw = await this.backend.queryRegions(this.handle, filter ?? {});
387
+ return raw.map(toMemoryRegion);
388
+ }
389
+ /** 异步读取内存 */
390
+ async readMemoryAsync(address, size) {
391
+ this.assertOpen();
392
+ return syncResult(this.backend, this.backend.readProcessMemory(this.handle, address, size), 'readMemory');
393
+ }
394
+ /** 异步读取内存(不足则抛错) */
395
+ async readMemoryExactAsync(address, size) {
396
+ const buf = await this.readMemoryAsync(address, size);
397
+ if (buf.length !== size) {
398
+ throw new Error(`读取进程 ${this.pid} 内存失败:地址 0x${address.toString(16)},请求 ${size} 字节,实得 ${buf.length} 字节`);
399
+ }
400
+ return buf;
401
+ }
402
+ /** 异步写入内存 */
403
+ async writeMemoryAsync(address, data, fixProtection = true) {
404
+ this.assertOpen();
405
+ return syncResult(this.backend, this.backend.writeProcessMemory(this.handle, address, data, fixProtection), 'writeMemory');
406
+ }
407
+ /** 异步枚举模块 */
408
+ async modulesAsync() {
409
+ this.assertOpen();
410
+ const mods = await this.backend.queryModules(this.handle);
411
+ return mods.map((m) => ({
412
+ name: m.name,
413
+ path: m.path,
414
+ baseAddress: m.baseAddress,
415
+ size: m.size,
416
+ }));
417
+ }
418
+ /** 异步枚举线程 id */
419
+ async threadIdsAsync() {
420
+ this.assertOpen();
421
+ return syncResult(this.backend, this.backend.queryThreads(this.handle), 'threadIds');
422
+ }
423
+ /** 异步分配内存 */
424
+ async allocateAsync(size, protect = 0x04, address = 0n) {
425
+ this.assertOpen();
426
+ return syncResult(this.backend, this.backend.allocate(this.handle, size, protect, address), 'allocate');
427
+ }
428
+ /** 异步修改内存保护 */
429
+ async protectAsync(address, size, newProtect) {
430
+ this.assertOpen();
431
+ return syncResult(this.backend, this.backend.changeProtection(this.handle, address, size, newProtect), 'protect');
432
+ }
433
+ /** 异步判断是否 WOW64 */
434
+ async isWow64Async() {
435
+ this.assertOpen();
436
+ return syncResult(this.backend, this.backend.isWow64(this.handle), 'isWow64');
437
+ }
438
+ }
439
+ exports.Process = Process;
440
+ /** 打开进程的异步变体(原生 CE 后端下必须用它)。 */
441
+ async function openProcessAsync(pid, options) {
442
+ const backend = resolveBackend(options);
443
+ const handle = await backend.openProcess(pid);
444
+ const infos = await backend.listProcesses();
445
+ const info = infos.find((p) => p.pid === pid);
446
+ return Process.fromHandle(pid, info?.name ?? `<pid ${pid}>`, backend, handle);
447
+ }
448
+ /** 按名字打开进程(异步变体)。 */
449
+ async function openProcessByNameAsync(name, options) {
450
+ const backend = resolveBackend(options);
451
+ const all = (await backend.listProcesses()).map((p) => ({
452
+ pid: p.pid,
453
+ name: p.name,
454
+ parentPid: p.parentPid,
455
+ threadCount: p.threadCount,
456
+ }));
457
+ const needle = name.toLowerCase();
458
+ const matches = all.filter((p) => p.name.toLowerCase() === needle || p.name.toLowerCase().includes(needle));
459
+ if (matches.length === 0)
460
+ throw new Error(`找不到进程:${name}`);
461
+ return openProcessAsync(matches[0].pid, options);
462
+ }
463
+ /** 展示用:区域类型的可读名字 */
464
+ function regionTypeName(type) {
465
+ if (type === types_1.MEM_IMAGE)
466
+ return 'MEM_IMAGE';
467
+ if (type === types_1.MEM_MAPPED)
468
+ return 'MEM_MAPPED';
469
+ if (type === types_1.MEM_PRIVATE)
470
+ return 'MEM_PRIVATE';
471
+ return 'MEM_FREE';
472
+ }
473
+ /** 默认最大用户态地址(供上层限制扫描范围) */
474
+ exports.MAX_ADDRESS = types_1.MAX_USER_ADDRESS_64;
475
+ //# sourceMappingURL=process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../../../src/win/process.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAoCH,8CAGC;AAGD,8CAEC;AAgDD,sCAmBC;AAGD,kDAKC;AAOD,gDAkBC;AAGD,4DAQC;AA0BD,4CAUC;AAGD,wDAKC;AA8UD,4CASC;AAGD,wDAiBC;AAGD,wCAKC;AAxjBD,oCASkB;AAqjBmD,uGA7jBnE,8BAAsB,OA6jBmE;AAAtE,2FA5jBnB,kBAAU,OA4jBmB;AAAE,0FA3jB/B,iBAAS,OA2jB+B;AAAE,2FA1jB1C,kBAAU,OA0jB0C;AAAE,4FAzjBtD,mBAAW,OAyjBsD;AAA1D,2FAtjBP,kBAAU,OAsjBO;AA7iBnB,0DAMiC;AAEjC,wDAA+E;AAAtE,0GAAA,UAAU,OAAA;AAAE,0GAAA,UAAU,OAAA;AAAE,4GAAA,YAAY,OAAA;AAE7C;;wEAEwE;AAExE,IAAI,cAAc,GAAyB,IAAI,CAAC;AAEhD,yBAAyB;AACzB,SAAgB,iBAAiB;IAC/B,IAAI,CAAC,cAAc;QAAE,cAAc,GAAG,IAAI,0BAAW,EAAE,CAAC;IACxD,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,0CAA0C;AAC1C,SAAgB,iBAAiB,CAAC,OAA6B;IAC7D,cAAc,GAAG,OAAO,CAAC;AAC3B,CAAC;AAUD,SAAS,cAAc,CAAC,OAA4B;IAClD,IAAI,OAAO,EAAE,OAAO;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC;IAC7C,IAAI,OAAO,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO,IAAI,0BAAW,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,iBAAiB,EAAE,CAAC;AAC7B,CAAC;AAED;;;;;;GAMG;AACH,SAAS,UAAU,CAAI,OAAsB,EAAE,KAAsB,EAAE,SAAiB;IACtF,IAAI,OAAO,CAAC,YAAY,CAAC,IAAI;QAAE,OAAO,KAAU,CAAC;IACjD,MAAM,IAAI,KAAK,CACb,OAAO,OAAO,CAAC,IAAI,mBAAmB,SAAS,KAAK;QAClD,uCAAuC;QACvC,sBAAsB,CACzB,CAAC;AACJ,CAAC;AAeD,sDAAsD;AACtD,SAAgB,aAAa,CAAC,OAAuB;IACnD,MAAM,CAAC,GAAG,OAAO,IAAI,iBAAiB,EAAE,CAAC;IACzC,MAAM,GAAG,GAAkB,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,aAAa,EAAE,EAAE,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACvF,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,WAAW,EAAE,CAAC,CAAC,WAAW;KAC3B,CAAC,CAAC,CAAC;IAEJ,uBAAuB;IACvB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC;YAAE,CAAC,CAAC,aAAa,GAAG,IAAI,CAAC;IAC1E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,0BAA0B;AAC1B,SAAgB,mBAAmB,CAAC,IAAY,EAAE,OAAuB;IACvE,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAClC,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC,MAAM,CAClC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAChF,CAAC;AACJ,CAAC;AAED;;wEAEwE;AAExE,6BAA6B;AACtB,KAAK,UAAU,kBAAkB,CAAC,OAAuB;IAC9D,MAAM,CAAC,GAAG,OAAO,IAAI,iBAAiB,EAAE,CAAC;IACzC,MAAM,GAAG,GAAkB,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,WAAW,EAAE,CAAC,CAAC,WAAW;KAC3B,CAAC,CAAC,CAAC;IAEJ,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC;YAAE,CAAC,CAAC,aAAa,GAAG,IAAI,CAAC;IAC1E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,iBAAiB;AACV,KAAK,UAAU,wBAAwB,CAC5C,IAAY,EACZ,OAAuB;IAEvB,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAClC,OAAO,CAAC,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAC/C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAChF,CAAC;AACJ,CAAC;AASD,gCAAgC;AAChC,SAAS,cAAc,CAAC,CAAgB;IACtC,OAAO;QACL,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,SAAS,EAAE,CAAC,CAAC,KAAK,KAAK,kBAAU;QACjC,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,IAAI,EAAE,CAAC,CAAC,IAAI;KACb,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,gBAAgB,CAC9B,OAAgB,EAChB,UAA0D,EAAE;IAE5D,IAAI,CAAC,CAAC,OAAO,YAAY,OAAO,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,SAAS,CACjB,wEAAwE,CACzE,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC;AAED,oCAAoC;AACpC,SAAgB,sBAAsB,CACpC,OAAgB,EAChB,SAAuB,EAAE;IAEzB,OAAO,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAC1C,CAAC;AAED;;wEAEwE;AAExE,6CAA6C;AAC7C,MAAa,gBAAiB,SAAQ,KAAK;IAE9B;IACA;IAFX,YACW,GAAW,EACX,SAAiB,EAC1B,OAAgB;QAEhB,KAAK,CAAC,OAAO,IAAI,UAAU,GAAG,aAAa,SAAS,EAAE,CAAC,CAAC;QAJ/C,QAAG,GAAH,GAAG,CAAQ;QACX,cAAS,GAAT,SAAS,CAAQ;QAI1B,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AATD,4CASC;AASD;;;;;;;;;GASG;AACH,MAAa,OAAO;IAIP;IACA;IACA;IACQ;IANX,MAAM,GAAG,KAAK,CAAC;IAEvB,YACW,GAAW,EACX,IAAY,EACZ,OAAsB,EACd,MAA4B;QAHpC,QAAG,GAAH,GAAG,CAAQ;QACX,SAAI,GAAJ,IAAI,CAAQ;QACZ,YAAO,GAAP,OAAO,CAAe;QACd,WAAM,GAAN,MAAM,CAAsB;IAC5C,CAAC;IAEJ,iDAAiD;IACjD,MAAM,CAAC,IAAI,CAAC,GAAW,EAAE,OAA4B;QACnD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,MAA4B,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,GAAG,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,GAAG,GAAG,CAAiD,CAAC;YAC9D,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,IAAI,GAAG,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBACnE,MAAM,IAAI,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,SAAS,IAAI,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YACnE,CAAC;YACD,MAAM,CAAC,CAAC;QACV,CAAC;QACD,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,EAAE,EAAE,eAAe,CAAC,CAAC,IAAI,CAC7E,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CACrB,CAAC;QACF,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,IAAI,QAAQ,GAAG,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED,wBAAwB;IACxB,MAAM,CAAC,UAAU,CAAC,IAAY,EAAE,OAA4B;QAC1D,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QACxC,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QAC3D,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED,mBAAmB;IACnB,MAAM,CAAC,aAAa,CAAC,IAAY,EAAE,OAA4B;QAC7D,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QACxC,OAAO,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IACrF,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,UAAU,CACf,GAAW,EACX,IAAY,EACZ,OAAsB,EACtB,MAA4B;QAE5B,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,MAAM;QACR,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;IACtB,CAAC;IAED,aAAa;IACb,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACH,IAAI,aAAa;QACf,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAEO,UAAU;QAChB,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;IAC5D,CAAC;IAED,wBAAwB;IACxB,OAAO;QACL,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC;IAChF,CAAC;IAED,eAAe;IACf,OAAO,CAAC,OAAwD;QAC9D,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE;YAC3E,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,IAAI;YACzC,UAAU,EAAE,OAAO,EAAE,UAAU;SAChC,CAAC,EAAE,SAAS,CAAC,CAAC;QACf,OAAO,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAClC,CAAC;IAED,cAAc;IACd,gBAAgB,CAAC,MAAqB;QACpC,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC,EAAE,kBAAkB,CAAC,CAAC;QAC/G,OAAO,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACjC,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,OAAe,EAAE,IAAY;QACtC,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC;IAC5G,CAAC;IAED,mBAAmB;IACnB,eAAe,CAAC,OAAe,EAAE,IAAY;QAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC3C,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,QAAQ,IAAI,CAAC,GAAG,cAAc,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,IAAI,UAAU,GAAG,CAAC,MAAM,KAAK,CACvF,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;;OAGG;IACH,WAAW,CAAC,OAAe,EAAE,IAAY,EAAE,aAAa,GAAG,IAAI;QAC7D,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,EAAE,aAAa,CAAC,CAAC;IAC7H,CAAC;IAED,iBAAiB;IACjB,QAAQ,CAAC,IAAY,EAAE,OAAO,GAAG,IAAI,EAAE,OAAO,GAAG,EAAE;QACjD,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC;IAC1G,CAAC;IAED,yBAAyB;IACzB,IAAI,CAAC,OAAe;QAClB,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5E,CAAC;IAED,sBAAsB;IACtB,OAAO,CAAC,OAAe,EAAE,IAAY,EAAE,UAAkB;QACvD,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,SAAS,CAAC,CAAC;IACpH,CAAC;IAED,aAAa;IACb,OAAO;QACL,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7F,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,IAAI,EAAE,CAAC,CAAC,IAAI;SACb,CAAC,CAAC,CAAC;IACN,CAAC;IAED,cAAc;IACd,SAAS;QACP,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC;IACvF,CAAC;IAED;;;OAGG;IACH,OAAO;QACL,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,CAAC,GAAG,IAAI,CAAC,OAEd,CAAC;QACF,IAAI,OAAO,CAAC,CAAC,iBAAiB,KAAK,UAAU,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CACb,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,8BAA8B,CACvD,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,gBAAgB;IAChB,MAAM,CAAC,KAAc;QACnB,MAAM,CAAC,GAAG,IAAI,CAAC,OAAoE,CAAC;QACpF,IAAI,OAAO,CAAC,CAAC,aAAa,KAAK,UAAU,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,WAAW,CAAC,CAAC;QACvD,CAAC;QACD,CAAC,CAAC,aAAa,CAAC,KAAiB,CAAC,CAAC;IACrC,CAAC;IAED,kBAAkB;IAClB,KAAK;QACH,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,KAAK,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED,oBAAoB;IACpB,CAAC,MAAM,CAAC,OAAO,CAAC;QACd,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;IAED;;;;;;;;0EAQsE;IAEtE,aAAa;IACb,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/C,CAAC;IAED,iBAAiB;IACjB,KAAK,CAAC,YAAY,CAAC,OAAwD;QACzE,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE;YACxD,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,IAAI;YACzC,UAAU,EAAE,OAAO,EAAE,UAAU;SAChC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAClC,CAAC;IAED,gBAAgB;IAChB,KAAK,CAAC,qBAAqB,CAAC,MAAqB;QAC/C,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;QACvE,OAAO,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACjC,CAAC;IAED,aAAa;IACb,KAAK,CAAC,eAAe,CAAC,OAAe,EAAE,IAAY;QACjD,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC;IAC5G,CAAC;IAED,oBAAoB;IACpB,KAAK,CAAC,oBAAoB,CAAC,OAAe,EAAE,IAAY;QACtD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACtD,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,QAAQ,IAAI,CAAC,GAAG,cAAc,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,IAAI,UAAU,GAAG,CAAC,MAAM,KAAK,CACvF,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,aAAa;IACb,KAAK,CAAC,gBAAgB,CAAC,OAAe,EAAE,IAAY,EAAE,aAAa,GAAG,IAAI;QACxE,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,EAAE,aAAa,CAAC,CAAC;IAC7H,CAAC;IAED,aAAa;IACb,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACtB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,IAAI,EAAE,CAAC,CAAC,IAAI;SACb,CAAC,CAAC,CAAC;IACN,CAAC;IAED,gBAAgB;IAChB,KAAK,CAAC,cAAc;QAClB,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC;IACvF,CAAC;IAED,aAAa;IACb,KAAK,CAAC,aAAa,CAAC,IAAY,EAAE,OAAO,GAAG,IAAI,EAAE,OAAO,GAAG,EAAE;QAC5D,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC;IAC1G,CAAC;IAED,eAAe;IACf,KAAK,CAAC,YAAY,CAAC,OAAe,EAAE,IAAY,EAAE,UAAkB;QAClE,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,SAAS,CAAC,CAAC;IACpH,CAAC;IAED,mBAAmB;IACnB,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC;IAChF,CAAC;CACF;AAxSD,0BAwSC;AAED,gCAAgC;AACzB,KAAK,UAAU,gBAAgB,CACpC,GAAW,EACX,OAA4B;IAE5B,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,aAAa,EAAE,CAAC;IAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;IAC9C,OAAO,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,IAAI,QAAQ,GAAG,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAChF,CAAC;AAED,qBAAqB;AACd,KAAK,UAAU,sBAAsB,CAC1C,IAAY,EACZ,OAA4B;IAE5B,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,CAAC,MAAM,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACtD,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,WAAW,EAAE,CAAC,CAAC,WAAW;KAC3B,CAAC,CAAC,CAAC;IACJ,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAClC,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CACxB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAChF,CAAC;IACF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IAC3D,OAAO,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AACnD,CAAC;AAED,oBAAoB;AACpB,SAAgB,cAAc,CAAC,IAAY;IACzC,IAAI,IAAI,KAAK,iBAAS;QAAE,OAAO,WAAW,CAAC;IAC3C,IAAI,IAAI,KAAK,kBAAU;QAAE,OAAO,YAAY,CAAC;IAC7C,IAAI,IAAI,KAAK,mBAAW;QAAE,OAAO,aAAa,CAAC;IAC/C,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,2BAA2B;AACd,QAAA,WAAW,GAAG,2BAAmB,CAAC"}
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ /**
3
+ * 扫描 worker —— 在独立线程中读取目标进程内存、执行比较,并把结果写入共享内存。
4
+ *
5
+ * 对应 CE 的 TScanner(TThread 子类):CE 每条扫描线程负责一段内存,
6
+ * 通过临界区/信号量把结果写回主线程的地址缓冲区。
7
+ * 这里用 SharedArrayBuffer + Atomics 达到同样目的。
8
+ *
9
+ * 共享内存之所以必须共享:扫描 API 是同步的(对齐 CE 的阻塞语义),
10
+ * 主线程用 Atomics.wait 等待,此时无法处理 worker 的 postMessage。
11
+ *
12
+ * 容量约束:V8 对单个 SharedArrayBuffer 有约 1.5GB 上限,
13
+ * 因此每个 worker 批次使用**独立的、容量受控的**共享段,
14
+ * 而不是一个大段。详见 shared-layout.ts 的 createBatchLayout。
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ const node_worker_threads_1 = require("node:worker_threads");
18
+ const process_1 = require("./process");
19
+ const matcher_1 = require("../scanner/matcher");
20
+ const shared_layout_1 = require("../scanner/shared-layout");
21
+ let proc = null;
22
+ let currentPid = -1;
23
+ function ensureProcess(pid) {
24
+ if (proc && currentPid === pid && proc.isOpen)
25
+ return proc;
26
+ proc?.close();
27
+ proc = process_1.Process.open(pid);
28
+ currentPid = pid;
29
+ return proc;
30
+ }
31
+ const port = node_worker_threads_1.parentPort;
32
+ if (!port) {
33
+ throw new Error('scan-worker 必须在 worker_threads 中运行');
34
+ }
35
+ port.on('message', (msg) => {
36
+ if (msg.type !== 'scan')
37
+ return;
38
+ const layout = (0, shared_layout_1.createBatchLayout)(msg.layoutParams.jobCount, msg.layoutParams.slotCapacity, msg.layoutParams.arenaCapacity, msg.shared);
39
+ let p = null;
40
+ let failed = 0;
41
+ try {
42
+ p = ensureProcess(msg.pid);
43
+ }
44
+ catch {
45
+ p = null;
46
+ }
47
+ const cc = (0, matcher_1.compileConfig)(msg.config);
48
+ for (let i = 0; i < msg.jobs.length; i++) {
49
+ const job = msg.jobs[i];
50
+ if (!p) {
51
+ (0, shared_layout_1.writeSlot)(layout, i, []);
52
+ (0, shared_layout_1.markHandled)(layout, i);
53
+ (0, shared_layout_1.markDone)(layout, true);
54
+ failed++;
55
+ continue;
56
+ }
57
+ try {
58
+ const buf = p.readMemory(BigInt(job.address), job.size);
59
+ if (buf.length === 0) {
60
+ (0, shared_layout_1.writeSlot)(layout, i, []);
61
+ (0, shared_layout_1.markHandled)(layout, i);
62
+ (0, shared_layout_1.markDone)(layout, false);
63
+ continue;
64
+ }
65
+ const offsets = [];
66
+ (0, matcher_1.scanBlock)(cc, buf, null, offsets, undefined);
67
+ (0, shared_layout_1.writeSlot)(layout, i, offsets);
68
+ if (msg.keepSnapshot && offsets.length > 0) {
69
+ (0, shared_layout_1.writeSnapshot)(layout, i, buf);
70
+ }
71
+ (0, shared_layout_1.markHandled)(layout, i);
72
+ (0, shared_layout_1.markDone)(layout, false);
73
+ }
74
+ catch {
75
+ (0, shared_layout_1.writeSlot)(layout, i, []);
76
+ (0, shared_layout_1.markHandled)(layout, i);
77
+ (0, shared_layout_1.markDone)(layout, true);
78
+ failed++;
79
+ }
80
+ }
81
+ port.postMessage({ type: 'batchDone', failed });
82
+ });
83
+ port.postMessage({ type: 'ready' });
84
+ //# sourceMappingURL=scan-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-worker.js","sourceRoot":"","sources":["../../../src/win/scan-worker.ts"],"names":[],"mappings":"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"}