You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm trying to combine V8 bytecode source code protection with asarmor's ASAR encryption and I'm having some trouble. It looks like I am able to get it to build correctly, but the ASAR archive is not being decrypted by Electron at runtime.
Steps I followed:
I created an Electron app using npm create @quick-start/electron@latest
I modified the following files with the following code:
electron-builder.yml: default file except I added the afterPack and beforePack lines
beforePack.js: this is mostly based on this repo's README, but I had to modify some things to get it to build
const{ join }=require('path');const{ copyFile }=require('fs/promises');exports.default=async(context)=>{try{console.log('copying native dependencies');constrelease=join(__dirname,'node_modules','asarmor','build','Release');// copy main.node from asarmor to our dist/build/release folder; this will become the entrypoint later on.awaitcopyFile(join(release,'main.node'),join(context.packager.info.projectDir,'out','main','main.node'));// copy renderer.node to our dist/build/release folder; the render process will be bootstrapped from the main process later on.awaitcopyFile(join(release,'renderer.node'),join(context.packager.info.projectDir,'out','renderer','renderer.node'));}catch(err){console.error(err);}};
afterPack.js: this is mostly based on this repo's README, but I had to modify some things to get it to build
constasarmor=require('asarmor')exports.default=async({ appOutDir, packager })=>{try{constasarPath=packager.getResourcesDir(appOutDir)+'/app.asar';console.log(` \x1B[34m•\x1B[0m asarmor encrypting contents of ${asarPath}`);awaitasarmor.encrypt({src: asarPath,dst: asarPath,});// then patch the headerconsole.log(` \x1B[34m•\x1B[0m asarmor applying patches to ${asarPath}`);constarchive=awaitasarmor.open(asarPath);archive.patch();// apply default patchesawaitarchive.write(asarPath);}catch(err){console.error(err);}};
index.js: this is mostly the default file created by npm create @quick-start/electron@latest but I modified it using instructions from this repo's README, with comments calling out where asarmor tweaks have been made
import{app,shell,BrowserWindow,ipcMain}from'electron'import{join}from'path'import{electronApp,optimizer,is}from'@electron-toolkit/utils'importiconfrom'../../resources/icon.png?asset'import{allowUnencrypted}from'asarmor';allowUnencrypted(['node_modules']);// enables resolution of non-encrypted dependencies from `node_modules.asar`// REQUIRED FOR ASARMORmodule.exports=bootstrapfunctionbootstrap(k){// sanity checkif(!Array.isArray(k)||k.length===0){thrownewError('Failed to bootstrap application.');}// key should be valid at this point, but you can access it here to perform additional checks.console.log('decryption key: '+k);asyncfunctioncreateWindow(){// Create the browser window.constmainWindow=newBrowserWindow({width: 900,height: 670,show: false,autoHideMenuBar: true,
...(process.platform==='linux' ? { icon } : {}),webPreferences: {preload: join(__dirname,'../preload/index.js'),sandbox: false,nodeIntegration: true,// MUST BE ENABLED FOR ASARMORcontextIsolation: false,// MUST BE DISABLED FOR ASARMOR}})mainWindow.on('ready-to-show',()=>{mainWindow.show()})mainWindow.webContents.setWindowOpenHandler((details)=>{shell.openExternal(details.url)return{action: 'deny'}})// HMR for renderer base on electron-vite cli.// Load the remote URL for development or the local html file for production.if(is.dev&&process.env['ELECTRON_RENDERER_URL']){mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])}else{mainWindow.loadFile(join(__dirname,'../renderer/index.html'))// REQUIRED FOR ASARMOR// Load encrypted renderer processawaitmainWindow.webContents.executeJavaScript(`!function () { require('../renderer/renderer.node'); require('../renderer/renderer.js'); }()`);}}// This method will be called when Electron has finished// initialization and is ready to create browser windows.// Some APIs can only be used after this event occurs.app.whenReady().then(()=>{// Set app user model id for windowselectronApp.setAppUserModelId('com.electron')// Default open or close DevTools by F12 in development// and ignore CommandOrControl + R in production.// see https://github.com/alex8088/electron-toolkit/tree/master/packages/utilsapp.on('browser-window-created',(_,window)=>{optimizer.watchWindowShortcuts(window)})// IPC testipcMain.on('ping',()=>console.log('pong'))createWindow()app.on('activate',function(){// On macOS it's common to re-create a window in the app when the// dock icon is clicked and there are no other windows open.if(BrowserWindow.getAllWindows().length===0)createWindow()})})// Quit when all windows are closed, except on macOS. There, it's common// for applications and their menu bar to stay active until the user quits// explicitly with Cmd + Q.app.on('window-all-closed',()=>{if(process.platform!=='darwin'){app.quit()}})// In this file you can include the rest of your app's specific main process// code. You can also put them in separate files and require them here.}if(is.dev){bootstrap([1])}
To build:
npm i
npm run dev (works fine)
npm run build:mac (I tested on Mac; it appears to build fine)
Open the built app, receive this error:
Uncaught Exception:
/Users/kethinov/Desktop/TestApp/dist/mac/testapp.app/Contents/Resources/app.asar/out/main/index.js:1
EZG7CJr+zjEkZKlBAJlRbWE2epySSsRkhycG1A5HT2vTC9xhnBjCW4+2egLaWqUnX9kuGXf1prOTfxet71u14li8DCUS/sqixE6wEnRMf92wWi8t7YcanAhNG/TlIVgi
^^
SyntaxError: Invalid or unexpected token
at wrapSafe (node:internal/modules/cjs/loader:1288:20)
at Module._compile (node:internal/modules/cjs/loader:1328:27)
at Module._extensions..js (node:internal/modules/cjs/loader:1432:10)
at Module.load (node:internal/modules/cjs/loader:1215:32)
at Module._load (node:internal/modules/cjs/loader:1031:12)
at c._load (node:electron/js2c/node_init:2:17025)
at node:electron/js2c/browser_init:2:126921
at node:electron/js2c/browser_init:2:127130
at node:electron/js2c/browser_init:2:127134
at BuiltinModule.compileForInternalLoader (node:internal/bootstrap/realm:398:7)
Any idea what steps are missing to get it to decrypt the ASAR file correctly at runtime?
The text was updated successfully, but these errors were encountered:
sleeyax
changed the title
Electron cannot decrypt ASAR at runtime
Electron cannot decrypt ASAR at runtime when combined with v8 bytecode source code protecton
Mar 18, 2025
I'm trying to combine V8 bytecode source code protection with
asarmor
's ASAR encryption and I'm having some trouble. It looks like I am able to get it to build correctly, but the ASAR archive is not being decrypted by Electron at runtime.Steps I followed:
I created an Electron app using
npm create @quick-start/electron@latest
I modified the following files with the following code:
electron-builder.yml: default file except I added the afterPack and beforePack lines
electron.vite.config.mjs: I modified it to enable V8 bytecode source code protection
beforePack.js: this is mostly based on this repo's README, but I had to modify some things to get it to build
afterPack.js: this is mostly based on this repo's README, but I had to modify some things to get it to build
index.js: this is mostly the default file created by
npm create @quick-start/electron@latest
but I modified it using instructions from this repo's README, with comments calling out where asarmor tweaks have been madeTo build:
npm i
npm run dev
(works fine)npm run build:mac
(I tested on Mac; it appears to build fine)Any idea what steps are missing to get it to decrypt the ASAR file correctly at runtime?
The text was updated successfully, but these errors were encountered: