deepadb 1.0.6 → 1.0.7
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 +27 -15
- package/build/bridge/local-bridge.d.ts +40 -1
- package/build/bridge/local-bridge.d.ts.map +1 -1
- package/build/bridge/local-bridge.js +155 -5
- package/build/bridge/local-bridge.js.map +1 -1
- package/build/index.js +2 -1
- package/build/index.js.map +1 -1
- package/build/middleware/auth.d.ts +10 -0
- package/build/middleware/auth.d.ts.map +1 -1
- package/build/middleware/auth.js +48 -0
- package/build/middleware/auth.js.map +1 -1
- package/build/server.d.ts.map +1 -1
- package/build/server.js +3 -1
- package/build/server.js.map +1 -1
- package/build/tools/at-commands.d.ts.map +1 -1
- package/build/tools/at-commands.js +192 -0
- package/build/tools/at-commands.js.map +1 -1
- package/build/tools/firmware-analysis.d.ts.map +1 -1
- package/build/tools/firmware-analysis.js +24 -0
- package/build/tools/firmware-analysis.js.map +1 -1
- package/build/tools/multi-device.d.ts.map +1 -1
- package/build/tools/multi-device.js +186 -0
- package/build/tools/multi-device.js.map +1 -1
- package/build/tools/qemu.d.ts.map +1 -1
- package/build/tools/qemu.js +246 -2
- package/build/tools/qemu.js.map +1 -1
- package/build/tools/wireless-firmware.d.ts +16 -0
- package/build/tools/wireless-firmware.d.ts.map +1 -0
- package/build/tools/wireless-firmware.js +566 -0
- package/build/tools/wireless-firmware.js.map +1 -0
- package/package.json +3 -3
|
@@ -134,5 +134,191 @@ export function registerMultiDeviceTools(ctx) {
|
|
|
134
134
|
return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
|
|
135
135
|
}
|
|
136
136
|
});
|
|
137
|
+
/**
|
|
138
|
+
* Predefined comparative test profiles.
|
|
139
|
+
* Each profile is a set of shell commands with labels, grouped by category.
|
|
140
|
+
* Commands must be safe, read-only operations suitable for automated execution.
|
|
141
|
+
*/
|
|
142
|
+
const TEST_PROFILES = {
|
|
143
|
+
firmware: {
|
|
144
|
+
description: "Compare firmware components across devices",
|
|
145
|
+
checks: [
|
|
146
|
+
{ label: "Baseband version", command: "getprop gsm.version.baseband" },
|
|
147
|
+
{ label: "Bootloader", command: "getprop ro.bootloader" },
|
|
148
|
+
{ label: "Kernel version", command: "uname -r" },
|
|
149
|
+
{ label: "Security patch", command: "getprop ro.build.version.security_patch" },
|
|
150
|
+
{ label: "Android version", command: "getprop ro.build.version.release" },
|
|
151
|
+
{ label: "Build fingerprint", command: "getprop ro.build.fingerprint" },
|
|
152
|
+
{ label: "Build ID", command: "getprop ro.build.id" },
|
|
153
|
+
{ label: "Vendor security patch", command: "getprop ro.vendor.build.security_patch" },
|
|
154
|
+
],
|
|
155
|
+
},
|
|
156
|
+
security: {
|
|
157
|
+
description: "Compare security configuration across devices",
|
|
158
|
+
checks: [
|
|
159
|
+
{ label: "SELinux mode", command: "getenforce" },
|
|
160
|
+
{ label: "Verified boot state", command: "getprop ro.boot.verifiedbootstate" },
|
|
161
|
+
{ label: "Flash lock", command: "getprop ro.boot.flash.locked" },
|
|
162
|
+
{ label: "Secure boot", command: "getprop ro.boot.secure_boot" },
|
|
163
|
+
{ label: "Security patch", command: "getprop ro.build.version.security_patch" },
|
|
164
|
+
{ label: "Encryption state", command: "getprop ro.crypto.state" },
|
|
165
|
+
{ label: "DM-verity mode", command: "getprop ro.boot.veritymode" },
|
|
166
|
+
{ label: "Build type", command: "getprop ro.build.type" },
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
network: {
|
|
170
|
+
description: "Compare network and radio state across devices",
|
|
171
|
+
checks: [
|
|
172
|
+
{ label: "Network type", command: "getprop gsm.network.type" },
|
|
173
|
+
{ label: "Operator", command: "getprop gsm.operator.alpha" },
|
|
174
|
+
{ label: "SIM state", command: "getprop gsm.sim.state" },
|
|
175
|
+
{ label: "WiFi interface", command: "getprop wifi.interface" },
|
|
176
|
+
{ label: "Radio technology", command: "getprop ro.telephony.default_network" },
|
|
177
|
+
{ label: "Multisim config", command: "getprop persist.radio.multisim.config" },
|
|
178
|
+
],
|
|
179
|
+
},
|
|
180
|
+
identity: {
|
|
181
|
+
description: "Compare device identity and hardware across devices",
|
|
182
|
+
checks: [
|
|
183
|
+
{ label: "Model", command: "getprop ro.product.model" },
|
|
184
|
+
{ label: "Device codename", command: "getprop ro.product.device" },
|
|
185
|
+
{ label: "Chipset", command: "getprop ro.hardware.chipname" },
|
|
186
|
+
{ label: "Platform", command: "getprop ro.board.platform" },
|
|
187
|
+
{ label: "SOC model", command: "getprop ro.soc.model" },
|
|
188
|
+
{ label: "SDK version", command: "getprop ro.build.version.sdk" },
|
|
189
|
+
{ label: "Architecture", command: "getprop ro.product.cpu.abi" },
|
|
190
|
+
{ label: "RAM", command: "cat /proc/meminfo | head -1" },
|
|
191
|
+
],
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
ctx.server.tool("adb_multi_test", "Run a comparative test workflow across all connected devices (host + QEMU guests). Executes a predefined diagnostic profile or custom command list on every device in parallel, compares results per-check, and reports matches and differences. Profiles: 'firmware' (baseband, bootloader, kernel, security patch), 'security' (SELinux, verified boot, encryption), 'network' (radio, WiFi, SIM), 'identity' (model, chipset, architecture), 'full' (all profiles). Custom commands also supported.", {
|
|
195
|
+
profile: z.enum(["firmware", "security", "network", "identity", "full"]).optional()
|
|
196
|
+
.describe("Predefined test profile to run. 'full' runs all profiles."),
|
|
197
|
+
commands: z.array(z.object({
|
|
198
|
+
label: z.string().describe("Human-readable label for this check"),
|
|
199
|
+
command: z.string().describe("Shell command to execute"),
|
|
200
|
+
})).max(50).optional()
|
|
201
|
+
.describe("Custom checks to run (max 50). Each has a label and command."),
|
|
202
|
+
devices: z.array(z.string()).optional()
|
|
203
|
+
.describe("Device serials to target (omit for all online devices)"),
|
|
204
|
+
timeout: z.number().min(1000).max(60000).optional().default(10000)
|
|
205
|
+
.describe("Timeout per command per device in ms (1s-60s, default 10s)"),
|
|
206
|
+
}, async ({ profile, commands, devices, timeout }) => {
|
|
207
|
+
try {
|
|
208
|
+
if (!profile && !commands) {
|
|
209
|
+
// List available profiles
|
|
210
|
+
const profileList = Object.entries(TEST_PROFILES)
|
|
211
|
+
.map(([name, p]) => ` ${name}: ${p.description} (${p.checks.length} checks)`)
|
|
212
|
+
.join("\n");
|
|
213
|
+
return {
|
|
214
|
+
content: [{
|
|
215
|
+
type: "text",
|
|
216
|
+
text: `Specify a profile or custom commands.\n\nAvailable profiles:\n${profileList}\n full: Run all profiles combined\n\nExample: adb_multi_test profile="firmware"\nCustom: adb_multi_test commands=[{label: "Uptime", command: "uptime"}]`,
|
|
217
|
+
}],
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
// Build the check list
|
|
221
|
+
let checks = [];
|
|
222
|
+
if (profile === "full") {
|
|
223
|
+
for (const p of Object.values(TEST_PROFILES)) {
|
|
224
|
+
checks.push(...p.checks);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else if (profile) {
|
|
228
|
+
checks = TEST_PROFILES[profile].checks;
|
|
229
|
+
}
|
|
230
|
+
if (commands) {
|
|
231
|
+
checks.push(...commands);
|
|
232
|
+
}
|
|
233
|
+
// Security check all commands
|
|
234
|
+
for (const check of checks) {
|
|
235
|
+
const blocked = ctx.security.checkCommand(check.command);
|
|
236
|
+
if (blocked) {
|
|
237
|
+
return { content: [{ type: "text", text: `Blocked command in check "${check.label}": ${blocked}` }], isError: true };
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
// Resolve target devices
|
|
241
|
+
const allDevices = await ctx.deviceManager.listDevices();
|
|
242
|
+
const online = allDevices.filter((d) => d.state === "device");
|
|
243
|
+
const targets = devices
|
|
244
|
+
? online.filter((d) => devices.includes(d.serial))
|
|
245
|
+
: online;
|
|
246
|
+
if (targets.length === 0) {
|
|
247
|
+
return { content: [{ type: "text", text: "No matching online devices found." }], isError: true };
|
|
248
|
+
}
|
|
249
|
+
const sections = [];
|
|
250
|
+
const profileName = profile === "full" ? "Full Diagnostic" : profile ? TEST_PROFILES[profile].description : "Custom";
|
|
251
|
+
sections.push(`=== Comparative Test: ${profileName} ===`);
|
|
252
|
+
sections.push(`Devices: ${targets.map(d => d.model ? `${d.serial} (${d.model})` : d.serial).join(", ")}`);
|
|
253
|
+
sections.push(`Checks: ${checks.length}`);
|
|
254
|
+
let matches = 0;
|
|
255
|
+
let differences = 0;
|
|
256
|
+
let errors = 0;
|
|
257
|
+
// Run each check across all devices
|
|
258
|
+
for (const check of checks) {
|
|
259
|
+
const results = await Promise.allSettled(targets.map(async (d) => {
|
|
260
|
+
const result = await ctx.bridge.shell(check.command, {
|
|
261
|
+
device: d.serial, timeout, ignoreExitCode: true,
|
|
262
|
+
});
|
|
263
|
+
return { serial: d.serial, model: d.model, output: result.stdout.trim() };
|
|
264
|
+
}));
|
|
265
|
+
const succeeded = results
|
|
266
|
+
.filter((r) => r.status === "fulfilled")
|
|
267
|
+
.map((r) => r.value);
|
|
268
|
+
const failed = results.filter((r) => r.status === "rejected");
|
|
269
|
+
if (succeeded.length === 0) {
|
|
270
|
+
sections.push(`\n✗ ${check.label}: All devices failed`);
|
|
271
|
+
errors += targets.length;
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
errors += failed.length;
|
|
275
|
+
// Compare outputs
|
|
276
|
+
const allSame = succeeded.length >= 2 && succeeded.every((r) => r.output === succeeded[0].output);
|
|
277
|
+
if (allSame) {
|
|
278
|
+
matches++;
|
|
279
|
+
const value = succeeded[0].output || "(empty)";
|
|
280
|
+
// Truncate long identical values
|
|
281
|
+
const display = value.length > 120 ? value.substring(0, 120) + "..." : value;
|
|
282
|
+
sections.push(`\n✓ ${check.label}: MATCH — ${display}`);
|
|
283
|
+
}
|
|
284
|
+
else if (succeeded.length === 1) {
|
|
285
|
+
matches++;
|
|
286
|
+
sections.push(`\n✓ ${check.label}: ${succeeded[0].output || "(empty)"}`);
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
differences++;
|
|
290
|
+
sections.push(`\n✗ ${check.label}: DIFFERS`);
|
|
291
|
+
for (const r of succeeded) {
|
|
292
|
+
const label = r.model ? `${r.serial} (${r.model})` : r.serial;
|
|
293
|
+
const value = r.output || "(empty)";
|
|
294
|
+
const display = value.length > 200 ? value.substring(0, 200) + "..." : value;
|
|
295
|
+
sections.push(` ${label}: ${display}`);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (failed.length > 0) {
|
|
299
|
+
for (let i = 0; i < results.length; i++) {
|
|
300
|
+
if (results[i].status === "rejected") {
|
|
301
|
+
const reason = results[i].reason;
|
|
302
|
+
const label = targets[i].model ? `${targets[i].serial} (${targets[i].model})` : targets[i].serial;
|
|
303
|
+
sections.push(` ${label}: Error — ${reason instanceof Error ? reason.message : reason}`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
// Summary
|
|
309
|
+
sections.push(`\n${"─".repeat(50)}`);
|
|
310
|
+
sections.push(`Summary: ${checks.length} checks, ${matches} match${matches !== 1 ? "es" : ""}, ${differences} difference${differences !== 1 ? "s" : ""}, ${errors} error${errors !== 1 ? "s" : ""}`);
|
|
311
|
+
if (differences === 0 && errors === 0 && targets.length >= 2) {
|
|
312
|
+
sections.push("✓ All checks consistent across devices");
|
|
313
|
+
}
|
|
314
|
+
else if (differences > 0) {
|
|
315
|
+
sections.push("⚠ Differences detected — review per-check details above");
|
|
316
|
+
}
|
|
317
|
+
return { content: [{ type: "text", text: sections.join("\n") }] };
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
|
|
321
|
+
}
|
|
322
|
+
});
|
|
137
323
|
}
|
|
138
324
|
//# sourceMappingURL=multi-device.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-device.js","sourceRoot":"","sources":["../../src/tools/multi-device.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"multi-device.js","sourceRoot":"","sources":["../../src/tools/multi-device.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qemu.d.ts","sourceRoot":"","sources":["../../src/tools/qemu.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"qemu.d.ts","sourceRoot":"","sources":["../../src/tools/qemu.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA0QjD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAg5BxD"}
|
package/build/tools/qemu.js
CHANGED
|
@@ -16,10 +16,11 @@
|
|
|
16
16
|
import { z } from "zod";
|
|
17
17
|
import { join, resolve, basename } from "path";
|
|
18
18
|
import { mkdirSync, existsSync, readdirSync, statSync, unlinkSync } from "fs";
|
|
19
|
-
import { spawn, spawnSync } from "child_process";
|
|
19
|
+
import { execFile, spawn, spawnSync } from "child_process";
|
|
20
20
|
import { OutputProcessor } from "../middleware/output-processor.js";
|
|
21
21
|
import { isOnDevice } from "../config/config.js";
|
|
22
22
|
import { registerCleanup, unregisterCleanup } from "../middleware/cleanup.js";
|
|
23
|
+
import { LocalBridge } from "../bridge/local-bridge.js";
|
|
23
24
|
/** Maximum concurrent QEMU VMs to prevent resource exhaustion. */
|
|
24
25
|
const MAX_VMS = 3;
|
|
25
26
|
/**
|
|
@@ -156,11 +157,63 @@ function verifyContainment(filePath, imageDir) {
|
|
|
156
157
|
const resolvedDir = resolve(imageDir);
|
|
157
158
|
return resolved.startsWith(resolvedDir + "/") || resolved.startsWith(resolvedDir + "\\");
|
|
158
159
|
}
|
|
159
|
-
/**
|
|
160
|
+
/**
|
|
161
|
+
* Find the `adb` binary in the system PATH.
|
|
162
|
+
* Required for guest ADB connectivity (connecting to VMs).
|
|
163
|
+
* Returns null if not found — the tool will suggest installation instructions.
|
|
164
|
+
*
|
|
165
|
+
* SECURITY: The path is discovered from the system, never user-supplied.
|
|
166
|
+
* Only standard Termux locations are checked.
|
|
167
|
+
*/
|
|
168
|
+
function findAdbBinary() {
|
|
169
|
+
try {
|
|
170
|
+
const result = spawnSync("which", ["adb"], { timeout: 3000 });
|
|
171
|
+
if (result.status === 0 && result.stdout) {
|
|
172
|
+
const path = result.stdout.toString().trim();
|
|
173
|
+
if (path.length > 0 && existsSync(path))
|
|
174
|
+
return path;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch { /* which not available or failed */ }
|
|
178
|
+
// Fallback: common Termux location
|
|
179
|
+
const termuxAdb = "/data/data/com.termux/files/usr/bin/adb";
|
|
180
|
+
if (existsSync(termuxAdb))
|
|
181
|
+
return termuxAdb;
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Execute an ADB command directly using the system adb binary.
|
|
186
|
+
* Bypasses the bridge (which uses LocalBridge in on-device mode) because
|
|
187
|
+
* guest ADB connectivity requires the actual ADB client/server protocol.
|
|
188
|
+
*
|
|
189
|
+
* SECURITY: Only called with internally-constructed arguments (never raw user input).
|
|
190
|
+
* Host/port values are derived from the runningVms map, not user-supplied.
|
|
191
|
+
*/
|
|
192
|
+
function execAdb(adbPath, args, timeout = 15000) {
|
|
193
|
+
return new Promise((resolve) => {
|
|
194
|
+
execFile(adbPath, args, { timeout, maxBuffer: 1024 * 1024 }, (error, stdout, stderr) => {
|
|
195
|
+
resolve({
|
|
196
|
+
stdout: stdout?.toString() ?? "",
|
|
197
|
+
stderr: stderr?.toString() ?? "",
|
|
198
|
+
exitCode: error?.code != null ? (typeof error.code === "number" ? error.code : 1) : 0,
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
/** Register cleanup to disconnect and kill all QEMU VMs on process exit. */
|
|
160
204
|
function updateCleanup() {
|
|
161
205
|
if (runningVms.size > 0) {
|
|
162
206
|
registerCleanup("qemu-vms", () => {
|
|
207
|
+
const adbPath = findAdbBinary();
|
|
163
208
|
for (const [, vm] of runningVms) {
|
|
209
|
+
// Disconnect guest ADB before killing QEMU (best-effort, sync)
|
|
210
|
+
if (vm.connected && vm.guestSerial && adbPath) {
|
|
211
|
+
try {
|
|
212
|
+
spawnSync(adbPath, ["disconnect", vm.guestSerial], { timeout: 3000 });
|
|
213
|
+
}
|
|
214
|
+
catch { /* best-effort */ }
|
|
215
|
+
LocalBridge.unregisterGuestDevice(vm.guestSerial);
|
|
216
|
+
}
|
|
164
217
|
try {
|
|
165
218
|
vm.process.kill("SIGKILL");
|
|
166
219
|
}
|
|
@@ -607,6 +660,8 @@ export function registerQemuTools(ctx) {
|
|
|
607
660
|
qemuPid: null,
|
|
608
661
|
pidFile: pidFilePath,
|
|
609
662
|
rootElevated: useKvm,
|
|
663
|
+
connected: false,
|
|
664
|
+
guestSerial: null,
|
|
610
665
|
};
|
|
611
666
|
runningVms.set(safeName, vmInfo);
|
|
612
667
|
updateCleanup();
|
|
@@ -624,6 +679,14 @@ export function registerQemuTools(ctx) {
|
|
|
624
679
|
});
|
|
625
680
|
proc.on("exit", (code) => {
|
|
626
681
|
ctx.logger.info(`[qemu:${safeName}] Exited (code: ${code})`);
|
|
682
|
+
const exitedVm = runningVms.get(safeName);
|
|
683
|
+
if (exitedVm) {
|
|
684
|
+
if (exitedVm.guestSerial) {
|
|
685
|
+
LocalBridge.unregisterGuestDevice(exitedVm.guestSerial);
|
|
686
|
+
}
|
|
687
|
+
exitedVm.connected = false;
|
|
688
|
+
exitedVm.guestSerial = null;
|
|
689
|
+
}
|
|
627
690
|
runningVms.delete(safeName);
|
|
628
691
|
updateCleanup();
|
|
629
692
|
});
|
|
@@ -692,6 +755,20 @@ export function registerQemuTools(ctx) {
|
|
|
692
755
|
if (!vm) {
|
|
693
756
|
return { content: [{ type: "text", text: `VM '${safeName}' is not running.` }], isError: true };
|
|
694
757
|
}
|
|
758
|
+
// Disconnect guest ADB before killing QEMU (prevents stale ADB entries)
|
|
759
|
+
if (vm.connected && vm.guestSerial) {
|
|
760
|
+
const adbPath = findAdbBinary();
|
|
761
|
+
if (adbPath) {
|
|
762
|
+
try {
|
|
763
|
+
await execAdb(adbPath, ["disconnect", vm.guestSerial], 5000);
|
|
764
|
+
ctx.deviceManager.invalidateCache();
|
|
765
|
+
}
|
|
766
|
+
catch { /* best-effort */ }
|
|
767
|
+
}
|
|
768
|
+
LocalBridge.unregisterGuestDevice(vm.guestSerial);
|
|
769
|
+
vm.connected = false;
|
|
770
|
+
vm.guestSerial = null;
|
|
771
|
+
}
|
|
695
772
|
try {
|
|
696
773
|
vm.process.kill(force ? "SIGKILL" : "SIGTERM");
|
|
697
774
|
}
|
|
@@ -771,6 +848,12 @@ export function registerQemuTools(ctx) {
|
|
|
771
848
|
sections.push(` Image: ${basename(vm.imagePath)}`);
|
|
772
849
|
sections.push(` Resources: ${vm.memoryMb} MB RAM, ${vm.cpus} CPU(s)`);
|
|
773
850
|
sections.push(` ADB: localhost:${vm.adbPort} → guest:5555`);
|
|
851
|
+
if (vm.connected && vm.guestSerial) {
|
|
852
|
+
sections.push(` Guest ADB: ✓ connected (serial: ${vm.guestSerial})`);
|
|
853
|
+
}
|
|
854
|
+
else {
|
|
855
|
+
sections.push(` Guest ADB: not connected (use adb_qemu_connect)`);
|
|
856
|
+
}
|
|
774
857
|
sections.push(` Uptime: ${uptimeMin}m ${uptimeSec}s`);
|
|
775
858
|
}
|
|
776
859
|
}
|
|
@@ -787,5 +870,166 @@ export function registerQemuTools(ctx) {
|
|
|
787
870
|
return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
|
|
788
871
|
}
|
|
789
872
|
});
|
|
873
|
+
ctx.server.tool("adb_qemu_connect", "Connect to a running QEMU VM's ADB service, making the guest appear as a device for DeepADB tools. Requires the guest OS to have an ADB daemon running (e.g., Android guest with USB debugging enabled). Requires the 'adb' binary (install with: pkg install android-tools). Connections are restricted to localhost only — no remote host connections allowed.", {
|
|
874
|
+
name: z.string().describe("VM name to connect to (must be running)"),
|
|
875
|
+
timeout: z.number().min(3000).max(30000).optional().default(10000)
|
|
876
|
+
.describe("Connection timeout in milliseconds (3s-30s). Default 10s."),
|
|
877
|
+
}, async ({ name, timeout }) => {
|
|
878
|
+
try {
|
|
879
|
+
if (!isOnDevice()) {
|
|
880
|
+
return { content: [{ type: "text", text: "QEMU tools are only available in on-device mode." }], isError: true };
|
|
881
|
+
}
|
|
882
|
+
const safeName = sanitizeName(name);
|
|
883
|
+
const vm = runningVms.get(safeName);
|
|
884
|
+
if (!vm) {
|
|
885
|
+
return { content: [{ type: "text", text: `VM '${safeName}' is not running.` }], isError: true };
|
|
886
|
+
}
|
|
887
|
+
if (vm.connected) {
|
|
888
|
+
return { content: [{ type: "text", text: `VM '${safeName}' is already connected (serial: ${vm.guestSerial}).` }] };
|
|
889
|
+
}
|
|
890
|
+
// Find ADB binary
|
|
891
|
+
const adbPath = findAdbBinary();
|
|
892
|
+
if (!adbPath) {
|
|
893
|
+
return {
|
|
894
|
+
content: [{
|
|
895
|
+
type: "text",
|
|
896
|
+
text: "ADB binary not found. Install with: pkg install android-tools\nThen retry: adb_qemu_connect",
|
|
897
|
+
}],
|
|
898
|
+
isError: true,
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
// SECURITY: Only connect to localhost — never to external hosts.
|
|
902
|
+
// The port is derived from the running VM's configuration, not user input.
|
|
903
|
+
const guestSerial = `localhost:${vm.adbPort}`;
|
|
904
|
+
// Ensure ADB server is running
|
|
905
|
+
await execAdb(adbPath, ["start-server"], 10000);
|
|
906
|
+
// Connect to guest ADB
|
|
907
|
+
const connectResult = await execAdb(adbPath, ["connect", guestSerial], timeout);
|
|
908
|
+
const output = (connectResult.stdout + connectResult.stderr).trim();
|
|
909
|
+
// Check for success patterns
|
|
910
|
+
const isConnected = output.includes("connected to") || output.includes("already connected");
|
|
911
|
+
if (isConnected) {
|
|
912
|
+
vm.connected = true;
|
|
913
|
+
vm.guestSerial = guestSerial;
|
|
914
|
+
LocalBridge.registerGuestDevice(guestSerial);
|
|
915
|
+
ctx.deviceManager.invalidateCache();
|
|
916
|
+
// Verify the guest appears in device list
|
|
917
|
+
const devicesResult = await execAdb(adbPath, ["devices", "-l"], 5000);
|
|
918
|
+
const guestLine = devicesResult.stdout.split("\n")
|
|
919
|
+
.find(line => line.includes(guestSerial));
|
|
920
|
+
const sections = [];
|
|
921
|
+
sections.push(`✓ Connected to VM '${safeName}' guest ADB`);
|
|
922
|
+
sections.push(`Guest serial: ${guestSerial}`);
|
|
923
|
+
if (guestLine) {
|
|
924
|
+
sections.push(`Device status: ${guestLine.trim()}`);
|
|
925
|
+
}
|
|
926
|
+
sections.push(`\nRun commands on guest: adb_qemu_guest_shell name="${safeName}" command="getprop ro.build.display.id"`);
|
|
927
|
+
sections.push(`Disconnect: adb_qemu_disconnect name="${safeName}"`);
|
|
928
|
+
return { content: [{ type: "text", text: sections.join("\n") }] };
|
|
929
|
+
}
|
|
930
|
+
return {
|
|
931
|
+
content: [{
|
|
932
|
+
type: "text",
|
|
933
|
+
text: `Failed to connect to VM '${safeName}' on ${guestSerial}.\n${output}\n\nEnsure the guest OS has an ADB daemon running (e.g., Android with USB debugging enabled).`,
|
|
934
|
+
}],
|
|
935
|
+
isError: true,
|
|
936
|
+
};
|
|
937
|
+
}
|
|
938
|
+
catch (error) {
|
|
939
|
+
return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
|
|
940
|
+
}
|
|
941
|
+
});
|
|
942
|
+
ctx.server.tool("adb_qemu_disconnect", "Disconnect from a QEMU VM's ADB service. Removes the guest from the device list.", {
|
|
943
|
+
name: z.string().describe("VM name to disconnect from"),
|
|
944
|
+
}, async ({ name }) => {
|
|
945
|
+
try {
|
|
946
|
+
if (!isOnDevice()) {
|
|
947
|
+
return { content: [{ type: "text", text: "QEMU tools are only available in on-device mode." }], isError: true };
|
|
948
|
+
}
|
|
949
|
+
const safeName = sanitizeName(name);
|
|
950
|
+
const vm = runningVms.get(safeName);
|
|
951
|
+
if (!vm) {
|
|
952
|
+
return { content: [{ type: "text", text: `VM '${safeName}' is not running.` }], isError: true };
|
|
953
|
+
}
|
|
954
|
+
if (!vm.connected || !vm.guestSerial) {
|
|
955
|
+
return { content: [{ type: "text", text: `VM '${safeName}' is not connected.` }] };
|
|
956
|
+
}
|
|
957
|
+
const adbPath = findAdbBinary();
|
|
958
|
+
if (!adbPath) {
|
|
959
|
+
// Can't disconnect without ADB, but clear state anyway
|
|
960
|
+
LocalBridge.unregisterGuestDevice(vm.guestSerial);
|
|
961
|
+
vm.connected = false;
|
|
962
|
+
vm.guestSerial = null;
|
|
963
|
+
return { content: [{ type: "text", text: `Cleared connection state for '${safeName}' (ADB binary not found).` }] };
|
|
964
|
+
}
|
|
965
|
+
const serial = vm.guestSerial;
|
|
966
|
+
await execAdb(adbPath, ["disconnect", serial], 5000);
|
|
967
|
+
vm.connected = false;
|
|
968
|
+
vm.guestSerial = null;
|
|
969
|
+
LocalBridge.unregisterGuestDevice(serial);
|
|
970
|
+
ctx.deviceManager.invalidateCache();
|
|
971
|
+
return { content: [{ type: "text", text: `✓ Disconnected from VM '${safeName}' (was ${serial}).` }] };
|
|
972
|
+
}
|
|
973
|
+
catch (error) {
|
|
974
|
+
return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
|
|
975
|
+
}
|
|
976
|
+
});
|
|
977
|
+
ctx.server.tool("adb_qemu_guest_shell", "Execute a shell command on a QEMU guest VM via ADB. The VM must be connected first (use adb_qemu_connect). The guest serial is derived internally — no user-supplied host/IP reaches the ADB binary. Subject to the same security middleware checks as adb_shell.", {
|
|
978
|
+
name: z.string().describe("VM name (must be connected via adb_qemu_connect)"),
|
|
979
|
+
command: z.string().describe("Shell command to execute on the guest"),
|
|
980
|
+
timeout: z.number().min(1000).max(60000).optional().default(15000)
|
|
981
|
+
.describe("Command timeout in milliseconds (1s-60s). Default 15s."),
|
|
982
|
+
}, async ({ name, command, timeout }) => {
|
|
983
|
+
try {
|
|
984
|
+
if (!isOnDevice()) {
|
|
985
|
+
return { content: [{ type: "text", text: "QEMU tools are only available in on-device mode." }], isError: true };
|
|
986
|
+
}
|
|
987
|
+
// Security: command goes through the same security middleware as adb_shell
|
|
988
|
+
const blocked = ctx.security.checkCommand(command);
|
|
989
|
+
if (blocked) {
|
|
990
|
+
return { content: [{ type: "text", text: blocked }], isError: true };
|
|
991
|
+
}
|
|
992
|
+
const safeName = sanitizeName(name);
|
|
993
|
+
const vm = runningVms.get(safeName);
|
|
994
|
+
if (!vm) {
|
|
995
|
+
return { content: [{ type: "text", text: `VM '${safeName}' is not running.` }], isError: true };
|
|
996
|
+
}
|
|
997
|
+
if (!vm.connected || !vm.guestSerial) {
|
|
998
|
+
return {
|
|
999
|
+
content: [{
|
|
1000
|
+
type: "text",
|
|
1001
|
+
text: `VM '${safeName}' is not connected. Run adb_qemu_connect first.`,
|
|
1002
|
+
}],
|
|
1003
|
+
isError: true,
|
|
1004
|
+
};
|
|
1005
|
+
}
|
|
1006
|
+
const adbPath = findAdbBinary();
|
|
1007
|
+
if (!adbPath) {
|
|
1008
|
+
return { content: [{ type: "text", text: "ADB binary not found. Install with: pkg install android-tools" }], isError: true };
|
|
1009
|
+
}
|
|
1010
|
+
// SECURITY: The serial is derived from the running VM's internal state (localhost:<port>).
|
|
1011
|
+
// It is NEVER constructed from user input. This prevents injection of arbitrary
|
|
1012
|
+
// host addresses into the adb command.
|
|
1013
|
+
const result = await execAdb(adbPath, ["-s", vm.guestSerial, "shell", command], timeout);
|
|
1014
|
+
if (result.exitCode !== 0 && result.stderr.includes("device offline")) {
|
|
1015
|
+
if (vm.guestSerial)
|
|
1016
|
+
LocalBridge.unregisterGuestDevice(vm.guestSerial);
|
|
1017
|
+
vm.connected = false;
|
|
1018
|
+
vm.guestSerial = null;
|
|
1019
|
+
return {
|
|
1020
|
+
content: [{
|
|
1021
|
+
type: "text",
|
|
1022
|
+
text: `Guest '${safeName}' is offline (ADB connection lost). Reconnect with adb_qemu_connect.`,
|
|
1023
|
+
}],
|
|
1024
|
+
isError: true,
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
const output = result.stdout.trim() || result.stderr.trim() || "(no output)";
|
|
1028
|
+
return { content: [{ type: "text", text: OutputProcessor.process(output) }] };
|
|
1029
|
+
}
|
|
1030
|
+
catch (error) {
|
|
1031
|
+
return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
|
|
1032
|
+
}
|
|
1033
|
+
});
|
|
790
1034
|
}
|
|
791
1035
|
//# sourceMappingURL=qemu.js.map
|