- electron/electron#37147
-
[Bug]: performance.measureUserAgentSpecificMemory causes exception
- electron/electron#42267
-
fix: set up
performance_manager
in electron shell
-
- https://developer.mozilla.org/en-US/docs/Web/API/Performance/measureUserAgentSpecificMemory
-
Performance:
measureUserAgentSpecificMemory()
method -
The
measureUserAgentSpecificMemory()
method is used to estimate the memory usage of a web application including all its iframes and workers. -
Experimental: This is an experimental technology. Check the Browser compatibility table carefully before using this in production.
-
-
- https://stackoverflow.com/questions/69827243/how-to-properly-debug-electron-memory-issues
- https://seenaburns.com/debugging-electron-memory-usage/
- https://seenaburns.com/debugging-electron-memory-usage/#web-frames
webFrame.getResourceUsage()
require('electron').webFrame.getResourceUsage()
- https://seenaburns.com/debugging-electron-memory-usage/#web-frames
- https://www.electronjs.org/docs/latest/api/web-frame
-
Customize the rendering of the current web page.
-
Process: Renderer
- https://github.com/electron/electron/blob/main/docs/api/web-frame.md
- https://www.electronjs.org/docs/latest/api/web-frame#webframegetresourceusage
-
Returns an object describing usage information of Blink's internal memory caches.
-
- https://www.electronjs.org/docs/latest/api/web-frame#webframeclearcache
-
Attempts to free memory that is no longer being used (like images from a previous navigation).
-
Note that blindly calling this method probably makes Electron slower since it will have to refill these emptied caches, you should only call it if an event in your app has occurred that makes you think your page is actually using less memory (i.e. you have navigated from a super heavy page to a mostly empty one, and intend to stay there).
-
-
- https://www.electronjs.org/docs/latest/tutorial/application-debugging
-
Application Debugging
-
- https://www.electronjs.org/docs/latest/tutorial/debugging-main-process
-
Debugging the Main Process
-
--inspect=[port]
: Electron will listen for V8 inspector protocol messages on the specified port, an external debugger will need to connect on this port. The default port is5858
. -
--inspect-brk=[port]
: Like--inspect
but pauses execution on the first line of JavaScript. -
You will need to use a debugger that supports the V8 inspector protocol.
-
Connect Chrome by visiting
chrome://inspect
and selecting to inspect the launched Electron app present there.
-
-
- https://www.electronjs.org/docs/latest/api/command-line-switches
-
Command line switches supported by Electron.
-
- https://www.electronjs.org/docs/latest/api/environment-variables
-
Control application configuration and behavior without changing code
-
Certain Electron behaviors are controlled by environment variables because they are initialized earlier than the command line flags and the app's code.
-
- https://www.electronjs.org/docs/latest/api/extensions
-
Chrome Extension Support
-
Electron supports a subset of the Chrome Extensions API, primarily to support DevTools extensions and Chromium-internal extensions, but it also happens to support some other extension capabilities.
-
- https://www.electronjs.org/docs/latest/tutorial/asar-archives
- https://www.electronjs.org/docs/latest/tutorial/asar-archives#adding-unpacked-files-to-asar-archives
-
you can leave various files unpacked using the
--unpack
option -
After running the command, you will notice that a folder named
app.asar.unpacked
was created together with theapp.asar
file. It contains the unpacked files and should be shipped together with theapp.asar
archive. - https://infosecwriteups.com/bug-bounty-tips-and-getting-persistence-with-electron-applications-c538d4dda446
- https://github.com/doyensec/electronegativity
-
Electronegativity is a tool to identify misconfigurations and security anti-patterns in Electron applications.
-
- https://blog.doyensec.com/2018/07/19/instrumenting-electron-app.html
-
npm install -g asar
-
asar extract core.asar destinationfolder
-
- https://github.com/doyensec/electronegativity
-
- https://www.electronjs.org/docs/latest/tutorial/asar-archives#adding-unpacked-files-to-asar-archives
- https://nodejs.org/en/docs/guides/debugging-getting-started
- https://stackoverflow.com/questions/54835751/opening-chromium-devtools-in-production-builds-of-electron-apps-without-source-c
-
Opening Chromium DevTools in production builds of Electron apps without source code or build process
-
The way to do this without third-party code is indeed using the --remote-debugging-port flag.
-
signal-desktop --remote-debugging-port
-
Open the debugging URL in a Google Chrome browser (in this case http://localhost:39733/), this will open a page with the app name on it
-
Click the to open a screen were you can click around to use the app and see output in the devtools
-
Alternatively, you can open
chrome://inspect/#devices
in the Google Chrome browser and click "inspect" (underneath the app name) to open the same window
-
-
- https://stackoverflow.com/questions/45485262/how-to-debug-electron-production-binaries
-
How to debug electron production binaries
- https://stackoverflow.com/a/56634497/1137085
-
Here's what worked for me on Mac.
-
In terminal type
lldb path/to/build.app
-
In the opened debugger type
run --remote-debugging-port=8315
. It should open a window of your app. -
Open Chrome at http://localhost:8315/
-
Click on the name of the app. For example, Webpack App.
-
If you don't see anything in the opened tab, focus on the window of your app.
-
-
For those running into the same issue,
./dist/mac/<your product identifier>.app/Contents/MacOS/<your product identifier> --remote-debugging-port=8315
may at least give a glimpse as to where the error is thrown, since it’ll log to console. I couldn’t get to a stage where http://127.0.0.1:8315 shows anything, though. -
if you get error:
process exited with status -1
make sure you have the debugging entitlements set,<key>com.apple.security.cs.debugger</key>
set totrue
-
- https://stackoverflow.com/a/65870502/1137085
-
Launch your Electron application with the
--remote-debugging-port=8315
flag set and navigate tochrome://inspect/#devices
in Chrome 80+. Then clickConfigure...
and addlocalhost:8315
as a discovery server. -
Then, wait for your Electron instance to appear in the devices list and click
inspect
-
- https://stackoverflow.com/a/61640271/1137085
-
On Mac just run
open /Applications/WhatsApp.app --args --remote-debugging-port=8315
and then open http://localhost:8315
-
- https://stackoverflow.com/a/59134941/1137085
-
Debugtron is an app to debug in-production Electron based app. It is also built with Electron.
- https://github.com/bytedance/debugtron
-
-
eg.
Open the electron app, and enable debugging for the main electron process:
open /Applications/Beeper.app --args --inspect=1337
Connect to this debug process from chrome://inspect/#devices
Run the following in the DevTools console:
- https://www.electronjs.org/docs/latest/api/web-frame-main
- https://www.electronjs.org/docs/latest/api/web-contents
const _electron = require('electron')
// Get "Array of ProcessMetric objects that correspond to memory and CPU usage statistics of all the processes associated with the app."
// https://www.electronjs.org/docs/latest/api/app#appgetappmetrics
// https://www.electronjs.org/docs/latest/api/structures/process-metric
// https://www.electronjs.org/docs/latest/api/structures/memory-info
_electron.app.getAppMetrics()
// Looking at the PID's of the object returned, and contrasting them against the Process Name in macOS' Activity Monitor:
// [0] with `type: 'Browser'` seems to correspond to the main 'Beeper' process
// [1] with `type: 'GPU', serviceName: 'GPU'` seems to correspond to the 'Beeper Helper (GPU)' process
// [2] with `type: 'Utility', serviceName: 'network.mojom.NetworkService', name: 'Network Service'` seems to correspond to the 'Beeper Helper' process
// [3] with `type: 'Tab'` seems to correspond to the 'Beeper Helper (Renderer)' process
// Open devtools for the first webContents (can do similar for others if there are more than one listed)
_electron.webContents.getAllWebContents()[0].openDevTools()
// Find the webContents for the main Beeper app
const beeperWebContents = _electron.webContents.getAllWebContents().find(wc => wc.mainFrame.origin === 'nova://nova-web')
// Access the .mainFrame
beeperWebContents.mainFrame
// View the preload paths
beepereWebContents._getPreloadPaths()
// [
// '/Applications/Beeper.app/Contents/Resources/app.asar/node_modules/@sentry/electron/preload/index.js',
// '/Applications/Beeper.app/Contents/Resources/app.asar/lib/preload.js'
// ]
Extract the *.asar
bundle code:
⇒ npm install -g @electron/asar
⇒ nodenv rehash
⇒ asar -h
Usage: asar [options] [command]
Manipulate asar archive files
Options:
-V, --version output the version number
-h, --help display help for command
Commands:
pack|p [options] <dir> <output> create asar archive
list|l [options] <archive> list files of asar archive
extract-file|ef <archive> <filename> extract one file from archive
extract|e <archive> <dest> extract archive
*
help [command] display help for command
⇒ ls /Applications/Beeper.app/Contents/Resources/*.asar
/Applications/Beeper.app/Contents/Resources/app.asar
/Applications/Beeper.app/Contents/Resources/webapp.asar
⇒ asar extract /Applications/Beeper.app/Contents/Resources/app.asar ~/Desktop/Beeper-app.asar
⇒ asar extract /Applications/Beeper.app/Contents/Resources/webapp.asar ~/Desktop/Beeper-webapp.asar
- https://github.com/0xdevalias/chatgpt-source-watch : Analyzing the evolution of ChatGPT's codebase through time with curated archives and scripts.
- Deobfuscating / Unminifying Obfuscated Web App Code (0xdevalias' gist)
- Reverse Engineering Webpack Apps (0xdevalias' gist)
- Reverse Engineered Webpack Tailwind-Styled-Component (0xdevalias' gist)
- React Server Components, Next.js v13+, and Webpack: Notes on Streaming Wire Format (
__next_f
, etc) (0xdevalias' gist)) - Fingerprinting Minified JavaScript Libraries / AST Fingerprinting / Source Code Similarity / Etc (0xdevalias' gist)
- Bypassing Cloudflare, Akamai, etc (0xdevalias' gist)
- Debugging Electron Apps (and related memory issues) (0xdevalias gist)
- devalias' Beeper CSS Hacks (0xdevalias' gist)
- Reverse Engineering Golang (0xdevalias' gist)
- Reverse Engineering on macOS (0xdevalias' gist)
Edit: This has also been duplicated across to my Beeper CSS Hacks gist as well:
On macOS you can get to the Beeper
*.asar
files by:⇒ cd /Applications/Beeper.app/Contents/Resources ⇒ ls af.lproj/ cs.lproj/ fa.lproj/ icon.icns ml.lproj/ ru.lproj/ todesktop-runtime-config.json am.lproj/ da.lproj/ fi.lproj/ icons/ mr.lproj/ sk.lproj/ tr.lproj/ app-update.yml de.lproj/ fil.lproj/ id.lproj/ ms.lproj/ sl.lproj/ uk.lproj/ app.asar el.lproj/ fr.lproj/ it.lproj/ nb.lproj/ sr.lproj/ ur.lproj/ app.asar.unpacked/ en.lproj/ gu.lproj/ ja.lproj/ nl.lproj/ sv.lproj/ vi.lproj/ ar.lproj/ en_GB.lproj/ he.lproj/ kn.lproj/ pl.lproj/ sw.lproj/ webapp.asar bg.lproj/ es.lproj/ hi.lproj/ ko.lproj/ pt_BR.lproj/ ta.lproj/ zh_CN.lproj/ bn.lproj/ es_419.lproj/ hr.lproj/ lt.lproj/ pt_PT.lproj/ te.lproj/ zh_TW.lproj/ ca.lproj/ et.lproj/ hu.lproj/ lv.lproj/ ro.lproj/ th.lproj/
Where the most relevant files/folders there are:
app.asar
app.asar.unpacked/
webapp.asar
From memory, I believe
app.asar
is more related to the core electron/element type features, andwebapp.asar
was more related to the more custom Beeper features; but I didn't look super deeply into that side of things.We can then use the node
asar
package vianpx
to inspect the contents of the*.asar
files:We can then run Beeper passing the node remote debugging
--inspect-brk
command to set a breakpoint at the entrypoint of the code:Which we can then connect to by opening a Chrome browser, navigating to
chrome://inspect/#devices
, and under 'Remote Target' looking for something like the following:Then clicking on 'inspect', which will open the Chrome DevTools 'Sources' tab and show the entrypoint line where the debugger has stopped execution, in this case, in the
file:///Applications/Beeper.app/Contents/Resources/app.asar/lib/electron-main.js
file:We can then skim around the code in this file to understand what it does, and what other options are available.
For example, here are some command line arguments documentation; of which
--devtools
sounds interesting:We can also see some path loading aspects of where the app looks for
webapp.asar
:There are also some hidden/undocumented CLI arguments,
localdev
/localapi
:We find the code that processes the
--devtools
arg here:A little further down we see how
localdev
/localapi
are handled:Then beyond that, you're sort of getting deeper into the internals of Electron apps and how Beeper / Element is built on top of Electron; so really depends what you're wanting to achieve at that point.
While at the initial 'entrypoint' debugger breakpoint (from
--inspect-brk
), we could also choose to manually load/inject some custom code of our own. For example:With a code file like:
We could run the following in the Chrome Devtools console while at the initial app loading debug breakpoint:
Which would show an output message such as: