diff --git a/gui/inject/main-inject.cjs b/gui/inject/main-inject.cjs index a79cdad..cc36ce5 100644 --- a/gui/inject/main-inject.cjs +++ b/gui/inject/main-inject.cjs @@ -1,12 +1,13 @@ import renderer from './renderer-inject.js' module.exports = function() { - const { app, ipcMain, BrowserWindow, webContents, dialog, shell } = require('electron') + const cp = require('child_process'), originalSpawn = cp.spawn const path = require('path') const fs = require('fs') - const parse = require('shell-quote/parse') - const semver = require('semver') const https = require('https') + const { app, webContents, dialog, shell, BrowserWindow, ipcMain } = require('electron') + const semver = require('semver') + const parse = require('shell-quote/parse') const installDir = path.dirname(__dirname) @@ -60,6 +61,18 @@ module.exports = function() { } } + ipcMain.on('LCQT_READ_CONFIG', event => { + event.returnValue = readConfigSync() + }) + + ipcMain.on('LCQT_WRITE_CONFIG', async (event, config) => { + await fs.promises.writeFile( + configPath, + JSON.stringify(config, null, 4), + 'utf8' + ) + }) + ipcMain.on('LCQT_OPEN_WINDOW', event => { let mainWin = BrowserWindow.fromWebContents(event.sender) @@ -73,7 +86,6 @@ module.exports = function() { webPreferences: { nodeIntegration: true, contextIsolation: false, - additionalArguments: [configPath] }, autoHideMenuBar: true }) @@ -85,34 +97,44 @@ module.exports = function() { window.loadURL(`file://${__dirname}/index.html`) }) - ipcMain.on('LCQT_GET_LAUNCH_OPTIONS', (event) => { + cp.spawn = (cmd, args, opts) => { + if(!['javaw', 'java'].includes(path.basename(cmd, '.exe'))) { + return originalSpawn(cmd, args, opts) + } + let config = readConfigSync() - event.returnValue = { - customJvm: config.customJvmEnabled && config.customJvm, - jvmArgs: [ - ...config.agents - ? config.agents.filter(a => a.enabled).map(a => `-javaagent:${a.path}=${a.option}`) - : [], - `-javaagent:${path.join(installDir, 'agent.jar')}`, - ...config.jvmArgsEnabled ? parse(config.jvmArgs) : [] - ], - minecraftArgs: config.crackedEnabled && config.crackedUsername ? [ - '--username', config.crackedUsername - ] : [] + args = args.filter(e => e !== '-XX:+DisableAttachMechanism'); + delete opts.env['_JAVA_OPTIONS']; + delete opts.env['JAVA_TOOL_OPTIONS']; + delete opts.env['JDK_JAVA_OPTIONS']; + + args.splice( + Math.max(0, args.indexOf('-cp')), + 0, + ...config.agents ? config.agents.filter(a => a.enabled).map(a => `-javaagent:${a.path}=${a.option}`) : [], + `-javaagent:${path.join(installDir, 'agent.jar')}`, + ...config.jvmArgsEnabled ? parse(config.jvmArgs) : [] + ) + + if(config.crackedEnabled && config.crackedUsername) { + args.push('--username', config.crackedUsername) } - }) + + return originalSpawn( + config.customJvmEnabled && config.customJvm || cmd, + args, + opts + ) + } for(const contents of webContents.getAllWebContents()) { - contents.removeAllListeners('devtools-opened') contents.executeJavaScript(renderer) } app.on('web-contents-created', (event, webContents) => { webContents.on('dom-ready', () => { if(webContents.getURL().includes(__dirname)) return - - webContents.removeAllListeners('devtools-opened') webContents.executeJavaScript(renderer) }) }) diff --git a/gui/inject/renderer-inject.js b/gui/inject/renderer-inject.js index a0f47a4..f6506a7 100644 --- a/gui/inject/renderer-inject.js +++ b/gui/inject/renderer-inject.js @@ -1,33 +1,4 @@ import syringe from './syringe.svg' -const { ipcRenderer } = require('electron') -const path = require('path') -const cp = require('child_process'), originalSpawn = cp.spawn - -cp.spawn = function (cmd, args, opts) { - if (!['javaw', 'java'].includes(path.basename(cmd, '.exe'))) { - return originalSpawn(cmd, args, opts) - } - - args = args.filter(e => e !== '-XX:+DisableAttachMechanism'); - - delete opts.env['_JAVA_OPTIONS']; - delete opts.env['JAVA_TOOL_OPTIONS']; - delete opts.env['JDK_JAVA_OPTIONS']; - - let lcqtOpts = ipcRenderer.sendSync('LCQT_GET_LAUNCH_OPTIONS') - - args.splice( - Math.max(0, args.indexOf('-cp')), - 0, - ...lcqtOpts.jvmArgs - ) - - return originalSpawn( - lcqtOpts.customJvm || cmd, - [...args, ...lcqtOpts.minecraftArgs], - opts - ) -} function waitForElement(selector) { return new Promise(resolve => { @@ -49,10 +20,13 @@ function waitForElement(selector) { }) } -waitForElement("#exit-button").then(exitButton => { - let clone = exitButton.cloneNode(false) +waitForElement(".fa-gears").then(faGears => { + let settingsButton = faGears.parentNode + + let clone = settingsButton.cloneNode(false) clone.id = null - clone.innerHTML = `` - clone.addEventListener('click', () => ipcRenderer.send('LCQT_OPEN_WINDOW')) - exitButton.parentNode.insertBefore(clone, exitButton) -}) \ No newline at end of file + clone.innerHTML = `lcqt` + clone.addEventListener('click', () => window.electron.ipcRenderer.sendMessage('LCQT_OPEN_WINDOW')) + + settingsButton.parentNode.insertBefore(clone, settingsButton) +}) diff --git a/gui/src/config.ts b/gui/src/config.ts index 6333ef7..2a8e2ce 100644 --- a/gui/src/config.ts +++ b/gui/src/config.ts @@ -36,25 +36,15 @@ function createConfig() { let config: Config = { ...defaultConfig } if (!dev) { - const configPath: string = window.process.argv.pop() - const fs = require('fs') - - try { - config = {...config, ...JSON.parse(fs.readFileSync(configPath, 'utf8'))} - }catch(e) { - console.error(e) - } + const { ipcRenderer } = require('electron') + config = {...config, ...ipcRenderer.sendSync('LCQT_READ_CONFIG')} if (typeof(config.customJvm) == 'boolean') { config.customJvm = '' } window.onchange = () => { - fs.writeFileSync( - configPath, - JSON.stringify(config, null, 4), - 'utf8' - ) + ipcRenderer.send('LCQT_WRITE_CONFIG', config) } } diff --git a/injector/src/main.rs b/injector/src/main.rs index 82e542a..babaf5f 100644 --- a/injector/src/main.rs +++ b/injector/src/main.rs @@ -89,6 +89,8 @@ fn run() -> Result<(), Box> { serde_json::to_string(env::current_exe()?.parent().unwrap())? ); + println!("[LCQT] Sending payload"); + debugger.send("Runtime.evaluate", json!({ "expression": payload, "includeCommandLineAPI": true