@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.
- package/LICENSE +21 -0
- package/README.md +175 -0
- package/dist/crt.d.ts +24 -0
- package/dist/crt.d.ts.map +1 -0
- package/dist/crt.js +28 -0
- package/dist/crt.js.map +1 -0
- package/dist/errors.d.ts +50 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +84 -0
- package/dist/errors.js.map +1 -0
- package/dist/globals.d.ts +48 -0
- package/dist/globals.d.ts.map +1 -0
- package/dist/globals.js +132 -0
- package/dist/globals.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +2 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +3 -0
- package/dist/logger.js.map +1 -0
- package/dist/memory/alloc-options.d.ts +23 -0
- package/dist/memory/alloc-options.d.ts.map +1 -0
- package/dist/memory/alloc-options.js +1 -0
- package/dist/memory/alloc-options.js.map +1 -0
- package/dist/memory/heap.d.ts +147 -0
- package/dist/memory/heap.d.ts.map +1 -0
- package/dist/memory/heap.js +276 -0
- package/dist/memory/heap.js.map +1 -0
- package/dist/memory/romem.d.ts +69 -0
- package/dist/memory/romem.d.ts.map +1 -0
- package/dist/memory/romem.js +108 -0
- package/dist/memory/romem.js.map +1 -0
- package/dist/nthread-heap.d.ts +65 -0
- package/dist/nthread-heap.d.ts.map +1 -0
- package/dist/nthread-heap.js +193 -0
- package/dist/nthread-heap.js.map +1 -0
- package/dist/nthread.d.ts +146 -0
- package/dist/nthread.d.ts.map +1 -0
- package/dist/nthread.js +421 -0
- package/dist/nthread.js.map +1 -0
- package/dist/thread/captured-thread.d.ts +68 -0
- package/dist/thread/captured-thread.d.ts.map +1 -0
- package/dist/thread/captured-thread.js +167 -0
- package/dist/thread/captured-thread.js.map +1 -0
- package/dist/thread/proxy-thread.d.ts +92 -0
- package/dist/thread/proxy-thread.d.ts.map +1 -0
- package/dist/thread/proxy-thread.js +154 -0
- package/dist/thread/proxy-thread.js.map +1 -0
- 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
|
package/dist/crt.js.map
ADDED
|
@@ -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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -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"}
|
package/dist/globals.js
ADDED
|
@@ -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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"}
|
package/dist/index.d.ts
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.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"}
|
package/dist/logger.d.ts
ADDED
|
@@ -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 @@
|
|
|
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"}
|