Skip to content

Instantly share code, notes, and snippets.

@rpxs
Created February 3, 2024 01:08
Show Gist options
  • Save rpxs/e881ed7daec8ec695ace5515e3796624 to your computer and use it in GitHub Desktop.
Save rpxs/e881ed7daec8ec695ace5515e3796624 to your computer and use it in GitHub Desktop.
iOS 17 working spoofer, just a small wrapper around pymobiledevice3, run w sudo!
const { exec, spawn } = require("child_process");
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
function stripAnsi(str) {
return str.replace(
/[\u001B\u009B][[\]()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nq-uy=><]/g,
""
);
}
function installPymobileDevice() {
return new Promise((resolve, reject) => {
exec(
"python3 -m pip install -U pymobiledevice3",
(error, stdout, stderr) => {
if (error) {
console.error("Error installing pymobiledevice3.");
return reject(error);
}
resolve();
}
);
});
}
function startTunnel() {
return new Promise((resolve, reject) => {
const tunnelProcess = spawn("sudo", [
"python3",
"-m",
"pymobiledevice3",
"remote",
"start-tunnel",
]);
let fullOutput = "";
tunnelProcess.stdout.on("data", (data) => {
fullOutput += stripAnsi(data.toString());
if (fullOutput.includes("Use the follow connection option:")) {
const hostMatch = fullOutput.match(/RSD Address: (\S+)/);
const portMatch = fullOutput.match(/RSD Port: (\d+)/);
if (hostMatch && portMatch) {
resolve({ host: hostMatch[1], port: portMatch[1], tunnelProcess });
}
}
});
tunnelProcess.stderr.on("data", (data) => {
console.error("Error encountered during tunnel setup.");
});
tunnelProcess.on("error", (error) => {
reject(error);
});
tunnelProcess.on("close", (code) => {
if (code !== 0) {
reject(new Error("Tunnel process exited unexpectedly."));
}
});
});
}
function simulateLocation(host, port, longitude, latitude, tunnelProcess) {
const simulateCommand = `pymobiledevice3 developer dvt simulate-location set --rsd ${host} ${port} -- ${longitude} ${latitude}`;
exec(simulateCommand, (error, stdout, stderr) => {
if (error) {
console.error("Error simulating location:", error);
return;
}
console.log(`Location spoofing to ${longitude}, ${latitude} initiated.`);
console.log(stdout);
if (stderr) console.log(stderr);
});
}
function askForCoordinates(host, port, tunnelProcess) {
rl.question(
"Enter the longitude and latitude as comma-separated values (e.g., -73.935242,40.730610): ",
(input) => {
const coords = input.split(",").map((coord) => coord.trim());
if (coords.length === 2) {
const longitude = coords[0];
const latitude = coords[1];
rl.close();
simulateLocation(host, port, longitude, latitude, tunnelProcess);
} else {
console.log(
"Invalid format. Please enter the values as comma-separated."
);
askForCoordinates(host, port, tunnelProcess);
}
}
);
}
async function main() {
try {
await installPymobileDevice();
const { host, port, tunnelProcess } = await startTunnel();
console.log("Tunnel setup complete.");
askForCoordinates(host, port, tunnelProcess);
} catch (error) {
console.error("An error occurred during the setup process:", error);
}
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment