@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,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lua 的 Auto Assembler 绑定。
|
|
3
|
+
*
|
|
4
|
+
* 把引擎层的 `AutoAssembler`(见 `../asm/autoassembler.ts`)包成 CE 的 Lua 全局函数:
|
|
5
|
+
*
|
|
6
|
+
* | Lua 函数 | 对应 CE | 返回 |
|
|
7
|
+
* | --- | --- | --- |
|
|
8
|
+
* | `autoAssemble(script [, enable])` | `autoAssemble` | 成功 `true`,失败 `false`(原因进 sink) |
|
|
9
|
+
* | `autoAssembleCheck(script [, enable])` | `autoAssembleCheck` | 同上,但不写目标进程 |
|
|
10
|
+
* | `autoAssembleError()` | —(本移植扩展) | 最近一次 AA 错误文本,无错误返回 `nil` |
|
|
11
|
+
*
|
|
12
|
+
* ## 符号双向流通(只使用引擎的公开 API 实现)
|
|
13
|
+
*
|
|
14
|
+
* - **AA → Lua**:每次执行后,把 `AutoAssembleResult.symbols` 快照灌回 Lua 的
|
|
15
|
+
* `SymbolTable`,因此脚本里 `alloc`/`label`/`aobscan`/`registersymbol`
|
|
16
|
+
* 产生的名字对 Lua 的 `getAddress()` 立即可见(与 CE 一致)。
|
|
17
|
+
* - **Lua → AA**:执行前把 Lua 符号表里已有的名字**做文本替换**成
|
|
18
|
+
* `0x...` 字面量。之所以用替换而不是注入符号表:`AutoAssembler` 的
|
|
19
|
+
* `symbols` 是只读快照、构造器也不接受初值,
|
|
20
|
+
* 而子串替换与 `assembler.ts` 的 `symbols` 选项语义一致、结果可预测。
|
|
21
|
+
*
|
|
22
|
+
* ## 与 CE 的差异(有意为之)
|
|
23
|
+
*
|
|
24
|
+
* 1. **不抛 Lua 错误,返回布尔值**。CE 的 `autoAssemble` 失败时会弹窗;
|
|
25
|
+
* 本移植遵循 Lua 惯用法返回 `false`,原因用 `autoAssembleError()` 取,
|
|
26
|
+
* 避免脚本因弹窗中断。
|
|
27
|
+
* 2. **`createthread` 只校验不执行**(Node 没有 `CreateRemoteThread`)。
|
|
28
|
+
* 脚本不会因此失败,但也不会真的建线程;错误文本里会写明。
|
|
29
|
+
* 3. **`[ENABLE]`/`[DISABLE]` 必须成对**:还原记录按**脚本原文**分桶
|
|
30
|
+
* (等价 CE 每条 memoryrecord 一份 `TDisableInfo`),
|
|
31
|
+
* 因此多个脚本各自独立开关互不影响。
|
|
32
|
+
* 4. **换目标进程会重建 AA 实例**:旧的 alloc 记录对新进程没有意义
|
|
33
|
+
* (那块内存已随旧进程消失)。CE 在换进程时同样会清表。
|
|
34
|
+
*/
|
|
35
|
+
import type { Process } from '../win/process';
|
|
36
|
+
import type { LuaValue } from './types';
|
|
37
|
+
import type { ErrorSink } from './api';
|
|
38
|
+
/** Lua 侧需要的引擎能力 */
|
|
39
|
+
export interface LuaAutoAssemblerContext {
|
|
40
|
+
/** 取当前已打开的目标进程(没有则语法检查模式) */
|
|
41
|
+
currentProcess(): Process | null;
|
|
42
|
+
/** Lua 的符号表(getAddress / registerSymbol 用的那份) */
|
|
43
|
+
symbols: {
|
|
44
|
+
snapshot(): Map<string, bigint>;
|
|
45
|
+
mergeFrom(source: Map<string, bigint>): void;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Lua 的 Auto Assembler 绑定对象。
|
|
50
|
+
*
|
|
51
|
+
* 生命期与 LuaEngine 一致:持有一个 `AutoAssembler` 实例,
|
|
52
|
+
* 这样多次 `autoAssemble` 调用之间共享 alloc 记录与还原历史
|
|
53
|
+
* (`[ENABLE]` 之后才能 `[DISABLE]`)。
|
|
54
|
+
*/
|
|
55
|
+
export declare class LuaAutoAssembler {
|
|
56
|
+
private readonly ctx;
|
|
57
|
+
private assembler;
|
|
58
|
+
private lastError;
|
|
59
|
+
/** 最近一次同步进 Lua 符号表的条目(诊断用) */
|
|
60
|
+
private synced;
|
|
61
|
+
/** 缓存的进程引用:换了目标进程要重建 assembler */
|
|
62
|
+
private boundProcess;
|
|
63
|
+
constructor(ctx: LuaAutoAssemblerContext);
|
|
64
|
+
/** 按当前进程取(必要时重建)引擎实例 */
|
|
65
|
+
private engine;
|
|
66
|
+
/** 目标进程被关闭/更换时调用,丢弃旧状态 */
|
|
67
|
+
invalidate(): void;
|
|
68
|
+
/** 最近一次 AA 错误(无错误返回 null) */
|
|
69
|
+
getLastError(): string | null;
|
|
70
|
+
/** 最近一次同步进 Lua 符号表的条目 */
|
|
71
|
+
getSyncedSymbols(): ReadonlyMap<string, bigint>;
|
|
72
|
+
/** 执行 `autoAssemble`(真正写目标进程) */
|
|
73
|
+
run(script: string, enable: boolean): boolean;
|
|
74
|
+
/** 执行 `autoAssembleCheck`(只检查语法与编码,不写目标进程) */
|
|
75
|
+
check(script: string, enable: boolean): boolean;
|
|
76
|
+
private execute;
|
|
77
|
+
/**
|
|
78
|
+
* 把 Lua 符号表里已有的名字替换成 `0x...` 字面量。
|
|
79
|
+
*
|
|
80
|
+
* 边界:
|
|
81
|
+
* - 只替换**独立标识符**(两侧非标识符字符),避免误伤 `0xAB` 这类字面量与寄存器名;
|
|
82
|
+
* - 跳过 AA 自己的指令关键字行(`alloc(`/`label(`/`define(`/`registersymbol(`/
|
|
83
|
+
* `aobscan*`),否则 `alloc(newmem,256)` 里的 `newmem` 会被替换成地址,
|
|
84
|
+
* 而那一行的语义是"声明名字"而不是"引用地址"。
|
|
85
|
+
*/
|
|
86
|
+
private injectLuaSymbols;
|
|
87
|
+
}
|
|
88
|
+
/** 把 AutoAssemblerError 转成带行号的可读文本 */
|
|
89
|
+
export declare function formatAutoAssemblerError(e: unknown): string;
|
|
90
|
+
/** 注册进 Lua 的函数实现签名(与 api.ts 的 ApiFunction 结构兼容) */
|
|
91
|
+
export type LuaAaFunction = (args: LuaValue[], m: {
|
|
92
|
+
argToString(args: LuaValue[], n: number, funcName: string): string;
|
|
93
|
+
argToBoolean(args: LuaValue[], n: number, def?: boolean): boolean;
|
|
94
|
+
}) => LuaValue;
|
|
95
|
+
/** 注册结果:函数表 + 绑定对象(后者供 LuaEngine 在换进程时 invalidate) */
|
|
96
|
+
export interface AutoAssemblerApiBundle {
|
|
97
|
+
functions: Record<string, LuaAaFunction>;
|
|
98
|
+
instance: LuaAutoAssembler;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 构造要注册进 Lua 的函数表。
|
|
102
|
+
*
|
|
103
|
+
* 单独成函数(而不是塞进 api.ts)是为了让 Lua 的 AA 绑定与引擎层保持清晰边界,
|
|
104
|
+
* 也便于单测。
|
|
105
|
+
*/
|
|
106
|
+
export declare function createAutoAssemblerApi(ctx: LuaAutoAssemblerContext, errorSink: ErrorSink): AutoAssemblerApiBundle;
|
|
107
|
+
//# sourceMappingURL=aa.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aa.d.ts","sourceRoot":"","sources":["../../../src/lua/aa.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAOH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,mBAAmB;AACnB,MAAM,WAAW,uBAAuB;IACtC,6BAA6B;IAC7B,cAAc,IAAI,OAAO,GAAG,IAAI,CAAC;IACjC,iDAAiD;IACjD,OAAO,EAAE;QACP,QAAQ,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChC,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;KAC9C,CAAC;CACH;AAED;;;;;;GAMG;AACH,qBAAa,gBAAgB;IAQf,OAAO,CAAC,QAAQ,CAAC,GAAG;IAPhC,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,SAAS,CAAuB;IACxC,8BAA8B;IAC9B,OAAO,CAAC,MAAM,CAA6B;IAC3C,kCAAkC;IAClC,OAAO,CAAC,YAAY,CAAwB;gBAEf,GAAG,EAAE,uBAAuB;IAEzD,wBAAwB;IACxB,OAAO,CAAC,MAAM;IAWd,0BAA0B;IAC1B,UAAU,IAAI,IAAI;IAMlB,6BAA6B;IAC7B,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B,yBAAyB;IACzB,gBAAgB,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC;IAI/C,iCAAiC;IACjC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO;IAI7C,8CAA8C;IAC9C,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO;IAI/C,OAAO,CAAC,OAAO;IAgCf;;;;;;;;OAQG;IACH,OAAO,CAAC,gBAAgB;CA8BzB;AAMD,sCAAsC;AACtC,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAS3D;AAMD,mDAAmD;AACnD,MAAM,MAAM,aAAa,GAAG,CAC1B,IAAI,EAAE,QAAQ,EAAE,EAChB,CAAC,EAAE;IACD,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IACnE,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;CACnE,KACE,QAAQ,CAAC;AAEd,sDAAsD;AACtD,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACzC,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,uBAAuB,EAC5B,SAAS,EAAE,SAAS,GACnB,sBAAsB,CAmDxB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 地址表达式解析(CE 的 getAddress / getAddressFromName 的简化实现)。
|
|
3
|
+
*
|
|
4
|
+
* 支持的写法(与 CE Lua 脚本里常见的写法对齐):
|
|
5
|
+
* 1234 / 0012AB00 十六进制(CE 的地址表达式里裸数字按十六进制解释)
|
|
6
|
+
* 0x7FF6A000 / $7FF6A000
|
|
7
|
+
* kernel32.dll 模块基址(大小写不敏感,可省略 .dll)
|
|
8
|
+
* kernel32.dll+1A2B 模块基址 + 偏移
|
|
9
|
+
* mySymbol+40 已注册符号 + 偏移
|
|
10
|
+
* a+b-c 多个项按 +/- 连接
|
|
11
|
+
*
|
|
12
|
+
* 注意:只有**字符串**里的裸数字按十六进制解释;
|
|
13
|
+
* `getAddress(4096)` 传 Lua 数字时原样返回 4096。
|
|
14
|
+
*
|
|
15
|
+
* 不支持:括号、乘法/除法、指针解引用(CE 里靠 `[[addr]+4]` 这类写法,本移植未实现)。
|
|
16
|
+
*/
|
|
17
|
+
import type { ProcessModule } from '../win/process';
|
|
18
|
+
import type { LuaValue, SymbolTable } from './types';
|
|
19
|
+
export interface AddressResolverDeps {
|
|
20
|
+
symbols: SymbolTable;
|
|
21
|
+
/** 按名字找模块(大小写不敏感,可省略扩展名) */
|
|
22
|
+
findModule(name: string): ProcessModule | null;
|
|
23
|
+
}
|
|
24
|
+
export declare class AddressResolver {
|
|
25
|
+
private readonly deps;
|
|
26
|
+
constructor(deps: AddressResolverDeps);
|
|
27
|
+
/**
|
|
28
|
+
* 解析地址。number/bigint 直接返回;字符串走表达式解析。
|
|
29
|
+
* 解析失败抛 Error(中文信息),由调用方决定是抛 Lua 错误还是返回 nil。
|
|
30
|
+
*/
|
|
31
|
+
resolve(value: LuaValue): bigint;
|
|
32
|
+
/** 失败返回 null(对应 getAddressSafe 的语义)。 */
|
|
33
|
+
tryResolve(value: LuaValue): bigint | null;
|
|
34
|
+
/** 解析字符串表达式。 */
|
|
35
|
+
parseExpression(expr: string): bigint;
|
|
36
|
+
/** 按 +/- 切分表达式(不考虑括号)。 */
|
|
37
|
+
private splitTerms;
|
|
38
|
+
/** 解析单项:字面量、模块名或符号。 */
|
|
39
|
+
private parseTerm;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=addressing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addressing.d.ts","sourceRoot":"","sources":["../../../src/lua/addressing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAErD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,WAAW,CAAC;IACrB,4BAA4B;IAC5B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAAC;CAChD;AAOD,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,mBAAmB;IAEtD;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM;IAYhC,wCAAwC;IACxC,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI;IAQ1C,gBAAgB;IAChB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAarC,0BAA0B;IAC1B,OAAO,CAAC,UAAU;IAwBlB,uBAAuB;IACvB,OAAO,CAAC,SAAS;CAsBlB"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cheat Engine Lua API 的 Node 版实现(子集)。
|
|
3
|
+
*
|
|
4
|
+
* 约定(与 CE 官方 Lua API 的对齐与差异都写在 docs/lua-api.md):
|
|
5
|
+
* - 参数顺序尽量与 CE 一致,方便直接搬运脚本;
|
|
6
|
+
* - 读内存失败返回 nil(CE 风格);参数错误 / 地址无法解析直接抛 Lua 错误
|
|
7
|
+
* (CE 的 getAddress 也是抛错,脚本可以用 pcall 捕获);
|
|
8
|
+
* - 地址参数可以是整数,也可以是字符串表达式('base+40'、'kernel32.dll+1000'、'mySymbol')。
|
|
9
|
+
*
|
|
10
|
+
* 类型映射:
|
|
11
|
+
* - readInteger 返回 32 位整数,**默认按有符号解释**(signed=true);
|
|
12
|
+
* CE 官方默认 signed=false(返回 dword)。这是本移植与 CE 的**有意差异**,
|
|
13
|
+
* 需要无符号语义时显式传 readInteger(addr, false)。
|
|
14
|
+
* - readByte / readSmallInteger 保持 CE 默认(无符号)。
|
|
15
|
+
* - readQword 返回 64 位整数(Lua 5.4 的 integer 是 int64,超出 2^63-1 按位回绕)。
|
|
16
|
+
*/
|
|
17
|
+
import { AddressResolver } from './addressing';
|
|
18
|
+
import { MultiReturn, type ApiContext, type LuaValue } from './types';
|
|
19
|
+
import { type LuaMarshal } from './marshal';
|
|
20
|
+
import { LuaAddressList } from './objects';
|
|
21
|
+
import { type LuaAutoAssembler } from './aa';
|
|
22
|
+
/** 一个 CE Lua API 函数的实现签名。 */
|
|
23
|
+
export type ApiFunction = (args: LuaValue[], m: LuaMarshal) => LuaValue | MultiReturn | void;
|
|
24
|
+
/** 引擎当前的最后一条错误信息(对齐 CE 的 getLastError 思路)。 */
|
|
25
|
+
export declare class ErrorSink {
|
|
26
|
+
private message;
|
|
27
|
+
set(text: string): void;
|
|
28
|
+
clear(): void;
|
|
29
|
+
get(): string;
|
|
30
|
+
}
|
|
31
|
+
export interface ApiBundle {
|
|
32
|
+
functions: Record<string, ApiFunction>;
|
|
33
|
+
errorSink: ErrorSink;
|
|
34
|
+
resolver: AddressResolver;
|
|
35
|
+
/** 共享的地址列表(getAddressList 每次返回同一个对象,和 CE 一致) */
|
|
36
|
+
addressList: LuaAddressList;
|
|
37
|
+
/** Auto Assembler 绑定实例(LuaEngine 换进程时需要 invalidate) */
|
|
38
|
+
autoAssembler: LuaAutoAssembler;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 创建全部 API 函数。
|
|
42
|
+
*
|
|
43
|
+
* @param ctx 引擎能力(进程、符号表、扫描会话、输出)
|
|
44
|
+
*/
|
|
45
|
+
export declare function createApi(ctx: ApiContext): ApiBundle;
|
|
46
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/lua/api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AACtE,OAAO,EAAgC,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAkD,MAAM,WAAW,CAAC;AAQ3F,OAAO,EAA0B,KAAK,gBAAgB,EAAE,MAAM,MAAM,CAAC;AAUrE,6BAA6B;AAC7B,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,EAAE,UAAU,KAAK,QAAQ,GAAG,WAAW,GAAG,IAAI,CAAC;AAE7F,8CAA8C;AAC9C,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAM;IACrB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAGvB,KAAK,IAAI,IAAI;IAGb,GAAG,IAAI,MAAM;CAGd;AAED,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACvC,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,eAAe,CAAC;IAC1B,gDAAgD;IAChD,WAAW,EAAE,cAAc,CAAC;IAC5B,uDAAuD;IACvD,aAAa,EAAE,gBAAgB,CAAC;CACjC;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,SAAS,CAuqBpD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lua 侧的汇编 / 反汇编绑定。
|
|
3
|
+
*
|
|
4
|
+
* 把引擎层的 `assemble` / `disassemble` 包成 CE 的 Lua 全局函数:
|
|
5
|
+
*
|
|
6
|
+
* | Lua 函数 | 语义 |
|
|
7
|
+
* | --- | --- |
|
|
8
|
+
* | `assemble(instruction [, targetAddress])` | 汇编成机器码**并写入当前打开的进程** |
|
|
9
|
+
* | `assembleBytes(instruction [, targetAddress])` | 只汇编,返回字节表(**不写内存**) |
|
|
10
|
+
* | `disassemble(address [, count])` | 读内存并反汇编,返回 CE 风格字符串数组 |
|
|
11
|
+
* | `disassembleBytes(bytes [, address [, count]])` | 反汇编给定字节(不读内存) |
|
|
12
|
+
*
|
|
13
|
+
* ## 与 CE 的差异
|
|
14
|
+
*
|
|
15
|
+
* 1. **`assemble` 默认不写内存**。CE 的 `assemble(instruction)` 会直接写进
|
|
16
|
+
* 当前打开的进程;为了避免脚本一个手滑就把代码段改坏,这里把
|
|
17
|
+
* 「只编码」和「写内存」拆成两个函数(`assembleBytes` / `assemble`),
|
|
18
|
+
* 需要写入时显式调用 `assemble`。
|
|
19
|
+
* 2. **架构自动跟随目标进程**:`targetIs64Bit()` 为假时按 x86 编码,
|
|
20
|
+
* 否则按 x64 —— 与 CE 的默认行为一致。需要覆盖时用 `assembleBytes`
|
|
21
|
+
* 的第 3 个参数显式指定。
|
|
22
|
+
* 3. 汇编失败**抛 Lua 错误**(CE 是弹窗),可用 `pcall` 捕获。
|
|
23
|
+
*/
|
|
24
|
+
import type { Process } from '../win/process';
|
|
25
|
+
import type { LuaValue } from './types';
|
|
26
|
+
export interface LuaAsmContext {
|
|
27
|
+
/** 当前已打开的目标进程(没有则 assemble 无法写内存) */
|
|
28
|
+
currentProcess(): Process | null;
|
|
29
|
+
/** 符号表:让 `jmp label` 这类写法能在汇编里解析 */
|
|
30
|
+
symbols(): Map<string, bigint>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 构造要注册进 Lua 的函数表。
|
|
34
|
+
*
|
|
35
|
+
* 单独成模块(与 `aa.ts` 同款做法)以保持 api.ts 的可读性。
|
|
36
|
+
*/
|
|
37
|
+
export declare function createAsmApi(ctx: LuaAsmContext,
|
|
38
|
+
/** 抛 Lua 错误的回调(api.ts 传入 marshal.raise 的等价物) */
|
|
39
|
+
raise: (message: string) => never,
|
|
40
|
+
/** 把解析结果当地址用(整数或字符串表达式) */
|
|
41
|
+
resolveAddress: (value: LuaValue) => bigint): Record<string, (args: LuaValue[]) => LuaValue>;
|
|
42
|
+
//# sourceMappingURL=asm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asm.d.ts","sourceRoot":"","sources":["../../../src/lua/asm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGxC,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,cAAc,IAAI,OAAO,GAAG,IAAI,CAAC;IACjC,oCAAoC;IACpC,OAAO,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAiCD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,aAAa;AAClB,gDAAgD;AAChD,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,KAAK;AACjC,2BAA2B;AAC3B,cAAc,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,MAAM,GAC1C,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,QAAQ,CAAC,CAiJhD"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lua 脚本桥 —— Cheat Engine Lua API 的 Node 版子集。
|
|
3
|
+
*
|
|
4
|
+
* 依赖选型:**wasmoon**(真实 Lua 5.4 的 WASM 构建)。
|
|
5
|
+
* 理由:CE 用的就是 Lua 5.3/5.4,wasmoon 提供的是 Lua 5.4,
|
|
6
|
+
* 整数语义(64 位 integer + float)、`string.format("%d")`、协程、goto 等
|
|
7
|
+
* 都与 CE 一致;fengari 是纯 JS 的 Lua 5.1,没有整数子类型
|
|
8
|
+
* (所有数字都是 double),地址精度会对不上。
|
|
9
|
+
*
|
|
10
|
+
* 但 wasmoon 的高层 JS↔Lua 函数桥不能直接用:
|
|
11
|
+
* 实测 `global.set('f', f)` 之后,Lua 的 integer 会被转成 JS number
|
|
12
|
+
* (9007199254740993 → 9007199254740992,丢精度),而且 JS 返回 bigint 会抛
|
|
13
|
+
* "The type 'bigint' is not supported by Lua"。
|
|
14
|
+
* 所以本桥绕过它,直接用 Lua C API 注册 C 闭包:
|
|
15
|
+
* - 入参:lua_tointegerx 返回 BigInt(原始精度)
|
|
16
|
+
* - 出参:lua_pushinteger 接受 BigInt
|
|
17
|
+
*
|
|
18
|
+
* 用法:
|
|
19
|
+
* ```ts
|
|
20
|
+
* const lua = new LuaEngine({ onOutput: (t) => console.log(t) });
|
|
21
|
+
* await lua.createState();
|
|
22
|
+
* lua.attachProcess(Process.open(pid)); // 或者脚本里 openProcess(pid)
|
|
23
|
+
* const value = await lua.doString('return readInteger(getAddress("0x7ff00000"))');
|
|
24
|
+
* await lua.dispose();
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
import type { Process, ProcessModule } from '../win/process';
|
|
28
|
+
import { LuaScanSession } from './objects';
|
|
29
|
+
import { SymbolTable, type ApiContext, type LuaEngineOptions, type LuaValue, type ScannerFacade } from './types';
|
|
30
|
+
/** Lua 脚本执行失败(语法错误 / 运行时错误)。 */
|
|
31
|
+
export declare class LuaScriptError extends Error {
|
|
32
|
+
readonly luaMessage: string;
|
|
33
|
+
constructor(message: string, luaMessage: string);
|
|
34
|
+
}
|
|
35
|
+
export declare class LuaEngine implements ApiContext {
|
|
36
|
+
/** 输出历史(print / showMessage) */
|
|
37
|
+
readonly outputLines: string[];
|
|
38
|
+
/** 符号表 */
|
|
39
|
+
readonly symbols: SymbolTable;
|
|
40
|
+
private readonly options;
|
|
41
|
+
private factory;
|
|
42
|
+
private wasm;
|
|
43
|
+
private raw;
|
|
44
|
+
private statePointer;
|
|
45
|
+
private marshal;
|
|
46
|
+
private objects;
|
|
47
|
+
private api;
|
|
48
|
+
private proc;
|
|
49
|
+
private readonly chunkRefs;
|
|
50
|
+
private readonly functionPointers;
|
|
51
|
+
private messageHandlerPointer;
|
|
52
|
+
private moduleCache;
|
|
53
|
+
private session;
|
|
54
|
+
private apiRegistered;
|
|
55
|
+
private disposed;
|
|
56
|
+
/** 扫描能力外观(转发给 src/scanner,不重复实现算法)。 */
|
|
57
|
+
readonly scanner: ScannerFacade;
|
|
58
|
+
constructor(options?: LuaEngineOptions);
|
|
59
|
+
get isReady(): boolean;
|
|
60
|
+
get maxSleepMs(): number;
|
|
61
|
+
/** 主 Lua state(仅在 createState 之后可用)。 */
|
|
62
|
+
get luaState(): number;
|
|
63
|
+
/** 创建(或重建)Lua 状态并注册 API。 */
|
|
64
|
+
createState(): Promise<this>;
|
|
65
|
+
/**
|
|
66
|
+
* 注册 CE Lua API。
|
|
67
|
+
*
|
|
68
|
+
* 如果还没 createState,会记下请求并在 createState 时自动注册 ——
|
|
69
|
+
* 也就是说 `new LuaEngine(); engine.registerApi(); await engine.createState();` 也能工作。
|
|
70
|
+
*/
|
|
71
|
+
registerApi(): void;
|
|
72
|
+
/** 已注册的 API 函数名(按字典序)。 */
|
|
73
|
+
apiFunctionNames(): string[];
|
|
74
|
+
/** 直接以 JS 参数调用某个 API(不需要写 Lua 代码,便于测试与集成)。 */
|
|
75
|
+
invoke(name: string, ...args: LuaValue[]): LuaValue | undefined;
|
|
76
|
+
/** 编译一段 Lua 代码,返回可复用的函数句柄。 */
|
|
77
|
+
loadString(code: string, chunkName?: string): Promise<number>;
|
|
78
|
+
/** 从文件加载 Lua 脚本(对应 CE 的 doFile)。 */
|
|
79
|
+
loadFile(path: string): Promise<number>;
|
|
80
|
+
/** 执行 Lua 代码,返回**第一个**返回值(无返回值时返回 undefined)。 */
|
|
81
|
+
doString(code: string): Promise<LuaValue | undefined>;
|
|
82
|
+
/** 执行 Lua 代码,返回全部返回值。 */
|
|
83
|
+
doStringAll(code: string): Promise<LuaValue[]>;
|
|
84
|
+
/** 执行 Lua 文件,返回第一个返回值。 */
|
|
85
|
+
doFile(path: string): Promise<LuaValue | undefined>;
|
|
86
|
+
/** 调用 Lua 全局函数或 loadString 得到的句柄,返回第一个返回值。 */
|
|
87
|
+
callFunction(nameOrHandle: string | number, ...args: LuaValue[]): Promise<LuaValue | undefined>;
|
|
88
|
+
/** 调用 Lua 函数,返回全部返回值。 */
|
|
89
|
+
callFunctionAll(nameOrHandle: string | number, ...args: LuaValue[]): Promise<LuaValue[]>;
|
|
90
|
+
currentProcess(): Process | null;
|
|
91
|
+
requireProcess(): Process;
|
|
92
|
+
processId(): number;
|
|
93
|
+
/** 绑定(或解绑)目标进程;旧进程句柄会被关闭,扫描会话与模块缓存会失效。 */
|
|
94
|
+
attachProcess(proc: Process | null): void;
|
|
95
|
+
listModules(): ProcessModule[];
|
|
96
|
+
/** 按名字找模块:大小写不敏感,支持全路径、带/不带扩展名。 */
|
|
97
|
+
findModule(name: string): ProcessModule | null;
|
|
98
|
+
output(text: string, kind: 'print' | 'message'): void;
|
|
99
|
+
/** 当前捕获到的输出历史(print / showMessage)。 */
|
|
100
|
+
get capturedOutput(): readonly string[];
|
|
101
|
+
clearOutput(): void;
|
|
102
|
+
defaultScanSession(): LuaScanSession;
|
|
103
|
+
dropDefaultScanSession(): void;
|
|
104
|
+
/** 释放 Lua 状态、注册的 C 函数与本引擎打开的进程句柄。 */
|
|
105
|
+
dispose(options?: {
|
|
106
|
+
closeProcess?: boolean;
|
|
107
|
+
}): Promise<void>;
|
|
108
|
+
private ensureState;
|
|
109
|
+
/** 注册全部 API 为 Lua 全局函数(用原始 C 闭包,保住 int64 精度)。 */
|
|
110
|
+
private registerApiNow;
|
|
111
|
+
/** API 闭包的统一入口:把 Lua 栈上的参数解码成 JS 值,再把结果编码回 Lua。 */
|
|
112
|
+
private invokeApi;
|
|
113
|
+
/** pcall 的错误消息处理器(errfunc):补 traceback。 */
|
|
114
|
+
private messageHandler;
|
|
115
|
+
/** 把一段代码编译成函数压栈;出错抛 LuaScriptError。 */
|
|
116
|
+
private compileChunk;
|
|
117
|
+
/**
|
|
118
|
+
* 受保护地调用栈上的函数。
|
|
119
|
+
*
|
|
120
|
+
* 栈布局:base+1 = 错误处理器,base+2 = 被调函数,随后是参数。
|
|
121
|
+
* setup 负责压入函数(编译好的 chunk / 全局函数 / 注册表句柄)。
|
|
122
|
+
*/
|
|
123
|
+
private protectedCall;
|
|
124
|
+
}
|
|
125
|
+
export { LuaMarshal } from './marshal';
|
|
126
|
+
export type { LuaValue, LuaEngineOptions } from './types';
|
|
127
|
+
export type { ApiFunction } from './api';
|
|
128
|
+
export { LuaScriptError as LuaError };
|
|
129
|
+
//# sourceMappingURL=bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../../src/lua/bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lua 原始 C API 的 JS 封装(栈操作 + 值编解码)。
|
|
3
|
+
*
|
|
4
|
+
* 为什么不用 wasmoon 的高层 JS↔Lua 函数桥:
|
|
5
|
+
* wasmoon 的 `global.set(fn)` 走的是它自己的类型扩展,Lua integer → JS number
|
|
6
|
+
* (>2^53 直接丢精度),且**不支持 JS bigint 返回值**(抛
|
|
7
|
+
* "The type 'bigint' is not supported by Lua")。
|
|
8
|
+
* 地址是本项目的核心数据(64 位),因此本桥直接用 Lua C API:
|
|
9
|
+
* - JS → Lua:lua_pushinteger(L, BigInt)
|
|
10
|
+
* - Lua → JS:lua_tointegerx(L, i) —— wasmoon 的绑定在 wasm64/BIGINT 构建下返回 BigInt
|
|
11
|
+
* 实测(Node v24 + wasmoon 1.16.0,Lua 5.4)9007199254740993 可以原样往返。
|
|
12
|
+
*
|
|
13
|
+
* 所有在 C 闭包里执行的栈操作都必须使用闭包收到的那个 `state`
|
|
14
|
+
* —— 如果 Lua 脚本在协程里调用我们的函数,state 是协程的 state,
|
|
15
|
+
* 在它上面压栈/取值才是正确的(注册表是全局共享的,仍可用)。
|
|
16
|
+
*/
|
|
17
|
+
import type { ILuaBridgeObject, LuaTable, LuaValue } from './types';
|
|
18
|
+
import { MultiReturn } from './types';
|
|
19
|
+
export declare const LUA_TNONE = -1;
|
|
20
|
+
export declare const LUA_TNIL = 0;
|
|
21
|
+
export declare const LUA_TBOOLEAN = 1;
|
|
22
|
+
export declare const LUA_TLIGHTUSERDATA = 2;
|
|
23
|
+
export declare const LUA_TNUMBER = 3;
|
|
24
|
+
export declare const LUA_TSTRING = 4;
|
|
25
|
+
export declare const LUA_TTABLE = 5;
|
|
26
|
+
export declare const LUA_TFUNCTION = 6;
|
|
27
|
+
export declare const LUA_TUSERDATA = 7;
|
|
28
|
+
export declare const LUA_TTHREAD = 8;
|
|
29
|
+
/** lua_pcallk / lua_resume 的状态码 */
|
|
30
|
+
export declare const LUA_OK = 0;
|
|
31
|
+
export declare const LUA_YIELD = 1;
|
|
32
|
+
export declare const LUA_ERRRUN = 2;
|
|
33
|
+
export declare const LUA_ERRSYNTAX = 3;
|
|
34
|
+
export declare const LUA_ERRMEM = 4;
|
|
35
|
+
/** LUAI_MAXSTACK = 1000000;LUA_REGISTRYINDEX = -LUAI_MAXSTACK - 1000 */
|
|
36
|
+
export declare const LUA_REGISTRYINDEX = -1001000;
|
|
37
|
+
export declare const LUA_MULTRET = -1;
|
|
38
|
+
export interface LuaRawModule {
|
|
39
|
+
ccall(name: string, returnType: string | null, argTypes: string[], args: unknown[]): unknown;
|
|
40
|
+
addFunction(fn: (...args: number[]) => number, signature: string): number;
|
|
41
|
+
removeFunction(pointer: number): void;
|
|
42
|
+
setValue(pointer: number, value: number, type: string): void;
|
|
43
|
+
getValue(pointer: number, type: string): number;
|
|
44
|
+
_malloc(size: number): number;
|
|
45
|
+
_free(pointer: number): void;
|
|
46
|
+
stringToUTF8(str: string, pointer: number, maxBytes: number): void;
|
|
47
|
+
lengthBytesUTF8(str: string): number;
|
|
48
|
+
}
|
|
49
|
+
/** wasmoon 的 LuaWasm 实例(LuaEngine 的私有字段 cmodule),只列出用到的部分。 */
|
|
50
|
+
export interface LuaRaw {
|
|
51
|
+
module: LuaRawModule;
|
|
52
|
+
lua_gettop(L: number): number;
|
|
53
|
+
lua_settop(L: number, idx: number): void;
|
|
54
|
+
lua_rotate(L: number, idx: number, n: number): void;
|
|
55
|
+
lua_type(L: number, idx: number): number;
|
|
56
|
+
lua_typename(L: number, tp: number): string;
|
|
57
|
+
lua_isinteger(L: number, idx: number): number;
|
|
58
|
+
lua_isnumber(L: number, idx: number): number;
|
|
59
|
+
lua_isstring(L: number, idx: number): number;
|
|
60
|
+
lua_toboolean(L: number, idx: number): number;
|
|
61
|
+
lua_tonumberx(L: number, idx: number, isnum: number | null): number;
|
|
62
|
+
lua_tointegerx(L: number, idx: number, isnum: number | null): bigint;
|
|
63
|
+
lua_tolstring(L: number, idx: number, len: number | null): string;
|
|
64
|
+
lua_rawlen(L: number, idx: number): bigint;
|
|
65
|
+
lua_touserdata(L: number, idx: number): number;
|
|
66
|
+
lua_pushnil(L: number): void;
|
|
67
|
+
lua_pushboolean(L: number, b: number): void;
|
|
68
|
+
lua_pushinteger(L: number, n: bigint): void;
|
|
69
|
+
lua_pushnumber(L: number, n: number): void;
|
|
70
|
+
lua_pushlstring(L: number, s: string, len: number): string;
|
|
71
|
+
lua_pushstring(L: number, s: string): string;
|
|
72
|
+
lua_pushvalue(L: number, idx: number): void;
|
|
73
|
+
lua_pushcclosure(L: number, fn: number, n: number): void;
|
|
74
|
+
lua_createtable(L: number, narr: number, nrec: number): void;
|
|
75
|
+
lua_newuserdatauv(L: number, size: number, nuvalue: number): number;
|
|
76
|
+
lua_setglobal(L: number, name: string): void;
|
|
77
|
+
lua_getglobal(L: number, name: string): number;
|
|
78
|
+
lua_getfield(L: number, idx: number, k: string): number;
|
|
79
|
+
lua_setfield(L: number, idx: number, k: string): void;
|
|
80
|
+
lua_rawgeti(L: number, idx: number, n: bigint): number;
|
|
81
|
+
lua_rawseti(L: number, idx: number, n: bigint): void;
|
|
82
|
+
lua_rawget(L: number, idx: number): number;
|
|
83
|
+
lua_rawset(L: number, idx: number): void;
|
|
84
|
+
lua_gettable(L: number, idx: number): number;
|
|
85
|
+
lua_settable(L: number, idx: number): void;
|
|
86
|
+
lua_next(L: number, idx: number): number;
|
|
87
|
+
lua_setmetatable(L: number, objindex: number): number;
|
|
88
|
+
lua_getmetatable(L: number, objindex: number): number;
|
|
89
|
+
lua_rawequal(L: number, idx1: number, idx2: number): number;
|
|
90
|
+
luaL_ref(L: number, t: number): number;
|
|
91
|
+
luaL_unref(L: number, t: number, ref: number): void;
|
|
92
|
+
luaL_loadbufferx(L: number, buff: number, sz: number, name: string, mode: string | null): number;
|
|
93
|
+
luaL_tolstring(L: number, idx: number, len: number | null): string;
|
|
94
|
+
luaL_traceback(L: number, L1: number, msg: string | null, level: number): void;
|
|
95
|
+
lua_pcallk(L: number, nargs: number, nresults: number, errfunc: number, ctx: number, k: number | null): number;
|
|
96
|
+
lua_error(L: number): number;
|
|
97
|
+
lua_upvalueindex(index: number): number;
|
|
98
|
+
lua_pop(L: number, count: number): void;
|
|
99
|
+
}
|
|
100
|
+
/** 桥接对象层需要向 marshal 暴露的最小能力。 */
|
|
101
|
+
export interface MarshalObjectAccess {
|
|
102
|
+
/** 若该索引是桥的 userdata,返回宿主 JS 对象 */
|
|
103
|
+
readUserdata(m: LuaMarshal, index: number): {
|
|
104
|
+
found: boolean;
|
|
105
|
+
value?: unknown;
|
|
106
|
+
};
|
|
107
|
+
/** 把一个桥接对象压栈(返回 true 表示已处理) */
|
|
108
|
+
pushObject(m: LuaMarshal, obj: ILuaBridgeObject): boolean;
|
|
109
|
+
}
|
|
110
|
+
/** 一个 Lua 值的来源类型(错误提示用)。 */
|
|
111
|
+
export declare function describeValue(v: LuaValue): string;
|
|
112
|
+
/** 当前使用的哨兵值(测试与诊断用;注意它不是 JSON 可序列化的)。 */
|
|
113
|
+
export declare function currentLongjmpSentinel(): unknown;
|
|
114
|
+
/**
|
|
115
|
+
* 手动指定 longjmp 哨兵值。
|
|
116
|
+
*
|
|
117
|
+
* 仅在确认 emscripten/wasmoon 换了实现时使用。
|
|
118
|
+
*/
|
|
119
|
+
export declare function setLongjmpSentinel(sentinel: unknown): void;
|
|
120
|
+
/**
|
|
121
|
+
* 判断是不是 `lua_error` 的 longjmp 哨兵。
|
|
122
|
+
*
|
|
123
|
+
* 判定规则:**非 Error 值** 且严格等于当前哨兵值。
|
|
124
|
+
*
|
|
125
|
+
* 额外排除 `Error` 实例是有意为之:某些实现可能把哨兵包装成 Error,
|
|
126
|
+
* 那种情况宁可走正常错误路径(有堆栈可查),也不要静默吞掉。
|
|
127
|
+
*/
|
|
128
|
+
export declare function isLuaLongjmp(e: unknown): boolean;
|
|
129
|
+
/** 把任意异常转成可读的中文错误信息。 */
|
|
130
|
+
export declare function describeError(e: unknown): string;
|
|
131
|
+
/**
|
|
132
|
+
* 绑定到某一个 Lua state(主 state 或协程 state)的栈操作器。
|
|
133
|
+
*
|
|
134
|
+
* 轻量对象:每个 C 闭包调用创建一个即可,不持有需要释放的资源。
|
|
135
|
+
*/
|
|
136
|
+
export declare class LuaMarshal {
|
|
137
|
+
readonly cm: LuaRaw;
|
|
138
|
+
readonly state: number;
|
|
139
|
+
private readonly objects;
|
|
140
|
+
constructor(cm: LuaRaw, state: number, objects?: MarshalObjectAccess | null);
|
|
141
|
+
/** 换一个 state(协程场景)。 */
|
|
142
|
+
withState(state: number): LuaMarshal;
|
|
143
|
+
top(): number;
|
|
144
|
+
setTop(n: number): void;
|
|
145
|
+
pop(n?: number): void;
|
|
146
|
+
/** 把(可能是负数的)索引转成绝对索引。 */
|
|
147
|
+
abs(index: number): number;
|
|
148
|
+
type(index: number): number;
|
|
149
|
+
typeName(index: number): string;
|
|
150
|
+
isNil(index: number): boolean;
|
|
151
|
+
isNone(index: number): boolean;
|
|
152
|
+
isBoolean(index: number): boolean;
|
|
153
|
+
isNumber(index: number): boolean;
|
|
154
|
+
isInteger(index: number): boolean;
|
|
155
|
+
isString(index: number): boolean;
|
|
156
|
+
/** 数字或数字字符串(对应 Lua 的 lua_isstring / lua_isnumber 语义) */
|
|
157
|
+
isNumberOrString(index: number): boolean;
|
|
158
|
+
isTable(index: number): boolean;
|
|
159
|
+
isFunction(index: number): boolean;
|
|
160
|
+
isUserdata(index: number): boolean;
|
|
161
|
+
toBigInt(index: number): bigint;
|
|
162
|
+
toNumber(index: number): number;
|
|
163
|
+
toString(index: number): string;
|
|
164
|
+
toBoolean(index: number): boolean;
|
|
165
|
+
/**
|
|
166
|
+
* 数字取值:Lua integer 在 JS 安全整数范围内返回 number,否则返回 bigint。
|
|
167
|
+
*
|
|
168
|
+
* 这样 `readInteger` 这种小值在 Lua/JS 两侧都是普通数字,
|
|
169
|
+
* 而 64 位地址/计数不会丢精度。
|
|
170
|
+
*/
|
|
171
|
+
toLuaNumber(index: number): number | bigint;
|
|
172
|
+
/** 读取任意 Lua 值。 */
|
|
173
|
+
read(index: number, depth?: number): LuaValue;
|
|
174
|
+
/**
|
|
175
|
+
* 读取一张表:1..n 连续整数键 → JS 数组;否则 → 字符串键的对象。
|
|
176
|
+
* 数字键在对象形式下转成十进制字符串(例如 `{1000, x=1}`)。
|
|
177
|
+
*/
|
|
178
|
+
readTable(index: number, depth?: number): LuaTable | LuaValue[];
|
|
179
|
+
/** 读取一张 Lua 表为普通对象(数组表会变成 {'1': .., '2': ..})。 */
|
|
180
|
+
readTableObject(index: number): LuaTable;
|
|
181
|
+
/** 以字符串键读取表字段(不存在或非表时返回 undefined)。 */
|
|
182
|
+
getTableField(index: number, key: string): LuaValue | undefined;
|
|
183
|
+
pushNil(): void;
|
|
184
|
+
pushBoolean(b: boolean): void;
|
|
185
|
+
pushInteger(v: bigint): void;
|
|
186
|
+
pushNumber(v: number): void;
|
|
187
|
+
/** 压入字符串(按 UTF-8 编码字节数给长度,避免 Lua 侧截断)。 */
|
|
188
|
+
pushString(s: string): void;
|
|
189
|
+
/** 压入任意值。 */
|
|
190
|
+
push(v: LuaValue): void;
|
|
191
|
+
/** 压入 1..n 的数组表。 */
|
|
192
|
+
pushArray(items: LuaValue[]): void;
|
|
193
|
+
/** 压入字符串键的表。 */
|
|
194
|
+
pushTable(entries: LuaTable): void;
|
|
195
|
+
/** 压入一个 C 闭包(先压 upvalue 再 pushcclosure)。 */
|
|
196
|
+
pushClosure(pointer: number, upvalues?: LuaValue[]): void;
|
|
197
|
+
/**
|
|
198
|
+
* 把「处理结果」压栈,返回 Lua 返回值个数。
|
|
199
|
+
* - undefined → 0 个返回值(CE 里大量 API 就是这样)
|
|
200
|
+
* - MultiReturn → 多个返回值
|
|
201
|
+
* - 其它 → 1 个返回值
|
|
202
|
+
*/
|
|
203
|
+
pushResult(result: LuaValue | MultiReturn | void): number;
|
|
204
|
+
/**
|
|
205
|
+
* 抛出一个 Lua 错误(等价于 Lua 的 error())。
|
|
206
|
+
*
|
|
207
|
+
* 实测(wasmoon 1.16.0 / emscripten 的 JS 版 longjmp):
|
|
208
|
+
* 在 addFunction 的 JS 帧里调用 lua_error 可以正常被 pcall 捕获,
|
|
209
|
+
* 且不需要返回值(longjmp 不会返回到 JS)。
|
|
210
|
+
* 因此所有「参数错误 / 地址无法解析」都按 CE 的做法直接抛错,
|
|
211
|
+
* 而不是静默返回 nil。
|
|
212
|
+
*/
|
|
213
|
+
raise(message: string): never;
|
|
214
|
+
/** 取第 n 个参数(1 基),越界返回 undefined。 */
|
|
215
|
+
arg(args: LuaValue[], n: number): LuaValue | undefined;
|
|
216
|
+
/** 要求某个参数存在,否则抛 Lua 错误。 */
|
|
217
|
+
requireArg(args: LuaValue[], n: number, funcName: string): LuaValue;
|
|
218
|
+
/**
|
|
219
|
+
* 把参数转成 bigint 整数(**只接受 number / bigint**)。
|
|
220
|
+
*
|
|
221
|
+
* 注意:地址参数不要用这个函数 —— 地址还允许字符串表达式
|
|
222
|
+
* (`"game.exe"+1000`),那要走 `api.ts` 里的 `addrOf`(它会调用地址表达式解析器)。
|
|
223
|
+
* 这里刻意不做字符串解析,避免"看起来能传模块名其实只当字面量"的歧义。
|
|
224
|
+
*/
|
|
225
|
+
argToBigInt(args: LuaValue[], n: number, funcName: string): bigint;
|
|
226
|
+
/** 整数参数(默认值可选)。 */
|
|
227
|
+
argToInt(args: LuaValue[], n: number, funcName: string, def?: number): number;
|
|
228
|
+
/** 浮点参数。 */
|
|
229
|
+
argToNumber(args: LuaValue[], n: number, funcName: string, def?: number): number;
|
|
230
|
+
/** 字符串参数。 */
|
|
231
|
+
argToString(args: LuaValue[], n: number, funcName: string, def?: string): string;
|
|
232
|
+
/**
|
|
233
|
+
* 布尔参数。
|
|
234
|
+
*
|
|
235
|
+
* 语义严格对齐 Lua 的 `lua_toboolean`:**只有 `nil` 和 `false` 为假**,
|
|
236
|
+
* 其它一切都是真 —— 包括 `0`、`0.0`、空字符串 `""`、空表。
|
|
237
|
+
*
|
|
238
|
+
* 早期实现写成 `typeof v === 'string' ? v.length > 0 : ...`,
|
|
239
|
+
* 把 `""` 判成了 false,这与 Lua 相反:CE 脚本里 `if flag then` 且 `flag = ""` 时
|
|
240
|
+
* 行为会不一致。请勿改回。
|
|
241
|
+
*/
|
|
242
|
+
argToBoolean(args: LuaValue[], n: number, def?: boolean): boolean;
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=marshal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marshal.d.ts","sourceRoot":"","sources":["../../../src/lua/marshal.ts"],"names":[],"mappings":"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"}
|