@cheatron/native-mock 1.0.0 → 1.0.2
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/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +6 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/kernel32.d.ts +31 -0
- package/dist/src/kernel32.d.ts.map +1 -0
- package/dist/src/kernel32.js +232 -0
- package/dist/src/kernel32.js.map +1 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/{logger.js → src/logger.js} +1 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/msvcrt.d.ts +15 -0
- package/dist/src/msvcrt.d.ts.map +1 -0
- package/dist/src/msvcrt.js +43 -0
- package/dist/src/msvcrt.js.map +1 -0
- package/dist/src/os/handles.d.ts +17 -0
- package/dist/src/os/handles.d.ts.map +1 -0
- package/dist/{os → src/os}/handles.js +2 -0
- package/dist/src/os/handles.js.map +1 -0
- package/dist/src/os/kernel.d.ts +21 -0
- package/dist/src/os/kernel.d.ts.map +1 -0
- package/dist/{os → src/os}/kernel.js +36 -1
- package/dist/src/os/kernel.js.map +1 -0
- package/dist/{os → src/os}/memory.d.ts +1 -5
- package/dist/src/os/memory.d.ts.map +1 -0
- package/dist/{os → src/os}/memory.js +3 -8
- package/dist/src/os/memory.js.map +1 -0
- package/dist/src/os/module.d.ts +11 -0
- package/dist/src/os/module.d.ts.map +1 -0
- package/dist/src/os/module.js +20 -0
- package/dist/src/os/module.js.map +1 -0
- package/dist/{os → src/os}/process.d.ts +4 -0
- package/dist/src/os/process.d.ts.map +1 -0
- package/dist/{os → src/os}/process.js +12 -0
- package/dist/src/os/process.js.map +1 -0
- package/dist/{os → src/os}/thread.d.ts +4 -4
- package/dist/src/os/thread.d.ts.map +1 -0
- package/dist/{os → src/os}/thread.js +1 -0
- package/dist/src/os/thread.js.map +1 -0
- package/dist/utils/src/handle.d.ts +26 -0
- package/dist/utils/src/handle.d.ts.map +1 -0
- package/dist/utils/src/handle.js +56 -0
- package/dist/utils/src/handle.js.map +1 -0
- package/dist/utils/src/index.d.ts +4 -0
- package/dist/utils/src/index.d.ts.map +1 -0
- package/dist/utils/src/index.js +4 -0
- package/dist/utils/src/index.js.map +1 -0
- package/dist/utils/src/module.d.ts +22 -0
- package/dist/utils/src/module.d.ts.map +1 -0
- package/dist/utils/src/module.js +54 -0
- package/dist/utils/src/module.js.map +1 -0
- package/dist/utils/src/process.d.ts +30 -0
- package/dist/utils/src/process.d.ts.map +1 -0
- package/dist/utils/src/process.js +103 -0
- package/dist/utils/src/process.js.map +1 -0
- package/dist/utils/src/thread.d.ts +38 -0
- package/dist/utils/src/thread.d.ts.map +1 -0
- package/dist/utils/src/thread.js +136 -0
- package/dist/utils/src/thread.js.map +1 -0
- package/package.json +7 -7
- package/dist/constants.d.ts +0 -175
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js +0 -173
- package/dist/index.d.ts +0 -5
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -4
- package/dist/kernel32.d.ts +0 -22
- package/dist/kernel32.d.ts.map +0 -1
- package/dist/kernel32.js +0 -170
- package/dist/logger.d.ts.map +0 -1
- package/dist/os/handles.d.ts +0 -17
- package/dist/os/handles.d.ts.map +0 -1
- package/dist/os/kernel.d.ts +0 -18
- package/dist/os/kernel.d.ts.map +0 -1
- package/dist/os/memory.d.ts.map +0 -1
- package/dist/os/process.d.ts.map +0 -1
- package/dist/os/thread.d.ts.map +0 -1
- package/dist/process.d.ts +0 -30
- package/dist/process.d.ts.map +0 -1
- package/dist/process.js +0 -124
- package/dist/thread.d.ts +0 -28
- package/dist/thread.d.ts.map +0 -1
- package/dist/thread.js +0 -113
- /package/dist/{logger.d.ts → src/logger.d.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../../../src/os/module.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,eAAe;IACnB,EAAE,CAAS;IACX,IAAI,CAAS;IACb,WAAW,CAAS;IACpB,IAAI,CAAS;IACb,OAAO,GAAwB,IAAI,GAAG,EAAE,CAAC;IAEhD,YAAY,EAAU,EAAE,IAAY,EAAE,WAAmB,EAAE,IAAY;QACrE,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,SAAS,CAAC,IAAY,EAAE,MAAc;QACpC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,CAAC;IACpD,CAAC;IAED,cAAc,CAAC,IAAY;QACzB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;CACF"}
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import { MemoryManager } from './memory';
|
|
2
2
|
import { HandleTable } from './handles';
|
|
3
3
|
import { SimulatedThread } from './thread';
|
|
4
|
+
import { SimulatedModule } from './module';
|
|
4
5
|
export declare class SimulatedProcess {
|
|
5
6
|
id: number;
|
|
6
7
|
name: string;
|
|
7
8
|
memory: MemoryManager;
|
|
8
9
|
handles: HandleTable;
|
|
9
10
|
threads: Map<number, SimulatedThread>;
|
|
11
|
+
modules: Map<string, SimulatedModule>;
|
|
10
12
|
exitCode: number | null;
|
|
11
13
|
private nextThreadId;
|
|
12
14
|
constructor(pid: number, name: string);
|
|
13
15
|
createThread(): SimulatedThread;
|
|
16
|
+
createModule(name: string, baseAddress: number, size: number): SimulatedModule;
|
|
17
|
+
getModule(name: string): SimulatedModule | undefined;
|
|
14
18
|
getThread(tid: number): SimulatedThread | undefined;
|
|
15
19
|
terminate(exitCode?: number): void;
|
|
16
20
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../../src/os/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,qBAAa,gBAAgB;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACtC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAa;IAClD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEtC,OAAO,CAAC,YAAY,CAAgB;gBAExB,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAQrC,YAAY,IAAI,eAAe;IAO/B,YAAY,CACV,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GACX,eAAe;IAOlB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAIpD,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAInD,SAAS,CAAC,QAAQ,GAAE,MAAU;CAO/B"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { MemoryManager } from './memory';
|
|
2
2
|
import { HandleTable } from './handles';
|
|
3
3
|
import { SimulatedThread } from './thread';
|
|
4
|
+
import { SimulatedModule } from './module';
|
|
4
5
|
export class SimulatedProcess {
|
|
5
6
|
id;
|
|
6
7
|
name;
|
|
7
8
|
memory;
|
|
8
9
|
handles;
|
|
9
10
|
threads;
|
|
11
|
+
modules = new Map();
|
|
10
12
|
exitCode = null;
|
|
11
13
|
nextThreadId = 1000;
|
|
12
14
|
constructor(pid, name) {
|
|
@@ -22,6 +24,15 @@ export class SimulatedProcess {
|
|
|
22
24
|
this.threads.set(tid, thread);
|
|
23
25
|
return thread;
|
|
24
26
|
}
|
|
27
|
+
createModule(name, baseAddress, size) {
|
|
28
|
+
const id = this.modules.size + 1;
|
|
29
|
+
const mod = new SimulatedModule(id, name, baseAddress, size);
|
|
30
|
+
this.modules.set(name.toLowerCase(), mod);
|
|
31
|
+
return mod;
|
|
32
|
+
}
|
|
33
|
+
getModule(name) {
|
|
34
|
+
return this.modules.get(name.toLowerCase());
|
|
35
|
+
}
|
|
25
36
|
getThread(tid) {
|
|
26
37
|
return this.threads.get(tid);
|
|
27
38
|
}
|
|
@@ -33,3 +44,4 @@ export class SimulatedProcess {
|
|
|
33
44
|
// In a real OS, handles are closed.
|
|
34
45
|
}
|
|
35
46
|
}
|
|
47
|
+
//# sourceMappingURL=process.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.js","sourceRoot":"","sources":["../../../src/os/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,OAAO,gBAAgB;IACpB,EAAE,CAAS;IACX,IAAI,CAAS;IACb,MAAM,CAAgB;IACtB,OAAO,CAAc;IACrB,OAAO,CAA+B;IACtC,OAAO,GAAiC,IAAI,GAAG,EAAE,CAAC;IAClD,QAAQ,GAAkB,IAAI,CAAC;IAE9B,YAAY,GAAW,IAAI,CAAC;IAEpC,YAAY,GAAW,EAAE,IAAY;QACnC,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC;QACd,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QACjC,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;IAC3B,CAAC;IAED,YAAY;QACV,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC9B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,YAAY,CACV,IAAY,EACZ,WAAmB,EACnB,IAAY;QAEZ,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC;QACjC,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;QAC7D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,GAAG,CAAC,CAAC;QAC1C,OAAO,GAAG,CAAC;IACb,CAAC;IAED,SAAS,CAAC,IAAY;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,SAAS,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED,SAAS,CAAC,WAAmB,CAAC;QAC5B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,kBAAkB;QAClB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,mBAAmB;QACnB,oCAAoC;IACtC,CAAC;CACF"}
|
|
@@ -5,7 +5,7 @@ export declare enum ThreadState {
|
|
|
5
5
|
WAITING = 3,
|
|
6
6
|
TERMINATED = 4
|
|
7
7
|
}
|
|
8
|
-
export interface
|
|
8
|
+
export interface SimulatedThreadContext {
|
|
9
9
|
Rip: bigint;
|
|
10
10
|
Rax: bigint;
|
|
11
11
|
Rbx: bigint;
|
|
@@ -29,12 +29,12 @@ export declare class SimulatedThread {
|
|
|
29
29
|
id: number;
|
|
30
30
|
state: ThreadState;
|
|
31
31
|
suspendCount: number;
|
|
32
|
-
context:
|
|
32
|
+
context: SimulatedThreadContext;
|
|
33
33
|
ownerProcessId: number;
|
|
34
34
|
constructor(tid: number, ownerPid: number);
|
|
35
35
|
suspend(): number;
|
|
36
36
|
resume(): number;
|
|
37
|
-
getContext(_flags: number):
|
|
38
|
-
setContext(ctx: Partial<
|
|
37
|
+
getContext(_flags: number): SimulatedThreadContext;
|
|
38
|
+
setContext(ctx: Partial<SimulatedThreadContext>): void;
|
|
39
39
|
}
|
|
40
40
|
//# sourceMappingURL=thread.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../../src/os/thread.ts"],"names":[],"mappings":"AAAA,oBAAY,WAAW;IACrB,WAAW,IAAA;IACX,KAAK,IAAA;IACL,OAAO,IAAA;IACP,OAAO,IAAA;IACP,UAAU,IAAA;CACX;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,eAAe;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,WAAW,CAAC;IACnB,YAAY,EAAE,MAAM,CAAK;IACzB,OAAO,EAAE,sBAAsB,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;gBAElB,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IA4BzC,OAAO,IAAI,MAAM;IAQjB,MAAM,IAAI,MAAM;IAUhB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,sBAAsB;IAKlD,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,sBAAsB,CAAC,GAAG,IAAI;CAGvD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread.js","sourceRoot":"","sources":["../../../src/os/thread.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,WAMX;AAND,WAAY,WAAW;IACrB,2DAAW,CAAA;IACX,+CAAK,CAAA;IACL,mDAAO,CAAA;IACP,mDAAO,CAAA;IACP,yDAAU,CAAA;AACZ,CAAC,EANW,WAAW,KAAX,WAAW,QAMtB;AAuBD,MAAM,OAAO,eAAe;IACnB,EAAE,CAAS;IACX,KAAK,CAAc;IACnB,YAAY,GAAW,CAAC,CAAC;IACzB,OAAO,CAAyB;IAChC,cAAc,CAAS;IAE9B,YAAY,GAAW,EAAE,QAAgB;QACvC,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC;QACd,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC;QAC/B,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,WAAW,CAAC;QAErC,mDAAmD;QACnD,IAAI,CAAC,OAAO,GAAG;YACb,GAAG,EAAE,eAAe,EAAE,oBAAoB;YAC1C,GAAG,EAAE,EAAE;YACP,GAAG,EAAE,EAAE;YACP,GAAG,EAAE,EAAE;YACP,GAAG,EAAE,EAAE;YACP,GAAG,EAAE,EAAE;YACP,GAAG,EAAE,EAAE;YACP,GAAG,EAAE,EAAE;YACP,GAAG,EAAE,cAAc,EAAE,cAAc;YACnC,EAAE,EAAE,EAAE;YACN,EAAE,EAAE,EAAE;YACN,GAAG,EAAE,EAAE;YACP,GAAG,EAAE,EAAE;YACP,GAAG,EAAE,EAAE;YACP,GAAG,EAAE,EAAE;YACP,GAAG,EAAE,EAAE;YACP,GAAG,EAAE,EAAE;YACP,MAAM,EAAE,KAAK,EAAE,aAAa;SAC7B,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,CAAC,OAAO,EAAE,CAAC;YACvC,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,iBAAiB;QACrD,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,wBAAwB;IACxD,CAAC;IAED,MAAM;QACJ,IAAI,IAAI,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,IAAI,CAAC,YAAY,KAAK,CAAC,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,eAAe;YACjD,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,UAAU,CAAC,MAAc;QACvB,0EAA0E;QAC1E,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED,UAAU,CAAC,GAAoC;QAC7C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACnC,CAAC;CACF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { WaitReturn, type HANDLE } from '@cheatron/native';
|
|
2
|
+
/**
|
|
3
|
+
* Base class for Win32 handles
|
|
4
|
+
*/
|
|
5
|
+
export declare class Handle {
|
|
6
|
+
protected _handle: HANDLE;
|
|
7
|
+
constructor(handle: HANDLE, autoClose?: boolean);
|
|
8
|
+
/**
|
|
9
|
+
* Checks if the handle is valid
|
|
10
|
+
*/
|
|
11
|
+
isValid(): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Closes the handle
|
|
14
|
+
*/
|
|
15
|
+
close(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Waits for the handle to signal
|
|
18
|
+
* @param timeoutMs Timeout in milliseconds (default: INFINITE)
|
|
19
|
+
*/
|
|
20
|
+
wait(timeoutMs?: number): WaitReturn;
|
|
21
|
+
/**
|
|
22
|
+
* Gets the raw handle
|
|
23
|
+
*/
|
|
24
|
+
get handle(): HANDLE;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=handle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handle.d.ts","sourceRoot":"","sources":["../../../utils/src/handle.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,UAAU,EACV,KAAK,MAAM,EACZ,MAAM,kBAAkB,CAAC;AAa1B;;GAEG;AACH,qBAAa,MAAM;IACjB,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEd,MAAM,EAAE,MAAM,EAAE,SAAS,GAAE,OAAc;IAOrD;;OAEG;IACH,OAAO,IAAI,OAAO;IAIlB;;OAEG;IACH,KAAK;IASL;;;OAGG;IACH,IAAI,CAAC,SAAS,GAAE,MAAiB,GAAG,UAAU;IAS9C;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;CACF"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Kernel32Impl, log, INFINITE, WaitReturn, } from '@cheatron/native';
|
|
2
|
+
const handleLog = log.child('Handle');
|
|
3
|
+
/**
|
|
4
|
+
* Handle management registry for automatic cleanup
|
|
5
|
+
*/
|
|
6
|
+
const registry = new FinalizationRegistry((handle) => {
|
|
7
|
+
if (handle) {
|
|
8
|
+
Kernel32Impl.CloseHandle(handle);
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
/**
|
|
12
|
+
* Base class for Win32 handles
|
|
13
|
+
*/
|
|
14
|
+
export class Handle {
|
|
15
|
+
_handle;
|
|
16
|
+
constructor(handle, autoClose = true) {
|
|
17
|
+
this._handle = handle;
|
|
18
|
+
if (autoClose && handle) {
|
|
19
|
+
registry.register(this, handle, this);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Checks if the handle is valid
|
|
24
|
+
*/
|
|
25
|
+
isValid() {
|
|
26
|
+
return this._handle !== null && this._handle !== undefined;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Closes the handle
|
|
30
|
+
*/
|
|
31
|
+
close() {
|
|
32
|
+
if (this.isValid()) {
|
|
33
|
+
const h = this._handle;
|
|
34
|
+
this._handle = null;
|
|
35
|
+
registry.unregister(this);
|
|
36
|
+
Kernel32Impl.CloseHandle(h);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Waits for the handle to signal
|
|
41
|
+
* @param timeoutMs Timeout in milliseconds (default: INFINITE)
|
|
42
|
+
*/
|
|
43
|
+
wait(timeoutMs = INFINITE) {
|
|
44
|
+
if (!this.isValid())
|
|
45
|
+
throw new Error('Handle is closed');
|
|
46
|
+
handleLog.debug(`Waiting for handle to signal (Timeout: ${timeoutMs}ms)`);
|
|
47
|
+
return Kernel32Impl.WaitForSingleObject(this._handle, timeoutMs);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Gets the raw handle
|
|
51
|
+
*/
|
|
52
|
+
get handle() {
|
|
53
|
+
return this._handle;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=handle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handle.js","sourceRoot":"","sources":["../../../utils/src/handle.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,GAAG,EACH,QAAQ,EACR,UAAU,GAEX,MAAM,kBAAkB,CAAC;AAE1B,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;AAEtC;;GAEG;AACH,MAAM,QAAQ,GAAG,IAAI,oBAAoB,CAAS,CAAC,MAAM,EAAE,EAAE;IAC3D,IAAI,MAAM,EAAE,CAAC;QACX,YAAY,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;AACH,CAAC,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,OAAO,MAAM;IACP,OAAO,CAAS;IAE1B,YAAY,MAAc,EAAE,YAAqB,IAAI;QACnD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,SAAS,IAAI,MAAM,EAAE,CAAC;YACxB,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,OAAO;QACL,OAAO,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC;IAC7D,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YACnB,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;YACvB,IAAI,CAAC,OAAO,GAAG,IAAK,CAAC;YACrB,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC1B,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,IAAI,CAAC,YAAoB,QAAQ;QAC/B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACzD,SAAS,CAAC,KAAK,CAAC,0CAA0C,SAAS,KAAK,CAAC,CAAC;QAC1E,OAAO,YAAY,CAAC,mBAAmB,CACrC,IAAI,CAAC,OAAO,EACZ,SAAS,CACI,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../utils/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../utils/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type HANDLE, type HMODULE } from '@cheatron/native';
|
|
2
|
+
import { Handle } from './handle';
|
|
3
|
+
/**
|
|
4
|
+
* Represents a loaded module
|
|
5
|
+
*/
|
|
6
|
+
export declare class Module extends Handle {
|
|
7
|
+
protected _name: string;
|
|
8
|
+
private static _kernel32;
|
|
9
|
+
private static _crt;
|
|
10
|
+
constructor(handle: HMODULE, name: string);
|
|
11
|
+
static get kernel32(): Module;
|
|
12
|
+
static get crt(): Module;
|
|
13
|
+
/**
|
|
14
|
+
* Gets a module handle for the specified module name
|
|
15
|
+
* Automatically detects if the name is ANSI or Unicode
|
|
16
|
+
* @param name Module name (e.g., 'kernel32.dll')
|
|
17
|
+
*/
|
|
18
|
+
static get(name: string): Module;
|
|
19
|
+
getProcAddress(procName: string): HANDLE;
|
|
20
|
+
get name(): string;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../utils/src/module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,MAAM,EAAE,KAAK,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAIlC;;GAEG;AACH,qBAAa,MAAO,SAAQ,MAAM;IAChC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,MAAM,CAAC,SAAS,CAAS;IACjC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAS;gBAEhB,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM;IAMzC,MAAM,KAAK,QAAQ,IAAI,MAAM,CAK5B;IAED,MAAM,KAAK,GAAG,IAAI,MAAM,CAKvB;IAED;;;;OAIG;IACH,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAehC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAQxC,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Kernel32Impl, log } from '@cheatron/native';
|
|
2
|
+
import { Handle } from './handle';
|
|
3
|
+
const moduleLog = log.child('Module');
|
|
4
|
+
/**
|
|
5
|
+
* Represents a loaded module
|
|
6
|
+
*/
|
|
7
|
+
export class Module extends Handle {
|
|
8
|
+
_name;
|
|
9
|
+
static _kernel32;
|
|
10
|
+
static _crt;
|
|
11
|
+
constructor(handle, name) {
|
|
12
|
+
// Module handles from GetModuleHandle should not be closed with CloseHandle
|
|
13
|
+
super(handle, false);
|
|
14
|
+
this._name = name;
|
|
15
|
+
}
|
|
16
|
+
static get kernel32() {
|
|
17
|
+
if (!this._kernel32) {
|
|
18
|
+
this._kernel32 = this.get('kernel32.dll');
|
|
19
|
+
}
|
|
20
|
+
return this._kernel32;
|
|
21
|
+
}
|
|
22
|
+
static get crt() {
|
|
23
|
+
if (!this._crt) {
|
|
24
|
+
this._crt = this.get('msvcrt.dll');
|
|
25
|
+
}
|
|
26
|
+
return this._crt;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Gets a module handle for the specified module name
|
|
30
|
+
* Automatically detects if the name is ANSI or Unicode
|
|
31
|
+
* @param name Module name (e.g., 'kernel32.dll')
|
|
32
|
+
*/
|
|
33
|
+
static get(name) {
|
|
34
|
+
moduleLog.debug(`Getting module handle for: ${name}`);
|
|
35
|
+
// Simple ASCII check: any char > 127 means we should use Unicode API
|
|
36
|
+
const isUnicode = Array.from(name).some((char) => char.charCodeAt(0) > 127);
|
|
37
|
+
const handle = isUnicode
|
|
38
|
+
? Kernel32Impl.GetModuleHandleW(name)
|
|
39
|
+
: Kernel32Impl.GetModuleHandleA(name);
|
|
40
|
+
if (!handle) {
|
|
41
|
+
throw new Error(`Failed to get module handle for ${name}`);
|
|
42
|
+
}
|
|
43
|
+
return new Module(handle, name);
|
|
44
|
+
}
|
|
45
|
+
getProcAddress(procName) {
|
|
46
|
+
if (!this.isValid())
|
|
47
|
+
throw new Error('Module handle is closed');
|
|
48
|
+
return Kernel32Impl.GetProcAddress(this._handle, procName);
|
|
49
|
+
}
|
|
50
|
+
get name() {
|
|
51
|
+
return this._name;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../../../utils/src/module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,GAAG,EAA6B,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;AAEtC;;GAEG;AACH,MAAM,OAAO,MAAO,SAAQ,MAAM;IACtB,KAAK,CAAS;IAChB,MAAM,CAAC,SAAS,CAAS;IACzB,MAAM,CAAC,IAAI,CAAS;IAE5B,YAAY,MAAe,EAAE,IAAY;QACvC,4EAA4E;QAC5E,KAAK,CAAC,MAA2B,EAAE,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED,MAAM,KAAK,QAAQ;QACjB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,MAAM,KAAK,GAAG;QACZ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACrC,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,GAAG,CAAC,IAAY;QACrB,SAAS,CAAC,KAAK,CAAC,8BAA8B,IAAI,EAAE,CAAC,CAAC;QAEtD,qEAAqE;QACrE,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,SAAS;YACtB,CAAC,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC;YACrC,CAAC,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAExC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,mCAAmC,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,cAAc,CAAC,QAAgB;QAC7B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAChE,OAAO,YAAY,CAAC,cAAc,CAChC,IAAI,CAAC,OAA6B,EAClC,QAAQ,CACT,CAAC;IACJ,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;CACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Thread } from './thread';
|
|
2
|
+
import { ThreadCreationFlags, type SecurityAttributes, type MemoryBasicInformation, type HANDLE, type LPVOID, type SIZE_T } from '@cheatron/native';
|
|
3
|
+
import { Handle } from './handle';
|
|
4
|
+
/**
|
|
5
|
+
* Represents a process handle
|
|
6
|
+
*/
|
|
7
|
+
export declare class Process extends Handle {
|
|
8
|
+
protected _pid: number;
|
|
9
|
+
constructor(handle: HANDLE, pid?: number);
|
|
10
|
+
static open(pid: number, access?: number): Process;
|
|
11
|
+
readMemory(address: LPVOID, size: number): Buffer;
|
|
12
|
+
read: (address: LPVOID, size: number) => Buffer;
|
|
13
|
+
writeMemory(address: LPVOID, buffer: Buffer): void;
|
|
14
|
+
write: (address: LPVOID, buffer: Buffer) => void;
|
|
15
|
+
createThread(startAddress: LPVOID, parameter?: LPVOID | null, stackSize?: SIZE_T, flags?: ThreadCreationFlags | number, attributes?: SecurityAttributes | LPVOID | null): Thread;
|
|
16
|
+
virtualQuery(address: LPVOID): MemoryBasicInformation;
|
|
17
|
+
query: (address: LPVOID) => MemoryBasicInformation;
|
|
18
|
+
static current(): CurrentProcess;
|
|
19
|
+
get pid(): number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Represents the current process (singleton)
|
|
23
|
+
*/
|
|
24
|
+
export declare class CurrentProcess extends Process {
|
|
25
|
+
constructor();
|
|
26
|
+
createThread(startAddress: LPVOID, parameter?: LPVOID | null, stackSize?: SIZE_T, flags?: ThreadCreationFlags | number, attributes?: SecurityAttributes | LPVOID | null): Thread;
|
|
27
|
+
close(): void;
|
|
28
|
+
}
|
|
29
|
+
export declare const currentProcess: CurrentProcess;
|
|
30
|
+
//# sourceMappingURL=process.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../../utils/src/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAKL,mBAAmB,EAGnB,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,MAAM,EACX,KAAK,MAAM,EACX,KAAK,MAAM,EACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAIlC;;GAEG;AACH,qBAAa,OAAQ,SAAQ,MAAM;IACjC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEX,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM;IAKxC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAiC,GAAG,OAAO;IAU5E,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAkBjD,IAAI,YAlBgB,MAAM,QAAQ,MAAM,KAAG,MAAM,CAkB1B;IAEvB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAkBlD,KAAK,YAlBgB,MAAM,UAAU,MAAM,KAAG,IAAI,CAkBzB;IAEzB,YAAY,CACV,YAAY,EAAE,MAAM,EACpB,SAAS,GAAE,MAAM,GAAG,IAAW,EAC/B,SAAS,GAAE,MAAoB,EAC/B,KAAK,GAAE,mBAAmB,GAAG,MAAsC,EACnE,UAAU,GAAE,kBAAkB,GAAG,MAAM,GAAG,IAAW,GACpD,MAAM;IAsBT,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,sBAAsB;IAkBrD,KAAK,YAlBiB,MAAM,KAAG,sBAAsB,CAkB3B;IAE1B,MAAM,CAAC,OAAO,IAAI,cAAc;IAIhC,IAAI,GAAG,IAAI,MAAM,CAEhB;CACF;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,OAAO;;IAMhC,YAAY,CACnB,YAAY,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,EACzB,SAAS,GAAE,MAAoB,EAC/B,KAAK,CAAC,EAAE,mBAAmB,GAAG,MAAM,EACpC,UAAU,CAAC,EAAE,kBAAkB,GAAG,MAAM,GAAG,IAAI,GAC9C,MAAM;IAIA,KAAK;CAGf;AAID,eAAO,MAAM,cAAc,EAAE,cAU3B,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Thread } from './thread';
|
|
2
|
+
import { Kernel32Impl, log, ffi, ProcessAccess, ThreadCreationFlags, MEMORY_BASIC_INFORMATION, MBI_SIZE, } from '@cheatron/native';
|
|
3
|
+
import { Handle } from './handle';
|
|
4
|
+
const processLog = log.child('Process');
|
|
5
|
+
/**
|
|
6
|
+
* Represents a process handle
|
|
7
|
+
*/
|
|
8
|
+
export class Process extends Handle {
|
|
9
|
+
_pid;
|
|
10
|
+
constructor(handle, pid) {
|
|
11
|
+
super(handle);
|
|
12
|
+
this._pid = pid ?? Kernel32Impl.GetProcessId(handle);
|
|
13
|
+
}
|
|
14
|
+
static open(pid, access = ProcessAccess.ALL_ACCESS) {
|
|
15
|
+
processLog.debug(`Opening process ${pid} with access ${access}`);
|
|
16
|
+
const handle = Kernel32Impl.OpenProcess(access, 0, pid);
|
|
17
|
+
if (!handle) {
|
|
18
|
+
processLog.warn(`Failed to open process ${pid}`);
|
|
19
|
+
throw new Error(`Failed to open process ${pid}`);
|
|
20
|
+
}
|
|
21
|
+
return new Process(handle, pid);
|
|
22
|
+
}
|
|
23
|
+
readMemory(address, size) {
|
|
24
|
+
if (!this.isValid())
|
|
25
|
+
throw new Error('Process handle is closed');
|
|
26
|
+
const buf = Buffer.alloc(size);
|
|
27
|
+
const success = Kernel32Impl.ReadProcessMemory(this._handle, address, buf, size, null);
|
|
28
|
+
if (!success) {
|
|
29
|
+
processLog.error(`ReadProcessMemory failed at 0x${address.toString(16)}`);
|
|
30
|
+
throw new Error(`ReadProcessMemory failed at 0x${address.toString(16)}`);
|
|
31
|
+
}
|
|
32
|
+
return buf;
|
|
33
|
+
}
|
|
34
|
+
read = this.readMemory;
|
|
35
|
+
writeMemory(address, buffer) {
|
|
36
|
+
if (!this.isValid())
|
|
37
|
+
throw new Error('Process handle is closed');
|
|
38
|
+
const success = Kernel32Impl.WriteProcessMemory(this._handle, address, buffer, buffer.length, null);
|
|
39
|
+
if (!success) {
|
|
40
|
+
processLog.error(`WriteProcessMemory failed at 0x${address.toString(16)}`);
|
|
41
|
+
throw new Error(`WriteProcessMemory failed at 0x${address.toString(16)}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
write = this.writeMemory;
|
|
45
|
+
createThread(startAddress, parameter = null, stackSize = 0, flags = ThreadCreationFlags.IMMEDIATE, attributes = null) {
|
|
46
|
+
if (!this.isValid())
|
|
47
|
+
throw new Error('Process handle is closed');
|
|
48
|
+
processLog.debug(`Creating remote thread at 0x${startAddress.toString(16)} (PID: ${this._pid})`);
|
|
49
|
+
const handle = Kernel32Impl.CreateRemoteThread(this._handle, attributes, stackSize, startAddress, parameter, flags, null);
|
|
50
|
+
if (!handle) {
|
|
51
|
+
processLog.error('CreateRemoteThread failed');
|
|
52
|
+
throw new Error('CreateRemoteThread failed');
|
|
53
|
+
}
|
|
54
|
+
return new Thread(handle);
|
|
55
|
+
}
|
|
56
|
+
virtualQuery(address) {
|
|
57
|
+
if (!this.isValid())
|
|
58
|
+
throw new Error('Process handle is closed');
|
|
59
|
+
const buf = Buffer.alloc(MBI_SIZE);
|
|
60
|
+
const result = Kernel32Impl.VirtualQueryEx(this._handle, address, buf, MBI_SIZE);
|
|
61
|
+
if (result === 0) {
|
|
62
|
+
processLog.error(`VirtualQueryEx failed at 0x${address.toString(16)}`);
|
|
63
|
+
throw new Error(`VirtualQueryEx failed at 0x${address.toString(16)}`);
|
|
64
|
+
}
|
|
65
|
+
return ffi.decode(buf, MEMORY_BASIC_INFORMATION);
|
|
66
|
+
}
|
|
67
|
+
query = this.virtualQuery;
|
|
68
|
+
static current() {
|
|
69
|
+
return currentProcess;
|
|
70
|
+
}
|
|
71
|
+
get pid() {
|
|
72
|
+
return this._pid;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Represents the current process (singleton)
|
|
77
|
+
*/
|
|
78
|
+
export class CurrentProcess extends Process {
|
|
79
|
+
constructor() {
|
|
80
|
+
// Current process uses a pseudo-handle that doesn't need closing
|
|
81
|
+
super(Kernel32Impl.GetCurrentProcess(), Kernel32Impl.GetCurrentProcessId());
|
|
82
|
+
}
|
|
83
|
+
createThread(startAddress, parameter, stackSize = 0, flags, attributes) {
|
|
84
|
+
return Thread.create(startAddress, parameter, stackSize, flags, attributes);
|
|
85
|
+
}
|
|
86
|
+
close() {
|
|
87
|
+
this._handle = null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Export a pre-initialized instance of the current process (lazy via Proxy)
|
|
91
|
+
let _currentProcess;
|
|
92
|
+
export const currentProcess = new Proxy({}, {
|
|
93
|
+
get(_target, prop, receiver) {
|
|
94
|
+
if (!_currentProcess) {
|
|
95
|
+
_currentProcess = new CurrentProcess();
|
|
96
|
+
}
|
|
97
|
+
return Reflect.get(_currentProcess, prop, receiver);
|
|
98
|
+
},
|
|
99
|
+
getPrototypeOf() {
|
|
100
|
+
return CurrentProcess.prototype;
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
//# sourceMappingURL=process.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.js","sourceRoot":"","sources":["../../../utils/src/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EACL,YAAY,EACZ,GAAG,EACH,GAAG,EACH,aAAa,EACb,mBAAmB,EACnB,wBAAwB,EACxB,QAAQ,GAMT,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AAExC;;GAEG;AACH,MAAM,OAAO,OAAQ,SAAQ,MAAM;IACvB,IAAI,CAAS;IAEvB,YAAY,MAAc,EAAE,GAAY;QACtC,KAAK,CAAC,MAAM,CAAC,CAAC;QACd,IAAI,CAAC,IAAI,GAAG,GAAG,IAAI,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,GAAW,EAAE,SAAiB,aAAa,CAAC,UAAU;QAChE,UAAU,CAAC,KAAK,CAAC,mBAAmB,GAAG,gBAAgB,MAAM,EAAE,CAAC,CAAC;QACjE,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,UAAU,CAAC,IAAI,CAAC,0BAA0B,GAAG,EAAE,CAAC,CAAC;YACjD,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,UAAU,CAAC,OAAe,EAAE,IAAY;QACtC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAEjE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,OAAO,GAAG,YAAY,CAAC,iBAAiB,CAC5C,IAAI,CAAC,OAAO,EACZ,OAAO,EACP,GAAG,EACH,IAAI,EACJ,IAAI,CACL,CAAC;QACF,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,UAAU,CAAC,KAAK,CAAC,iCAAiC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YAC1E,MAAM,IAAI,KAAK,CAAC,iCAAiC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC;IAEvB,WAAW,CAAC,OAAe,EAAE,MAAc;QACzC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAEjE,MAAM,OAAO,GAAG,YAAY,CAAC,kBAAkB,CAC7C,IAAI,CAAC,OAAO,EACZ,OAAO,EACP,MAAM,EACN,MAAM,CAAC,MAAM,EACb,IAAI,CACL,CAAC;QACF,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,UAAU,CAAC,KAAK,CACd,kCAAkC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CACzD,CAAC;YACF,MAAM,IAAI,KAAK,CAAC,kCAAkC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC;IAEzB,YAAY,CACV,YAAoB,EACpB,YAA2B,IAAI,EAC/B,YAAoB,CAAW,EAC/B,QAAsC,mBAAmB,CAAC,SAAS,EACnE,aAAiD,IAAI;QAErD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAEjE,UAAU,CAAC,KAAK,CACd,+BAA+B,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,IAAI,CAAC,IAAI,GAAG,CAC/E,CAAC;QACF,MAAM,MAAM,GAAG,YAAY,CAAC,kBAAkB,CAC5C,IAAI,CAAC,OAAO,EACZ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,SAAS,EACT,KAAK,EACL,IAAI,CACL,CAAC;QACF,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,UAAU,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC9C,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED,YAAY,CAAC,OAAe;QAC1B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAEjE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,YAAY,CAAC,cAAc,CACxC,IAAI,CAAC,OAAO,EACZ,OAAO,EACP,GAAG,EACH,QAAQ,CACT,CAAC;QACF,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;YACjB,UAAU,CAAC,KAAK,CAAC,8BAA8B,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACvE,MAAM,IAAI,KAAK,CAAC,8BAA8B,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACxE,CAAC;QAED,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,wBAAwB,CAA2B,CAAC;IAC7E,CAAC;IAED,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC;IAE1B,MAAM,CAAC,OAAO;QACZ,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,cAAe,SAAQ,OAAO;IACzC;QACE,iEAAiE;QACjE,KAAK,CAAC,YAAY,CAAC,iBAAiB,EAAE,EAAE,YAAY,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAC9E,CAAC;IAEQ,YAAY,CACnB,YAAoB,EACpB,SAAyB,EACzB,YAAoB,CAAW,EAC/B,KAAoC,EACpC,UAA+C;QAE/C,OAAO,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAC9E,CAAC;IAEQ,KAAK;QACZ,IAAI,CAAC,OAAO,GAAG,IAAK,CAAC;IACvB,CAAC;CACF;AAED,4EAA4E;AAC5E,IAAI,eAA2C,CAAC;AAChD,MAAM,CAAC,MAAM,cAAc,GAAmB,IAAI,KAAK,CAAC,EAAoB,EAAE;IAC5E,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ;QACzB,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,eAAe,GAAG,IAAI,cAAc,EAAE,CAAC;QACzC,CAAC;QACD,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IACtD,CAAC;IACD,cAAc;QACZ,OAAO,cAAc,CAAC,SAAS,CAAC;IAClC,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ThreadCreationFlags, type SecurityAttributes, type ThreadContext, type HANDLE, type LPVOID, type SIZE_T } from '@cheatron/native';
|
|
2
|
+
import { Handle } from './handle';
|
|
3
|
+
/**
|
|
4
|
+
* Represents a thread handle
|
|
5
|
+
*/
|
|
6
|
+
export declare class Thread extends Handle {
|
|
7
|
+
protected _tid: number;
|
|
8
|
+
constructor(handle: HANDLE, tid?: number, autoClose?: boolean);
|
|
9
|
+
static open(threadId: number, access?: number): Thread;
|
|
10
|
+
static create(startAddress: LPVOID, parameter?: LPVOID | null, stackSize?: SIZE_T, flags?: ThreadCreationFlags | number, attributes?: SecurityAttributes | LPVOID | null): Thread;
|
|
11
|
+
static current(): CurrentThread;
|
|
12
|
+
static currentId(): number;
|
|
13
|
+
suspend(): number;
|
|
14
|
+
resume(): number;
|
|
15
|
+
getContext(flags?: number): ThreadContext;
|
|
16
|
+
setContext(ctx: ThreadContext): void;
|
|
17
|
+
/**
|
|
18
|
+
* Gets the thread exit code
|
|
19
|
+
* @returns Exit code (STILL_ACTIVE means it's still running)
|
|
20
|
+
*/
|
|
21
|
+
getExitCode(): number;
|
|
22
|
+
get tid(): number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Thread states
|
|
26
|
+
*/
|
|
27
|
+
export declare const ThreadState: {
|
|
28
|
+
STILL_ACTIVE: number;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Represents the current thread (singleton)
|
|
32
|
+
*/
|
|
33
|
+
export declare class CurrentThread extends Thread {
|
|
34
|
+
constructor();
|
|
35
|
+
close(): void;
|
|
36
|
+
}
|
|
37
|
+
export declare const currentThread: CurrentThread;
|
|
38
|
+
//# sourceMappingURL=thread.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../../utils/src/thread.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,mBAAmB,EAGnB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,MAAM,EACX,KAAK,MAAM,EACX,KAAK,MAAM,EACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAIlC;;GAEG;AACH,qBAAa,MAAO,SAAQ,MAAM;IAChC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEX,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,SAAS,GAAE,OAAc;IAKnE,MAAM,CAAC,IAAI,CACT,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,MAAgC,GACvC,MAAM;IAUT,MAAM,CAAC,MAAM,CACX,YAAY,EAAE,MAAM,EACpB,SAAS,GAAE,MAAM,GAAG,IAAW,EAC/B,SAAS,GAAE,MAAoB,EAC/B,KAAK,GAAE,mBAAmB,GAAG,MAAsC,EACnE,UAAU,GAAE,kBAAkB,GAAG,MAAM,GAAG,IAAW,GACpD,MAAM;IAqBT,MAAM,CAAC,OAAO,IAAI,aAAa;IAI/B,MAAM,CAAC,SAAS,IAAI,MAAM;IAI1B,OAAO,IAAI,MAAM;IAajB,MAAM,IAAI,MAAM;IAahB,UAAU,CAAC,KAAK,GAAE,MAA0B,GAAG,aAAa;IAmB5D,UAAU,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI;IAgBpC;;;OAGG;IACH,WAAW,IAAI,MAAM;IAWrB,IAAI,GAAG,IAAI,MAAM,CAEhB;CACF;AAED;;GAEG;AACH,eAAO,MAAM,WAAW;;CAEvB,CAAC;AAEF;;GAEG;AACH,qBAAa,aAAc,SAAQ,MAAM;;IAU9B,KAAK;CAGf;AAID,eAAO,MAAM,aAAa,EAAE,aAU1B,CAAC"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { Kernel32Impl, log, ffi, ThreadAccess, ContextFlags, ThreadCreationFlags, CONTEXT, CONTEXT_SIZE, } from '@cheatron/native';
|
|
2
|
+
import { Handle } from './handle';
|
|
3
|
+
const threadLog = log.child('Thread');
|
|
4
|
+
/**
|
|
5
|
+
* Represents a thread handle
|
|
6
|
+
*/
|
|
7
|
+
export class Thread extends Handle {
|
|
8
|
+
_tid;
|
|
9
|
+
constructor(handle, tid, autoClose = true) {
|
|
10
|
+
super(handle, autoClose);
|
|
11
|
+
this._tid = tid ?? Kernel32Impl.GetThreadId(handle);
|
|
12
|
+
}
|
|
13
|
+
static open(threadId, access = ThreadAccess.ALL_ACCESS) {
|
|
14
|
+
threadLog.debug(`Opening thread ${threadId} with access ${access}`);
|
|
15
|
+
const handle = Kernel32Impl.OpenThread(access, 0, threadId);
|
|
16
|
+
if (!handle) {
|
|
17
|
+
threadLog.warn(`Failed to open thread ${threadId}`);
|
|
18
|
+
throw new Error(`Failed to open thread ${threadId}`);
|
|
19
|
+
}
|
|
20
|
+
return new Thread(handle, threadId);
|
|
21
|
+
}
|
|
22
|
+
static create(startAddress, parameter = null, stackSize = 0, flags = ThreadCreationFlags.IMMEDIATE, attributes = null) {
|
|
23
|
+
threadLog.debug(`Creating thread at 0x${startAddress.toString(16)} with param 0x${(parameter || 0).toString(16)}`);
|
|
24
|
+
const tidBuf = Buffer.alloc(4);
|
|
25
|
+
const handle = Kernel32Impl.CreateThread(attributes, stackSize, startAddress, parameter, flags, tidBuf);
|
|
26
|
+
if (!handle) {
|
|
27
|
+
threadLog.error('CreateThread failed');
|
|
28
|
+
throw new Error('CreateThread failed');
|
|
29
|
+
}
|
|
30
|
+
return new Thread(handle, tidBuf.readUInt32LE(0));
|
|
31
|
+
}
|
|
32
|
+
static current() {
|
|
33
|
+
return currentThread;
|
|
34
|
+
}
|
|
35
|
+
static currentId() {
|
|
36
|
+
return Kernel32Impl.GetCurrentThreadId();
|
|
37
|
+
}
|
|
38
|
+
suspend() {
|
|
39
|
+
if (!this.isValid())
|
|
40
|
+
throw new Error('Thread handle is closed');
|
|
41
|
+
threadLog.debug(`Suspending thread (Handle: ${this._handle}, TID: ${this._tid})`);
|
|
42
|
+
const count = Kernel32Impl.SuspendThread(this._handle);
|
|
43
|
+
if (count === 0xffffffff) {
|
|
44
|
+
threadLog.error('SuspendThread failed');
|
|
45
|
+
throw new Error('SuspendThread failed');
|
|
46
|
+
}
|
|
47
|
+
return count;
|
|
48
|
+
}
|
|
49
|
+
resume() {
|
|
50
|
+
if (!this.isValid())
|
|
51
|
+
throw new Error('Thread handle is closed');
|
|
52
|
+
threadLog.debug(`Resuming thread (Handle: ${this._handle}, TID: ${this._tid})`);
|
|
53
|
+
const count = Kernel32Impl.ResumeThread(this._handle);
|
|
54
|
+
if (count === 0xffffffff) {
|
|
55
|
+
threadLog.error('ResumeThread failed');
|
|
56
|
+
throw new Error('ResumeThread failed');
|
|
57
|
+
}
|
|
58
|
+
return count;
|
|
59
|
+
}
|
|
60
|
+
getContext(flags = ContextFlags.FULL) {
|
|
61
|
+
if (!this.isValid())
|
|
62
|
+
throw new Error('Thread handle is closed');
|
|
63
|
+
threadLog.debug(`Getting thread context (Handle: ${this._handle}, TID: ${this._tid}, Flags: ${flags})`);
|
|
64
|
+
const buf = Buffer.alloc(CONTEXT_SIZE);
|
|
65
|
+
// ContextFlags is at offset 0x30 (after 6 × uint64 P*Home registers)
|
|
66
|
+
buf.writeUInt32LE(flags, 0x30);
|
|
67
|
+
const success = Kernel32Impl.GetThreadContext(this._handle, buf);
|
|
68
|
+
if (!success) {
|
|
69
|
+
threadLog.error('GetThreadContext failed');
|
|
70
|
+
throw new Error('GetThreadContext failed');
|
|
71
|
+
}
|
|
72
|
+
return ffi.decode(buf, CONTEXT);
|
|
73
|
+
}
|
|
74
|
+
setContext(ctx) {
|
|
75
|
+
if (!this.isValid())
|
|
76
|
+
throw new Error('Thread handle is closed');
|
|
77
|
+
threadLog.debug(`Setting thread context (Handle: ${this._handle}, TID: ${this._tid})`);
|
|
78
|
+
const buf = Buffer.alloc(CONTEXT_SIZE);
|
|
79
|
+
ffi.encode(buf, CONTEXT, ctx);
|
|
80
|
+
const success = Kernel32Impl.SetThreadContext(this._handle, buf);
|
|
81
|
+
if (!success) {
|
|
82
|
+
threadLog.error('SetThreadContext failed');
|
|
83
|
+
throw new Error('SetThreadContext failed');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Gets the thread exit code
|
|
88
|
+
* @returns Exit code (STILL_ACTIVE means it's still running)
|
|
89
|
+
*/
|
|
90
|
+
getExitCode() {
|
|
91
|
+
if (!this.isValid())
|
|
92
|
+
throw new Error('Thread handle is closed');
|
|
93
|
+
const buf = Buffer.alloc(4);
|
|
94
|
+
const success = Kernel32Impl.GetExitCodeThread(this._handle, buf);
|
|
95
|
+
if (!success) {
|
|
96
|
+
threadLog.error('GetExitCodeThread failed');
|
|
97
|
+
throw new Error('GetExitCodeThread failed');
|
|
98
|
+
}
|
|
99
|
+
return buf.readUInt32LE(0);
|
|
100
|
+
}
|
|
101
|
+
get tid() {
|
|
102
|
+
return this._tid;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Thread states
|
|
107
|
+
*/
|
|
108
|
+
export const ThreadState = {
|
|
109
|
+
STILL_ACTIVE: 259,
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Represents the current thread (singleton)
|
|
113
|
+
*/
|
|
114
|
+
export class CurrentThread extends Thread {
|
|
115
|
+
constructor() {
|
|
116
|
+
// Current thread uses a pseudo-handle that doesn't need closing
|
|
117
|
+
super(Kernel32Impl.GetCurrentThread(), Kernel32Impl.GetCurrentThreadId(), false);
|
|
118
|
+
}
|
|
119
|
+
close() {
|
|
120
|
+
this._handle = null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Export a pre-initialized instance of the current thread (lazy via Proxy)
|
|
124
|
+
let _currentThread;
|
|
125
|
+
export const currentThread = new Proxy({}, {
|
|
126
|
+
get(_target, prop, receiver) {
|
|
127
|
+
if (!_currentThread) {
|
|
128
|
+
_currentThread = new CurrentThread();
|
|
129
|
+
}
|
|
130
|
+
return Reflect.get(_currentThread, prop, receiver);
|
|
131
|
+
},
|
|
132
|
+
getPrototypeOf() {
|
|
133
|
+
return CurrentThread.prototype;
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
//# sourceMappingURL=thread.js.map
|