@bingine/cemem 0.0.0-stage → 0.1.1

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,434 @@
1
+ /**
2
+ * Auto Assembler —— Cheat Engine 脚本语言的解析与执行层。
3
+ *
4
+ * 对齐 `Cheat Engine/autoassembler.pas`(3752 行)与 `Assemblerunit.pas` 里
5
+ * 属于 Auto Assembler 的那部分(`db/dw/dd/dq`、`nop N`、`align`)。
6
+ *
7
+ * ## 它解决什么问题
8
+ *
9
+ * CE 的 Auto Assembler 是"把一段脚本变成对目标进程内存的修改"的编译器 + 执行器:
10
+ *
11
+ * ```text
12
+ * [ENABLE]
13
+ * alloc(newmem,2048) // 1. 在目标进程分配内存
14
+ * label(returnhere) // 2. 声明一个脚本内标签
15
+ * aobscan(sig, DE AD BE EF 90 90 ?? 7*) // 3. 在目标进程里搜特征码
16
+ * newmem: // 4. 地址定位(后续指令从这里排布)
17
+ * mov dword ptr [sig], 1337 // 5. 写代码
18
+ * jmp returnhere
19
+ * sig: // 6. 回到 aobscan 找到的地址
20
+ * jmp newmem
21
+ * returnhere:
22
+ * [DISABLE]
23
+ * dealloc(newmem)
24
+ * ```
25
+ *
26
+ * ## 执行流水线(与 CE 一一对应)
27
+ *
28
+ * ```
29
+ * stripComments ← removecomments() 去 // ; {} 注释(字符串感知)
30
+ * expandIncludes ← INCLUDE() 分支 把 include 的文件内容就地展开
31
+ * analyzeSections ← getenableanddisablepos() 找 [ENABLE]/[DISABLE]
32
+ * selectLines ← getEnableOrDisableScript() 取「外层代码 + 选中段」
33
+ * stripCpuSpecific ← stripCPUspecificCode() 处理 [32-BIT]/[64-BIT]
34
+ * preprocess ← autoassemble2 的解析循环 alloc/aobscan/label/define/db/...
35
+ * layout ← AutoassemblerCodePass2() 逐行定地址 + 汇编(迭代到稳定)
36
+ * apply ← 写内存分支 写目标进程并记录原字节
37
+ * ```
38
+ *
39
+ * ## 三个最容易静默出错、因此被重点处理的地方
40
+ *
41
+ * 1. **地址定位**。CE 的脚本不是"从头顺序汇编",而是由**地址定义行**(`name:`)切块:
42
+ * 遇到已知符号(alloc/aobscan/registered)或地址表达式(`"game.exe"+1234:`)时,
43
+ * 当前地址被**重置**到该值;否则标签取当前地址。若不实现这条,
44
+ * `newmem:` 之后那段代码会被写到地址 0。
45
+ * 2. **前向引用的指令长度**。`jmp returnhere` 里的 `returnhere` 定义在后面,
46
+ * 它的地址又取决于前面指令的长度 —— 循环依赖。CE 的做法是用
47
+ * 「当前地址 + 0xFFFFF」当远占位符、用「当前地址」当近占位符各编一次,
48
+ * 取**较长**的那个,保证后续地址不会因为编码变短而漂移。本移植沿用这一策略,
49
+ * 并额外做迭代收敛(见 `MAX_LAYOUT_PASSES`)。
50
+ * 3. **原字节保留**。[ENABLE] 写入前逐字节记录被覆盖的原字节;[DISABLE] 时按记录
51
+ * 逆序精确还原(`restoreMode: 'original'`,默认)。这正是 CE 教程里
52
+ * 「关掉作弊后游戏恢复正常」的底层机制。
53
+ *
54
+ * ## 与 CE 的差异(完整清单见 docs/autoassembler.md)
55
+ *
56
+ * - **数字进制是一致的**(实测):Keystone 的 Intel 语法把裸数字按**十六进制**解析,
57
+ * 与 CE 相同 —— `mov eax, 100` 编出 `B8 00 01 00 00`(即 0x100)。
58
+ * 想写十进制只能写 `0x` 形式的十六进制值(Keystone 不支持 CE 的 `#123`)。
59
+ * - `db/dw/dd/dq`、`nop N`、`align N` 由本层自己实现,同样是十六进制语义。
60
+ * - `alloc`/`readmem` 的**大小**参数按十进制(对齐 CE 的 `StrToInt`),
61
+ * 需要十六进制时写 `0x` 或 `$` 前缀。
62
+ * - `createthread`/`createthreadandwait` 只做参数校验与记录,不创建远程线程
63
+ * (Node 没有 CreateRemoteThread;见 `allowCreateThread`)。
64
+ * - `luaCall`/`reassemble`/`struct`/`kalloc`/`sharedalloc`/`loadlibrary`/
65
+ * `allocnx`/`allocxo`/`aobscanex`/`{$...}` 条件编译未实现,会给出明确的中文错误。
66
+ *
67
+ * ## 用法
68
+ *
69
+ * ```ts
70
+ * await ensureAsmBackend(); // WASM 后端必须先初始化
71
+ * const aa = new AutoAssembler({ process });
72
+ * aa.autoAssemble(script, { enable: true }); // 注入并记录原字节
73
+ * aa.autoAssemble(script, { enable: false }); // 精确还原
74
+ * ```
75
+ */
76
+ import { Process } from '../win/process';
77
+ import { type AsmArchitecture, type AsmBitness } from './backend';
78
+ import { type ParsedPseudoDirective, type PseudoDirectiveKind } from './autoassembler-directives';
79
+ /** 错误发生的阶段 */
80
+ export type AutoAssemblerPhase = 'parse' | 'scan' | 'assemble' | 'write';
81
+ /** Auto Assembler 错误(带脚本行号与列内容,便于定位) */
82
+ export declare class AutoAssemblerError extends Error {
83
+ /** 出错的源码行(已去注释) */
84
+ readonly line?: string;
85
+ /** 出错的源码行号(1-based;include 的文件里是文件内行号) */
86
+ readonly lineNumber?: number;
87
+ /** 出错行所属文件(主脚本为 `<script>`) */
88
+ readonly file?: string;
89
+ /** 阶段 */
90
+ readonly phase: AutoAssemblerPhase;
91
+ constructor(message: string, options?: {
92
+ line?: string;
93
+ lineNumber?: number;
94
+ file?: string;
95
+ phase?: AutoAssemblerPhase;
96
+ });
97
+ }
98
+ /** DISABLE 的还原策略 */
99
+ export type RestoreMode =
100
+ /** 默认:优先用 [ENABLE] 时记录的原字节精确还原(等价于 CE 的还原效果,且不依赖脚本写全) */
101
+ 'original'
102
+ /** CE 原生:完全听 [DISABLE] 段脚本的,历史记录只用于诊断 */
103
+ | 'script';
104
+ /** 选项 */
105
+ export interface AutoAssemblerOptions {
106
+ /**
107
+ * 目标进程。**省略时自动进入 syntaxCheckOnly 模式**:
108
+ * 只解析与汇编、不分配内存、不写内存,用于语法检查与"预演"。
109
+ */
110
+ process?: Process;
111
+ /** 位数;省略时按 `process.isWow64()` 推断(推断失败按 64) */
112
+ bitness?: AsmBitness;
113
+ /**
114
+ * 架构,支持 `x86` / `x64` / `arm` / `thumb` / `arm64`。
115
+ * ARM 目标必须显式给(只给 bitness 无法区分 arm 与 thumb)。
116
+ * 省略时按 `bitness` → 目标进程位数 → `x64` 推断。
117
+ */
118
+ arch?: AsmArchitecture;
119
+ /** `include()` 的额外搜索目录(会在脚本目录、cwd 之后依次尝试) */
120
+ includeDirs?: string[];
121
+ /** 主脚本路径,用于解析 `include()` 的相对路径 */
122
+ scriptPath?: string;
123
+ /**
124
+ * 是否真的执行 `createthread` 创建远程线程。
125
+ * 本移植**不支持**(Node 无 CreateRemoteThread),因此 `true` 会直接报错;
126
+ * 默认 `false` 时只做参数校验并记录到 `AutoAssembleResult.createThreads`。
127
+ */
128
+ allowCreateThread?: boolean;
129
+ /** DISABLE 还原策略,默认 `'original'` */
130
+ restoreMode?: RestoreMode;
131
+ /** 重复 enable 时是否复用已分配的地址(默认 true,避免重复分配导致泄漏) */
132
+ reuseAllocations?: boolean;
133
+ /** aobscan 的扫描块大小,默认 1MB */
134
+ scanBlockSize?: number;
135
+ /** aobscan 是否使用 worker 并行(默认 false:脚本场景要求确定性) */
136
+ scanParallel?: boolean;
137
+ /**
138
+ * `db/dw/dd/dq`、`nop N`、`align N` 的裸数字是否按十六进制解释。
139
+ * 默认 true —— **CE 行为**,不要轻易改(真实脚本的 `db 89 01` 依赖它)。
140
+ */
141
+ dataHexDefault?: boolean;
142
+ /**
143
+ * 段内代码开始前的起始地址。默认 `undefined`:
144
+ * 此时在出现任何地址定义行之前写代码会直接报错(与 CE 一致,防止写到地址 0)。
145
+ */
146
+ startAddress?: bigint;
147
+ }
148
+ /** 一次 alloc 的记录 */
149
+ export interface AutoAssemblerAllocation {
150
+ name: string;
151
+ address: bigint;
152
+ size: number;
153
+ protection: number;
154
+ /** 是否由 `globalalloc` 申请(全局可见) */
155
+ global: boolean;
156
+ }
157
+ /** 一条写入记录 */
158
+ export interface AutoAssemblerEntry {
159
+ address: bigint;
160
+ bytes: Buffer;
161
+ /** 写入前该区间的原字节(写内存失败或只做语法检查时可能为 null) */
162
+ originalBytes: Buffer | null;
163
+ /** 该条目的字节是否来自"还原记录的原字节"(DISABLE 时) */
164
+ restoredFromOriginal: boolean;
165
+ /** 来源脚本行 */
166
+ line: string;
167
+ lineNumber: number;
168
+ file: string;
169
+ }
170
+ /** 布局后的脚本行(诊断/测试用) */
171
+ export interface AutoAssemblerLineInfo {
172
+ /** 该行对应的指令/伪指令文本(标签已剥离、define 已替换) */
173
+ text: string;
174
+ address: bigint;
175
+ bytes: Buffer;
176
+ /** 该行是否不产生字节(纯标签行/空行) */
177
+ empty: boolean;
178
+ /** 本行定义的标签名 */
179
+ labels: string[];
180
+ lineNumber: number;
181
+ file: string;
182
+ }
183
+ /** 一次 aobscan 的结果 */
184
+ export interface AobScanRecord {
185
+ name: string;
186
+ /** 全部命中地址(升序) */
187
+ matches: bigint[];
188
+ /** 实际选用的地址(= matches[0],对齐 CE"取第一处") */
189
+ address: bigint;
190
+ /** 扫描形态 */
191
+ scope: 'all' | 'module' | 'region' | 'unique';
192
+ }
193
+ /** 执行结果 */
194
+ export interface AutoAssembleResult {
195
+ /** 本次执行的是 ENABLE(true)还是 DISABLE(false)段 */
196
+ enable: boolean;
197
+ /** 是否只做语法检查(未写目标进程) */
198
+ syntaxCheckOnly: boolean;
199
+ /** 实际写入(或"将要写入")的条目 */
200
+ entries: AutoAssemblerEntry[];
201
+ /** 写入的总字节数 */
202
+ bytesWritten: number;
203
+ /** 布局后的全部脚本行 */
204
+ lines: AutoAssemblerLineInfo[];
205
+ /** 执行结束时的符号表快照(只读副本) */
206
+ symbols: Map<string, bigint>;
207
+ /** 当前会话的全部 alloc */
208
+ allocations: AutoAssemblerAllocation[];
209
+ /** 通过 registersymbol 注册(跨脚本可见)的符号名 */
210
+ registeredSymbols: string[];
211
+ /** createthread 校验通过的地址(本移植不执行) */
212
+ createThreads: bigint[];
213
+ /** 本次脚本里所有 aobscan 的命中情况(诊断用:CE 只暴露第一处,这里把全部给出) */
214
+ aobScans: AobScanRecord[];
215
+ /** 非致命问题 */
216
+ warnings: string[];
217
+ /** 段位置 */
218
+ sections: {
219
+ enableLine: number | null;
220
+ disableLine: number | null;
221
+ };
222
+ }
223
+ /** 一行源码(注释已剥离) */
224
+ export interface SourceLine {
225
+ text: string;
226
+ /** 1-based 行号(所属文件内) */
227
+ number: number;
228
+ file: string;
229
+ }
230
+ /** 一个待布局的汇编行 */
231
+ export interface AsmLine {
232
+ /** 指令/伪指令文本(标签已剥离、define 已替换) */
233
+ text: string;
234
+ pseudo: ParsedPseudoDirective | null;
235
+ /** readmem 预读出来的字节 */
236
+ readmemBytes: Buffer | null;
237
+ /** 本行定义的标签(`known` 非 null 表示地址来自 alloc/aobscan/registered/地址表达式) */
238
+ labels: Array<{
239
+ name: string;
240
+ known: bigint | null;
241
+ }>;
242
+ /** 原始行内容(报错用) */
243
+ raw: string;
244
+ lineNumber: number;
245
+ file: string;
246
+ address: bigint;
247
+ bytes: Buffer;
248
+ }
249
+ /**
250
+ * 一个 Auto Assembler 会话。
251
+ *
252
+ * 会话保存跨调用的状态(符号表、alloc、原字节记录),因此
253
+ * `autoAssemble(script, {enable:true})` 之后
254
+ * `autoAssemble(script, {enable:false})` 才能精确还原。
255
+ * 这与 CE 里 `TMemoryRecord` 持有 `TDisableInfo` 是同一个设计。
256
+ */
257
+ export declare class AutoAssembler {
258
+ private readonly options;
259
+ /** 跨脚本可见的符号(alloc / aobscan / registersymbol 的结果) */
260
+ private readonly persistentSymbols;
261
+ /** 当前会话的 alloc */
262
+ private readonly allocations;
263
+ /** registersymbol 注册的名字 */
264
+ private readonly registeredSymbols;
265
+ /**
266
+ * 每个脚本 key 对应一份"ENABLE 期间记录的原字节"。
267
+ *
268
+ * 为什么按脚本分开存:CE 的 `TDisableInfo` 是**每个内存记录一份**的,
269
+ * 因此可以同时启用多个脚本、再各自独立关闭。若共用一份历史,
270
+ * 启用脚本 B 会冲掉脚本 A 的记录,导致 A 无法还原。
271
+ */
272
+ private readonly histories;
273
+ /** 模块列表缓存(地址表达式反复求值用) */
274
+ private moduleCache;
275
+ constructor(options?: AutoAssemblerOptions);
276
+ /** 目标进程(可能为 undefined:纯语法检查模式) */
277
+ get process(): Process | undefined;
278
+ /** 当前已知符号(只读快照) */
279
+ get symbols(): ReadonlyMap<string, bigint>;
280
+ /** 当前 alloc(只读快照) */
281
+ get allocationsList(): readonly AutoAssemblerAllocation[];
282
+ /** 释放本会话分配的全部内存并清空符号/历史 */
283
+ cleanup(): void;
284
+ /** 本会话是否记录过该脚本的 ENABLE 原字节 */
285
+ hasHistory(script: string): boolean;
286
+ /** 取某脚本记录的原字节(只读副本,诊断用) */
287
+ historyOf(script: string): Array<{
288
+ address: bigint;
289
+ bytes: Buffer;
290
+ }>;
291
+ /** 执行 ENABLE 段 */
292
+ enable(script: string): AutoAssembleResult;
293
+ /** 执行 DISABLE 段(按 `restoreMode` 还原) */
294
+ disable(script: string): AutoAssembleResult;
295
+ /** 只做语法检查与汇编(不分配、不写内存、无副作用) */
296
+ check(script: string): AutoAssembleResult;
297
+ /**
298
+ * 解析脚本并执行,对齐 CE 的 `autoassemble(code, enable)`。
299
+ *
300
+ * @param script 脚本原文
301
+ * @param opts.enable 执行 ENABLE(默认)还是 DISABLE 段
302
+ * @param opts.syntaxCheckOnly 只检查不执行(没有 process 时自动开启)
303
+ */
304
+ autoAssemble(script: string, opts?: {
305
+ enable?: boolean;
306
+ syntaxCheckOnly?: boolean;
307
+ }): AutoAssembleResult;
308
+ private toSourceLines;
309
+ /** 展开 `include(file.cea)`(就地插入,保留被包含文件自己的行号) */
310
+ private expandIncludes;
311
+ private resolveIncludePath;
312
+ /**
313
+ * 遍历选中段的每一行,把 CE 指令转换成"汇编行"。
314
+ *
315
+ * 处理顺序与 CE 的解析循环一致:先做指令匹配,未匹配的按普通汇编行处理
316
+ * (因此 `db/nop/align` 也走这里)。
317
+ */
318
+ private preprocess;
319
+ /** 判断是否为明确不支持的指令;返回指令名(大写)或 null */
320
+ private matchUnsupported;
321
+ private tryAobScan;
322
+ /** 按 `maxParts` 上限在顶层逗号处切分(引号内不切) */
323
+ private splitTopLevel;
324
+ private performAobScan;
325
+ private tryCreateThread;
326
+ private tryAlloc;
327
+ private allocate;
328
+ private deallocate;
329
+ private trySymbolDirective;
330
+ /**
331
+ * `define(name, whatever)` —— **纯文本替换**,对齐 CE(autoassembler.pas 2004~2043)。
332
+ *
333
+ * 注意 CE 的语义细节:`whatever` 不是"值"而是"文本"。因此
334
+ * `define(myVal, 1337)` 之后 `mov [x], myVal` 等价于 `mov [x], 1337`。
335
+ * 值的解析发生在最终汇编/伪指令解析时,所以同一份 define 在指令里与
336
+ * `db` 里的进制解释可能不同(详见 docs/autoassembler.md 的差异表)。
337
+ */
338
+ private handleDefine;
339
+ /** 应用当前生效的全部 define(按定义顺序;跳过 `skipName` 自身,避免自替换) */
340
+ private applyDefines;
341
+ private tryMemoryUtility;
342
+ /**
343
+ * 解析地址定义行。支持三种形态:
344
+ *
345
+ * 1. `newmem:` —— 已知符号(alloc/aobscan/registered)→ 重置当前地址
346
+ * 2. `returnhere:` —— 脚本标签 → 取当前地址
347
+ * 3. `00401000:` / `"game.exe"+1234:` —— 地址表达式 → 重置当前地址
348
+ *
349
+ * 也支持 `name: 指令` 的同行写法(CE 只支持独立定义行,这里是超集)。
350
+ */
351
+ private parseAddressSetter;
352
+ /**
353
+ * 把布局得到的标签地址登记为符号。
354
+ *
355
+ * 对齐 CE:脚本里的 `label(x)` + `x:` 也会进入符号表
356
+ * (`disableinfo.allsymbols`,autoassembler.pas 4350~4360),
357
+ * 因此同一个会话里后续脚本 / [DISABLE] 段都能引用它。
358
+ */
359
+ private commitLabelSymbols;
360
+ /**
361
+ * 解析延后的 `registersymbol` 请求。
362
+ *
363
+ * 必须在布局之后调用:`registersymbol(mylabel)` 里的标签地址只有在
364
+ * 所有指令长度确定之后才是最终值。
365
+ */
366
+ private resolvePendingRegisters;
367
+ /** 查符号(alloc/aobscan/registered/持久符号),忽略大小写 */
368
+ private lookupSymbol;
369
+ /**
370
+ * 求值地址表达式。
371
+ *
372
+ * 优先按 CE 的整数语义解析裸数字(十六进制),否则交给 `resolveAddress`;
373
+ * 送进去之前会把裸数字改写成 `0x` 形式(`hexifyBareNumbers`),
374
+ * 因为 `addr/expression.ts` 把无 a-f 字母的裸数字当十进制。
375
+ */
376
+ private resolveExpression;
377
+ private registerSymbol;
378
+ private layout;
379
+ private sameLabelMap;
380
+ /** 编码 `db/dw/dd/dq`、`nop N`、`align N[,b]` */
381
+ private encodePseudo;
382
+ /**
383
+ * 编码一条指令。
384
+ *
385
+ * 前向引用的标签用「近/远两个占位符各编一次、取较长者」的策略
386
+ * (对齐 CE autoassembler.pas 3741~3763 行),保证地址不会因为
387
+ * 编码从长变短而漂移。
388
+ */
389
+ private encodeInstruction;
390
+ private tryAssembleLine;
391
+ private assembleLine;
392
+ private apply;
393
+ private readOriginal;
394
+ private writeBlock;
395
+ /**
396
+ * 记录被覆盖的原字节。
397
+ *
398
+ * 记录集保持"按地址升序、互不重叠":与已有记录重叠的部分会被裁掉
399
+ * (保留最早的原始内容),相邻的会合并。
400
+ */
401
+ private recordOriginal;
402
+ /**
403
+ * 从历史里摘掉一段区间。
404
+ *
405
+ * `dealloc`/`realloc` 释放内存后必须调用:那块内存已经还给系统,
406
+ * 再去"还原"它只会得到 ERROR_INVALID_ADDRESS(实测踩过)。
407
+ */
408
+ private dropHistoryRange;
409
+ private resolveBitness;
410
+ /**
411
+ * 解析汇编用的架构。
412
+ *
413
+ * 优先级:显式 `arch` > 由 `bitness` 推断 > 按目标进程位数推断 > `x64`。
414
+ * 支持 ARM 之后,只给 `bitness` 已不足以表达架构
415
+ * (`arm` 与 `thumb` 都是 32 位),因此 ARM 目标请显式给 `arch`。
416
+ */
417
+ private resolveArch;
418
+ /** 构造带行号/文件/阶段的错误 */
419
+ private error;
420
+ }
421
+ /**
422
+ * 一次性执行脚本(ENABLE 或 DISABLE)。
423
+ *
424
+ * 注意:**成对往返请用 `new AutoAssembler(...)` 复用同一个会话**,
425
+ * 因为 [DISABLE] 的精确还原依赖 [ENABLE] 时记录的原字节。
426
+ * 这个便捷函数适合"一次注入 / 语法检查"这类无状态场景。
427
+ */
428
+ export declare function autoAssemble(script: string, options?: AutoAssemblerOptions & {
429
+ enable?: boolean;
430
+ syntaxCheckOnly?: boolean;
431
+ }): AutoAssembleResult;
432
+ /** 暴露给上层做"纯解析"的辅助类型(测试与文档用) */
433
+ export type { PseudoDirectiveKind };
434
+ //# sourceMappingURL=autoassembler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autoassembler.d.ts","sourceRoot":"","sources":["../../../src/asm/autoassembler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,167 @@
1
+ /**
2
+ * 反汇编/汇编的后端封装(x86 / x64 / ARM / ARM64)。
3
+ *
4
+ * ## 为什么用外部引擎而不是手写指令表
5
+ *
6
+ * Cheat Engine 自己**也不手写 x86 解码器**:Windows 上它优先用 binutils 的
7
+ * `objdump`(见 `binutils.pas` 的 `TBinUtils.disassemble` → `CreateProcess objdump`),
8
+ * `disassembler.pas` 那 13,933 行只是无 binutils 时的回退路径。
9
+ * ARM 那套(`disassemblerarm64.pas` 4,608 行、`disassemblerthumb.pas` 4,414 行、
10
+ * `assemblerarm.pas` 1,074 行)同理。
11
+ *
12
+ * 本移植沿用这一架构,选两个成熟引擎,两者都覆盖 x86/x64/ARM/ARM64:
13
+ * - **capstone-wasm**:Capstone 官方 WASM 绑定(反汇编)
14
+ * - **keystone-wasm**:Keystone 官方 WASM 绑定(v0.9,汇编)
15
+ *
16
+ * ## 支持的架构
17
+ *
18
+ * | 架构名 | 说明 | 对齐 |
19
+ * | --- | --- | --- |
20
+ * | `x86` / `x64` | 32 / 64 位 x86 | 可变长度(1–15 字节),无对齐 |
21
+ * | `arm` | ARM A32(ARMv7 及以前) | 固定 4 字节,4 字节对齐 |
22
+ * | `thumb` | ARM Thumb / Thumb-2 | 2 或 4 字节,2 字节对齐 |
23
+ * | `arm64` | AArch64(ARMv8) | 固定 4 字节,4 字节对齐 |
24
+ *
25
+ * ## 实测踩到的坑(都在这里处理掉)
26
+ *
27
+ * 1. **Capstone 不接受 bigint 地址** —— 传 bigint 会在 WASM 边界抛错。
28
+ * 这里统一转 number,并在超过 `Number.MAX_SAFE_INTEGER` 时**明确报错**。
29
+ * 2. **`disasm()` 返回的 address 相对缓冲区起点**,不是绝对地址。本模块加回基址。
30
+ * 3. **`disasm()` 的参数是选项对象**(`{address, count}`),不是位置参数。
31
+ * 4. **Capstone 构造器只有 `(arch, mode)`**;x86 的 Intel 语法靠
32
+ * `CS_OPT_SYNTAX` 设置。注意 `capstone-wasm` 的 `Const` **没有导出
33
+ * `CS_OPT_SYNTAX`**(实测为 undefined),因此本移植不设语法选项 ——
34
+ * 好在 x86 默认就是 Intel 语法,ARM 也只有一种语法。
35
+ * 5. **Capstone 不暴露 `readInsn`/detail**,拿不到操作数与分组结构;
36
+ * 语义分类由上层按助记符表处理(见 disassembler.ts)。
37
+ * 6. **Thumb 指令长度可变**(2 或 4 字节),且 `disasm()` 的 count 语义
38
+ * 与 x86 一致,无需特殊处理 —— 但**地址必须是 2 的倍数**。
39
+ */
40
+ import type { Keystone as KeystoneType, Const as KeystoneConstType } from 'keystone-wasm';
41
+ import type { Capstone as CapstoneType, Const as CapstoneConstType } from 'capstone-wasm';
42
+ /** 支持的架构 */
43
+ export type AsmArchitecture = 'x86' | 'x64' | 'arm' | 'thumb' | 'arm64';
44
+ /** 大端模式(CE 的 ARM 目标可能是大端) */
45
+ export type AsmEndianness = 'little' | 'big';
46
+ /** 架构静态属性(与引擎无关的元信息,上层用来决定对齐与默认值) */
47
+ export interface ArchitectureInfo {
48
+ /** 规范化名称 */
49
+ arch: AsmArchitecture;
50
+ /** 引擎用的家族:'x86' | 'arm' | 'arm64' */
51
+ family: 'x86' | 'arm' | 'arm64';
52
+ /** 指令对齐(字节):决定反汇编推进的最小步长 */
53
+ alignment: number;
54
+ /** 指令是否定长;定长时 `fixedSize` 有效 */
55
+ fixedSize: boolean;
56
+ /** 定长指令的宽度(字节);变长时为 0 */
57
+ instructionSize: number;
58
+ /** 显示用地址宽度(十六进制字符数) */
59
+ addressWidth: number;
60
+ /** 是否为 64 位目标 */
61
+ is64Bit: boolean;
62
+ }
63
+ /** 取架构元信息 */
64
+ export declare function architectureInfo(arch: AsmArchitecture): ArchitectureInfo;
65
+ /**
66
+ * 把宽松的架构写法规范化为 `AsmArchitecture`。
67
+ *
68
+ * 接受:`x64`/`amd64`/`x86_64`/`64`、`x86`/`i386`/`ia32`/`32`、
69
+ * `arm`/`arm32`/`a32`/`armv7`、`thumb`/`t32`/`thumb2`、
70
+ * `arm64`/`aarch64`/`armv8`/`x64arm`。
71
+ */
72
+ export declare function normalizeArchitecture(input: string | number | undefined, fallback?: AsmArchitecture): AsmArchitecture;
73
+ /** 兼容旧的 `bitness` 写法(32/64)→ 架构名 */
74
+ export declare function archFromBitness(bitness: 32 | 64 | undefined): AsmArchitecture;
75
+ /**
76
+ * @deprecated 用 `AsmArchitecture` 代替(支持 ARM 后"位数"无法表达架构)。
77
+ * 保留此别名仅为兼容已有调用签名。
78
+ */
79
+ export type AsmBitness = 32 | 64;
80
+ /** 反汇编出的一条指令(后端层,尽量少加工) */
81
+ export interface RawInstruction {
82
+ /** 绝对地址(已把基址加回) */
83
+ address: bigint;
84
+ /** 指令长度(字节) */
85
+ size: number;
86
+ /** 机器码字节 */
87
+ bytes: Buffer;
88
+ /** 助记符(小写,Capstone 风格) */
89
+ mnemonic: string;
90
+ /** 操作数字符串(Capstone 风格) */
91
+ operands: string;
92
+ /** Capstone 指令 id */
93
+ id: number;
94
+ /** 该指令所属分组(当前后端拿不到 detail,恒为空数组) */
95
+ groups: number[];
96
+ }
97
+ /** 汇编结果 */
98
+ export interface RawAssembleResult {
99
+ /** 编码后的字节 */
100
+ bytes: Buffer;
101
+ /** 源文本 */
102
+ source: string;
103
+ }
104
+ /** 后端不可用/参数错误时的错误 */
105
+ export declare class AsmBackendError extends Error {
106
+ /** 底层原因(不用 `Error.cause` 的名字,避免与标准属性冲突) */
107
+ readonly underlying?: unknown;
108
+ constructor(message: string, underlying?: unknown);
109
+ }
110
+ /** 把 bigint 地址转成 Capstone/Keystone 能接受的 number,并守卫精度 */
111
+ export declare function toSafeNumberAddress(address: bigint, context: string): number;
112
+ interface BackendState {
113
+ capstone: typeof CapstoneType;
114
+ capstoneConst: typeof CapstoneConstType;
115
+ keystone: typeof KeystoneType;
116
+ keystoneConst: typeof KeystoneConstType;
117
+ }
118
+ /**
119
+ * 确保后端已初始化(WASM 需要异步装载)。
120
+ *
121
+ * 幂等;初始化失败时**不缓存失败结果**,允许重试。
122
+ */
123
+ export declare function ensureAsmBackend(): Promise<BackendState>;
124
+ /** 后端是否已就绪(同步查询,不会触发初始化) */
125
+ export declare function isAsmBackendReady(): boolean;
126
+ /** 测试用:重置后端单例 */
127
+ export declare function resetAsmBackendForTests(): void;
128
+ export interface DisassembleRawOptions {
129
+ /** 代码所在地址(必需,用于计算相对跳转的绝对目标) */
130
+ address: bigint;
131
+ /** 架构,默认 `x64` */
132
+ arch?: AsmArchitecture;
133
+ /** 兼容旧写法:位数。arch 优先 */
134
+ bitness?: 32 | 64;
135
+ /** 字节序,默认 little */
136
+ endianness?: AsmEndianness;
137
+ /** 最多反汇编多少条(默认 1) */
138
+ maxInstructions?: number;
139
+ }
140
+ /** 反汇编一段机器码(多架构)。 */
141
+ export declare function disassembleRaw(code: Buffer, options: DisassembleRawOptions): RawInstruction[];
142
+ /** 通过 Capstone 反查助记符(id → 名称,例如 260 → 'je') */
143
+ export declare function instructionNameOf(id: number, arch?: AsmArchitecture): string;
144
+ export interface AssembleRawOptions {
145
+ /** 代码将放置的地址(必需) */
146
+ address: bigint;
147
+ /** 架构,默认 `x64` */
148
+ arch?: AsmArchitecture;
149
+ /** 兼容旧写法:位数。arch 优先 */
150
+ bitness?: 32 | 64;
151
+ /** 字节序,默认 little */
152
+ endianness?: AsmEndianness;
153
+ /** x86 语法(仅 x86/x64 有意义),默认 intel */
154
+ syntax?: 'intel' | 'att' | 'nasm' | 'masm' | 'gas';
155
+ }
156
+ /** 把汇编文本编码成机器码(多架构)。 */
157
+ export declare function assembleRaw(source: string, options: AssembleRawOptions): RawAssembleResult;
158
+ /** 取后端版本信息(诊断用) */
159
+ export declare function backendVersions(): {
160
+ capstone: string;
161
+ keystone: string;
162
+ architectures: AsmArchitecture[];
163
+ };
164
+ /** 查询某架构是否被两个引擎都支持(都支持才可用) */
165
+ export declare function isArchitectureSupported(arch: AsmArchitecture): boolean;
166
+ export {};
167
+ //# sourceMappingURL=backend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../../src/asm/backend.ts"],"names":[],"mappings":"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"}