@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
@@ -0,0 +1,421 @@
1
+ import * as Native from '@cheatron/native';
2
+ import { getRandomSleepAddress, getRandomPushretAddress, } from './globals.js';
3
+ import { log } from './logger';
4
+ import { ProxyThread } from './thread/proxy-thread.js';
5
+ import { CapturedThread } from './thread/captured-thread.js';
6
+ import { crt } from './crt.js';
7
+ import { NoSleepAddressError, NoPushretAddressError, InjectTimeoutError, CallTooManyArgsError, CallRipMismatchError, CallTimeoutError, CallThreadDiedError, } from './errors.js';
8
+ import { findOverlappingRegion, getOverlapInfo, updateSnapshot, } from './memory/romem.js';
9
+ export { STACK_ADD } from './thread/captured-thread.js';
10
+ const nthreadLog = log.child('');
11
+ /**
12
+ * NThread: Orchestrates non-invasive thread hijacking.
13
+ *
14
+ * It works by suspending a target thread, redirecting its Rip to a 'pushreg/ret' gadget,
15
+ * setting a 'sleep' address as the target, and waiting for the thread to 'land'
16
+ * at said sleep address. Once landed, the thread is effectively seized without
17
+ * stopping the underlying process or requiring complex debugging APIs.
18
+ *
19
+ * The actual thread state (context cache, suspend tracking, proxy) is managed by
20
+ * the contained CapturedThread instance, created during inject().
21
+ */
22
+ export class NThread {
23
+ /** Optional process ID for diagnostics and logging */
24
+ processId;
25
+ /** Address of an infinite loop gadget ('jmp .') used to hold the thread */
26
+ sleepAddress;
27
+ /** Address of a pivot gadget ('push reg; ret') used to redirect execution */
28
+ pushretAddress;
29
+ /** The register key (e.g., 'Rbx') used for the pushret pivot */
30
+ regKey;
31
+ /**
32
+ * Creates an NThread instance and prepares redirect gadgets.
33
+ * @param processId Optional process ID for diagnostics and logging.
34
+ * @param sleepAddress Optional explicit sleep gadget.
35
+ * @param pushretAddress Optional explicit pushret gadget.
36
+ * @param regKey Optional register preference for the pushret gadget.
37
+ */
38
+ constructor(processId, sleepAddress, pushretAddress, regKey) {
39
+ this.processId = processId;
40
+ // 1. Resolve Sleep Address
41
+ if (sleepAddress) {
42
+ this.sleepAddress = sleepAddress;
43
+ }
44
+ else {
45
+ const randomSleepAddress = getRandomSleepAddress();
46
+ if (!randomSleepAddress) {
47
+ throw new NoSleepAddressError();
48
+ }
49
+ this.sleepAddress = randomSleepAddress;
50
+ }
51
+ // 2. Resolve PushRet Address and Key
52
+ if (pushretAddress !== undefined) {
53
+ this.pushretAddress = pushretAddress;
54
+ this.regKey = regKey ?? 'Rbp';
55
+ }
56
+ else {
57
+ const randomPushret = getRandomPushretAddress(regKey);
58
+ if (!randomPushret) {
59
+ throw new NoPushretAddressError();
60
+ }
61
+ this.pushretAddress = randomPushret.address;
62
+ this.regKey = randomPushret.regKey;
63
+ }
64
+ }
65
+ /**
66
+ * Executes the hijacking flow:
67
+ * 1. Create a CapturedThread from the given thread parameter.
68
+ * 2. Suspend the thread.
69
+ * 3. Capture and save current register state.
70
+ * 4. Redirect Rip to PushRet gadget.
71
+ * 5. Point the chosen register (RegKey) to the Sleep gadget.
72
+ * 6. Adjust stack (Rsp) to a safe scratch area.
73
+ * 7. Resume and wait for the thread to 'trap' itself in the loop.
74
+ *
75
+ * @param thread Thread object or Thread ID to hijack.
76
+ */
77
+ async inject(thread) {
78
+ const captured = new CapturedThread(thread, this.regKey, this.sleepAddress, this.processId);
79
+ captured.suspend();
80
+ captured.fetchContext();
81
+ captured.savedContext = captured.getContext();
82
+ // Preserve original values to restore them later
83
+ const targetReg = captured.savedContext[this.regKey];
84
+ const rip = captured.savedContext.Rip;
85
+ const rsp = captured.savedContext.Rsp;
86
+ // Hijack:
87
+ // RIP -> [push reg; ret] (The pivot)
88
+ // REG -> [jmp .] (The final destination)
89
+ // pushret will 'push sleep; ret' → sleep addr lands at [stackBegin - 8]
90
+ // call() later sets RSP to that same address so 'ret' pops sleep again.
91
+ const stackBegin = captured.calcStackBegin(BigInt(rsp));
92
+ captured.callRsp = stackBegin - 8n;
93
+ captured.setRIP(this.pushretAddress.address);
94
+ captured.setRSP(stackBegin);
95
+ captured.setTargetReg(this.sleepAddress.address);
96
+ captured.applyContext();
97
+ captured.resume();
98
+ nthreadLog.info(`Waiting for thread ${captured.tid} to reach ${this.sleepAddress}...`);
99
+ // Poll until Rip matches our infinite loop address
100
+ const res = await captured.wait(5000);
101
+ if (res != Native.WaitReturn.OBJECT_0) {
102
+ throw new InjectTimeoutError(res);
103
+ }
104
+ // Refresh context now that we are stably 'parked' at sleepAddress
105
+ captured.savedContext = captured.getContext();
106
+ // Restore original state into our local copy so we can resume naturally later
107
+ captured.savedContext[this.regKey] = targetReg;
108
+ captured.savedContext.Rip = rip;
109
+ captured.savedContext.Rsp = rsp;
110
+ // Ensure we capture integer and control registers for maximum control
111
+ captured.latestContext.ContextFlags =
112
+ Native.ContextFlags.INTEGER | Native.ContextFlags.CONTROL;
113
+ const proxy = new ProxyThread((_proxy, suicide) => this.threadClose(_proxy, captured, suicide));
114
+ /*proxy.setReader((_proxy, address, size) =>
115
+ Promise.resolve(Native.currentProcess.memory.read(address, size)),
116
+ );*/
117
+ proxy.setCaller((_proxy, address, ...proxyArgs) => this.threadCall(captured, address, [...proxyArgs]));
118
+ proxy.setWriter((_proxy, address, data, size) => this.threadWrite(_proxy, address, data, size));
119
+ proxy.setAllocer((_proxy, size, opts) => this.threadAlloc(_proxy, size, opts));
120
+ proxy.setFreer((_proxy, ptr) => this.threadFree(_proxy, ptr));
121
+ nthreadLog.info(`Successfully injected into thread ${captured.tid}`);
122
+ return [proxy, captured];
123
+ }
124
+ /** Writes data to the target process; dispatches NativePointer vs Buffer. */
125
+ async threadWrite(proxy, address, data, size) {
126
+ if (data instanceof Native.NativePointer) {
127
+ if (!size) {
128
+ throw new Error('Size must be specified when writing a pointer.');
129
+ }
130
+ await this.writeMemoryWithPointer(proxy, address, data, size);
131
+ return size;
132
+ }
133
+ const buf = data instanceof Buffer ? data : Buffer.from(data);
134
+ const writeSize = size ?? buf.length;
135
+ await this.writeMemory(proxy, address, buf.subarray(0, writeSize));
136
+ return writeSize;
137
+ }
138
+ /**
139
+ * Hook: called to release the proxy and captured thread.
140
+ * Subclasses can override to perform cleanup (e.g. destroy a heap pool)
141
+ * before closing. Default: terminate (if suicide) then close the handle.
142
+ */
143
+ async threadClose(_proxy, captured, suicide) {
144
+ if (suicide !== undefined)
145
+ captured.terminate(suicide);
146
+ captured.close();
147
+ }
148
+ /**
149
+ * Hook: allocates memory in the target process.
150
+ * Default: `malloc` / `calloc` / `malloc+memset` depending on `opts.fill`;
151
+ * delegates to `msvcrt!realloc` when `opts.address` is provided.
152
+ * Subclasses can override to use a pre-allocated heap instead.
153
+ */
154
+ async threadAlloc(proxy, size, opts) {
155
+ if (opts?.address) {
156
+ const ptr = await proxy.realloc(opts.address.address, BigInt(size));
157
+ if (ptr.address === 0n)
158
+ throw new Error(`realloc(0x${opts.address.address.toString(16)}, ${size}) returned NULL`);
159
+ return ptr;
160
+ }
161
+ const fill = opts?.fill;
162
+ if (fill === undefined) {
163
+ return proxy.malloc(BigInt(size));
164
+ }
165
+ else if (fill === 0) {
166
+ return proxy.calloc(1n, BigInt(size));
167
+ }
168
+ else {
169
+ const ptr = await proxy.malloc(BigInt(size));
170
+ await proxy.memset(ptr.address, BigInt(fill & 0xff), BigInt(size));
171
+ return ptr;
172
+ }
173
+ }
174
+ /**
175
+ * Hook: frees a pointer in the target process.
176
+ * Default: `msvcrt!free`.
177
+ * Subclasses can override to return the block to a managed heap instead.
178
+ */
179
+ async threadFree(proxy, ptr) {
180
+ await proxy.call(crt.free, ptr.address);
181
+ }
182
+ /**
183
+ * Allocates memory for a string and writes it into the remote process via the captured thread.
184
+ * Null-terminates automatically.
185
+ *
186
+ * @param proxy The proxy for the captured thread.
187
+ * @param str String to encode and write.
188
+ * @param encoding Buffer encoding — defaults to `'utf16le'` (Windows wide string).
189
+ * @param opts Optional alloc options forwarded to `proxy.alloc()`.
190
+ */
191
+ async allocString(proxy, str, encoding = 'utf16le', opts) {
192
+ const encoded = Buffer.from(str, encoding);
193
+ const nullBytes = encoding === 'utf16le' || encoding === 'ucs2' ? 2 : 1;
194
+ const buf = Buffer.alloc(encoded.length + nullBytes);
195
+ encoded.copy(buf);
196
+ const ptr = await proxy.alloc(buf.length, opts);
197
+ await proxy.write(ptr, buf);
198
+ return ptr;
199
+ }
200
+ /**
201
+ * Executes a function call on a captured thread using the Windows x64 calling convention.
202
+ * The thread must be parked at the sleep address (after inject()).
203
+ *
204
+ * Supports up to 4 parameters mapped to RCX, RDX, R8, R9.
205
+ * Returns the value from RAX after the function completes.
206
+ *
207
+ * @param thread The captured thread to execute on.
208
+ * @param target Address of the function to call.
209
+ * @param args Up to 4 arguments (RCX, RDX, R8, R9).
210
+ * @param timeoutMs Timeout in ms for waiting on the function return (default: 5000).
211
+ * @returns RAX value as NativePointer.
212
+ */
213
+ async threadCall(thread, target, args = [], timeoutMs = 5000) {
214
+ if (args.length > 4) {
215
+ throw new CallTooManyArgsError(args.length);
216
+ }
217
+ const toBigInt = (v) => {
218
+ if (v instanceof Native.NativePointer)
219
+ return v.address;
220
+ return BigInt(v);
221
+ };
222
+ const targetAddr = target instanceof Native.NativePointer ? target.address : BigInt(target);
223
+ // 1. Suspend the thread (should be parked at sleep 'jmp .')
224
+ thread.suspend();
225
+ thread.fetchContext();
226
+ // Safety check: verify thread is actually at the sleep address
227
+ const currentRip = BigInt(thread.getContext().Rip);
228
+ if (currentRip !== this.sleepAddress.address) {
229
+ thread.resume();
230
+ throw new CallRipMismatchError(targetAddr, currentRip, this.sleepAddress.address);
231
+ }
232
+ // 2. Map arguments to x64 calling convention registers
233
+ const ctx = thread.getContext();
234
+ if (args.length > 0)
235
+ ctx.Rcx = toBigInt(args[0]);
236
+ if (args.length > 1)
237
+ ctx.Rdx = toBigInt(args[1]);
238
+ if (args.length > 2)
239
+ ctx.R8 = toBigInt(args[2]);
240
+ if (args.length > 3)
241
+ ctx.R9 = toBigInt(args[3]);
242
+ // 3. Redirect execution to target function
243
+ // callRsp points to the pre-written return address (sleep gadget), set once in inject()
244
+ ctx.Rip = targetAddr;
245
+ ctx.Rsp = thread.callRsp;
246
+ thread.setContext(ctx);
247
+ thread.applyContext();
248
+ thread.resume();
249
+ nthreadLog.debug(`Calling 0x${targetAddr.toString(16)} with ${args.length} arg(s)...`);
250
+ // 6. Wait for the function to return (RIP lands back at sleep address)
251
+ const res = await thread.wait(timeoutMs);
252
+ if (res === Native.WaitReturn.FAILED) {
253
+ throw new CallThreadDiedError(targetAddr);
254
+ }
255
+ if (res !== Native.WaitReturn.OBJECT_0) {
256
+ throw new CallTimeoutError(targetAddr, res);
257
+ }
258
+ // 7. Return value is in RAX
259
+ const rax = new Native.NativePointer(thread.getContext().Rax);
260
+ nthreadLog.debug(`Call returned: 0x${rax.toString()}`);
261
+ return rax;
262
+ }
263
+ /**
264
+ * Writes arbitrary data to the target process memory using hijacked memset calls.
265
+ * Decomposes the source buffer into runs of equal bytes and issues one
266
+ * `msvcrt!memset(dest + offset, value, runLength)` call per run.
267
+ *
268
+ * If the write range overlaps a registered read-only memory region, the
269
+ * overlapping portion is routed through writeMemorySafeBuffer (skips unchanged
270
+ * bytes) and the non-overlapping parts are written normally via recursive calls.
271
+ *
272
+ * @param dest Target address to write to.
273
+ * @param source The data to write.
274
+ */
275
+ async writeMemory(proxy, dest, source) {
276
+ const destAddr = dest instanceof Native.NativePointer ? dest.address : dest;
277
+ const data = source instanceof Buffer ? source : Buffer.from(source);
278
+ const length = data.length;
279
+ if (length === 0)
280
+ return 0;
281
+ // Check if the write overlaps a read-only memory region
282
+ const romem = findOverlappingRegion(destAddr, length);
283
+ if (romem) {
284
+ const { writeOffset, overlapLen, snapshot } = getOverlapInfo(destAddr, length, romem);
285
+ let written = 0;
286
+ // Part before the overlap — plain writeMemory
287
+ if (writeOffset > 0) {
288
+ written += await this.writeMemory(proxy, destAddr, data.subarray(0, writeOffset));
289
+ }
290
+ // Overlapping part — safe write using the snapshot
291
+ const overlapDest = new Native.NativePointer(destAddr + BigInt(writeOffset));
292
+ const overlapData = data.subarray(writeOffset, writeOffset + overlapLen);
293
+ written += await this.writeMemorySafeBuffer(proxy, overlapDest, overlapData, snapshot);
294
+ updateSnapshot(romem, overlapData, overlapDest.address);
295
+ // Part after the overlap — plain writeMemory
296
+ const afterOffset = writeOffset + overlapLen;
297
+ if (afterOffset < length) {
298
+ written += await this.writeMemory(proxy, destAddr + BigInt(afterOffset), data.subarray(afterOffset));
299
+ }
300
+ return written;
301
+ }
302
+ // No overlap — standard decomposed memset
303
+ let i = 0;
304
+ while (i < length) {
305
+ const value = data[i];
306
+ let j = i + 1;
307
+ while (j < length && data[j] === value) {
308
+ j++;
309
+ }
310
+ const runLen = j - i;
311
+ const addr = await proxy.call(crt.memset, destAddr + BigInt(i), value, runLen);
312
+ if (addr.address === 0n)
313
+ return i;
314
+ i = j;
315
+ }
316
+ return length;
317
+ }
318
+ /**
319
+ * Writes data from a NativePointer source to the target process memory
320
+ * using hijacked memset calls. Reads the source pointer byte-by-byte into
321
+ * a local buffer first, then delegates to the standard decomposed memset.
322
+ *
323
+ * Does NOT check read-only memory regions — this is intended for writing
324
+ * data we don't already know the contents of.
325
+ *
326
+ * @param thread The captured thread to execute on.
327
+ * @param dest Target address to write to.
328
+ * @param source Source pointer to read from (in our process).
329
+ * @param size Number of bytes to write.
330
+ */
331
+ async writeMemoryWithPointer(proxy, dest, source, size) {
332
+ const destAddr = dest instanceof Native.NativePointer ? dest.address : dest;
333
+ const buf = Native.currentProcess.memory.read(source, size);
334
+ if (buf.length === 0)
335
+ return 0;
336
+ // Standard decomposed memset — no romem check
337
+ let i = 0;
338
+ while (i < buf.length) {
339
+ const value = buf[i];
340
+ let j = i + 1;
341
+ while (j < buf.length && buf[j] === value) {
342
+ j++;
343
+ }
344
+ const runLen = j - i;
345
+ const addr = await proxy.call(crt.memset, destAddr + BigInt(i), value, runLen);
346
+ if (addr.address === 0n)
347
+ return i;
348
+ i = j;
349
+ }
350
+ return buf.length;
351
+ }
352
+ /**
353
+ * Safe write dispatcher: routes to the optimized variant based on `lastDest` type.
354
+ *
355
+ * @param dest Target address to write to.
356
+ * @param source The data to write.
357
+ * @param lastDest Either a snapshot Buffer of the previous state, or a single byte value
358
+ * representing a uniform fill (e.g. 0 means the region is all zeroes).
359
+ */
360
+ async writeMemorySafe(proxy, dest, source, lastDest) {
361
+ if (typeof lastDest === 'number') {
362
+ return this.writeMemorySafeUniform(proxy, dest, source, lastDest);
363
+ }
364
+ return this.writeMemorySafeBuffer(proxy, dest, source, lastDest);
365
+ }
366
+ /**
367
+ * Safe write against a uniform fill value.
368
+ * Skips bytes that already equal `fillByte`.
369
+ */
370
+ async writeMemorySafeUniform(proxy, dest, source, fillByte) {
371
+ const destAddr = dest.address;
372
+ const length = source.length;
373
+ if (length === 0)
374
+ return 0;
375
+ let i = 0;
376
+ while (i < length) {
377
+ while (i < length && source[i] === fillByte)
378
+ i++;
379
+ if (i >= length)
380
+ break;
381
+ const value = source[i];
382
+ let j = i + 1;
383
+ while (j < length && source[j] === value)
384
+ j++;
385
+ const runLen = j - i;
386
+ const addr = await proxy.call(crt.memset, destAddr + BigInt(i), value, runLen);
387
+ if (addr.address === 0n)
388
+ return i;
389
+ i = j;
390
+ }
391
+ return length;
392
+ }
393
+ /**
394
+ * Safe write against a snapshot Buffer.
395
+ * Skips bytes that match the corresponding byte in `last`.
396
+ */
397
+ async writeMemorySafeBuffer(proxy, dest, source, last) {
398
+ const destAddr = dest.address;
399
+ const length = source.length;
400
+ if (length === 0)
401
+ return 0;
402
+ let i = 0;
403
+ while (i < length) {
404
+ while (i < length && source[i] === last[i])
405
+ i++;
406
+ if (i >= length)
407
+ break;
408
+ const value = source[i];
409
+ let j = i + 1;
410
+ while (j < length && source[j] === value)
411
+ j++;
412
+ const runLen = j - i;
413
+ const addr = await proxy.call(crt.memset, destAddr + BigInt(i), value, runLen);
414
+ if (addr.address === 0n)
415
+ return i;
416
+ i = j;
417
+ }
418
+ return length;
419
+ }
420
+ }
421
+ //# sourceMappingURL=nthread.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nthread.js","sourceRoot":"","sources":["../src/nthread.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import * as Native from '@cheatron/native';
2
+ import type { GeneralPurposeRegs } from '../globals.js';
3
+ export declare const STACK_ADD = -8192n;
4
+ /**
5
+ * CapturedThread: A specialized Thread wrapper that manages the low-level state
6
+ * of a captured thread, including context caching, suspend/resume tracking,
7
+ * and register manipulation.
8
+ *
9
+ * It extends Native.Thread. A ProxyThread holds the reference back to this instance.
10
+ */
11
+ export declare class CapturedThread extends Native.Thread {
12
+ /** Count of active suspensions to ensure balanced resume calls on close */
13
+ protected suspendCount: number;
14
+ /** The register context captured immediately before hijacking */
15
+ savedContext: Native.ThreadContext;
16
+ /** The current live or modified context of the thread */
17
+ latestContext: Native.ThreadContext;
18
+ /** Pre-computed RSP value used for call() — set once during inject() */
19
+ callRsp: bigint;
20
+ /** Address of an infinite loop gadget ('jmp .') used to hold the thread */
21
+ sleepAddress: Native.NativePointer;
22
+ /** The register key (e.g., 'Rbx') used for the pushret pivot */
23
+ regKey: GeneralPurposeRegs;
24
+ /**
25
+ * Creates a CapturedThread instance.
26
+ * @param thread Thread object or Thread ID to attach to.
27
+ * @param regKey The register key used for the pushret pivot.
28
+ * @param sleepAddress The sleep gadget address for parking the thread.
29
+ * @param processId Optional process ID for diagnostics and logging.
30
+ */
31
+ constructor(thread: Native.Thread | number, regKey: GeneralPurposeRegs, sleepAddress: Native.NativePointer, processId?: number);
32
+ /** Calculates a new stack pointer offset from the current RSP */
33
+ calcStackBegin(baseRsp?: bigint): bigint;
34
+ /** Gets the value of the pivot register */
35
+ getTargetReg(): Native.UINT64;
36
+ /** Sets the value of the pivot register */
37
+ setTargetReg(reg: Native.UINT64): void;
38
+ /** Helper to get RSP */
39
+ getRSP(): Native.UINT64;
40
+ /** Helper to set RSP */
41
+ setRSP(rsp: Native.UINT64): void;
42
+ /** Helper to get RIP */
43
+ getRIP(): Native.UINT64;
44
+ /** Helper to set RIP */
45
+ setRIP(rip: Native.UINT64): void;
46
+ /** Returns the last fetched/modified context cache */
47
+ getContext(): Native.ThreadContext;
48
+ /** Updates the context cache (does not apply to hardware yet) */
49
+ setContext(ctx: Native.ThreadContext): void;
50
+ /** Explicitly fetches context from the hardware into the cache */
51
+ fetchContext(): void;
52
+ /** Explicitly applies the cached context to the hardware */
53
+ applyContext(): void;
54
+ /** Suspends the thread and increments internal counter */
55
+ suspend(): number;
56
+ /** Resumes the thread and decrements internal counter */
57
+ resume(): number;
58
+ /** Restores the saved context and resumes the thread (without closing the handle) */
59
+ release(): void;
60
+ /** Closes the handle and ensures the thread is resumed if it was suspended by us */
61
+ close(): void;
62
+ /**
63
+ * Custom wait that polls the thread's RIP to see if it landed at the sleepAddress.
64
+ * If the thread dies or crashes during wait, it returns FAILED.
65
+ */
66
+ wait(timeoutMs?: number): Promise<Native.WaitReturn>;
67
+ }
68
+ //# sourceMappingURL=captured-thread.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"captured-thread.d.ts","sourceRoot":"","sources":["../../src/thread/captured-thread.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAC3C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,eAAO,MAAM,SAAS,SAAS,CAAC;AAEhC;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,MAAM,CAAC,MAAM;IAC/C,2EAA2E;IAC3E,SAAS,CAAC,YAAY,SAAK;IAE3B,iEAAiE;IAC1D,YAAY,EAAG,MAAM,CAAC,aAAa,CAAC;IAE3C,yDAAyD;IAClD,aAAa,EAAG,MAAM,CAAC,aAAa,CAAC;IAE5C,wEAAwE;IACjE,OAAO,EAAE,MAAM,CAAM;IAE5B,2EAA2E;IACpE,YAAY,EAAE,MAAM,CAAC,aAAa,CAAC;IAE1C,gEAAgE;IACzD,MAAM,EAAE,kBAAkB,CAAC;IAElC;;;;;;OAMG;gBAED,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,EAC9B,MAAM,EAAE,kBAAkB,EAC1B,YAAY,EAAE,MAAM,CAAC,aAAa,EAClC,SAAS,CAAC,EAAE,MAAM;IAkBpB,iEAAiE;IACjE,cAAc,CAAC,OAAO,GAAE,MAAsC,GAAG,MAAM;IAIvE,2CAA2C;IAC3C,YAAY,IAAI,MAAM,CAAC,MAAM;IAI7B,2CAA2C;IAC3C,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI;IAMtC,wBAAwB;IACxB,MAAM,IAAI,MAAM,CAAC,MAAM;IAIvB,wBAAwB;IACxB,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI;IAMhC,wBAAwB;IACxB,MAAM,IAAI,MAAM,CAAC,MAAM;IAIvB,wBAAwB;IACxB,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI;IAMhC,sDAAsD;IAC7C,UAAU,IAAI,MAAM,CAAC,aAAa;IAO3C,iEAAiE;IACxD,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,aAAa,GAAG,IAAI;IAIpD,kEAAkE;IAClE,YAAY,IAAI,IAAI;IAIpB,4DAA4D;IAC5D,YAAY,IAAI,IAAI;IAIpB,0DAA0D;IACjD,OAAO,IAAI,MAAM;IAQ1B,yDAAyD;IAChD,MAAM,IAAI,MAAM;IAQzB,qFAAqF;IACrF,OAAO,IAAI,IAAI;IAOf,oFAAoF;IAC3E,KAAK;IAiBd;;;OAGG;IACY,IAAI,CACjB,SAAS,GAAE,MAAwB,GAClC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC;CAwB9B"}