@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.
- package/PORT-SCOPE.md +169 -0
- package/README.md +451 -2
- package/dist/cjs/addr/expression.js +650 -0
- package/dist/cjs/addr/expression.js.map +1 -0
- package/dist/cjs/addresslist/memory-record.js +612 -0
- package/dist/cjs/addresslist/memory-record.js.map +1 -0
- package/dist/cjs/asm/assembler.js +354 -0
- package/dist/cjs/asm/assembler.js.map +1 -0
- package/dist/cjs/asm/autoassembler-directives.js +362 -0
- package/dist/cjs/asm/autoassembler-directives.js.map +1 -0
- package/dist/cjs/asm/autoassembler.js +2163 -0
- package/dist/cjs/asm/autoassembler.js.map +1 -0
- package/dist/cjs/asm/backend.js +394 -0
- package/dist/cjs/asm/backend.js.map +1 -0
- package/dist/cjs/asm/disassembler.js +715 -0
- package/dist/cjs/asm/disassembler.js.map +1 -0
- package/dist/cjs/backend/dbk-backend.js +683 -0
- package/dist/cjs/backend/dbk-backend.js.map +1 -0
- package/dist/cjs/backend/native-ce-backend.js +667 -0
- package/dist/cjs/backend/native-ce-backend.js.map +1 -0
- package/dist/cjs/backend/self-backend.js +449 -0
- package/dist/cjs/backend/self-backend.js.map +1 -0
- package/dist/cjs/backend/types.js +48 -0
- package/dist/cjs/backend/types.js.map +1 -0
- package/dist/cjs/cheattable/ct-format.js +533 -0
- package/dist/cjs/cheattable/ct-format.js.map +1 -0
- package/dist/cjs/index.js +219 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/lua/aa.js +230 -0
- package/dist/cjs/lua/aa.js.map +1 -0
- package/dist/cjs/lua/addressing.js +118 -0
- package/dist/cjs/lua/addressing.js.map +1 -0
- package/dist/cjs/lua/api.js +736 -0
- package/dist/cjs/lua/api.js.map +1 -0
- package/dist/cjs/lua/asm.js +220 -0
- package/dist/cjs/lua/asm.js.map +1 -0
- package/dist/cjs/lua/bridge.js +526 -0
- package/dist/cjs/lua/bridge.js.map +1 -0
- package/dist/cjs/lua/marshal.js +562 -0
- package/dist/cjs/lua/marshal.js.map +1 -0
- package/dist/cjs/lua/memory.js +213 -0
- package/dist/cjs/lua/memory.js.map +1 -0
- package/dist/cjs/lua/objects.js +1070 -0
- package/dist/cjs/lua/objects.js.map +1 -0
- package/dist/cjs/lua/scan.js +543 -0
- package/dist/cjs/lua/scan.js.map +1 -0
- package/dist/cjs/lua/types.js +103 -0
- package/dist/cjs/lua/types.js.map +1 -0
- package/dist/cjs/scanner/matcher.js +781 -0
- package/dist/cjs/scanner/matcher.js.map +1 -0
- package/dist/cjs/scanner/pointer-scan.js +546 -0
- package/dist/cjs/scanner/pointer-scan.js.map +1 -0
- package/dist/cjs/scanner/scanner.js +513 -0
- package/dist/cjs/scanner/scanner.js.map +1 -0
- package/dist/cjs/scanner/shared-layout.js +207 -0
- package/dist/cjs/scanner/shared-layout.js.map +1 -0
- package/dist/cjs/types.js +190 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/value-codec.js +515 -0
- package/dist/cjs/value-codec.js.map +1 -0
- package/dist/cjs/win/process.js +475 -0
- package/dist/cjs/win/process.js.map +1 -0
- package/dist/cjs/win/scan-worker.js +84 -0
- package/dist/cjs/win/scan-worker.js.map +1 -0
- package/dist/cjs/win/winapi.js +403 -0
- package/dist/cjs/win/winapi.js.map +1 -0
- package/dist/types/addr/expression.d.ts +98 -0
- package/dist/types/addr/expression.d.ts.map +1 -0
- package/dist/types/addresslist/memory-record.d.ts +218 -0
- package/dist/types/addresslist/memory-record.d.ts.map +1 -0
- package/dist/types/asm/assembler.d.ts +106 -0
- package/dist/types/asm/assembler.d.ts.map +1 -0
- package/dist/types/asm/autoassembler-directives.d.ts +118 -0
- package/dist/types/asm/autoassembler-directives.d.ts.map +1 -0
- package/dist/types/asm/autoassembler.d.ts +434 -0
- package/dist/types/asm/autoassembler.d.ts.map +1 -0
- package/dist/types/asm/backend.d.ts +167 -0
- package/dist/types/asm/backend.d.ts.map +1 -0
- package/dist/types/asm/disassembler.d.ts +194 -0
- package/dist/types/asm/disassembler.d.ts.map +1 -0
- package/dist/types/backend/dbk-backend.d.ts +353 -0
- package/dist/types/backend/dbk-backend.d.ts.map +1 -0
- package/dist/types/backend/native-ce-backend.d.ts +213 -0
- package/dist/types/backend/native-ce-backend.d.ts.map +1 -0
- package/dist/types/backend/self-backend.d.ts +64 -0
- package/dist/types/backend/self-backend.d.ts.map +1 -0
- package/dist/types/backend/types.d.ts +176 -0
- package/dist/types/backend/types.d.ts.map +1 -0
- package/dist/types/cheattable/ct-format.d.ts +100 -0
- package/dist/types/cheattable/ct-format.d.ts.map +1 -0
- package/dist/types/index.d.ts +54 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/lua/aa.d.ts +107 -0
- package/dist/types/lua/aa.d.ts.map +1 -0
- package/dist/types/lua/addressing.d.ts +41 -0
- package/dist/types/lua/addressing.d.ts.map +1 -0
- package/dist/types/lua/api.d.ts +46 -0
- package/dist/types/lua/api.d.ts.map +1 -0
- package/dist/types/lua/asm.d.ts +42 -0
- package/dist/types/lua/asm.d.ts.map +1 -0
- package/dist/types/lua/bridge.d.ts +129 -0
- package/dist/types/lua/bridge.d.ts.map +1 -0
- package/dist/types/lua/marshal.d.ts +244 -0
- package/dist/types/lua/marshal.d.ts.map +1 -0
- package/dist/types/lua/memory.d.ts +61 -0
- package/dist/types/lua/memory.d.ts.map +1 -0
- package/dist/types/lua/objects.d.ts +210 -0
- package/dist/types/lua/objects.d.ts.map +1 -0
- package/dist/types/lua/scan.d.ts +106 -0
- package/dist/types/lua/scan.d.ts.map +1 -0
- package/dist/types/lua/types.d.ts +146 -0
- package/dist/types/lua/types.d.ts.map +1 -0
- package/dist/types/scanner/matcher.d.ts +122 -0
- package/dist/types/scanner/matcher.d.ts.map +1 -0
- package/dist/types/scanner/pointer-scan.d.ts +187 -0
- package/dist/types/scanner/pointer-scan.d.ts.map +1 -0
- package/dist/types/scanner/scanner.d.ts +150 -0
- package/dist/types/scanner/scanner.d.ts.map +1 -0
- package/dist/types/scanner/shared-layout.d.ts +96 -0
- package/dist/types/scanner/shared-layout.d.ts.map +1 -0
- package/dist/types/types.d.ts +239 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/value-codec.d.ts +134 -0
- package/dist/types/value-codec.d.ts.map +1 -0
- package/dist/types/win/process.d.ts +190 -0
- package/dist/types/win/process.d.ts.map +1 -0
- package/dist/types/win/scan-worker.d.ts +51 -0
- package/dist/types/win/scan-worker.d.ts.map +1 -0
- package/dist/types/win/winapi.d.ts +144 -0
- package/dist/types/win/winapi.d.ts.map +1 -0
- package/docs/assembler.md +371 -0
- package/docs/autoassembler.md +423 -0
- package/docs/backend-dbk.md +305 -0
- package/docs/backends.md +273 -0
- package/docs/evidence/atomics-wait-io.js +20 -0
- package/docs/evidence/mini-repro.js +98 -0
- package/docs/lua-api.md +718 -0
- package/package.json +60 -4
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 地址表与内存记录 —— 对齐 Cheat Engine `MemoryRecordUnit.pas` / `addresslist.pas`。
|
|
3
|
+
*
|
|
4
|
+
* CE 的地址表(Cheat Table)是一棵树 + 一组带类型的条目:
|
|
5
|
+
* - 每个条目有:描述、地址表达式、变量类型、当前值、偏移链、是否锁定(frozen)
|
|
6
|
+
* - 条目可以互相引用(`Address` 写 `+8` 表示"上一项的地址 +8"),
|
|
7
|
+
* 也可以引用其它条目的描述作为基址
|
|
8
|
+
* - "锁定"条目会由后台定时器不断写回固定值(CE 的 freeze)
|
|
9
|
+
*
|
|
10
|
+
* 本模块提供纯数据模型 + 求值 + 读写,定时锁定由宿主调用 `tickFrozen()` 驱动
|
|
11
|
+
* (不在这里起定时器,避免与宿主的生命周期纠缠)。
|
|
12
|
+
*/
|
|
13
|
+
import { EvalContext } from '../addr/expression';
|
|
14
|
+
import { Process } from '../win/process';
|
|
15
|
+
import { RoundingType, ScanOption, VariableType } from '../types';
|
|
16
|
+
/** 一个地址表条目 */
|
|
17
|
+
export interface MemoryRecordData {
|
|
18
|
+
/** 稳定 id(保存/加载表时用来还原引用关系) */
|
|
19
|
+
id: number;
|
|
20
|
+
description: string;
|
|
21
|
+
/** 地址表达式,例如 `"game.exe"+12AB34`、`[[base]+10]+8`、`+8`(相对上级) */
|
|
22
|
+
address: string;
|
|
23
|
+
variableType: VariableType;
|
|
24
|
+
/** 写入用的值(字符串形式,便于精确保留用户输入) */
|
|
25
|
+
value?: string;
|
|
26
|
+
/** 指针偏移链(CE 表里 <Offsets> 的等价物);给出时 address 视为基址表达式 */
|
|
27
|
+
offsets?: number[];
|
|
28
|
+
/** 是否锁定(持续写回 value) */
|
|
29
|
+
frozen?: boolean;
|
|
30
|
+
/** 是否启用(未启用的条目不求值也不显示) */
|
|
31
|
+
active?: boolean;
|
|
32
|
+
/** 备注/注释 */
|
|
33
|
+
comment?: string;
|
|
34
|
+
/** 是否按十六进制显示 */
|
|
35
|
+
hexadecimal?: boolean;
|
|
36
|
+
/** 布尔显示(CE 的 "Show as binary") */
|
|
37
|
+
binary?: boolean;
|
|
38
|
+
/** 显示用的字符编码(字符串类型) */
|
|
39
|
+
codePage?: number;
|
|
40
|
+
/** 字符串长度(字符数) */
|
|
41
|
+
stringLength?: number;
|
|
42
|
+
/**
|
|
43
|
+
* 解析地址失败时是否忽略该条目(CE 表里常见 "address failed" 的容错)。
|
|
44
|
+
* 默认 true:求值失败时不抛错,返回 null。
|
|
45
|
+
*/
|
|
46
|
+
tolerant?: boolean;
|
|
47
|
+
/** 子条目(CE 的树形结构) */
|
|
48
|
+
children?: MemoryRecordData[];
|
|
49
|
+
/** 来源文件(表里的 <FileOffset> 之类,保留原字段以便往返不丢信息) */
|
|
50
|
+
extra?: Record<string, string>;
|
|
51
|
+
}
|
|
52
|
+
/** 求值结果 */
|
|
53
|
+
export interface RecordEvaluation {
|
|
54
|
+
/** 最终地址(解引用、加偏移之后) */
|
|
55
|
+
address: bigint | null;
|
|
56
|
+
/** 求值失败原因 */
|
|
57
|
+
error?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 归一化 CE 风格的带引号地址。
|
|
61
|
+
*
|
|
62
|
+
* 关键语义区分(早期实现搞错了,会破坏模块相对地址):
|
|
63
|
+
* - `"生命值"` —— 引号是**外层包裹**,内容才是真正的地址表达式;要剥掉引号。
|
|
64
|
+
* - `"node.exe"+0` —— 引号是**表达式内部的模块名定界符**,是地址的一部分;
|
|
65
|
+
* 绝不能剥掉,否则表达式变成 `node.exe"+0` 直接解析失败。
|
|
66
|
+
*
|
|
67
|
+
* 另外 CE 里还有 `"a"+"b"` 这种拼接,所以剥引号前要求"去掉首尾后内部不再有引号"。
|
|
68
|
+
*/
|
|
69
|
+
export declare function normalizeAddressExpression(s: string): string;
|
|
70
|
+
/**
|
|
71
|
+
* 一个内存记录(运行时对象)。对应 CE 的 TMemoryRecord。
|
|
72
|
+
*/
|
|
73
|
+
export declare class MemoryRecord {
|
|
74
|
+
private readonly list;
|
|
75
|
+
readonly id: number;
|
|
76
|
+
description: string;
|
|
77
|
+
/** 地址表达式(内部始终保存去引号形式) */
|
|
78
|
+
address: string;
|
|
79
|
+
variableType: VariableType;
|
|
80
|
+
offsets: number[];
|
|
81
|
+
frozen: boolean;
|
|
82
|
+
active: boolean;
|
|
83
|
+
comment: string;
|
|
84
|
+
hexadecimal: boolean;
|
|
85
|
+
binary: boolean;
|
|
86
|
+
codePage: number;
|
|
87
|
+
stringLength: number;
|
|
88
|
+
tolerant: boolean;
|
|
89
|
+
children: MemoryRecord[];
|
|
90
|
+
parent: MemoryRecord | null;
|
|
91
|
+
extra: Record<string, string>;
|
|
92
|
+
/** 用户设定的值(字符串) */
|
|
93
|
+
private userValue;
|
|
94
|
+
/** 最近一次解析出的地址 */
|
|
95
|
+
private cachedAddress;
|
|
96
|
+
/** 最近一次读取到的原始字节 */
|
|
97
|
+
private cachedBytes;
|
|
98
|
+
/** 最近一次错误 */
|
|
99
|
+
private lastError;
|
|
100
|
+
private readonly compiled;
|
|
101
|
+
constructor(data: MemoryRecordData, list: AddressList);
|
|
102
|
+
/** 编译期语法错误(null 表示语法正确) */
|
|
103
|
+
get parseError(): Error | null;
|
|
104
|
+
/** 本记录占用的字节数;变长类型返回显式长度或 0 */
|
|
105
|
+
get byteWidth(): number;
|
|
106
|
+
/**
|
|
107
|
+
* 解析最终地址(缓存到下次 invalidate)。
|
|
108
|
+
*
|
|
109
|
+
* 容错语义(重要):
|
|
110
|
+
* - `tolerant` 只针对**基址表达式**(例如引用了当前进程里不存在的模块名)——
|
|
111
|
+
* 这种失败在加载别人的表时很常见,返回 null 让调用方跳过即可。
|
|
112
|
+
* - **偏移链解引用失败必须抛错**:链断了意味着地址是错的,
|
|
113
|
+
* 如果也静默返回 null/原地址,就会得到一个"看起来对其实错"的地址,
|
|
114
|
+
* 进而写坏目标进程的内存。CE 在偏移链失败时同样不会给出地址。
|
|
115
|
+
*/
|
|
116
|
+
resolve(): RecordEvaluation;
|
|
117
|
+
/** 最近一次解析结果(不重新求值) */
|
|
118
|
+
get resolvedAddress(): bigint | null;
|
|
119
|
+
/** 最近一次错误 */
|
|
120
|
+
get error(): string | null;
|
|
121
|
+
/** 强制下次 resolve 重新求值 */
|
|
122
|
+
invalidate(): void;
|
|
123
|
+
/** 读取当前值(返回字符串形式,便于显示) */
|
|
124
|
+
read(): string | null;
|
|
125
|
+
/** 把原始字节格式化成显示字符串 */
|
|
126
|
+
formatBytes(buf: Buffer): string;
|
|
127
|
+
private formatInt;
|
|
128
|
+
/** 读取原始值(数值类型返回 number | bigint;字符串返回 string) */
|
|
129
|
+
readValue(): number | bigint | string | null;
|
|
130
|
+
/** 写入值(字符串形式,按变量类型解析)。返回是否成功。 */
|
|
131
|
+
write(value?: string): boolean;
|
|
132
|
+
/** 把字符串值编码成对应类型的字节 */
|
|
133
|
+
encodeValue(v: string): Buffer | null;
|
|
134
|
+
private intBuffer;
|
|
135
|
+
/** 用户设定的值 */
|
|
136
|
+
get value(): string;
|
|
137
|
+
set value(v: string);
|
|
138
|
+
/** 是否锁定且在本次 tick 中成功写回 */
|
|
139
|
+
tickFrozen(): boolean;
|
|
140
|
+
/** 转回纯数据(用于保存)。地址已在内部归一化为去引号形式。 */
|
|
141
|
+
toData(): MemoryRecordData;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* 地址表 —— 对齐 CE 的 TAddressList + 表级设置。
|
|
145
|
+
*/
|
|
146
|
+
export declare class AddressList {
|
|
147
|
+
private records;
|
|
148
|
+
private nextId;
|
|
149
|
+
private processRef;
|
|
150
|
+
/** 已注册符号(供地址表达式引用) */
|
|
151
|
+
readonly symbols: Map<string, bigint>;
|
|
152
|
+
/** 模块列表缓存;为 null 时按需重新枚举 */
|
|
153
|
+
private moduleCache;
|
|
154
|
+
/** 表级注释 */
|
|
155
|
+
comment: string;
|
|
156
|
+
/** 表版本(CE 的 <CheatTable> 根节点属性) */
|
|
157
|
+
version: number;
|
|
158
|
+
constructor(process?: Process | null);
|
|
159
|
+
get process(): Process | null;
|
|
160
|
+
/** 绑定/切换目标进程(会清空模块缓存与所有记录的地址缓存)。 */
|
|
161
|
+
attachProcess(process: Process | null): void;
|
|
162
|
+
get count(): number;
|
|
163
|
+
/** 按索引取记录(CE 的 getMemoryRecord(i),0 基) */
|
|
164
|
+
get(index: number): MemoryRecord | undefined;
|
|
165
|
+
/** 按 id 取记录 */
|
|
166
|
+
getById(id: number): MemoryRecord | undefined;
|
|
167
|
+
/** 按描述取记录(CE 的 getRecordWithDescription) */
|
|
168
|
+
getByDescription(description: string): MemoryRecord | undefined;
|
|
169
|
+
/** 全部记录(返回浅拷贝数组) */
|
|
170
|
+
all(): MemoryRecord[];
|
|
171
|
+
/** 追加一个条目 */
|
|
172
|
+
add(data: Partial<MemoryRecordData> & {
|
|
173
|
+
address: string;
|
|
174
|
+
variableType: VariableType;
|
|
175
|
+
}): MemoryRecord;
|
|
176
|
+
/** 删除记录(含子记录) */
|
|
177
|
+
remove(record: MemoryRecord | number): boolean;
|
|
178
|
+
/** 清空 */
|
|
179
|
+
clear(): void;
|
|
180
|
+
/** 求值上下文(供地址表达式使用) */
|
|
181
|
+
evalContext(): EvalContext;
|
|
182
|
+
/** 预加载模块列表缓存(可选,避免每条记录都枚举一次模块) */
|
|
183
|
+
preloadModules(): void;
|
|
184
|
+
/** 注册符号 */
|
|
185
|
+
registerSymbol(name: string, address: bigint): void;
|
|
186
|
+
/** 注销符号 */
|
|
187
|
+
unregisterSymbol(name: string): void;
|
|
188
|
+
/** 解析一个地址表达式(会用到符号表与模块列表)。 */
|
|
189
|
+
resolveExpression(expression: string): bigint;
|
|
190
|
+
/** 驱动一次"锁定写回";返回成功写回的条目数。宿主自行决定调用频率。 */
|
|
191
|
+
tickFrozen(): number;
|
|
192
|
+
/** 读取全部记录的当前值,返回便于展示的快照 */
|
|
193
|
+
snapshot(): Array<{
|
|
194
|
+
id: number;
|
|
195
|
+
description: string;
|
|
196
|
+
address: bigint | null;
|
|
197
|
+
addressText: string;
|
|
198
|
+
type: VariableType;
|
|
199
|
+
value: string | null;
|
|
200
|
+
frozen: boolean;
|
|
201
|
+
active: boolean;
|
|
202
|
+
error: string | null;
|
|
203
|
+
}>;
|
|
204
|
+
/** 转成纯数据(用于保存) */
|
|
205
|
+
toData(): MemoryRecordData[];
|
|
206
|
+
/** 从纯数据恢复 */
|
|
207
|
+
static fromData(data: MemoryRecordData[], process?: Process | null): AddressList;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* 把扫描结果导入地址表 —— 对齐 CE「把扫描结果加入地址表」。
|
|
211
|
+
*/
|
|
212
|
+
export declare function addScanResults(list: AddressList, addresses: readonly bigint[], variableType: VariableType, description?: string): MemoryRecord[];
|
|
213
|
+
/**
|
|
214
|
+
* 用一次扫描结果构建地址表条目,并把当前值填入 value —— 便于导出成可用的表。
|
|
215
|
+
*/
|
|
216
|
+
export declare function buildRecordsFromScan(list: AddressList, addresses: readonly bigint[], variableType: VariableType, descriptionPrefix?: string): MemoryRecord[];
|
|
217
|
+
export { RoundingType, ScanOption, VariableType };
|
|
218
|
+
//# sourceMappingURL=memory-record.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-record.d.ts","sourceRoot":"","sources":["../../../src/addresslist/memory-record.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 汇编器 —— 文本汇编 → 机器码,对齐 Cheat Engine `Assemblerunit.pas` 的对外行为。
|
|
3
|
+
*
|
|
4
|
+
* 后端是 Keystone(见 `backend.ts` 的说明:CE 在 Windows 上也是调 binutils 的 `as`)。
|
|
5
|
+
* 本文件负责 Keystone 之外的那一层,也就是 CE 汇编器真正做的事:
|
|
6
|
+
*
|
|
7
|
+
* 1. **符号解析**:`jmp someLabel` 里的未定义符号要在编码前解析成地址。
|
|
8
|
+
* Keystone 支持通过符号回调注册,本模块提供 `symbols` 选项。
|
|
9
|
+
* 2. **`nop` 与对齐**:CE 的 `nop` 可带数量(`nop 5` 表示填充 5 字节的 nop)。
|
|
10
|
+
* 3. **CE 的强制宽度写法**:`mov [rax],1` 在 CE 里需要显式宽度,
|
|
11
|
+
* 本模块会把 CE 风格的 `mov dword ptr [rax],1` 原样交给 Keystone,
|
|
12
|
+
* 同时兼容省略写法(Keystone/NASM 语法自己会报错,错误信息里指明)。
|
|
13
|
+
* 4. **`int 3` 特例**:Keystone 会把 `int 3` 编成 `CD 03`(两字节),
|
|
14
|
+
* 而 x86 惯例与 CE 都用单字节 `CC`。这里做修正。
|
|
15
|
+
* 5. **逐行模式**:CE 的 `assemble` 是`逐行`语义(每行一条指令),
|
|
16
|
+
* 本模块提供 `assembleLines` 返回每行的字节边界,便于 Auto Assembler
|
|
17
|
+
* 把脚本按行映射回地址。
|
|
18
|
+
*
|
|
19
|
+
* ## 与 CE 的差异
|
|
20
|
+
* - CE 支持 `E8 ?? ?? ?? ??` 这种"带通配的模板",那属于 Auto Assembler 层
|
|
21
|
+
* (见 `autoassembler.ts`),不在汇编器里。
|
|
22
|
+
* - CE 的汇编器有大量针对旧语法的兼容分支(`$` 前缀十六进制、`offset` 关键字等),
|
|
23
|
+
* 本模块只保留主流写法,遇到不支持时会给出明确的汇编错误。
|
|
24
|
+
*/
|
|
25
|
+
import { AsmBackendError, type AsmArchitecture, type AsmBitness, type AsmEndianness } from './backend';
|
|
26
|
+
/** 汇编选项 */
|
|
27
|
+
export interface AssembleOptions {
|
|
28
|
+
/** 代码将放置的地址。**必需**:相对跳转/相对寻址的编码取决于它 */
|
|
29
|
+
address: bigint;
|
|
30
|
+
/**
|
|
31
|
+
* 架构,默认 `x64`。
|
|
32
|
+
* 支持 `x86` / `x64` / `arm`(A32)/ `thumb`(Thumb-2)/ `arm64`(AArch64)。
|
|
33
|
+
*/
|
|
34
|
+
arch?: AsmArchitecture;
|
|
35
|
+
/** 兼容旧写法:位数(32/64)。`arch` 优先 */
|
|
36
|
+
bitness?: AsmBitness;
|
|
37
|
+
/** 字节序,默认 little(ARM 目标可能用大端) */
|
|
38
|
+
endianness?: AsmEndianness;
|
|
39
|
+
/**
|
|
40
|
+
* 符号表:名字 → 地址。
|
|
41
|
+
* 用于解析 `jmp label` 这类引用(Auto Assembler 的 label/define/aobscan 结果)。
|
|
42
|
+
*/
|
|
43
|
+
symbols?: Record<string, bigint> | Map<string, bigint>;
|
|
44
|
+
/** x86 语法,默认 Intel(CE 用 Intel 语法);ARM 只有一种语法,此选项无效 */
|
|
45
|
+
syntax?: 'intel' | 'att' | 'nasm' | 'masm' | 'gas';
|
|
46
|
+
/**
|
|
47
|
+
* 是否自动为未定义符号抛出更友好的错误。
|
|
48
|
+
* 默认 true:把 Keystone 的 "Cannot find a symbol" 换成"符号 X 未定义"。
|
|
49
|
+
*/
|
|
50
|
+
friendlyErrors?: boolean;
|
|
51
|
+
}
|
|
52
|
+
/** 单行汇编的结果(`assembleLines` 用) */
|
|
53
|
+
export interface AssembledLine {
|
|
54
|
+
/** 源文本(已 trim,注释已剥离) */
|
|
55
|
+
source: string;
|
|
56
|
+
/** 该行对应的字节 */
|
|
57
|
+
bytes: Buffer;
|
|
58
|
+
/** 该行在输出中的起始地址 */
|
|
59
|
+
address: bigint;
|
|
60
|
+
/** 该行是否为空行/纯注释(此时 bytes 为空) */
|
|
61
|
+
empty: boolean;
|
|
62
|
+
}
|
|
63
|
+
/** 汇编结果 */
|
|
64
|
+
export interface AssembleResult {
|
|
65
|
+
/** 完整机器码 */
|
|
66
|
+
bytes: Buffer;
|
|
67
|
+
/** 起始地址 */
|
|
68
|
+
address: bigint;
|
|
69
|
+
/** 编码结束后的下一个地址 */
|
|
70
|
+
endAddress: bigint;
|
|
71
|
+
/** 逐行结果(`assembleLines` 时填充;`assemble` 只有一行整体) */
|
|
72
|
+
lines: AssembledLine[];
|
|
73
|
+
/** 本次汇编用到的符号(诊断用) */
|
|
74
|
+
usedSymbols: Record<string, string>;
|
|
75
|
+
}
|
|
76
|
+
/** 汇编失败 */
|
|
77
|
+
export declare class AssemblerError extends Error {
|
|
78
|
+
readonly line?: string | undefined;
|
|
79
|
+
readonly lineNumber?: number | undefined;
|
|
80
|
+
constructor(message: string, line?: string | undefined, lineNumber?: number | undefined);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* 汇编一段文本(可多行)。
|
|
84
|
+
*
|
|
85
|
+
* ```ts
|
|
86
|
+
* const r = assemble('mov rax, 1\nret', { address: 0x1000n });
|
|
87
|
+
* r.bytes; // <Buffer b8 01 00 00 00 c3>
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export declare function assemble(source: string, options: AssembleOptions): AssembleResult;
|
|
91
|
+
/**
|
|
92
|
+
* 逐行汇编,返回每行的字节与地址。
|
|
93
|
+
*
|
|
94
|
+
* CE 的 Auto Assembler 需要"脚本行 → 地址"的映射
|
|
95
|
+
* (`label`/`alloc` 之后要把行号换算成地址),所以逐行编码是必要的。
|
|
96
|
+
*
|
|
97
|
+
* 注意:逐行编码无法处理"跨行的局部标签"(`jmp short_label` 后紧跟标号定义)。
|
|
98
|
+
* 调用方应先用 `assemble()` 传完整文本处理标签,或用 `symbols` 预解析。
|
|
99
|
+
*/
|
|
100
|
+
export declare function assembleLines(source: string, options: AssembleOptions): AssembleResult;
|
|
101
|
+
/**
|
|
102
|
+
* 便捷函数:只拿字节。
|
|
103
|
+
*/
|
|
104
|
+
export declare function assembleToBytes(source: string, options: AssembleOptions): Buffer;
|
|
105
|
+
export { AsmBackendError };
|
|
106
|
+
//# sourceMappingURL=assembler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assembler.d.ts","sourceRoot":"","sources":["../../../src/asm/assembler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EACL,eAAe,EAIf,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,aAAa,EACnB,MAAM,WAAW,CAAC;AAMnB,WAAW;AACX,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,gCAAgC;IAChC,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,iCAAiC;IACjC,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvD,sDAAsD;IACtD,MAAM,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;IACnD;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,iCAAiC;AACjC,MAAM,WAAW,aAAa;IAC5B,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc;IACd,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,WAAW;AACX,MAAM,WAAW,cAAc;IAC7B,YAAY;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,qBAAqB;IACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,WAAW;AACX,qBAAa,cAAe,SAAQ,KAAK;IAGrC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM;IACtB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM;gBAF5B,OAAO,EAAE,MAAM,EACN,IAAI,CAAC,EAAE,MAAM,YAAA,EACb,UAAU,CAAC,EAAE,MAAM,YAAA;CAS/B;AAqBD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,cAAc,CAyCjF;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,cAAc,CAmEtF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,MAAM,CAEhF;AAyMD,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto Assembler 的「汇编器级」指令实现。
|
|
3
|
+
*
|
|
4
|
+
* Cheat Engine 里这些指令**不在** autoassembler.pas,而在 `Assemblerunit.pas`
|
|
5
|
+
* 的 `Assemble()` 里(见该文件 4930~5100 行的 `case tokens[0][1] of`):
|
|
6
|
+
*
|
|
7
|
+
* - `db/dw/dd/dq` —— 数据定义(Assemblerunit 的 `DB`/`DW`/`DD`/`DQ` 分支)
|
|
8
|
+
* - `nop N` —— 多字节 NOP 填充(Assemblerunit 的 `NOP HEXVALUE` 分支)
|
|
9
|
+
* - `align N[,b]` —— 对齐填充(Assemblerunit 的 `ALIGN` 分支)
|
|
10
|
+
*
|
|
11
|
+
* 本移植的汇编后端是 Keystone,它**只认指令**,不认这些伪指令
|
|
12
|
+
* (`db`/`align` 会直接报错,`nop 5` 会被当成 `nop` 的操作数)。
|
|
13
|
+
* 因此这一层必须在 Auto Assembler 里自己做,且要**逐字节对齐 CE 的产出**。
|
|
14
|
+
*
|
|
15
|
+
* ## 数字字面量的进制(最容易静默出错的地方)
|
|
16
|
+
*
|
|
17
|
+
* CE 的 `Assemblerunit` 对 `db/dw/dd/dq/nop/align` 的参数统一走
|
|
18
|
+
* `HexStrToInt`(`parsers.pas` 的 `ConvertHexStrToRealStr`),规则是:
|
|
19
|
+
*
|
|
20
|
+
* - **裸数字按十六进制解释**(`db 89 01 00 00 00` 是 0x89 0x01 ...,不是十进制 89)
|
|
21
|
+
* - `#123` 才是十进制(`#` 前缀)
|
|
22
|
+
* - `-` / `+` 前缀保留符号
|
|
23
|
+
*
|
|
24
|
+
* 这一条**必须**保持 CE 语义:真实 CE 脚本的 `[DISABLE]` 段几乎都是
|
|
25
|
+
* `db 89 01 00 00 00` 这种写法,若按十进制解析会得到完全错误的字节(89 → 0x59)。
|
|
26
|
+
*
|
|
27
|
+
* 作为超集,本模块额外接受 `0x` 与 `$` 前缀(CE 的 HexStrToInt 其实不接受,
|
|
28
|
+
* 会返回空串然后抛异常)。
|
|
29
|
+
*/
|
|
30
|
+
/** 数据定义伪指令 */
|
|
31
|
+
export type DataDirectiveKind = 'db' | 'dw' | 'dd' | 'dq';
|
|
32
|
+
/** 本模块能编码的伪指令 */
|
|
33
|
+
export type PseudoDirectiveKind = DataDirectiveKind | 'nop' | 'align';
|
|
34
|
+
/** 伪指令编码上下文 */
|
|
35
|
+
export interface DirectiveContext {
|
|
36
|
+
/** 该行将要放置的地址(`align` 需要它) */
|
|
37
|
+
address: bigint;
|
|
38
|
+
/**
|
|
39
|
+
* 读取目标进程 1 字节(`db ??` / `db +1` 需要)。
|
|
40
|
+
* 没有目标进程时返回 null —— `db ??` 会退化成 0 并记一条警告。
|
|
41
|
+
*/
|
|
42
|
+
readByte?: (address: bigint) => number | null;
|
|
43
|
+
/** 裸数字是否按十六进制解释,默认 true(CE 行为) */
|
|
44
|
+
hexDefault?: boolean;
|
|
45
|
+
}
|
|
46
|
+
/** 编码结果 */
|
|
47
|
+
export interface DirectiveEncodeResult {
|
|
48
|
+
bytes: Buffer;
|
|
49
|
+
/** 非致命问题(例如 `db ??` 在没有目标进程时按 0 处理) */
|
|
50
|
+
warnings: string[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 按 CE 的 `HexStrToInt` 语义解析整数(裸数字 = 十六进制)。
|
|
54
|
+
*
|
|
55
|
+
* 支持 `#123`(十进制)、`0x1F`、`$1F`、裸 `1F`,以及 `-`/`+` 前缀。
|
|
56
|
+
* 无法解析时返回 null(调用方负责给出带行号的中文错误)。
|
|
57
|
+
*/
|
|
58
|
+
export declare function parseCeInteger(text: string, hexDefault?: boolean): bigint | null;
|
|
59
|
+
/**
|
|
60
|
+
* 把伪指令的参数串切成 token。
|
|
61
|
+
*
|
|
62
|
+
* 对齐 CE 的 `tokenize`(autoassembler.pas 383 行)的实用子集:
|
|
63
|
+
* - 分隔符:逗号、空格、制表符
|
|
64
|
+
* - 引号内的内容**不切分**(`db 'a b'` 是一个 token)
|
|
65
|
+
* - 保留引号本身(后续按字符串处理)
|
|
66
|
+
*/
|
|
67
|
+
export declare function splitDirectiveArguments(text: string): string[];
|
|
68
|
+
/**
|
|
69
|
+
* 编码 `db/dw/dd/dq`。
|
|
70
|
+
*
|
|
71
|
+
* 对齐 `Assemblerunit.pas` 4964~5048 行:
|
|
72
|
+
* - `db 'abc'` → latin1 字节(**不**反转,`AddString` 是按序拷贝)
|
|
73
|
+
* - `dw 'abc'` → UTF-16LE(`AddWideString` 直接 copy 宽字符内存)
|
|
74
|
+
* - `db ??` / `db **` / `db *` → **读目标进程当前字节**(保持原样)
|
|
75
|
+
* - `db +1` / `db -1` → 读目标进程当前字节后加/减
|
|
76
|
+
* - 其它 → 数字,按 CE 的十六进制语义
|
|
77
|
+
*
|
|
78
|
+
* 注意 `dd 'str'` / `dq 'str'` 在 CE 里会走 `HexStrToInt` 的字符分支(行为很怪),
|
|
79
|
+
* 本移植直接报错,避免产生难以察觉的错误字节。
|
|
80
|
+
*/
|
|
81
|
+
export declare function encodeDataDirective(kind: DataDirectiveKind, args: string, ctx: DirectiveContext): DirectiveEncodeResult;
|
|
82
|
+
/** 生成 `count` 字节的 NOP 填充(count<=0 返回空) */
|
|
83
|
+
export declare function encodeNop(count: number): Buffer;
|
|
84
|
+
/**
|
|
85
|
+
* 计算对齐填充。对齐 `Assemblerunit.pas` 4938~4959 行:
|
|
86
|
+
*
|
|
87
|
+
* ```pascal
|
|
88
|
+
* k := i - (address mod i);
|
|
89
|
+
* if k = i then exit; // 已对齐,不填
|
|
90
|
+
* for ... do Add(bytes, b); // b 默认 0
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* 注意 CE 的填充字节**默认是 0x00**(不是 0x90),第二个参数才是填充值:
|
|
94
|
+
* `align 10, 90` 表示对齐到 16 字节边界并用 0x90 填充。
|
|
95
|
+
*/
|
|
96
|
+
export declare function encodeAlign(address: bigint, alignment: bigint, fillByte?: number): Buffer;
|
|
97
|
+
/** 识别出的伪指令 */
|
|
98
|
+
export interface ParsedPseudoDirective {
|
|
99
|
+
kind: PseudoDirectiveKind;
|
|
100
|
+
/** 伪指令名之后的参数原文 */
|
|
101
|
+
args: string;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 判断一行是否是 `db/dw/dd/dq/nop/align` 伪指令。
|
|
105
|
+
*
|
|
106
|
+
* 返回 null 表示不是伪指令(交给 Keystone 汇编)。
|
|
107
|
+
* 注意 `nop`(不带参数)**不算**伪指令 —— Keystone 自己能编成 0x90,
|
|
108
|
+
* 保持与 `assembler.ts` 的行为一致。
|
|
109
|
+
*/
|
|
110
|
+
export declare function parsePseudoDirective(line: string): ParsedPseudoDirective | null;
|
|
111
|
+
/**
|
|
112
|
+
* 把 AOB 字符串转成伪指令用的 `db` 参数串(`aobscan` 回填原字节时用)。
|
|
113
|
+
* 通配位被替换为 `??`,保留「读取原字节」语义。
|
|
114
|
+
*/
|
|
115
|
+
export declare function patternToDbArguments(patternText: string): string;
|
|
116
|
+
/** 把一段内存按 `db` 参数串格式化(`readmem` 用) */
|
|
117
|
+
export declare function bytesToDbArguments(bytes: Buffer): string;
|
|
118
|
+
//# sourceMappingURL=autoassembler-directives.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autoassembler-directives.d.ts","sourceRoot":"","sources":["../../../src/asm/autoassembler-directives.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAQH,cAAc;AACd,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE1D,iBAAiB;AACjB,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,GAAG,KAAK,GAAG,OAAO,CAAC;AAEtE,eAAe;AACf,MAAM,WAAW,gBAAgB;IAC/B,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC9C,kCAAkC;IAClC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,WAAW;AACX,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAMD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,UAAO,GAAG,MAAM,GAAG,IAAI,CA2C7E;AAMD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAiC9D;AASD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,iBAAiB,EACvB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,gBAAgB,GACpB,qBAAqB,CA8DvB;AA8DD,0CAA0C;AAC1C,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAU/C;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,QAAQ,SAAI,GACX,MAAM,CASR;AAMD,cAAc;AACd,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAoB/E;AASD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAUhE;AAED,sCAAsC;AACtC,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAExD"}
|