@cheatron/nthread 1.0.1 → 1.0.3

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.
@@ -0,0 +1,82 @@
1
+ import * as Native from '@cheatron/native';
2
+ import { NThreadHeap } from './nthread-heap.js';
3
+ import type { CapturedThread } from './thread/captured-thread.js';
4
+ import type { ProxyThread } from './thread/proxy-thread.js';
5
+ import type { GeneralPurposeRegs } from './globals.js';
6
+ /** Per-proxy file channel state. */
7
+ interface FileChannelState {
8
+ /** Local temp file path used as the bidirectional I/O channel. */
9
+ filePath: string;
10
+ /** `FILE*` handle kept open in the target process (`"w+b"` mode). */
11
+ stream: Native.NativePointer;
12
+ }
13
+ /**
14
+ * Default maximum bytes transferred before rotating temp file paths.
15
+ * Reserved for future path-rotation support.
16
+ */
17
+ export declare const DEFAULT_FILE_MAX_TRANSFER: number;
18
+ /**
19
+ * NThreadFile extends {@link NThreadHeap} with filesystem-based I/O channels.
20
+ *
21
+ * Instead of `ReadProcessMemory` / `WriteProcessMemory` (or the base class's
22
+ * decomposed `memset` write strategy), all data flows through a single temp file:
23
+ *
24
+ * - **Write channel** (attacker → target): attacker writes to temp file locally,
25
+ * then `fseek(0)` + `fread` in the target reads it into the destination address.
26
+ * - **Read channel** (target → attacker): `fseek(0)` + `fwrite` + `fflush` in
27
+ * the target dumps memory to the file, then attacker reads it locally.
28
+ *
29
+ * The file is opened once during `inject()` with `"w+b"` mode (read+write) and
30
+ * kept open for the lifetime of the proxy. `fseek(0, SEEK_SET)` resets the
31
+ * stream position before each operation.
32
+ *
33
+ * ### When to prefer NThreadFile
34
+ * - Large bulk transfers: one `fread`/`fwrite` call vs many `memset` calls
35
+ * - Stealth: avoids RPM/WPM API calls entirely
36
+ *
37
+ * ### Lifecycle
38
+ * - `inject()` opens a single temp file and configures the proxy delegates.
39
+ * - `proxy.write()` / `proxy.read()` transparently route through the file channel.
40
+ * - `proxy.close()` closes the stream, deletes the temp file, restores the thread.
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * const nt = new NThreadFile();
45
+ * const [proxy] = await nt.inject(tid);
46
+ *
47
+ * const ptr = await proxy.alloc(256, { fill: 0 });
48
+ * await proxy.write(ptr, myBuffer); // goes through file channel
49
+ * const data = await proxy.read(ptr); // goes through file channel
50
+ *
51
+ * await proxy.close(); // closes stream, deletes temp file, destroys heaps, restores thread
52
+ * ```
53
+ */
54
+ export declare class NThreadFile extends NThreadHeap {
55
+ constructor(heapSize?: number, maxSize?: number, processId?: number, sleepAddress?: Native.NativePointer, pushretAddress?: Native.NativePointer, regKey?: GeneralPurposeRegs);
56
+ inject(thread: Native.Thread | number): Promise<[ProxyThread, CapturedThread]>;
57
+ /**
58
+ * Closes the file channel: closes the `FILE*` stream in the target, deletes
59
+ * the temp file, then delegates to the base `threadClose` for heap destruction
60
+ * and thread restore.
61
+ */
62
+ protected fileChannelClose(proxy: ProxyThread, state: FileChannelState, captured: CapturedThread, suicide?: number): Promise<void>;
63
+ /**
64
+ * Writes data to the target process through the filesystem channel.
65
+ *
66
+ * 1. Writes `data` to the local temp file (truncates).
67
+ * 2. `fseek(stream, 0, SEEK_SET)` to reset the target's stream position.
68
+ * 3. `fread` in the target reads from the file into the destination address.
69
+ */
70
+ protected fileChannelWrite(proxy: ProxyThread, state: FileChannelState, address: Native.NativePointer, data: Buffer | Native.NativePointer, size?: number): Promise<number>;
71
+ /**
72
+ * Reads data from the target process through the filesystem channel.
73
+ *
74
+ * 1. `fseek(stream, 0, SEEK_SET)` to reset the target's stream position.
75
+ * 2. `fwrite` in the target dumps memory to the file.
76
+ * 3. `fflush` ensures data reaches disk.
77
+ * 4. Reads the temp file locally.
78
+ */
79
+ protected fileChannelRead(proxy: ProxyThread, state: FileChannelState, address: Native.NativePointer, size: number): Promise<Buffer>;
80
+ }
81
+ export {};
82
+ //# sourceMappingURL=nthread-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nthread-file.d.ts","sourceRoot":"","sources":["../src/nthread-file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAavD,oCAAoC;AACpC,UAAU,gBAAgB;IACxB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC,aAAa,CAAC;CAC9B;AAED;;;GAGG;AACH,eAAO,MAAM,yBAAyB,QAAc,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBAAa,WAAY,SAAQ,WAAW;gBAExC,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,CAAC,aAAa,EACnC,cAAc,CAAC,EAAE,MAAM,CAAC,aAAa,EACrC,MAAM,CAAC,EAAE,kBAAkB;IASd,MAAM,CACnB,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,GAC7B,OAAO,CAAC,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IA8CzC;;;;OAIG;cACa,gBAAgB,CAC9B,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,gBAAgB,EACvB,QAAQ,EAAE,cAAc,EACxB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAgBhB;;;;;;OAMG;cACa,gBAAgB,CAC9B,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,gBAAgB,EACvB,OAAO,EAAE,MAAM,CAAC,aAAa,EAC7B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,aAAa,EACnC,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC;IAgClB;;;;;;;OAOG;cACa,eAAe,CAC7B,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,gBAAgB,EACvB,OAAO,EAAE,MAAM,CAAC,aAAa,EAC7B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC;CAgBnB"}
@@ -0,0 +1,164 @@
1
+ import * as Native from '@cheatron/native';
2
+ import { NThreadHeap } from './nthread-heap.js';
3
+ import { log } from './logger.js';
4
+ import { FileError, WriteSizeRequiredError } from './errors.js';
5
+ import { writeFileSync, readFileSync, unlinkSync } from 'node:fs';
6
+ import { tmpdir } from 'node:os';
7
+ import { join } from 'node:path';
8
+ import { randomBytes } from 'node:crypto';
9
+ const fileLog = log.child('File');
10
+ /** SEEK_SET constant for fseek — seek from beginning of file. */
11
+ const SEEK_SET = 0;
12
+ /**
13
+ * Default maximum bytes transferred before rotating temp file paths.
14
+ * Reserved for future path-rotation support.
15
+ */
16
+ export const DEFAULT_FILE_MAX_TRANSFER = 1024 * 1024; // 1 MiB
17
+ /**
18
+ * NThreadFile extends {@link NThreadHeap} with filesystem-based I/O channels.
19
+ *
20
+ * Instead of `ReadProcessMemory` / `WriteProcessMemory` (or the base class's
21
+ * decomposed `memset` write strategy), all data flows through a single temp file:
22
+ *
23
+ * - **Write channel** (attacker → target): attacker writes to temp file locally,
24
+ * then `fseek(0)` + `fread` in the target reads it into the destination address.
25
+ * - **Read channel** (target → attacker): `fseek(0)` + `fwrite` + `fflush` in
26
+ * the target dumps memory to the file, then attacker reads it locally.
27
+ *
28
+ * The file is opened once during `inject()` with `"w+b"` mode (read+write) and
29
+ * kept open for the lifetime of the proxy. `fseek(0, SEEK_SET)` resets the
30
+ * stream position before each operation.
31
+ *
32
+ * ### When to prefer NThreadFile
33
+ * - Large bulk transfers: one `fread`/`fwrite` call vs many `memset` calls
34
+ * - Stealth: avoids RPM/WPM API calls entirely
35
+ *
36
+ * ### Lifecycle
37
+ * - `inject()` opens a single temp file and configures the proxy delegates.
38
+ * - `proxy.write()` / `proxy.read()` transparently route through the file channel.
39
+ * - `proxy.close()` closes the stream, deletes the temp file, restores the thread.
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * const nt = new NThreadFile();
44
+ * const [proxy] = await nt.inject(tid);
45
+ *
46
+ * const ptr = await proxy.alloc(256, { fill: 0 });
47
+ * await proxy.write(ptr, myBuffer); // goes through file channel
48
+ * const data = await proxy.read(ptr); // goes through file channel
49
+ *
50
+ * await proxy.close(); // closes stream, deletes temp file, destroys heaps, restores thread
51
+ * ```
52
+ */
53
+ export class NThreadFile extends NThreadHeap {
54
+ constructor(heapSize, maxSize, processId, sleepAddress, pushretAddress, regKey) {
55
+ super(heapSize, maxSize, processId, sleepAddress, pushretAddress, regKey);
56
+ }
57
+ // ---------------------------------------------------------------------------
58
+ // inject override
59
+ // ---------------------------------------------------------------------------
60
+ async inject(thread) {
61
+ const [proxy, captured] = await super.inject(thread);
62
+ try {
63
+ // Generate a unique temp path
64
+ const id = randomBytes(8).toString('hex');
65
+ const filePath = join(tmpdir(), `nt_${id}`);
66
+ // Open the file in the target with read+write mode (kept open for the
67
+ // proxy's lifetime); fileOpen handles remote string alloc/free internally.
68
+ const stream = await this.fileOpen(proxy, filePath, 'w+b');
69
+ if (stream.address === 0n) {
70
+ throw new FileError(`fopen("${filePath}", "w+b") returned NULL`);
71
+ }
72
+ const state = { filePath, stream };
73
+ // Replace writer: file-based attacker→target channel
74
+ proxy.setWriter((_proxy, address, data, size) => this.fileChannelWrite(_proxy, state, address, data, size));
75
+ // Replace reader: file-based target→attacker channel
76
+ proxy.setReader((_proxy, address, size) => this.fileChannelRead(_proxy, state, address, size));
77
+ // Replace closer: clean up file channel, then delegate to base
78
+ proxy.setCloser((_proxy, suicide) => this.fileChannelClose(_proxy, state, captured, suicide));
79
+ fileLog.info(`File channel established: ${filePath}`);
80
+ return [proxy, captured];
81
+ }
82
+ catch (err) {
83
+ // If file channel setup fails, clean up the base injection
84
+ await proxy.close();
85
+ throw err;
86
+ }
87
+ }
88
+ // ---------------------------------------------------------------------------
89
+ // File Channel I/O
90
+ // ---------------------------------------------------------------------------
91
+ /**
92
+ * Closes the file channel: closes the `FILE*` stream in the target, deletes
93
+ * the temp file, then delegates to the base `threadClose` for heap destruction
94
+ * and thread restore.
95
+ */
96
+ async fileChannelClose(proxy, state, captured, suicide) {
97
+ // Close the FILE* stream (thread is still alive at this point;
98
+ // termination happens in the base threadClose call below).
99
+ await proxy.fclose(state.stream.address);
100
+ // Delete temp file (best-effort)
101
+ try {
102
+ unlinkSync(state.filePath);
103
+ }
104
+ catch {
105
+ /* file may not exist */
106
+ }
107
+ // Heap destruction + thread restore
108
+ await this.threadClose(proxy, captured, suicide);
109
+ }
110
+ /**
111
+ * Writes data to the target process through the filesystem channel.
112
+ *
113
+ * 1. Writes `data` to the local temp file (truncates).
114
+ * 2. `fseek(stream, 0, SEEK_SET)` to reset the target's stream position.
115
+ * 3. `fread` in the target reads from the file into the destination address.
116
+ */
117
+ async fileChannelWrite(proxy, state, address, data, size) {
118
+ let buf;
119
+ let writeSize;
120
+ if (data instanceof Native.NativePointer) {
121
+ if (!size)
122
+ throw new WriteSizeRequiredError();
123
+ buf = Native.currentProcess.memory.read(data, size);
124
+ writeSize = size;
125
+ }
126
+ else {
127
+ buf = data instanceof Buffer ? data : Buffer.from(data);
128
+ writeSize = size ?? buf.length;
129
+ if (writeSize < buf.length)
130
+ buf = buf.subarray(0, writeSize);
131
+ }
132
+ if (writeSize === 0)
133
+ return 0;
134
+ // 1. Write to local temp file
135
+ writeFileSync(state.filePath, buf);
136
+ // 2. Reset stream position in target
137
+ await proxy.fseek(state.stream, 0n, BigInt(SEEK_SET));
138
+ // 3. Read file contents into target address
139
+ const result = await proxy.fread(address.address, 1n, BigInt(writeSize), state.stream);
140
+ return Number(result.address);
141
+ }
142
+ /**
143
+ * Reads data from the target process through the filesystem channel.
144
+ *
145
+ * 1. `fseek(stream, 0, SEEK_SET)` to reset the target's stream position.
146
+ * 2. `fwrite` in the target dumps memory to the file.
147
+ * 3. `fflush` ensures data reaches disk.
148
+ * 4. Reads the temp file locally.
149
+ */
150
+ async fileChannelRead(proxy, state, address, size) {
151
+ if (size === 0)
152
+ return Buffer.alloc(0);
153
+ // 1. Reset stream position in target
154
+ await proxy.fseek(state.stream, 0n, BigInt(SEEK_SET));
155
+ // 2. Write target memory to file
156
+ await proxy.fwrite(address.address, 1n, BigInt(size), state.stream);
157
+ // 3. Flush to disk
158
+ await proxy.fflush(state.stream.address);
159
+ // 4. Read the file locally
160
+ const result = readFileSync(state.filePath);
161
+ return result.subarray(0, size);
162
+ }
163
+ }
164
+ //# sourceMappingURL=nthread-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nthread-file.js","sourceRoot":"","sources":["../src/nthread-file.ts"],"names":[],"mappings":"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"}
@@ -48,7 +48,7 @@ export declare class NThreadHeap extends NThread {
48
48
  private state;
49
49
  constructor(heapSize?: number, maxSize?: number, processId?: number, sleepAddress?: Native.NativePointer, pushretAddress?: Native.NativePointer, regKey?: GeneralPurposeRegs);
50
50
  protected threadClose(proxy: ProxyThread, captured: CapturedThread, suicide?: number): Promise<void>;
51
- protected threadAlloc(proxy: ProxyThread, size: number, opts?: AllocOptions): Promise<Native.NativePointer>;
51
+ protected threadAlloc(proxy: ProxyThread, size: number, opts?: AllocOptions): Promise<Native.NativeMemory>;
52
52
  protected threadFree(proxy: ProxyThread, ptr: Native.NativePointer): Promise<void>;
53
53
  private getState;
54
54
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"nthread-heap.d.ts","sourceRoot":"","sources":["../src/nthread-heap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,+CAA+C;AAC/C,eAAO,MAAM,yBAAyB,QAAQ,CAAC;AAE/C,8FAA8F;AAC9F,eAAO,MAAM,6BAA6B,QAAgC,CAAC;AAc3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,qBAAa,WAAY,SAAQ,OAAO;IACtC,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,OAAO,CAAC,KAAK,CAAsC;gBAGjD,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,CAAC,aAAa,EACnC,cAAc,CAAC,EAAE,MAAM,CAAC,aAAa,EACrC,MAAM,CAAC,EAAE,kBAAkB;cAWJ,WAAW,CAClC,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,cAAc,EACxB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;cAYS,WAAW,CAClC,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,YAAY,GAClB,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC;cAoBP,UAAU,CACjC,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,MAAM,CAAC,aAAa,GACxB,OAAO,CAAC,IAAI,CAAC;IAiBhB,OAAO,CAAC,QAAQ;IAShB;;;OAGG;YACW,aAAa;IA4C3B,4FAA4F;IAC5F,OAAO,CAAC,QAAQ;IAQhB,wDAAwD;IACxD,OAAO,CAAC,UAAU;YAIJ,eAAe;CA0D9B"}
1
+ {"version":3,"file":"nthread-heap.d.ts","sourceRoot":"","sources":["../src/nthread-heap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,+CAA+C;AAC/C,eAAO,MAAM,yBAAyB,QAAQ,CAAC;AAE/C,8FAA8F;AAC9F,eAAO,MAAM,6BAA6B,QAAgC,CAAC;AAc3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,qBAAa,WAAY,SAAQ,OAAO;IACtC,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,OAAO,CAAC,KAAK,CAAsC;gBAGjD,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,CAAC,aAAa,EACnC,cAAc,CAAC,EAAE,MAAM,CAAC,aAAa,EACrC,MAAM,CAAC,EAAE,kBAAkB;cAWJ,WAAW,CAClC,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,cAAc,EACxB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;cAYS,WAAW,CAClC,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,YAAY,GAClB,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC;cAoBN,UAAU,CACjC,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,MAAM,CAAC,aAAa,GACxB,OAAO,CAAC,IAAI,CAAC;IAiBhB,OAAO,CAAC,QAAQ;IAShB;;;OAGG;YACW,aAAa;IA4C3B,4FAA4F;IAC5F,OAAO,CAAC,QAAQ;IAQhB,wDAAwD;IACxD,OAAO,CAAC,UAAU;YAIJ,eAAe;CA0D9B"}
package/dist/nthread.d.ts CHANGED
@@ -9,7 +9,7 @@ export { STACK_ADD } from './thread/captured-thread.js';
9
9
  * All values are ultimately converted to bigint for register assignment (RCX, RDX, R8, R9).
10
10
  * Accepts NativePointer (→ .address) and number (→ BigInt()) for convenience.
11
11
  */
12
- export type Arg = bigint | number | Native.NativePointer;
12
+ export type Arg = bigint | number | Native.NativePointer | string;
13
13
  /**
14
14
  * NThread: Orchestrates non-invasive thread hijacking.
15
15
  *
@@ -60,7 +60,7 @@ export declare class NThread {
60
60
  *
61
61
  * @returns `true` if the module is loaded, `false` otherwise.
62
62
  */
63
- protected checkModuleLoaded(captured: CapturedThread, moduleBase: Arg, phModule?: Arg): Promise<boolean>;
63
+ protected checkModuleLoaded(proxy: ProxyThread, captured: CapturedThread, moduleBase: Arg, phModule?: Arg): Promise<boolean>;
64
64
  /** Writes data to the target process; dispatches NativePointer vs Buffer. */
65
65
  private threadWrite;
66
66
  /**
@@ -75,7 +75,7 @@ export declare class NThread {
75
75
  * delegates to `msvcrt!realloc` when `opts.address` is provided.
76
76
  * Subclasses can override to use a pre-allocated heap instead.
77
77
  */
78
- protected threadAlloc(proxy: ProxyThread, size: number, opts?: AllocOptions): Promise<Native.NativePointer>;
78
+ protected threadAlloc(proxy: ProxyThread, size: number, opts?: AllocOptions): Promise<Native.NativeMemory>;
79
79
  /**
80
80
  * Hook: frees a pointer in the target process.
81
81
  * Default: `msvcrt!free`.
@@ -91,7 +91,69 @@ export declare class NThread {
91
91
  * @param encoding Buffer encoding — defaults to `'utf16le'` (Windows wide string).
92
92
  * @param opts Optional alloc options forwarded to `proxy.alloc()`.
93
93
  */
94
- allocString(proxy: ProxyThread, str: string, encoding?: BufferEncoding, opts?: AllocOptions): Promise<Native.NativePointer>;
94
+ /**
95
+ /**
96
+ * Resolves an argument list, converting `string` values to remote pointers.
97
+ * Uses `resolveEncoding` to auto-detect encoding (ASCII → utf8, non-ASCII → utf16le)
98
+ * so callers can pass plain strings to both A and W variant Windows functions.
99
+ */
100
+ protected resolveArgs(proxy: ProxyThread, args: Arg[]): Promise<bigint[]>;
101
+ /**
102
+ * Allocates a null-terminated wide string (UTF-16LE) in the target process.
103
+ * Use `encoding` to override — e.g. `'utf8'` for ANSI (A-variant) APIs.
104
+ */
105
+ allocString(proxy: ProxyThread, str: string, opts?: AllocOptions): Promise<Native.NativeMemory>;
106
+ /**
107
+ * Encodes `str` with a null terminator and writes it into an already-allocated
108
+ * remote address. Auto-detects encoding via `resolveEncoding`
109
+ * (ASCII → UTF-8 + 1-byte null, non-ASCII → UTF-16LE + 2-byte null).
110
+ *
111
+ * @returns Number of bytes written.
112
+ */
113
+ writeString(proxy: ProxyThread, dest: Native.NativePointer, str: string): Promise<number>;
114
+ /**
115
+ * Opens a file in the target process via `msvcrt!fopen`.
116
+ * Both `path` and `mode` are automatically allocated as null-terminated ANSI
117
+ * strings and freed after the call.
118
+ *
119
+ * @returns `FILE*` pointer (`address === 0n` on failure).
120
+ */
121
+ fileOpen(proxy: ProxyThread, path: string | Native.NativePointer, mode: string | Native.NativePointer): Promise<Native.NativePointer>;
122
+ /**
123
+ * Writes data to an open `FILE*` stream via `msvcrt!fwrite`.
124
+ *
125
+ * **Two modes:**
126
+ * - `data: Buffer | string` — encodes locally, allocates a remote scratch buffer,
127
+ * calls `fwrite`, then frees it automatically.
128
+ * Strings are encoded as UTF-8 (raw bytes, no null terminator).
129
+ * - `data: NativeMemory` — already in the target process; byte count is taken
130
+ * from `data.size` automatically.
131
+ *
132
+ * @returns Number of bytes written.
133
+ */
134
+ fileWrite(proxy: ProxyThread, stream: Native.NativePointer, data: Buffer | string | Native.NativeMemory): Promise<number>;
135
+ /**
136
+ * Reads bytes from a `FILE*` stream via `msvcrt!fread`.
137
+ *
138
+ * **Two modes:**
139
+ * - `dest: NativeMemory` — reads directly into an existing remote buffer;
140
+ * byte count is taken from `dest.size` automatically. Returns number of bytes read.
141
+ * - `dest: number` (= byteCount) — allocates a remote scratch buffer,
142
+ * calls `fread`, copies the result back as a local `Buffer`, then frees the scratch.
143
+ *
144
+ * `size` is always `1` — byte-granular I/O.
145
+ */
146
+ fileRead(proxy: ProxyThread, stream: Native.NativePointer, dest: Native.NativeMemory | number): Promise<number | Buffer>;
147
+ /**
148
+ * Flushes a `FILE*` stream via `msvcrt!fflush`.
149
+ * Returns `0` on success, non-zero on failure (mirrors fflush).
150
+ */
151
+ fileFlush(proxy: ProxyThread, stream: Native.NativePointer): Promise<number>;
152
+ /**
153
+ * Closes a `FILE*` stream via `msvcrt!fclose`.
154
+ * Returns `0` on success, `EOF` on failure (mirrors fclose).
155
+ */
156
+ fileClose(proxy: ProxyThread, stream: Native.NativePointer): Promise<number>;
95
157
  /**
96
158
  * Executes a function call on a captured thread using the Windows x64 calling convention.
97
159
  * The thread must be parked at the sleep address (after inject()).
@@ -105,7 +167,7 @@ export declare class NThread {
105
167
  * @param timeoutMs Timeout in ms for waiting on the function return (default: 5000).
106
168
  * @returns RAX value as NativePointer.
107
169
  */
108
- threadCall(thread: CapturedThread, target: Native.NativePointer | bigint, args?: Arg[], timeoutMs?: number): Promise<Native.NativePointer>;
170
+ threadCall(proxy: ProxyThread, thread: CapturedThread, target: Native.NativePointer | bigint, args?: Arg[], timeoutMs?: number): Promise<Native.NativePointer>;
109
171
  /**
110
172
  * Writes arbitrary data to the target process memory using hijacked memset calls.
111
173
  * Decomposes the source buffer into runs of equal bytes and issues one
@@ -1 +1 @@
1
- {"version":3,"file":"nthread.d.ts","sourceRoot":"","sources":["../src/nthread.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"nthread.d.ts","sourceRoot":"","sources":["../src/nthread.ts"],"names":[],"mappings":"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"}