@cheatron/nthread 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +175 -0
  3. package/dist/crt.d.ts +24 -0
  4. package/dist/crt.d.ts.map +1 -0
  5. package/dist/crt.js +28 -0
  6. package/dist/crt.js.map +1 -0
  7. package/dist/errors.d.ts +50 -0
  8. package/dist/errors.d.ts.map +1 -0
  9. package/dist/errors.js +84 -0
  10. package/dist/errors.js.map +1 -0
  11. package/dist/globals.d.ts +48 -0
  12. package/dist/globals.d.ts.map +1 -0
  13. package/dist/globals.js +132 -0
  14. package/dist/globals.js.map +1 -0
  15. package/dist/index.d.ts +12 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +12 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/logger.d.ts +2 -0
  20. package/dist/logger.d.ts.map +1 -0
  21. package/dist/logger.js +3 -0
  22. package/dist/logger.js.map +1 -0
  23. package/dist/memory/alloc-options.d.ts +23 -0
  24. package/dist/memory/alloc-options.d.ts.map +1 -0
  25. package/dist/memory/alloc-options.js +1 -0
  26. package/dist/memory/alloc-options.js.map +1 -0
  27. package/dist/memory/heap.d.ts +147 -0
  28. package/dist/memory/heap.d.ts.map +1 -0
  29. package/dist/memory/heap.js +276 -0
  30. package/dist/memory/heap.js.map +1 -0
  31. package/dist/memory/romem.d.ts +69 -0
  32. package/dist/memory/romem.d.ts.map +1 -0
  33. package/dist/memory/romem.js +108 -0
  34. package/dist/memory/romem.js.map +1 -0
  35. package/dist/nthread-heap.d.ts +65 -0
  36. package/dist/nthread-heap.d.ts.map +1 -0
  37. package/dist/nthread-heap.js +193 -0
  38. package/dist/nthread-heap.js.map +1 -0
  39. package/dist/nthread.d.ts +146 -0
  40. package/dist/nthread.d.ts.map +1 -0
  41. package/dist/nthread.js +421 -0
  42. package/dist/nthread.js.map +1 -0
  43. package/dist/thread/captured-thread.d.ts +68 -0
  44. package/dist/thread/captured-thread.d.ts.map +1 -0
  45. package/dist/thread/captured-thread.js +167 -0
  46. package/dist/thread/captured-thread.js.map +1 -0
  47. package/dist/thread/proxy-thread.d.ts +92 -0
  48. package/dist/thread/proxy-thread.d.ts.map +1 -0
  49. package/dist/thread/proxy-thread.js +154 -0
  50. package/dist/thread/proxy-thread.js.map +1 -0
  51. package/package.json +57 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Cheatron
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,175 @@
1
+ # @cheatron/nthread
2
+
3
+ **NThread** is a thread hijacking library for x64 Windows that seizes control of existing threads — without injecting shellcode, allocating remote memory, or using `CreateRemoteThread`.
4
+
5
+ > Built on [@cheatron/native](https://github.com/Cheatron/cheatron-native). TypeScript port of the original [C/C++ NThread](https://github.com/woldann/NThread).
6
+
7
+ > [!IMPORTANT]
8
+ > **64-bit Windows only.** Requires Wine to develop/test on Linux.
9
+
10
+ ---
11
+
12
+ ## How It Works
13
+
14
+ NThread reuses two tiny instruction sequences (gadgets) already present in loaded modules:
15
+
16
+ | Gadget | Pattern | Purpose |
17
+ |--------|---------|--------|
18
+ | **Sleep** | `jmp .` (`EB FE`) | Parks the thread in an infinite loop |
19
+ | **Pivot** | `push reg; ret` | Redirects `RIP` to the sleep gadget |
20
+
21
+ Hijack sequence: suspend → capture context → redirect RIP through pivot → spin until RIP lands on sleep gadget. No shellcode, no remote allocation — just register writes.
22
+
23
+ ---
24
+
25
+ ## Features
26
+
27
+ - **No code injection** — reuses gadgets in `ntdll`, `kernel32`, `kernelbase`, `msvcrt`
28
+ - **No `WriteProcessMemory`** — memory ops are performed by hijacking the target thread to call its own `msvcrt` functions
29
+ - **Auto-discovery** — scans modules lazily via `Module.scan()`
30
+ - **Reversible** — saves full register context before hijacking; restores on `proxy.close()`
31
+ - **CRT bridge** — resolves `msvcrt!malloc`, `calloc`, `memset`, `fwrite`, etc. and calls them *from inside the target thread*
32
+ - **Write optimization** — `romem` tracks known region contents and lets `write()` skip unchanged bytes automatically
33
+ - **Heap allocator** — `NThreadHeap` pre-allocates a single heap block in the target and sub-allocates from it, minimising round-trips
34
+
35
+ ---
36
+
37
+ ## Installation
38
+
39
+ ```bash
40
+ bun add @cheatron/nthread
41
+ ```
42
+
43
+ ---
44
+
45
+ ## Quick Start
46
+
47
+ ```typescript
48
+ import { NThread, createReadOnlyMemory } from '@cheatron/nthread';
49
+
50
+ const nthread = new NThread();
51
+
52
+ // Hijack an existing thread by TID
53
+ const [proxy, captured] = await nthread.inject(tid);
54
+
55
+ // Call a function inside the target thread (x64 calling convention)
56
+ const ptr = await proxy.call(crt.malloc, 1024n);
57
+
58
+ // Write memory via hijacked memset calls
59
+ await proxy.write(ptr, Buffer.from([0xDE, 0xAD, 0xBE, 0xEF]));
60
+
61
+ // Allocate and write a wide string in one step
62
+ const strPtr = await proxy.allocString('Hello, target!');
63
+
64
+ // Read memory back
65
+ const buf = await proxy.read(ptr, 4);
66
+
67
+ // Restore original context and release
68
+ await proxy.close();
69
+ ```
70
+
71
+ ---
72
+
73
+ ## Core Components
74
+
75
+ ### `NThread`
76
+
77
+ Lightweight orchestrator — holds resolved gadget addresses and runs the hijack sequence.
78
+
79
+ ```typescript
80
+ new NThread(processId?, sleepAddress?, pushretAddress?, regKey?)
81
+ ```
82
+
83
+ | Method | Description |
84
+ |--------|-------------|
85
+ | `inject(thread)` | Hijack a thread (TID or `Thread`), returns `[ProxyThread, CapturedThread]` |
86
+ | `threadCall(thread, target, args, timeout)` | Execute a function call on a captured thread |
87
+ | `writeMemory(thread, dest, source)` | Write via decomposed `memset` calls; romem-aware |
88
+
89
+ Overridable hooks (for subclasses):
90
+ - `threadClose(proxy, captured, suicide?)` — called by `proxy.close()`
91
+ - `threadAlloc(proxy, size, opts?)` — called by `proxy.alloc()`
92
+ - `threadFree(proxy, ptr)` — called by `proxy.free()`
93
+
94
+ ### `NThreadHeap`
95
+
96
+ Subclass of `NThread`. Pre-allocates a single heap block (`calloc`) in the target and sub-allocates from it. The heap doubles on full (up to `maxSize`); oversized requests fall back to `msvcrt!malloc`.
97
+
98
+ ```typescript
99
+ new NThreadHeap(heapSize?, maxSize?, processId?, sleepAddress?, pushretAddress?, regKey?)
100
+ // Defaults: heapSize = 65536, maxSize = 65536 * 8
101
+ ```
102
+
103
+ All proxy allocations are **freed atomically on `proxy.close()`**.
104
+
105
+ ### `CapturedThread`
106
+
107
+ Extends `Native.Thread`. Owns the hardware context cache, suspend tracking, and register manipulation for a single captured thread.
108
+
109
+ | Method | Description |
110
+ |--------|-------------|
111
+ | `fetchContext()` / `applyContext()` | Sync hardware ↔ cache |
112
+ | `getRIP()` / `setRIP(addr)` | RIP convenience accessors |
113
+ | `wait(timeoutMs?)` | Poll until RIP == sleep address |
114
+ | `release()` | Restore saved context without closing handle |
115
+ | `close()` | `release()` → drain suspends → close handle |
116
+
117
+ ### `ProxyThread`
118
+
119
+ High-level interface for a captured thread. Each operation is a replaceable delegate.
120
+
121
+ ```typescript
122
+ new ProxyThread(close: CloseFn, process?: Native.Process)
123
+ ```
124
+
125
+ | Method | Description |
126
+ |--------|-------------|
127
+ | `read(address, size)` | Read memory |
128
+ | `write(address, data, size?)` | Write memory |
129
+ | `call(address, ...args)` | Call a function |
130
+ | `alloc(size, opts?)` | Allocate memory (`malloc`/`calloc`/realloc) |
131
+ | `free(ptr)` | Free memory |
132
+ | `allocString(str, encoding?, opts?)` | Alloc + write a string; null-terminated; default encoding `utf16le` |
133
+ | `close(suicide?)` | Release the thread (or terminate with exit code) |
134
+ | `setReader/setWriter/setCaller/setCloser/setAllocer/setFreer` | Replace delegates |
135
+
136
+ ### `globals.ts` — Gadget Registry
137
+
138
+ Manages sleep and pushret gadget pools. Auto-discovery runs once lazily on first use, scanning `ntdll`, `kernel32`, `kernelbase`, `msvcrt`. Register priority: `Rbx → Rbp → Rdi → Rsi`.
139
+
140
+ ### `crt.ts` — CRT Bridge
141
+
142
+ Resolves `msvcrt.dll` exports at load time (`malloc`, `calloc`, `free`, `memset`, `realloc`, `fopen`, `fread`, `fwrite`, `fflush`, `fclose`). All values are `NativePointer` — set as `RIP` on the hijacked thread.
143
+
144
+ ---
145
+
146
+ ## Read-Only Memory (`romem`)
147
+
148
+ `romem` tracks a known-content region as a `(remote: NativePointer, local: Buffer)` pair. `proxy.write()` auto-detects overlaps and skips unchanged bytes.
149
+
150
+ ```typescript
151
+ import { createReadOnlyMemory, unregisterReadOnlyMemory } from '@cheatron/nthread';
152
+
153
+ const romem = await createReadOnlyMemory(proxy, 256); // calloc in target
154
+ const data = Buffer.alloc(256);
155
+ data.writeUInt32LE(0xDEADBEEF, 0);
156
+ await proxy.write(romem.remote, data); // only changed bytes are written
157
+
158
+ unregisterReadOnlyMemory(romem);
159
+ ```
160
+
161
+ ---
162
+
163
+ ## Development
164
+
165
+ ```bash
166
+ bun install
167
+ bun run build
168
+ wine /path/to/bun.exe test
169
+ ```
170
+
171
+ ---
172
+
173
+ ## License
174
+
175
+ MIT
package/dist/crt.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ import * as Native from '@cheatron/native';
2
+ /**
3
+ * CRTFunctions: A collection of standard C Runtime functions resolved in the target process.
4
+ * These are essential for performing standard operations like memory allocation (malloc/free)
5
+ * and file I/O (fopen/fwrite) from native code within the hijacked thread.
6
+ */
7
+ export interface CRTFunctions {
8
+ fopen: Native.NativePointer;
9
+ memset: Native.NativePointer;
10
+ malloc: Native.NativePointer;
11
+ calloc: Native.NativePointer;
12
+ realloc: Native.NativePointer;
13
+ fwrite: Native.NativePointer;
14
+ fflush: Native.NativePointer;
15
+ fclose: Native.NativePointer;
16
+ fread: Native.NativePointer;
17
+ free: Native.NativePointer;
18
+ }
19
+ /**
20
+ * Global CRT function pointers.
21
+ * These are initialized lazily or on import to be used globally by other components.
22
+ */
23
+ export declare const crt: CRTFunctions;
24
+ //# sourceMappingURL=crt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crt.d.ts","sourceRoot":"","sources":["../src/crt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAG3C;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC,aAAa,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC,aAAa,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC,aAAa,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC,aAAa,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC,aAAa,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC,aAAa,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC,aAAa,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC,aAAa,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC,aAAa,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC,aAAa,CAAC;CAC5B;AAYD;;;GAGG;AACH,eAAO,MAAM,GAAG,EAAE,YAWjB,CAAC"}
package/dist/crt.js ADDED
@@ -0,0 +1,28 @@
1
+ import * as Native from '@cheatron/native';
2
+ import { log } from './logger.js';
3
+ /**
4
+ * Internal helper to resolve a function by name from the static `msvcrt.dll` module.
5
+ * This assumes `msvcrt.dll` is already loaded in the target process (common for Win32 apps).
6
+ */
7
+ const get = (name) => {
8
+ const addr = Native.Module.crt.getProcAddress(name);
9
+ log.debug('CRT', `Resolved ${name}: ${addr}`);
10
+ return addr;
11
+ };
12
+ /**
13
+ * Global CRT function pointers.
14
+ * These are initialized lazily or on import to be used globally by other components.
15
+ */
16
+ export const crt = {
17
+ fopen: get('fopen'),
18
+ memset: get('memset'),
19
+ malloc: get('malloc'),
20
+ calloc: get('calloc'),
21
+ realloc: get('realloc'),
22
+ fwrite: get('fwrite'),
23
+ fflush: get('fflush'),
24
+ fclose: get('fclose'),
25
+ fread: get('fread'),
26
+ free: get('free'),
27
+ };
28
+ //# sourceMappingURL=crt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crt.js","sourceRoot":"","sources":["../src/crt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAoBlC;;;GAGG;AACH,MAAM,GAAG,GAAG,CAAC,IAAY,EAAwB,EAAE;IACjD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IACpD,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,YAAY,IAAI,KAAK,IAAI,EAAE,CAAC,CAAC;IAC9C,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,GAAG,GAAiB;IAC/B,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC;IACnB,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC;IACrB,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC;IACrB,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC;IACrB,OAAO,EAAE,GAAG,CAAC,SAAS,CAAC;IACvB,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC;IACrB,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC;IACrB,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC;IACrB,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC;IACnB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC;CAClB,CAAC"}
@@ -0,0 +1,50 @@
1
+ declare abstract class BaseError extends Error {
2
+ constructor(message: string, options?: ErrorOptions);
3
+ }
4
+ export declare class NThreadError extends BaseError {
5
+ }
6
+ export declare class NoSleepAddressError extends NThreadError {
7
+ constructor();
8
+ }
9
+ export declare class NoPushretAddressError extends NThreadError {
10
+ constructor();
11
+ }
12
+ export declare class InjectError extends NThreadError {
13
+ }
14
+ export declare class InjectTimeoutError extends InjectError {
15
+ readonly waitResult: number;
16
+ constructor(waitResult: number);
17
+ }
18
+ export declare class CallError extends NThreadError {
19
+ readonly target: bigint;
20
+ constructor(message: string, target: bigint);
21
+ }
22
+ export declare class CallNotInjectedError extends CallError {
23
+ constructor();
24
+ }
25
+ export declare class CallTooManyArgsError extends CallError {
26
+ readonly argCount: number;
27
+ constructor(argCount: number);
28
+ }
29
+ export declare class CallRipMismatchError extends CallError {
30
+ readonly currentRip: bigint;
31
+ readonly expectedRip: bigint;
32
+ constructor(target: bigint, currentRip: bigint, expectedRip: bigint);
33
+ }
34
+ export declare class CallTimeoutError extends CallError {
35
+ readonly waitResult: number;
36
+ constructor(target: bigint, waitResult: number);
37
+ }
38
+ export declare class CallThreadDiedError extends CallError {
39
+ constructor(target: bigint);
40
+ }
41
+ export declare class WriteError extends NThreadError {
42
+ }
43
+ export declare class GadgetError extends NThreadError {
44
+ }
45
+ export declare class GadgetScanError extends GadgetError {
46
+ readonly pattern: string;
47
+ constructor(pattern: string);
48
+ }
49
+ export {};
50
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA,uBAAe,SAAU,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIpD;AAID,qBAAa,YAAa,SAAQ,SAAS;CAAG;AAE9C,qBAAa,mBAAoB,SAAQ,YAAY;;CAIpD;AAED,qBAAa,qBAAsB,SAAQ,YAAY;;CAItD;AAED,qBAAa,WAAY,SAAQ,YAAY;CAAG;AAEhD,qBAAa,kBAAmB,SAAQ,WAAW;aACrB,UAAU,EAAE,MAAM;gBAAlB,UAAU,EAAE,MAAM;CAG/C;AAID,qBAAa,SAAU,SAAQ,YAAY;IACzC,SAAgB,MAAM,EAAE,MAAM,CAAC;gBAEnB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAI5C;AAED,qBAAa,oBAAqB,SAAQ,SAAS;;CAIlD;AAED,qBAAa,oBAAqB,SAAQ,SAAS;IACjD,SAAgB,QAAQ,EAAE,MAAM,CAAC;gBAErB,QAAQ,EAAE,MAAM;CAO7B;AAED,qBAAa,oBAAqB,SAAQ,SAAS;IACjD,SAAgB,UAAU,EAAE,MAAM,CAAC;IACnC,SAAgB,WAAW,EAAE,MAAM,CAAC;gBAExB,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;CAQpE;AAED,qBAAa,gBAAiB,SAAQ,SAAS;IAC7C,SAAgB,UAAU,EAAE,MAAM,CAAC;gBAEvB,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;CAO/C;AAED,qBAAa,mBAAoB,SAAQ,SAAS;gBACpC,MAAM,EAAE,MAAM;CAM3B;AAID,qBAAa,UAAW,SAAQ,YAAY;CAAG;AAI/C,qBAAa,WAAY,SAAQ,YAAY;CAAG;AAEhD,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,SAAgB,OAAO,EAAE,MAAM,CAAC;gBAEpB,OAAO,EAAE,MAAM;CAI5B"}
package/dist/errors.js ADDED
@@ -0,0 +1,84 @@
1
+ // ── Base ──────────────────────────────────────────────────────────────────────
2
+ class BaseError extends Error {
3
+ constructor(message, options) {
4
+ super(message, options);
5
+ this.name = this.constructor.name;
6
+ }
7
+ }
8
+ // ── NThread errors ────────────────────────────────────────────────────────────
9
+ export class NThreadError extends BaseError {
10
+ }
11
+ export class NoSleepAddressError extends NThreadError {
12
+ constructor() {
13
+ super('No valid sleep address could be found or auto-discovered');
14
+ }
15
+ }
16
+ export class NoPushretAddressError extends NThreadError {
17
+ constructor() {
18
+ super('No valid pushret gadget could be found or auto-discovered');
19
+ }
20
+ }
21
+ export class InjectError extends NThreadError {
22
+ }
23
+ export class InjectTimeoutError extends InjectError {
24
+ waitResult;
25
+ constructor(waitResult) {
26
+ super(`Thread did not reach sleep address (wait result: ${waitResult})`);
27
+ this.waitResult = waitResult;
28
+ }
29
+ }
30
+ // ── Call errors ───────────────────────────────────────────────────────────────
31
+ export class CallError extends NThreadError {
32
+ target;
33
+ constructor(message, target) {
34
+ super(message);
35
+ this.target = target;
36
+ }
37
+ }
38
+ export class CallNotInjectedError extends CallError {
39
+ constructor() {
40
+ super('Thread not injected. Call inject() first.', 0n);
41
+ }
42
+ }
43
+ export class CallTooManyArgsError extends CallError {
44
+ argCount;
45
+ constructor(argCount) {
46
+ super(`x64 calling convention supports max 4 register arguments (RCX, RDX, R8, R9), got ${argCount}`, 0n);
47
+ this.argCount = argCount;
48
+ }
49
+ }
50
+ export class CallRipMismatchError extends CallError {
51
+ currentRip;
52
+ expectedRip;
53
+ constructor(target, currentRip, expectedRip) {
54
+ super(`Thread RIP (0x${currentRip.toString(16)}) is not at sleep address (0x${expectedRip.toString(16)})`, target);
55
+ this.currentRip = currentRip;
56
+ this.expectedRip = expectedRip;
57
+ }
58
+ }
59
+ export class CallTimeoutError extends CallError {
60
+ waitResult;
61
+ constructor(target, waitResult) {
62
+ super(`Thread did not return to sleep address (wait result: ${waitResult})`, target);
63
+ this.waitResult = waitResult;
64
+ }
65
+ }
66
+ export class CallThreadDiedError extends CallError {
67
+ constructor(target) {
68
+ super('Thread died during call (e.g. ExitThread / noreturn function)', target);
69
+ }
70
+ }
71
+ // ── Write errors ─────────────────────────────────────────────────────────────────
72
+ export class WriteError extends NThreadError {
73
+ }
74
+ // ── Gadget errors ─────────────────────────────────────────────────────────────
75
+ export class GadgetError extends NThreadError {
76
+ }
77
+ export class GadgetScanError extends GadgetError {
78
+ pattern;
79
+ constructor(pattern) {
80
+ super(`Failed to scan for gadget pattern: ${pattern}`);
81
+ this.pattern = pattern;
82
+ }
83
+ }
84
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAEjF,MAAe,SAAU,SAAQ,KAAK;IACpC,YAAY,OAAe,EAAE,OAAsB;QACjD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IACpC,CAAC;CACF;AAED,iFAAiF;AAEjF,MAAM,OAAO,YAAa,SAAQ,SAAS;CAAG;AAE9C,MAAM,OAAO,mBAAoB,SAAQ,YAAY;IACnD;QACE,KAAK,CAAC,0DAA0D,CAAC,CAAC;IACpE,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,YAAY;IACrD;QACE,KAAK,CAAC,2DAA2D,CAAC,CAAC;IACrE,CAAC;CACF;AAED,MAAM,OAAO,WAAY,SAAQ,YAAY;CAAG;AAEhD,MAAM,OAAO,kBAAmB,SAAQ,WAAW;IACrB;IAA5B,YAA4B,UAAkB;QAC5C,KAAK,CAAC,oDAAoD,UAAU,GAAG,CAAC,CAAC;QAD/C,eAAU,GAAV,UAAU,CAAQ;IAE9C,CAAC;CACF;AAED,iFAAiF;AAEjF,MAAM,OAAO,SAAU,SAAQ,YAAY;IACzB,MAAM,CAAS;IAE/B,YAAY,OAAe,EAAE,MAAc;QACzC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,SAAS;IACjD;QACE,KAAK,CAAC,2CAA2C,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,SAAS;IACjC,QAAQ,CAAS;IAEjC,YAAY,QAAgB;QAC1B,KAAK,CACH,oFAAoF,QAAQ,EAAE,EAC9F,EAAE,CACH,CAAC;QACF,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,SAAS;IACjC,UAAU,CAAS;IACnB,WAAW,CAAS;IAEpC,YAAY,MAAc,EAAE,UAAkB,EAAE,WAAmB;QACjE,KAAK,CACH,iBAAiB,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,gCAAgC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,EACnG,MAAM,CACP,CAAC;QACF,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,SAAS;IAC7B,UAAU,CAAS;IAEnC,YAAY,MAAc,EAAE,UAAkB;QAC5C,KAAK,CACH,wDAAwD,UAAU,GAAG,EACrE,MAAM,CACP,CAAC;QACF,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,SAAS;IAChD,YAAY,MAAc;QACxB,KAAK,CACH,+DAA+D,EAC/D,MAAM,CACP,CAAC;IACJ,CAAC;CACF;AAED,oFAAoF;AAEpF,MAAM,OAAO,UAAW,SAAQ,YAAY;CAAG;AAE/C,iFAAiF;AAEjF,MAAM,OAAO,WAAY,SAAQ,YAAY;CAAG;AAEhD,MAAM,OAAO,eAAgB,SAAQ,WAAW;IAC9B,OAAO,CAAS;IAEhC,YAAY,OAAe;QACzB,KAAK,CAAC,sCAAsC,OAAO,EAAE,CAAC,CAAC;QACvD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF"}
@@ -0,0 +1,48 @@
1
+ import * as Native from '@cheatron/native';
2
+ /**
3
+ * GeneralPurposeRegs: Supported 64-bit general purpose registers for x64 hijacking.
4
+ */
5
+ export type GeneralPurposeRegs = Extract<keyof Native.ThreadContext, 'Rax' | 'Rcx' | 'Rdx' | 'Rbx' | 'Rsp' | 'Rbp' | 'Rsi' | 'Rdi' | 'R8' | 'R9' | 'R10' | 'R11' | 'R12' | 'R13' | 'R14' | 'R15'>;
6
+ /**
7
+ * Register priority sequence for hijacking.
8
+ * We prefer registers that are traditionally "callee-saved" or less likely to be
9
+ * actively holding critical data during a random suspension point.
10
+ */
11
+ export declare const leastClobberedRegs: GeneralPurposeRegs[];
12
+ /**
13
+ * Manually registers a sleep address (gadget) into the global pool.
14
+ * @param address The NativePointer to the 'jmp .' instruction.
15
+ */
16
+ export declare function registerSleepAddress(address: Native.NativePointer): void;
17
+ /**
18
+ * Retrieves a random sleep address from the pool.
19
+ * If the pool is empty, it triggers auto-discovery.
20
+ */
21
+ export declare function getRandomSleepAddress(): Native.NativePointer | undefined;
22
+ /**
23
+ * Manually registers a pushret address (gadget) into the global pool.
24
+ * @param address The NativePointer to the 'push reg; ret' sequence.
25
+ * @param regKey The register used in the 'push' instruction.
26
+ */
27
+ export declare function registerPushretAddress(address: Native.NativePointer, regKey: GeneralPurposeRegs): void;
28
+ /**
29
+ * Retrieves a random pushret address from the pool, prioritized by stability.
30
+ * @param regKey Optional filter to find a gadget for a specific register.
31
+ * @returns An object containing the pointer and the register it targets.
32
+ *
33
+ * Logic:
34
+ * 1. If regKey is specified, search only for that register.
35
+ * 2. If no regKey is specified, search through `leastClobberedRegs` in order
36
+ * and return the first available gadget type found.
37
+ */
38
+ export declare function getRandomPushretAddress(regKey?: GeneralPurposeRegs): {
39
+ address: Native.NativePointer;
40
+ regKey: GeneralPurposeRegs;
41
+ } | undefined;
42
+ /**
43
+ * Scans all loaded modules in the current process for useful hijacking gadgets.
44
+ * Uses Keystone to assemble the target instructions on-the-fly to ensure
45
+ * architecture-perfect pattern matching.
46
+ */
47
+ export declare function autoDiscoverAddresses(): void;
48
+ //# sourceMappingURL=globals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../src/globals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAM3C;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,CACtC,MAAM,MAAM,CAAC,aAAa,EACxB,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,IAAI,GACJ,IAAI,GACJ,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,CACR,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,kBAAkB,EAMlD,CAAC;AAWF;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,aAAa,GAAG,IAAI,CAGxE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAAC,aAAa,GAAG,SAAS,CASxE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,CAAC,aAAa,EAC7B,MAAM,EAAE,kBAAkB,GACzB,IAAI,CAGN;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,CAAC,EAAE,kBAAkB,GAC1B;IAAE,OAAO,EAAE,MAAM,CAAC,aAAa,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,GAAG,SAAS,CA8B3E;AAKD;;;;GAIG;AACH,wBAAgB,qBAAqB,SAiDpC"}
@@ -0,0 +1,132 @@
1
+ import * as Native from '@cheatron/native';
2
+ import { log } from './logger.js';
3
+ import { KeystoneX86 } from '@cheatron/keystone';
4
+ const globalsLog = log.child('Globals');
5
+ /**
6
+ * Register priority sequence for hijacking.
7
+ * We prefer registers that are traditionally "callee-saved" or less likely to be
8
+ * actively holding critical data during a random suspension point.
9
+ */
10
+ export const leastClobberedRegs = [
11
+ 'Rbx',
12
+ 'Rbp',
13
+ 'Rdi',
14
+ 'Rsi', // Non-Volatile (stable frame pointers/iterators)
15
+ // "R12" - "R15" are also non-volatile but less common in simple gadgets
16
+ ];
17
+ /** Internal pool of discovered 'jmp .' addresses */
18
+ const sleepAddresses = [];
19
+ /** Internal mapping of discovered 'push reg; ret' addresses to their respective registers */
20
+ const pushretAddresses = new Map();
21
+ /**
22
+ * Manually registers a sleep address (gadget) into the global pool.
23
+ * @param address The NativePointer to the 'jmp .' instruction.
24
+ */
25
+ export function registerSleepAddress(address) {
26
+ sleepAddresses.push(address);
27
+ globalsLog.debug(`Registered sleepAddress: ${address}`);
28
+ }
29
+ /**
30
+ * Retrieves a random sleep address from the pool.
31
+ * If the pool is empty, it triggers auto-discovery.
32
+ */
33
+ export function getRandomSleepAddress() {
34
+ if (sleepAddresses.length === 0) {
35
+ autoDiscoverAddresses();
36
+ }
37
+ if (sleepAddresses.length === 0)
38
+ return undefined;
39
+ const randomIndex = Math.floor(Math.random() * sleepAddresses.length);
40
+ return sleepAddresses[randomIndex];
41
+ }
42
+ /**
43
+ * Manually registers a pushret address (gadget) into the global pool.
44
+ * @param address The NativePointer to the 'push reg; ret' sequence.
45
+ * @param regKey The register used in the 'push' instruction.
46
+ */
47
+ export function registerPushretAddress(address, regKey) {
48
+ pushretAddresses.set(address.address, { pointer: address, regKey });
49
+ globalsLog.debug(`Registered pushretAddress: ${address} (RegKey: ${regKey})`);
50
+ }
51
+ /**
52
+ * Retrieves a random pushret address from the pool, prioritized by stability.
53
+ * @param regKey Optional filter to find a gadget for a specific register.
54
+ * @returns An object containing the pointer and the register it targets.
55
+ *
56
+ * Logic:
57
+ * 1. If regKey is specified, search only for that register.
58
+ * 2. If no regKey is specified, search through `leastClobberedRegs` in order
59
+ * and return the first available gadget type found.
60
+ */
61
+ export function getRandomPushretAddress(regKey) {
62
+ if (pushretAddresses.size === 0) {
63
+ autoDiscoverAddresses();
64
+ }
65
+ if (pushretAddresses.size === 0)
66
+ return undefined;
67
+ let validEntries = Array.from(pushretAddresses.values());
68
+ if (regKey) {
69
+ validEntries = validEntries.filter((e) => e.regKey === regKey);
70
+ }
71
+ else {
72
+ // Step through priority list to find the "best" available gadget class
73
+ for (const bestReg of leastClobberedRegs) {
74
+ const bestEntries = validEntries.filter((e) => e.regKey === bestReg);
75
+ if (bestEntries.length > 0) {
76
+ validEntries = bestEntries;
77
+ break;
78
+ }
79
+ }
80
+ }
81
+ if (validEntries.length === 0)
82
+ return undefined;
83
+ const randomIndex = Math.floor(Math.random() * validEntries.length);
84
+ const selected = validEntries[randomIndex];
85
+ if (!selected)
86
+ return undefined;
87
+ return { address: selected.pointer, regKey: selected.regKey };
88
+ }
89
+ /** Flag to prevent redundant heavy scans */
90
+ let isAutoDiscovered = false;
91
+ /**
92
+ * Scans all loaded modules in the current process for useful hijacking gadgets.
93
+ * Uses Keystone to assemble the target instructions on-the-fly to ensure
94
+ * architecture-perfect pattern matching.
95
+ */
96
+ export function autoDiscoverAddresses() {
97
+ if (isAutoDiscovered)
98
+ return;
99
+ globalsLog.info('Starting auto-discovery of global execution addresses via pattern scanning...');
100
+ // Search only in executable memory (RX or RWX)
101
+ const protect = Native.MemoryProtection.EXECUTE_READ |
102
+ Native.MemoryProtection.EXECUTE_READWRITE;
103
+ const assembler = new KeystoneX86();
104
+ // 1. Scan for Sleep Gadgets ('jmp .')
105
+ const sleepCode = assembler.asm('jmp .');
106
+ const sleepPattern = new Native.Pattern(sleepCode)
107
+ .noLimit()
108
+ .addProtect(protect);
109
+ const sleepRes = Native.Module.scan(sleepPattern);
110
+ for (const match of sleepRes.all()) {
111
+ registerSleepAddress(match.pointer);
112
+ }
113
+ // 2. Scan for PushRet Gadgets ('push reg; ret')
114
+ const retCode = assembler.asm('ret');
115
+ for (const regKey of leastClobberedRegs) {
116
+ // Compile 'push rax' etc.
117
+ const pushCode = assembler.asm('push ' + regKey.toString().toLowerCase());
118
+ // Pattern = [Push opcode(s)] + [Ret opcode]
119
+ const pushretCode = [...pushCode, ...retCode];
120
+ const pushretPattern = new Native.Pattern(pushretCode)
121
+ .noLimit()
122
+ .addProtect(protect);
123
+ // Perform process-wide cross-module scan
124
+ const pushretRes = Native.Module.scan(pushretPattern);
125
+ for (const match of pushretRes.all()) {
126
+ registerPushretAddress(match.pointer, regKey);
127
+ }
128
+ }
129
+ isAutoDiscovered = true;
130
+ globalsLog.info(`Auto-discovery complete. Found ${sleepAddresses.length} sleep gadgets and ${pushretAddresses.size} pushret gadgets.`);
131
+ }
132
+ //# sourceMappingURL=globals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"globals.js","sourceRoot":"","sources":["../src/globals.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export * from './crt.js';
2
+ export * from './errors.js';
3
+ export * from './logger.js';
4
+ export * from './thread/captured-thread.js';
5
+ export * from './nthread.js';
6
+ export * from './nthread-heap.js';
7
+ export * from './globals.js';
8
+ export * from './thread/proxy-thread.js';
9
+ export * from './memory/romem.js';
10
+ export * from './memory/heap.js';
11
+ export * from './memory/alloc-options.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ export * from './crt.js';
2
+ export * from './errors.js';
3
+ export * from './logger.js';
4
+ export * from './thread/captured-thread.js';
5
+ export * from './nthread.js';
6
+ export * from './nthread-heap.js';
7
+ export * from './globals.js';
8
+ export * from './thread/proxy-thread.js';
9
+ export * from './memory/romem.js';
10
+ export * from './memory/heap.js';
11
+ export * from './memory/alloc-options.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const log: import("@cheatron/log").LoggerHelpers;
2
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,GAAG,uCAA6B,CAAC"}
package/dist/logger.js ADDED
@@ -0,0 +1,3 @@
1
+ import { createLogHelper } from '@cheatron/log';
2
+ export const log = createLogHelper('NThread');
3
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,CAAC,MAAM,GAAG,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC"}