exoproc 0.6.8 → 0.6.9

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/README.md CHANGED
@@ -4,13 +4,13 @@
4
4
  > One unified CLI and Model Context Protocol (MCP) server for thread hijacking, function detours, live memory manipulation, and C-to-shellcode compilation.
5
5
 
6
6
  [![npm version](https://img.shields.io/npm/v/exoproc?style=flat-square&color=cb3837)](https://www.npmjs.com/package/exoproc)
7
- [![MCP Catalog](https://img.shields.io/badge/MCP-22_tools-5c4ee5?style=flat-square)](https://github.com/woldann/exoproc)
7
+ [![MCP Catalog](https://img.shields.io/badge/MCP-22_tools-5c4ee5?style=flat-square)](https://github.com/aksoyserkan/exoproc)
8
8
  [![Bun Requirements](https://img.shields.io/badge/Bun-%3E%3D1.4.4-339933?style=flat-square&logo=bun&logoColor=white)](https://bun.sh)
9
9
  [![License: MIT](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
10
10
 
11
11
  ---
12
12
 
13
- ## ⚡ Instant Setup for AI Agents
13
+ ## Instant Setup for AI Agents
14
14
 
15
15
  Exoproc connects your AI coding agents (**Claude Code, Cursor, Windsurf, Claude Desktop, Antigravity, Cline, OpenCode, Zed**) directly to live Windows x64 processes.
16
16
 
@@ -32,7 +32,7 @@ Restart your agent, and all 22 MCP tools will be immediately available.
32
32
 
33
33
  ---
34
34
 
35
- ## 💻 CLI Commands
35
+ ## CLI Commands
36
36
 
37
37
  Exoproc provides a unified terminal command-line tool:
38
38
 
@@ -57,7 +57,7 @@ exoproc run script.ts # Execute standalone automation script
57
57
 
58
58
  ---
59
59
 
60
- ## 🛠️ MCP Tools (22 Tools)
60
+ ## MCP Tools (22 Tools)
61
61
 
62
62
  Exoproc exposes 22 high-performance tools over standard Model Context Protocol (stdio):
63
63
 
@@ -69,7 +69,7 @@ Exoproc exposes 22 high-performance tools over standard Model Context Protocol (
69
69
 
70
70
  ---
71
71
 
72
- ## 🤖 Supported Agents
72
+ ## Supported Agents
73
73
 
74
74
  - **Claude Code:** `~/.claude.json` + `~/.claude/skills/exoproc/`
75
75
  - **Cursor:** `~/.cursor/mcp.json` + `~/.cursor/rules/exoproc.mdc`
@@ -82,6 +82,6 @@ Exoproc exposes 22 high-performance tools over standard Model Context Protocol (
82
82
 
83
83
  ---
84
84
 
85
- ## 📜 License
85
+ ## License
86
86
 
87
87
  [MIT](LICENSE) © Serkan
package/dist/cli.js CHANGED
@@ -95445,7 +95445,7 @@ var init_dist8 = __esm(() => {
95445
95445
  getSessionMetadata() {
95446
95446
  return { ...this._sessionMetadata };
95447
95447
  }
95448
- toJSON() {
95448
+ toJSON(options) {
95449
95449
  const chainLayers = [];
95450
95450
  const visited = new Set;
95451
95451
  const traverse = (start) => {
@@ -95469,12 +95469,13 @@ var init_dist8 = __esm(() => {
95469
95469
  if (directNt && !visited.has(directNt)) {
95470
95470
  traverse(directNt);
95471
95471
  }
95472
+ const shouldHibernate = options?.hibernate ?? false;
95472
95473
  const pipeline = [];
95473
95474
  for (let i = chainLayers.length - 1;i >= 0; i--) {
95474
95475
  const layer = chainLayers[i];
95475
95476
  const type = layer.constructor?.name || "MiddlewareAccessor";
95476
95477
  let state = undefined;
95477
- if (typeof layer.hibernate === "function") {
95478
+ if (shouldHibernate && typeof layer.hibernate === "function") {
95478
95479
  state = layer.hibernate();
95479
95480
  } else if (typeof layer.saveState === "function") {
95480
95481
  state = layer.saveState();
@@ -95500,7 +95501,7 @@ var init_dist8 = __esm(() => {
95500
95501
  throw new Error("No target filePath specified for saveToFileSync() and no _sessionFilePath found");
95501
95502
  }
95502
95503
  const absPath = resolve3(targetPath);
95503
- const session = this.toJSON();
95504
+ const session = this.toJSON({ hibernate: true });
95504
95505
  withFileLockSync(absPath, () => {
95505
95506
  const dir = dirname6(absPath);
95506
95507
  if (!existsSync22(dir)) {
@@ -95519,7 +95520,7 @@ var init_dist8 = __esm(() => {
95519
95520
  throw new Error("No target filePath specified for saveToFile() and no _sessionFilePath found");
95520
95521
  }
95521
95522
  const absPath = resolve3(targetPath);
95522
- const session = this.toJSON();
95523
+ const session = this.toJSON({ hibernate: true });
95523
95524
  await withFileLock(absPath, async () => {
95524
95525
  const dir = dirname6(absPath);
95525
95526
  if (!existsSync22(dir)) {
@@ -98159,8 +98160,6 @@ var init_dist10 = __esm(() => {
98159
98160
  this.onceSuspendThread();
98160
98161
  this.fetchContext();
98161
98162
  this.savedContext = this.ctx.clone();
98162
- const originalRip = this.savedContext.Rip;
98163
- const originalJumpReg = this.savedContext[stubs.jumpRegKey];
98164
98163
  if (this.options.isParked) {
98165
98164
  nthreadLog.debug(`Thread ${this.tid} is already parked at 0x${this.savedContext.Rip.toString(16)}. Skipping jumpStub redirection.`);
98166
98165
  if (!this.isCallRspSet()) {
@@ -98180,9 +98179,6 @@ var init_dist10 = __esm(() => {
98180
98179
  nthreadLog.debug(`Parking thread ${this.tid} at spinStub 0x${stubs.spinStub.address.toString(16)}...`);
98181
98180
  await this.root.call(stubs.jumpStub);
98182
98181
  this.fetchContext();
98183
- this.savedContext = this.ctx.clone();
98184
- this.savedContext[stubs.jumpRegKey] = originalJumpReg;
98185
- this.savedContext.Rip = originalRip;
98186
98182
  if (!this.isCallRspSet()) {
98187
98183
  const baseRsp = BigInt(this.getContext().Rsp);
98188
98184
  const stackBegin = this.calcStackBegin();
@@ -98247,8 +98243,6 @@ var init_dist10 = __esm(() => {
98247
98243
  this.onceSuspendThread();
98248
98244
  this.fetchContext();
98249
98245
  this.savedContext = this.ctx.clone();
98250
- const originalRip = this.savedContext.Rip;
98251
- const originalJumpReg = this.savedContext[stubs.jumpRegKey];
98252
98246
  if (this.options.isParked) {
98253
98247
  if (!this.isCallRspSet()) {
98254
98248
  const stackBegin = this.calcStackBegin();
@@ -98267,9 +98261,6 @@ var init_dist10 = __esm(() => {
98267
98261
  nthreadLog.debug(`Parking thread ${this.tid} at spinStub 0x${stubs.spinStub.address.toString(16)}...`);
98268
98262
  this.root.callSync(stubs.jumpStub);
98269
98263
  this.fetchContext();
98270
- this.savedContext = this.ctx.clone();
98271
- this.savedContext[stubs.jumpRegKey] = originalJumpReg;
98272
- this.savedContext.Rip = originalRip;
98273
98264
  if (!this.isCallRspSet()) {
98274
98265
  const baseRsp = BigInt(this.getContext().Rsp);
98275
98266
  const stackBegin = this.calcStackBegin();
@@ -98303,11 +98294,11 @@ var init_dist10 = __esm(() => {
98303
98294
  this.nativeThread = undefined;
98304
98295
  }
98305
98296
  }
98306
- hibernate() {
98297
+ saveState() {
98307
98298
  if (!this.nativeThread) {
98308
98299
  throw new Error("NThread is not initialized or already closed");
98309
98300
  }
98310
- const state = {
98301
+ return {
98311
98302
  threadId: this.threadId,
98312
98303
  callRsp: `0x${this.callRsp.toString(16)}`,
98313
98304
  savedContext: this.savedContext.toBase64(),
@@ -98321,6 +98312,9 @@ var init_dist10 = __esm(() => {
98321
98312
  addRsp28RetStub: `0x${this.stubs.addRsp28RetStub.address.toString(16)}`
98322
98313
  }
98323
98314
  };
98315
+ }
98316
+ hibernate() {
98317
+ const state = this.saveState();
98324
98318
  this.nativeThread.close();
98325
98319
  this.nativeThread = undefined;
98326
98320
  this.markUninitialized();
@@ -111731,6 +111725,12 @@ var init_dist17 = __esm(() => {
111731
111725
  }
111732
111726
  }
111733
111727
  onInitSync() {}
111728
+ onDeinitSync() {
111729
+ const t = this.getTarget();
111730
+ if (t !== this && t !== this.root && isInittableAccessor(t)) {
111731
+ t.deinitSync();
111732
+ }
111733
+ }
111734
111734
  };
111735
111735
  RacingHostAccessor = class RacingHostAccessor extends RedirectorHostAccessor {
111736
111736
  racers = [];
@@ -111780,6 +111780,12 @@ var init_dist17 = __esm(() => {
111780
111780
  this.initNextSync();
111781
111781
  this.target = this.root;
111782
111782
  }
111783
+ async onDeinit() {
111784
+ this.target = this;
111785
+ }
111786
+ onDeinitSync() {
111787
+ this.target = this;
111788
+ }
111783
111789
  };
111784
111790
  CallRedirectorAccessor = class CallRedirectorAccessor extends MiddlewareAccessor {
111785
111791
  async alloc(size, address = null, protection = MemoryProtection.READWRITE, allocationType = MemoryState.COMMIT | MemoryState.RESERVE) {
@@ -113102,30 +113108,26 @@ var init_dist17 = __esm(() => {
113102
113108
  onInitSync() {
113103
113109
  this.bootstrapRoot.initSync();
113104
113110
  }
113105
- async onDeinit() {
113106
- try {
113107
- await this.bootstrapRoot.deinit();
113108
- } catch {}
113111
+ async deinit() {
113109
113112
  try {
113110
- const nt = this.nthread;
113111
- if (nt && typeof nt.deinit === "function") {
113112
- await nt.deinit();
113113
- }
113114
- } catch {}
113113
+ await super.deinit();
113114
+ } finally {
113115
+ try {
113116
+ await this.bootstrapRoot.deinit();
113117
+ } catch {}
113118
+ }
113115
113119
  }
113116
- onDeinitSync() {
113117
- try {
113118
- this.bootstrapRoot.deinitSync();
113119
- } catch {}
113120
+ deinitSync() {
113120
113121
  try {
113121
- const nt = this.nthread;
113122
- if (nt && typeof nt.deinitSync === "function") {
113123
- nt.deinitSync();
113124
- }
113125
- } catch {}
113122
+ super.deinitSync();
113123
+ } finally {
113124
+ try {
113125
+ this.bootstrapRoot.deinitSync();
113126
+ } catch {}
113127
+ }
113126
113128
  }
113127
- toJSON() {
113128
- const session = super.toJSON();
113129
+ toJSON(options) {
113130
+ const session = super.toJSON(options);
113129
113131
  session.accessorType = "IndirectNThreadHostAccessor";
113130
113132
  try {
113131
113133
  const nt = this.nthread;
@@ -113363,19 +113365,6 @@ async function closeAccessor(options) {
113363
113365
  } catch (err) {
113364
113366
  console.error("[closeAccessor] s.accessor.deinit error:", err);
113365
113367
  }
113366
- try {
113367
- const nt = s.accessor?.nthread;
113368
- if (nt && typeof nt.deinit === "function") {
113369
- await nt.deinit();
113370
- }
113371
- } catch (err) {
113372
- console.error("[closeAccessor] nt.deinit error:", err);
113373
- }
113374
- try {
113375
- s.accessor.close();
113376
- } catch (err) {
113377
- console.error("[closeAccessor] s.accessor.close error:", err);
113378
- }
113379
113368
  try {
113380
113369
  if (existsSync14(s.sessionFile)) {
113381
113370
  unlinkSync5(s.sessionFile);
@@ -121623,8 +121612,8 @@ var package_default = {
121623
121612
  publishConfig: {
121624
121613
  access: "public"
121625
121614
  },
121626
- mcpName: "io.github.woldann/exoproc",
121627
- version: "0.6.8",
121615
+ mcpName: "io.github.aksoyserkan/exoproc",
121616
+ version: "0.6.9",
121628
121617
  description: "Unified CLI and Model Context Protocol (MCP) server for native Windows x64 reverse engineering, thread hijacking, function redirection, memory inspection, and runtime instrumentation.",
121629
121618
  main: "./dist/index.js",
121630
121619
  bin: {
package/dist/index.js CHANGED
@@ -94968,7 +94968,7 @@ var init_dist8 = __esm(() => {
94968
94968
  getSessionMetadata() {
94969
94969
  return { ...this._sessionMetadata };
94970
94970
  }
94971
- toJSON() {
94971
+ toJSON(options) {
94972
94972
  const chainLayers = [];
94973
94973
  const visited = new Set;
94974
94974
  const traverse = (start) => {
@@ -94992,12 +94992,13 @@ var init_dist8 = __esm(() => {
94992
94992
  if (directNt && !visited.has(directNt)) {
94993
94993
  traverse(directNt);
94994
94994
  }
94995
+ const shouldHibernate = options?.hibernate ?? false;
94995
94996
  const pipeline = [];
94996
94997
  for (let i = chainLayers.length - 1;i >= 0; i--) {
94997
94998
  const layer = chainLayers[i];
94998
94999
  const type = layer.constructor?.name || "MiddlewareAccessor";
94999
95000
  let state = undefined;
95000
- if (typeof layer.hibernate === "function") {
95001
+ if (shouldHibernate && typeof layer.hibernate === "function") {
95001
95002
  state = layer.hibernate();
95002
95003
  } else if (typeof layer.saveState === "function") {
95003
95004
  state = layer.saveState();
@@ -95023,7 +95024,7 @@ var init_dist8 = __esm(() => {
95023
95024
  throw new Error("No target filePath specified for saveToFileSync() and no _sessionFilePath found");
95024
95025
  }
95025
95026
  const absPath = resolve3(targetPath);
95026
- const session = this.toJSON();
95027
+ const session = this.toJSON({ hibernate: true });
95027
95028
  withFileLockSync(absPath, () => {
95028
95029
  const dir = dirname6(absPath);
95029
95030
  if (!existsSync22(dir)) {
@@ -95042,7 +95043,7 @@ var init_dist8 = __esm(() => {
95042
95043
  throw new Error("No target filePath specified for saveToFile() and no _sessionFilePath found");
95043
95044
  }
95044
95045
  const absPath = resolve3(targetPath);
95045
- const session = this.toJSON();
95046
+ const session = this.toJSON({ hibernate: true });
95046
95047
  await withFileLock(absPath, async () => {
95047
95048
  const dir = dirname6(absPath);
95048
95049
  if (!existsSync22(dir)) {
@@ -97684,8 +97685,6 @@ var init_dist10 = __esm(() => {
97684
97685
  this.onceSuspendThread();
97685
97686
  this.fetchContext();
97686
97687
  this.savedContext = this.ctx.clone();
97687
- const originalRip = this.savedContext.Rip;
97688
- const originalJumpReg = this.savedContext[stubs.jumpRegKey];
97689
97688
  if (this.options.isParked) {
97690
97689
  nthreadLog.debug(`Thread ${this.tid} is already parked at 0x${this.savedContext.Rip.toString(16)}. Skipping jumpStub redirection.`);
97691
97690
  if (!this.isCallRspSet()) {
@@ -97705,9 +97704,6 @@ var init_dist10 = __esm(() => {
97705
97704
  nthreadLog.debug(`Parking thread ${this.tid} at spinStub 0x${stubs.spinStub.address.toString(16)}...`);
97706
97705
  await this.root.call(stubs.jumpStub);
97707
97706
  this.fetchContext();
97708
- this.savedContext = this.ctx.clone();
97709
- this.savedContext[stubs.jumpRegKey] = originalJumpReg;
97710
- this.savedContext.Rip = originalRip;
97711
97707
  if (!this.isCallRspSet()) {
97712
97708
  const baseRsp = BigInt(this.getContext().Rsp);
97713
97709
  const stackBegin = this.calcStackBegin();
@@ -97772,8 +97768,6 @@ var init_dist10 = __esm(() => {
97772
97768
  this.onceSuspendThread();
97773
97769
  this.fetchContext();
97774
97770
  this.savedContext = this.ctx.clone();
97775
- const originalRip = this.savedContext.Rip;
97776
- const originalJumpReg = this.savedContext[stubs.jumpRegKey];
97777
97771
  if (this.options.isParked) {
97778
97772
  if (!this.isCallRspSet()) {
97779
97773
  const stackBegin = this.calcStackBegin();
@@ -97792,9 +97786,6 @@ var init_dist10 = __esm(() => {
97792
97786
  nthreadLog.debug(`Parking thread ${this.tid} at spinStub 0x${stubs.spinStub.address.toString(16)}...`);
97793
97787
  this.root.callSync(stubs.jumpStub);
97794
97788
  this.fetchContext();
97795
- this.savedContext = this.ctx.clone();
97796
- this.savedContext[stubs.jumpRegKey] = originalJumpReg;
97797
- this.savedContext.Rip = originalRip;
97798
97789
  if (!this.isCallRspSet()) {
97799
97790
  const baseRsp = BigInt(this.getContext().Rsp);
97800
97791
  const stackBegin = this.calcStackBegin();
@@ -97828,11 +97819,11 @@ var init_dist10 = __esm(() => {
97828
97819
  this.nativeThread = undefined;
97829
97820
  }
97830
97821
  }
97831
- hibernate() {
97822
+ saveState() {
97832
97823
  if (!this.nativeThread) {
97833
97824
  throw new Error("NThread is not initialized or already closed");
97834
97825
  }
97835
- const state = {
97826
+ return {
97836
97827
  threadId: this.threadId,
97837
97828
  callRsp: `0x${this.callRsp.toString(16)}`,
97838
97829
  savedContext: this.savedContext.toBase64(),
@@ -97846,6 +97837,9 @@ var init_dist10 = __esm(() => {
97846
97837
  addRsp28RetStub: `0x${this.stubs.addRsp28RetStub.address.toString(16)}`
97847
97838
  }
97848
97839
  };
97840
+ }
97841
+ hibernate() {
97842
+ const state = this.saveState();
97849
97843
  this.nativeThread.close();
97850
97844
  this.nativeThread = undefined;
97851
97845
  this.markUninitialized();
@@ -111853,6 +111847,12 @@ var init_dist17 = __esm(() => {
111853
111847
  }
111854
111848
  }
111855
111849
  onInitSync() {}
111850
+ onDeinitSync() {
111851
+ const t = this.getTarget();
111852
+ if (t !== this && t !== this.root && isInittableAccessor(t)) {
111853
+ t.deinitSync();
111854
+ }
111855
+ }
111856
111856
  };
111857
111857
  RacingHostAccessor = class RacingHostAccessor extends RedirectorHostAccessor {
111858
111858
  racers = [];
@@ -111902,6 +111902,12 @@ var init_dist17 = __esm(() => {
111902
111902
  this.initNextSync();
111903
111903
  this.target = this.root;
111904
111904
  }
111905
+ async onDeinit() {
111906
+ this.target = this;
111907
+ }
111908
+ onDeinitSync() {
111909
+ this.target = this;
111910
+ }
111905
111911
  };
111906
111912
  CallRedirectorAccessor = class CallRedirectorAccessor extends MiddlewareAccessor {
111907
111913
  async alloc(size, address = null, protection = MemoryProtection.READWRITE, allocationType = MemoryState.COMMIT | MemoryState.RESERVE) {
@@ -113224,30 +113230,26 @@ var init_dist17 = __esm(() => {
113224
113230
  onInitSync() {
113225
113231
  this.bootstrapRoot.initSync();
113226
113232
  }
113227
- async onDeinit() {
113228
- try {
113229
- await this.bootstrapRoot.deinit();
113230
- } catch {}
113233
+ async deinit() {
113231
113234
  try {
113232
- const nt = this.nthread;
113233
- if (nt && typeof nt.deinit === "function") {
113234
- await nt.deinit();
113235
- }
113236
- } catch {}
113235
+ await super.deinit();
113236
+ } finally {
113237
+ try {
113238
+ await this.bootstrapRoot.deinit();
113239
+ } catch {}
113240
+ }
113237
113241
  }
113238
- onDeinitSync() {
113239
- try {
113240
- this.bootstrapRoot.deinitSync();
113241
- } catch {}
113242
+ deinitSync() {
113242
113243
  try {
113243
- const nt = this.nthread;
113244
- if (nt && typeof nt.deinitSync === "function") {
113245
- nt.deinitSync();
113246
- }
113247
- } catch {}
113244
+ super.deinitSync();
113245
+ } finally {
113246
+ try {
113247
+ this.bootstrapRoot.deinitSync();
113248
+ } catch {}
113249
+ }
113248
113250
  }
113249
- toJSON() {
113250
- const session = super.toJSON();
113251
+ toJSON(options) {
113252
+ const session = super.toJSON(options);
113251
113253
  session.accessorType = "IndirectNThreadHostAccessor";
113252
113254
  try {
113253
113255
  const nt = this.nthread;
@@ -113496,19 +113498,6 @@ async function closeAccessor(options) {
113496
113498
  } catch (err) {
113497
113499
  console.error("[closeAccessor] s.accessor.deinit error:", err);
113498
113500
  }
113499
- try {
113500
- const nt = s.accessor?.nthread;
113501
- if (nt && typeof nt.deinit === "function") {
113502
- await nt.deinit();
113503
- }
113504
- } catch (err) {
113505
- console.error("[closeAccessor] nt.deinit error:", err);
113506
- }
113507
- try {
113508
- s.accessor.close();
113509
- } catch (err) {
113510
- console.error("[closeAccessor] s.accessor.close error:", err);
113511
- }
113512
113501
  try {
113513
113502
  if (existsSync14(s.sessionFile)) {
113514
113503
  unlinkSync5(s.sessionFile);
@@ -136944,7 +136933,7 @@ class HostAccessor2 extends InittableMiddlewareAccessor2 {
136944
136933
  getSessionMetadata() {
136945
136934
  return { ...this._sessionMetadata };
136946
136935
  }
136947
- toJSON() {
136936
+ toJSON(options) {
136948
136937
  const chainLayers = [];
136949
136938
  const visited = new Set;
136950
136939
  const traverse = (start) => {
@@ -136968,12 +136957,13 @@ class HostAccessor2 extends InittableMiddlewareAccessor2 {
136968
136957
  if (directNt && !visited.has(directNt)) {
136969
136958
  traverse(directNt);
136970
136959
  }
136960
+ const shouldHibernate = options?.hibernate ?? false;
136971
136961
  const pipeline = [];
136972
136962
  for (let i = chainLayers.length - 1;i >= 0; i--) {
136973
136963
  const layer = chainLayers[i];
136974
136964
  const type = layer.constructor?.name || "MiddlewareAccessor";
136975
136965
  let state = undefined;
136976
- if (typeof layer.hibernate === "function") {
136966
+ if (shouldHibernate && typeof layer.hibernate === "function") {
136977
136967
  state = layer.hibernate();
136978
136968
  } else if (typeof layer.saveState === "function") {
136979
136969
  state = layer.saveState();
@@ -136999,7 +136989,7 @@ class HostAccessor2 extends InittableMiddlewareAccessor2 {
136999
136989
  throw new Error("No target filePath specified for saveToFileSync() and no _sessionFilePath found");
137000
136990
  }
137001
136991
  const absPath = resolve10(targetPath);
137002
- const session = this.toJSON();
136992
+ const session = this.toJSON({ hibernate: true });
137003
136993
  withFileLockSync2(absPath, () => {
137004
136994
  const dir = dirname10(absPath);
137005
136995
  if (!existsSync19(dir)) {
@@ -137018,7 +137008,7 @@ class HostAccessor2 extends InittableMiddlewareAccessor2 {
137018
137008
  throw new Error("No target filePath specified for saveToFile() and no _sessionFilePath found");
137019
137009
  }
137020
137010
  const absPath = resolve10(targetPath);
137021
- const session = this.toJSON();
137011
+ const session = this.toJSON({ hibernate: true });
137022
137012
  await withFileLock2(absPath, async () => {
137023
137013
  const dir = dirname10(absPath);
137024
137014
  if (!existsSync19(dir)) {
@@ -139394,8 +139384,6 @@ class NThread2 extends InittableMiddlewareAccessor {
139394
139384
  this.onceSuspendThread();
139395
139385
  this.fetchContext();
139396
139386
  this.savedContext = this.ctx.clone();
139397
- const originalRip = this.savedContext.Rip;
139398
- const originalJumpReg = this.savedContext[stubs.jumpRegKey];
139399
139387
  if (this.options.isParked) {
139400
139388
  nthreadLog2.debug(`Thread ${this.tid} is already parked at 0x${this.savedContext.Rip.toString(16)}. Skipping jumpStub redirection.`);
139401
139389
  if (!this.isCallRspSet()) {
@@ -139415,9 +139403,6 @@ class NThread2 extends InittableMiddlewareAccessor {
139415
139403
  nthreadLog2.debug(`Parking thread ${this.tid} at spinStub 0x${stubs.spinStub.address.toString(16)}...`);
139416
139404
  await this.root.call(stubs.jumpStub);
139417
139405
  this.fetchContext();
139418
- this.savedContext = this.ctx.clone();
139419
- this.savedContext[stubs.jumpRegKey] = originalJumpReg;
139420
- this.savedContext.Rip = originalRip;
139421
139406
  if (!this.isCallRspSet()) {
139422
139407
  const baseRsp = BigInt(this.getContext().Rsp);
139423
139408
  const stackBegin = this.calcStackBegin();
@@ -139482,8 +139467,6 @@ class NThread2 extends InittableMiddlewareAccessor {
139482
139467
  this.onceSuspendThread();
139483
139468
  this.fetchContext();
139484
139469
  this.savedContext = this.ctx.clone();
139485
- const originalRip = this.savedContext.Rip;
139486
- const originalJumpReg = this.savedContext[stubs.jumpRegKey];
139487
139470
  if (this.options.isParked) {
139488
139471
  if (!this.isCallRspSet()) {
139489
139472
  const stackBegin = this.calcStackBegin();
@@ -139502,9 +139485,6 @@ class NThread2 extends InittableMiddlewareAccessor {
139502
139485
  nthreadLog2.debug(`Parking thread ${this.tid} at spinStub 0x${stubs.spinStub.address.toString(16)}...`);
139503
139486
  this.root.callSync(stubs.jumpStub);
139504
139487
  this.fetchContext();
139505
- this.savedContext = this.ctx.clone();
139506
- this.savedContext[stubs.jumpRegKey] = originalJumpReg;
139507
- this.savedContext.Rip = originalRip;
139508
139488
  if (!this.isCallRspSet()) {
139509
139489
  const baseRsp = BigInt(this.getContext().Rsp);
139510
139490
  const stackBegin = this.calcStackBegin();
@@ -139538,11 +139518,11 @@ class NThread2 extends InittableMiddlewareAccessor {
139538
139518
  this.nativeThread = undefined;
139539
139519
  }
139540
139520
  }
139541
- hibernate() {
139521
+ saveState() {
139542
139522
  if (!this.nativeThread) {
139543
139523
  throw new Error("NThread is not initialized or already closed");
139544
139524
  }
139545
- const state = {
139525
+ return {
139546
139526
  threadId: this.threadId,
139547
139527
  callRsp: `0x${this.callRsp.toString(16)}`,
139548
139528
  savedContext: this.savedContext.toBase64(),
@@ -139556,6 +139536,9 @@ class NThread2 extends InittableMiddlewareAccessor {
139556
139536
  addRsp28RetStub: `0x${this.stubs.addRsp28RetStub.address.toString(16)}`
139557
139537
  }
139558
139538
  };
139539
+ }
139540
+ hibernate() {
139541
+ const state = this.saveState();
139559
139542
  this.nativeThread.close();
139560
139543
  this.nativeThread = undefined;
139561
139544
  this.markUninitialized();
@@ -152025,6 +152008,12 @@ class RedirectorHostAccessor2 extends HostAccessor {
152025
152008
  }
152026
152009
  }
152027
152010
  onInitSync() {}
152011
+ onDeinitSync() {
152012
+ const t = this.getTarget();
152013
+ if (t !== this && t !== this.root && isInittableAccessor(t)) {
152014
+ t.deinitSync();
152015
+ }
152016
+ }
152028
152017
  }
152029
152018
 
152030
152019
  class RacingHostAccessor2 extends RedirectorHostAccessor2 {
@@ -152076,6 +152065,12 @@ class BootstrapHostAccessor2 extends RedirectorHostAccessor2 {
152076
152065
  this.initNextSync();
152077
152066
  this.target = this.root;
152078
152067
  }
152068
+ async onDeinit() {
152069
+ this.target = this;
152070
+ }
152071
+ onDeinitSync() {
152072
+ this.target = this;
152073
+ }
152079
152074
  }
152080
152075
 
152081
152076
  class CallRedirectorAccessor2 extends MiddlewareAccessor {
@@ -153618,30 +153613,26 @@ class IndirectNThreadHostAccessor2 extends HostAccessor {
153618
153613
  onInitSync() {
153619
153614
  this.bootstrapRoot.initSync();
153620
153615
  }
153621
- async onDeinit() {
153622
- try {
153623
- await this.bootstrapRoot.deinit();
153624
- } catch {}
153616
+ async deinit() {
153625
153617
  try {
153626
- const nt = this.nthread;
153627
- if (nt && typeof nt.deinit === "function") {
153628
- await nt.deinit();
153629
- }
153630
- } catch {}
153618
+ await super.deinit();
153619
+ } finally {
153620
+ try {
153621
+ await this.bootstrapRoot.deinit();
153622
+ } catch {}
153623
+ }
153631
153624
  }
153632
- onDeinitSync() {
153633
- try {
153634
- this.bootstrapRoot.deinitSync();
153635
- } catch {}
153625
+ deinitSync() {
153636
153626
  try {
153637
- const nt = this.nthread;
153638
- if (nt && typeof nt.deinitSync === "function") {
153639
- nt.deinitSync();
153640
- }
153641
- } catch {}
153627
+ super.deinitSync();
153628
+ } finally {
153629
+ try {
153630
+ this.bootstrapRoot.deinitSync();
153631
+ } catch {}
153632
+ }
153642
153633
  }
153643
- toJSON() {
153644
- const session = super.toJSON();
153634
+ toJSON(options) {
153635
+ const session = super.toJSON(options);
153645
153636
  session.accessorType = "IndirectNThreadHostAccessor";
153646
153637
  try {
153647
153638
  const nt = this.nthread;
package/package.json CHANGED
@@ -3,8 +3,8 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "mcpName": "io.github.woldann/exoproc",
7
- "version": "0.6.8",
6
+ "mcpName": "io.github.aksoyserkan/exoproc",
7
+ "version": "0.6.9",
8
8
  "description": "Unified CLI and Model Context Protocol (MCP) server for native Windows x64 reverse engineering, thread hijacking, function redirection, memory inspection, and runtime instrumentation.",
9
9
  "main": "./dist/index.js",
10
10
  "bin": {