Created
January 9, 2021 22:16
-
-
Save Kyngo/a5d4aa7867f647b67b93cc9e50f3341b to your computer and use it in GitHub Desktop.
Boot an Xbox via LAN
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
/** | |
* This script crafts a magic packet for an Xbox One to boot up from the network. | |
* This has been tested on an Xbox One X in a sleeping state, | |
* it might not work if the console is totally powered off. | |
* No dependencies needed, just copy the script and off you go. | |
* You're free to use this as you wish, but consider mentioning me in your project's credits :) | |
* | |
* Example usage: ./xboxwol.js --ip=192.168.254.100 --liveid=F12345ABCDE12ABX | |
*/ | |
const dgram = require('dgram'); | |
const client = dgram.createSocket('udp4'); | |
const params = process.argv.splice(2); | |
const settings = { | |
liveId: null, | |
ipAddress: null, | |
requestedHelp: false, | |
limit: 5 | |
} | |
console.log("Xbox One Wake on LAN"); | |
params.forEach((idx) => { | |
const param = idx.split("="); | |
switch (param[0]) { | |
case "--liveid": | |
if (param[1].length !== 16) { | |
console.error("Invalid Xbox Live device ID!"); | |
process.exit(1); | |
} | |
settings.liveId = param[1]; | |
break; | |
case "--ip": | |
settings.ipAddress = param[1]; | |
break; | |
case "--limit": | |
settings.limit = parseInt(param[1]); | |
break; | |
case "--help": | |
settings.requestedHelp = true; | |
break; | |
default: | |
break; | |
} | |
}); | |
if (!settings.liveId || !settings.ipAddress || settings.requestedHelp) { | |
console.log("Required params: --ip (console IP address) , --liveid (Xbox Live device ID, can be found in the settings app)"); | |
console.log("Optional params: --limit (default: 5 -- amount of times the payload is sent)"); | |
process.exit(0); | |
} | |
// the payload part of the packet, specifying the live ID and its length | |
const payload = Buffer.from([ | |
0x00, | |
settings.liveId.length, | |
...Buffer.from(settings.liveId), | |
0x00 | |
]); | |
// the header of the packet, specifying the length of the payload and the boot request | |
const header = Buffer.from([ | |
0xdd, | |
0x02, | |
0x00, | |
parseInt(payload.length, 'hex'), | |
0x00, | |
0x00 | |
]); | |
// we join both buffers to make the final magic packet | |
const finalPkg = Buffer.from([...header, ...payload]); | |
// we initialize the UDP connector and send the payload every 100ms as long as specified by the limit | |
client.bind(() => { | |
client.setBroadcast(true); | |
let idx = 1; | |
setInterval(() => { | |
client.send(finalPkg, 0, finalPkg.length, 5050, settings.ipAddress, () => { | |
console.log(`Deploying payload... (${idx}/${settings.limit})`); | |
if (idx === settings.limit) { | |
console.log("Closing connection"); | |
process.exit(0); | |
} else { | |
idx++; | |
} | |
}); | |
}, 100); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment