Compare commits
52 Commits
b5f33ede39
...
4c742c521e
Author | SHA1 | Date |
---|---|---|
dr1ft | 4c742c521e | |
Astra | 7606296020 | |
Cynthia Foxwell | 41cc1d310f | |
Astra | 01cbda7656 | |
Astra | 7ae829b358 | |
Astra | 4b19d3e7af | |
Astra | 2170269bfb | |
Astra | 0b1180273e | |
Astra | 61552afd6e | |
Astra | 16ba644be8 | |
Astra | 6959ab9423 | |
Astra | d202a31908 | |
Astra | 9f354ebe5e | |
Astra | 146fad4150 | |
Astra | 19027ff6c4 | |
Astra | 6c1a27fd17 | |
Astra | ce6280459d | |
Astra | e3c07eb5c2 | |
Astra | 8efdb59e66 | |
Astra | 0d5a38976b | |
Astra | f24b599154 | |
Astra | 792b703145 | |
Astra | 13412fd1be | |
Astra | b62606a61b | |
Astra | ed27067fc9 | |
Astra | a8aca55ed5 | |
Astra | f430a4159f | |
Astra | d1afc1724f | |
Astra | f1db4daed6 | |
Astra | 0cade55978 | |
Astra | fa131c9bbf | |
Astra | b1f92360f6 | |
Astra | b212f64595 | |
Astra | 97fffd9fef | |
Astra | a9f2b9af53 | |
Astra | 6e71380afc | |
Astra | 2674a4dece | |
Astra | 99976473dd | |
Astra | 202572103c | |
Astra | 8780641777 | |
Astra | ef1d47dde7 | |
Astra | a9f17570e0 | |
Astra | efb1788a70 | |
Astra | 4e7807025e | |
Astra | 204e49e124 | |
Astra | e5855c27d2 | |
Astra | 8d3b5f2db7 | |
Astra | 0cac2ac2b8 | |
Astra | ed2dc53d8e | |
Astra | d31301bb50 | |
dr1ft | 4d7f3fe837 | |
Ash Lea | 0cd80b7f13 |
|
@ -36,20 +36,53 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
window.fs = require("original-fs");
|
window.fs = require("original-fs");
|
||||||
|
window.Buffer = require("buffer").Buffer;
|
||||||
|
|
||||||
var data = electron.app.getPath('userData');
|
var data = electron.app.getPath('userData');
|
||||||
|
|
||||||
|
// asarpwn
|
||||||
|
function asarinject(sig, inj) {
|
||||||
|
var dirlisting = fs.readdirSync(data);
|
||||||
|
var latestver = dirlisting.filter(d => d.indexOf("0.0.") > -1);
|
||||||
|
|
||||||
|
if (sig.length != inj.length) {
|
||||||
|
throw 'signature and injection not same size'
|
||||||
|
}
|
||||||
|
var bdata = new Buffer(fs.readFileSync(`${data}/${latestver[latestver.length - 1]}/modules/discord_desktop_core/core.asar`));
|
||||||
|
var index = bdata.indexOf(sig);
|
||||||
|
if (index == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bdata.write(inj, index);
|
||||||
|
fs.writeFileSync(`${data}/${latestver[latestver.length - 1]}/modules/discord_desktop_core/core.asar`, bdata);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// install endpwn
|
// install endpwn
|
||||||
var o = JSON.parse(fs.readFileSync(data + '/settings.json', 'utf8')); // load settings.json
|
var o = fs.existsSync(data + '/settings.json') ? JSON.parse(fs.readFileSync(data + '/settings.json', 'utf8')) : {}; // load settings.json
|
||||||
o['WEBAPP_ENDPOINT'] = 'https://endpwn.github.io/endpwn3'; // aim the app at stage 0
|
o['WEBAPP_ENDPOINT'] = location.href.split('?')[0] + '?'; // aim the app at stage 0
|
||||||
o['WEBAPP_PATH'] = '/app?_=' + Date.now(); // cache busting
|
o['WEBAPP_PATH'] = undefined; // clear old WEBAPP_PATH
|
||||||
fs.writeFileSync(data + '/settings.json', JSON.stringify(o, null, 2)); // commit changes to disk
|
fs.writeFileSync(data + '/settings.json', JSON.stringify(o, null, 2)); // commit changes to disk
|
||||||
|
|
||||||
|
try {
|
||||||
|
// install asarpwn3 for crispr
|
||||||
|
if (!window.__crisprloaded)
|
||||||
|
if (asarinject(
|
||||||
|
"// App preload script, used to provide a replacement native API now that\n// we turned off node integration.\nvar electron = require('electron'",
|
||||||
|
"var electron=require('electron');var d=electron.remote.app.getPath('userData')+'/crispr.js';if(require('fs').existsSync(d))require(d).go();//"
|
||||||
|
)) {
|
||||||
|
electron.app.relaunch();
|
||||||
|
electron.app.exit();
|
||||||
|
}
|
||||||
|
} catch (ex) {
|
||||||
|
alert(ex, 'asarpwn3');
|
||||||
|
}
|
||||||
|
|
||||||
// make a window
|
// make a window
|
||||||
window.__monitor = new electron.BrowserWindow({ show: false });
|
window.__monitor = new electron.BrowserWindow({ show: false });
|
||||||
|
|
||||||
// load the monitor
|
// load the monitor
|
||||||
__monitor.loadURL('https://endpwn.github.io/endpwn3/monitor.htm?_=' + Date.now());
|
__monitor.loadURL(location.href.substr(0, location.href.indexOf('/app/')) + '/monitor.html?_=' + Date.now());
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
|
@ -3,15 +3,21 @@
|
||||||
<head>
|
<head>
|
||||||
<title>EndPwn3</title>
|
<title>EndPwn3</title>
|
||||||
<meta property="og:title" content="EndPwn3" />
|
<meta property="og:title" content="EndPwn3" />
|
||||||
<meta property="og:description" content="Copy and paste the following string into your Discord console: DiscordNative.nativeModules.requireModule('discord_/../electron').remote.getCurrentWindow().loadURL('https://endpwn.github.io/endpwn3/app')" />
|
<meta property="og:description" content="Instructions for installing EndPwn3" />
|
||||||
<meta property="og:image" content="https://endpwn.github.io/sigma.png" />
|
<meta property="og:image" content="https://endpwn.github.io/sigma.png" />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function updatePayload(){
|
||||||
|
document.querySelector('code').innerText=`DiscordNative.nativeModules.requireModule("discord_/../electron").remote.getCurrentWindow().loadURL('${location.href}app')`
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body style="position:absolute;top:50%;left:50%;transform:translateX(-50%) translateY(-50%);font-family:sans-serif;text-align:center;background-color:#2f3136;color:#ffffff">
|
<body style="position:absolute;top:50%;left:50%;transform:translateX(-50%) translateY(-50%);font-family:sans-serif;text-align:center;background-color:#2f3136;color:#ffffff" onload="updatePayload()">
|
||||||
<div style="background:linear-gradient(to bottom right,#0ff,#f0f);-webkit-background-clip:text;-webkit-text-fill-color:transparent;font-size:72px;">ΣndPwn³</div>
|
<div style="background:linear-gradient(to bottom right,#0ff,#f0f);-webkit-background-clip:text;-webkit-text-fill-color:transparent;font-size:72px;">ΣndPwn³</div>
|
||||||
Copy and paste the following string into your Discord console:
|
Copy and paste the following string into your Discord console:
|
||||||
<br>
|
<br>
|
||||||
<code>DiscordNative.nativeModules.requireModule("discord_/../electron").remote.getCurrentWindow().loadURL('https://endpwn.github.io/endpwn3/app')</code>
|
<code>please wait...</code>
|
||||||
<br>
|
<br>
|
||||||
<br> Credit to bootsy for developing the ASAR-less code injection method (bootsyhax)
|
<br> Credit to bootsy for developing the ASAR-less code injection method (bootsyhax)
|
||||||
</body>
|
</body>
|
|
@ -40,30 +40,36 @@
|
||||||
win.webContents.executeJavaScript(stage2);
|
win.webContents.executeJavaScript(stage2);
|
||||||
});
|
});
|
||||||
|
|
||||||
function load() {
|
|
||||||
win.loadURL('https://' + (
|
|
||||||
navigator.userAgent.indexOf('Discord PTB') > -1 ?
|
|
||||||
'ptb.' :
|
|
||||||
navigator.userAgent.indexOf('Discord Canary') > -1 ?
|
|
||||||
'canary.' :
|
|
||||||
''
|
|
||||||
) + 'discordapp.com/channels/@me');
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the data path
|
// get the data path
|
||||||
var data = electron.app.getPath('userData');
|
var data = electron.app.getPath('userData');
|
||||||
|
|
||||||
// dont update EPAPI if DONTUPDATE exists
|
function load() {
|
||||||
|
var branch = require('path').basename(data).substr(7);
|
||||||
|
//if (branch != 'canary')
|
||||||
|
win.loadURL('https://' + (branch && branch != 'development' ? branch + '.' : '') + 'discordapp.com/channels/@me');
|
||||||
|
//else
|
||||||
|
//win.loadURL('https://dr1ft.xyz/channels/@me?branch=canary&build=15523'); // emergency, ugly, temp fix
|
||||||
|
}
|
||||||
|
|
||||||
|
// dont update EPAPI/CRISPR if DONTUPDATE exists
|
||||||
if (!fs.existsSync(data + '/DONTUPDATE')) {
|
if (!fs.existsSync(data + '/DONTUPDATE')) {
|
||||||
|
|
||||||
// grab EPAPI from master
|
// update EPAPI
|
||||||
fetch('https://endpwn.github.io/epapi/epapi.js?_=' + Date.now())
|
fetch('https://endpwn.github.io/epapi/epapi.js?_=' + Date.now())
|
||||||
.then(r => r.text())
|
.then(r => r.text())
|
||||||
.then(epapi => {
|
.then(epapi => {
|
||||||
fs.writeFileSync(data + '/epapi.js', epapi);
|
fs.writeFileSync(data + '/epapi.js', epapi);
|
||||||
|
|
||||||
|
// update CRISPR
|
||||||
|
fetch('https://endpwn.github.io/crispr/crispr.js?_=' + Date.now())
|
||||||
|
.then(r => r.text())
|
||||||
|
.then(epapi => {
|
||||||
|
fs.writeFileSync(data + '/crispr.js', epapi);
|
||||||
setTimeout(load, 1000);
|
setTimeout(load, 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setTimeout(load, 1000);
|
setTimeout(load, 1000);
|
96
shared.js
96
shared.js
|
@ -14,6 +14,10 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
function __epprint(str) {
|
||||||
|
console.log(`%c[EndPwn]%c ` + str, 'font-weight:bold;color:#0cc', '');
|
||||||
|
}
|
||||||
|
|
||||||
(() => {
|
(() => {
|
||||||
|
|
||||||
// define this with a default value as a fallback
|
// define this with a default value as a fallback
|
||||||
|
@ -23,15 +27,35 @@
|
||||||
users: {}
|
users: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function fetchGoodies() {
|
||||||
// fetch goodies.json
|
// fetch goodies.json
|
||||||
|
__epprint('fetching endpwn cutomizer data from server...');
|
||||||
fetch('https://endpwn.cathoderay.tube/goodies.json?_=' + Date.now())
|
fetch('https://endpwn.cathoderay.tube/goodies.json?_=' + Date.now())
|
||||||
.then(x => x.json())
|
.then(x => x.json())
|
||||||
.then(r => __goodies = r);
|
.then(r => __goodies = r);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch goodies now and every half hour
|
||||||
|
fetchGoodies();
|
||||||
|
setInterval(fetchGoodies, 1800000);
|
||||||
|
|
||||||
// early init payload
|
// early init payload
|
||||||
document.addEventListener('ep-prepared', () => {
|
document.addEventListener('ep-prepared', () => {
|
||||||
|
|
||||||
|
// disable that obnoxious warning about not pasting shit in the console
|
||||||
|
__epprint('disabling self xss warning...');
|
||||||
|
$api.util.findFuncExports('consoleWarning').consoleWarning = e => { };
|
||||||
|
|
||||||
|
// fuck sentry
|
||||||
|
__epprint('fucking sentry...');
|
||||||
|
var sentry = wc.findCache('_originalConsoleMethods')[0].exports;
|
||||||
|
window.console = Object.assign(window.console, sentry._originalConsoleMethods); // console
|
||||||
|
sentry._wrappedBuiltIns.forEach(x => x[0][x[1]] = x[2]); // other stuff
|
||||||
|
sentry._breadcrumbEventHandler = () => () => { }; // break most event logging
|
||||||
|
sentry.captureBreadcrumb = () => { }; // disable breadcrumb logging
|
||||||
|
|
||||||
// fetch the changelog
|
// fetch the changelog
|
||||||
|
__epprint('injecting changelog...');
|
||||||
fetch('https://endpwn.github.io/changelog.md?_=' + Date.now()).then(r => r.text()).then(l => {
|
fetch('https://endpwn.github.io/changelog.md?_=' + Date.now()).then(r => r.text()).then(l => {
|
||||||
|
|
||||||
// we're racing discord's initialization procedures; try and hit a timing sweetspot
|
// we're racing discord's initialization procedures; try and hit a timing sweetspot
|
||||||
|
@ -67,16 +91,27 @@
|
||||||
// post-init payload
|
// post-init payload
|
||||||
document.addEventListener('ep-ready', () => {
|
document.addEventListener('ep-ready', () => {
|
||||||
|
|
||||||
window.reload = () => { app.relaunch(); app.exit(); };
|
// disable analytics
|
||||||
|
__epprint('disabling analytics...');
|
||||||
|
$api.util.findFuncExports("AnalyticEventConfigs").default.track = () => { };
|
||||||
|
|
||||||
// enable experiments
|
// enable experiments
|
||||||
|
__epprint('enabling experiments menu...');
|
||||||
$api.util.findFuncExports('isDeveloper').__defineGetter__('isDeveloper', () => true);
|
$api.util.findFuncExports('isDeveloper').__defineGetter__('isDeveloper', () => true);
|
||||||
|
|
||||||
// disable that obnoxious warning about not pasting shit in the console
|
// apply custom discrims/bot tags/badges/server verif from EndPwn Customizer (endpwn.cathoderay.tube)
|
||||||
$api.util.findFuncExports('consoleWarning').consoleWarning = e => { };
|
__epprint('initializing endpwn cutomizer...');
|
||||||
|
|
||||||
// goodies for people directly associated with the endpwn project, and also kat bc shes my girlfriend
|
// add the endpwn dev badge to the class obfuscation table
|
||||||
// may be expanded to anyone through a web ui later on
|
wc.findFunc('profileBadges:"profileBadges')[0].exports['profileBadgeEndpwn'] = 'profileBadgeEndPwn';
|
||||||
|
|
||||||
|
// apply the css for endpwn dev badges
|
||||||
|
var badgecss = document.createElement("style");
|
||||||
|
badgecss.type = "text/css";
|
||||||
|
badgecss.innerHTML = ".profileBadgeEndPwn{background-image:url(https://dr1ft.xyz/sigma_solid.svg);background-position:center;background-repeat:no-repeat;width:16px;height:16px}";
|
||||||
|
document.body.appendChild(badgecss);
|
||||||
|
|
||||||
|
// hook getUser() so we can apply custom discrims/bot tags/badges
|
||||||
$api.util.wrapAfter(
|
$api.util.wrapAfter(
|
||||||
"wc.findCache('getUser')[0].exports.getUser",
|
"wc.findCache('getUser')[0].exports.getUser",
|
||||||
|
|
||||||
|
@ -84,14 +119,15 @@
|
||||||
|
|
||||||
if (x === undefined || x === null) return;
|
if (x === undefined || x === null) return;
|
||||||
|
|
||||||
if (__goodies.bots.contains(x.id)) x.bot = true;
|
if (__goodies.bots.includes(x.id)) x.bot = true;
|
||||||
if (__goodies.users[x.id] !== undefined) x.discriminator = __goodies.users[x.id];
|
if (__goodies.users[x.id] !== undefined) x.discriminator = __goodies.users[x.id];
|
||||||
|
if (__goodies.devs.includes(x.id)) x.flags += x.flags & 4096 ? 0 : 4096;
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// verify servers directly associated with the endpwn project
|
// hook getGuild() so we can verify servers
|
||||||
$api.util.wrapAfter(
|
$api.util.wrapAfter(
|
||||||
"wc.findCache('getGuild')[0].exports.getGuild",
|
"wc.findCache('getGuild')[0].exports.getGuild",
|
||||||
|
|
||||||
|
@ -99,12 +135,56 @@
|
||||||
|
|
||||||
if (x === undefined || x === null) return;
|
if (x === undefined || x === null) return;
|
||||||
|
|
||||||
if (__goodies.guilds.contains(x.id)) x.features.add('VERIFIED');
|
if (__goodies.guilds.includes(x.id)) x.features.add('VERIFIED');
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// check for epapi updates
|
||||||
|
if ($api.lite || !fs.existsSync($api.data + '/DONTUPDATE'))
|
||||||
|
(function () {
|
||||||
|
|
||||||
|
__epprint('checking for EPAPI updates...');
|
||||||
|
|
||||||
|
// fetch the latest build of epapi
|
||||||
|
fetch('https://endpwn.github.io/epapi/epapi.js?_=' + Date.now()).then(x => x.text()).then(x => {
|
||||||
|
|
||||||
|
// check the version
|
||||||
|
if (kparse(x).version > $api.version) {
|
||||||
|
|
||||||
|
// if the version on the server is newer, pester the user
|
||||||
|
$api.ui.showDialog({
|
||||||
|
|
||||||
|
title: 'EndPwn3: EPAPI Update Available',
|
||||||
|
body: 'An update to EPAPI has been released. It is recommended that you restart your client in order to gain access to new features and maintain compatibility.',
|
||||||
|
confirmText: 'Restart Now', cancelText: 'Later',
|
||||||
|
|
||||||
|
// user pressed "Restart Now"
|
||||||
|
onConfirm: () => {
|
||||||
|
|
||||||
|
// refresh the page if we're running in a browser, reboot the app if we're running outside of lite mode
|
||||||
|
reload();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
// they pressed "Later", for some reason
|
||||||
|
onCancel: () => {
|
||||||
|
|
||||||
|
// bother them again in 6 hrs (* 60 min * 60 sec * 1000 ms)
|
||||||
|
setTimeout(arguments.callee, 6 * 60 * 60 * 1000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
else setTimeout(arguments.callee, 6 * 60 * 60 * 1000);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
})();
|
})();
|
57
stage2.js
57
stage2.js
|
@ -17,22 +17,75 @@
|
||||||
|
|
||||||
(() => {
|
(() => {
|
||||||
|
|
||||||
|
// abort if we're not currently in the discord app
|
||||||
|
if (location.hostname.indexOf('discordapp') == -1 && location.hostname.indexOf('dr1ft.xyz') == -1) return;
|
||||||
|
|
||||||
// use the discord native api to require electron and get electron.remote
|
// use the discord native api to require electron and get electron.remote
|
||||||
var electron = DiscordNative.nativeModules.requireModule('discord_/../electron').remote;
|
var electron = DiscordNative.nativeModules.requireModule('discord_/../electron').remote;
|
||||||
var fs = electron.require('original-fs');
|
var fs = electron.require('original-fs');
|
||||||
|
|
||||||
// get the data path (where epapi.js should be)
|
// get the data path (where epapi.js should be)
|
||||||
var data = electron.app.getPath('userData').replace(/\\\\/g, "/") + '/';
|
var ___data = electron.app.getPath('userData').replace(/\\\\/g, "/") + '/';
|
||||||
|
|
||||||
// shakily reimplemented of require() intended for loading plugins and EPAPI itself
|
// shakily reimplemented of require() intended for loading plugins and EPAPI itself
|
||||||
function __krequire(path) {
|
function __krequire(path) {
|
||||||
return eval('(()=>{var exports={};' + fs.readFileSync(data + path, 'utf8').toString() + ';return exports})()');
|
return eval('(()=>{var exports={};' + fs.readFileSync(___data + path, 'utf8').toString() + ';return exports})()');
|
||||||
}
|
}
|
||||||
|
|
||||||
// load EPAPI
|
// load EPAPI
|
||||||
var epapi = __krequire('epapi.js');
|
var epapi = __krequire('epapi.js');
|
||||||
|
|
||||||
|
// add window.reload()
|
||||||
|
window.reload = () => { electron.app.relaunch(); electron.app.exit(); };
|
||||||
|
|
||||||
// call the entrypoint
|
// call the entrypoint
|
||||||
epapi.go('bootsyhax-dr1ft', 0, 1);
|
epapi.go('bootsyhax-dr1ft', 0, 1);
|
||||||
|
|
||||||
|
window.endpwn = {
|
||||||
|
uninstall: function () {
|
||||||
|
$api.ui.showDialog({
|
||||||
|
title: 'EndPwn: confirm uninstallation',
|
||||||
|
body: 'Are you sure you want to remove EndPwn from your client? You can reinstall it at any time.',
|
||||||
|
confirmText: 'Yes', cancelText: 'No',
|
||||||
|
|
||||||
|
onConfirm: () => {
|
||||||
|
|
||||||
|
var data = $api.data;
|
||||||
|
const Buffer = require('buffer').Buffer;
|
||||||
|
|
||||||
|
// asarpwn
|
||||||
|
function asarinject(sig, inj) {
|
||||||
|
var dirlisting = fs.readdirSync(data);
|
||||||
|
var latestver = dirlisting.filter(d => d.indexOf("0.0.") > -1);
|
||||||
|
|
||||||
|
if (sig.length != inj.length) {
|
||||||
|
throw 'signature and injection not same size'
|
||||||
|
}
|
||||||
|
var bdata = new Buffer(fs.readFileSync(`${data}/${latestver[latestver.length - 1]}/modules/discord_desktop_core/core.asar`));
|
||||||
|
var index = bdata.indexOf(sig);
|
||||||
|
if (index == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bdata.write(inj, index);
|
||||||
|
fs.writeFileSync(`${data}/${latestver[latestver.length - 1]}/modules/discord_desktop_core/core.asar`, bdata);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
asarinject(
|
||||||
|
"var electron=require('electron');var d=electron.remote.app.getPath('userData')+'/crispr.js';if(require('fs').existsSync(d))require(d).go();//",
|
||||||
|
"// App preload script, used to provide a replacement native API now that\n// we turned off node integration.\nvar electron = require('electron'"
|
||||||
|
);
|
||||||
|
|
||||||
|
$api.settings.set('WEBAPP_ENDPOINT');
|
||||||
|
$api.settings.set('WEBAPP_PATH');
|
||||||
|
|
||||||
|
reload();
|
||||||
|
|
||||||
|
},
|
||||||
|
onCancel: () => console.log('<3')
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
})();
|
})();
|
Loading…
Reference in New Issue