Introduction
Debuggers are invaluable tools when analyzing JavaScript, especially when dealing with obfuscated code and client-side protections. Developers and security researchers rely on them to understand how a web application functions, uncover vulnerabilities, or bypass restrictions.
Issue
However, many companies and developers implement anti-debugging techniques to make reversing their code more difficult. They inject scripts that detect when the browser is in debug mode, use obfuscation tricks, or even forcefully disable breakpoints. This makes the process of analyzing JavaScript incredibly frustrating, especially when dealing with proprietary protections or security mechanisms designed to prevent reverse engineering.
Disabling Breakpoints: A Simple but Limited Solution
A straightforward way to bypass some debugger detection mechanisms is to disable breakpoints entirely. This prevents JavaScript from pausing execution, making it harder for anti-debugging scripts to interfere.
However, this method has a significant trade-off: it also disables the ability to analyze JavaScript execution effectively. While this might work in some cases, it is not an ideal solution for deeper analysis, as losing the ability to set breakpoints severely limits our ability to inspect variables, modify execution flow, or analyze how the code behaves in real-time.
Renaming the Debugger in Firefox’s Source Code
⚠️ Important Note: This technique should only be used for legitimate security research, software development, and authorized testing. Unauthorized reverse engineering may violate terms of service or legal requirements.
The main issue with debugging restrictions is that websites rely on specific methods to detect the debugger’s presence. By changing the internal name of the Firefox debugger within the source code, we can bypass these detection mechanisms without losing debugging functionality.
Getting Firefox’s Source Code and Building It (macOS Instructions)
For detailed documentation, refer to:
🔗 Firefox Source Docs
1. Install Xcode
Download and install Xcode from the App Store. Then finalize the installation in your terminal:
$ sudo xcode-select --switch /Applications/Xcode.app
$ sudo xcodebuild -license
2. Install Mercurial
Mercurial is required to fetch the Firefox source code:
$ python3 -m pip install --user mercurial
3. Bootstrap a Copy of the Firefox Source Code
Run the following commands to get a local copy of the source:
$ curl https://hg.mozilla.org/mozilla-central/raw-file/default/python/mozboot/bin/bootstrap.py -O
$ python3 bootstrap.py
⚠️ Warning: Downloading the Firefox source code requires approximately 15GB of disk space and may take some time depending on your internet connection.
4. Configure Build Settings
When running the bootstrap script, you’ll be prompted to choose various configuration options:
$ python3 bootstrap.py
When running the bootstrap script, you’ll be prompted to select various configuration options. Follow the instructions and confirm the installation of required tools or dependencies.
4. Build and Run Firefox
Once configuration is complete:
$ cd mozilla-unified
$ hg up -C central
$ ./mach build
For reference, building Firefox took approximately 30 minutes using a system with 10 CPU cores and 32 GiB RAM.
After the build completes successfully, you can run the modified Firefox using:
$ ./mach run
After a successful build, you can find your compiled Firefox at:
obj-aarch64-apple-darwin*/dist/Nightly.app
*Note: The exact path may vary depending on your system architecture and version.
Editing the Source Code
Now comes the most interesting and surprisingly simple part: modifying the Firefox source code to rename the “debugger” keyword. To achieve this, I searched through the source code for all occurrences of “debugger”, compiled the browser multiple times, and identified the exact locations that needed to be changed. The goal was to rename the debugger internally to “debuggy” so that anti-debugging scripts would no longer detect it.
The changes were made in the following two files:
- mozilla-unified/js/src/frontend/ReservedWords.h
- mozilla-unified/js/src/vm/CommonPropertyNames.h
Here are the 2 changes that need to be made:
diff --git a/js/src/frontend/ReservedWords.h b/js/src/frontend/ReservedWords.h
--- a/js/src/frontend/ReservedWords.h
+++ b/js/src/frontend/ReservedWords.h
@@ -20,7 +20,7 @@
MACRO(catch, catch_, TokenKind::Catch) \
MACRO(const, const_, TokenKind::Const) \
MACRO(continue, continue_, TokenKind::Continue) \
- MACRO(debugger, debugger, TokenKind::Debugger) \
+ MACRO(debuggy, debugger, TokenKind::Debugger) \
MACRO(default, default_, TokenKind::Default) \
MACRO(delete, delete_, TokenKind::Delete) \
MACRO(do, do_, TokenKind::Do) \
diff --git a/js/src/vm/CommonPropertyNames.h b/js/src/vm/CommonPropertyNames.h
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -129,7 +129,7 @@
MACRO_(daysInMonth, "daysInMonth") \
MACRO_(daysInWeek, "daysInWeek") \
MACRO_(daysInYear, "daysInYear") \
- MACRO_(debugger, "debugger") \
+ MACRO_(debugger, "debuggy") \
MACRO_(decimal, "decimal") \
MACRO_(decodeURI, "decodeURI") \
MACRO_(decodeURIComponent, "decodeURIComponent") \
With the modifications in place, I rebuilt the browser using the same build command (it takes 15 seconds this time :D).
Results: Debugger Detection Bypassed!
As shown below, an anti-debugging script fails to detect our modified debugger keyword:
The website’s protection now fails to detect debugging:
And our debugger still works perfectly, just under a different name:
Conclusion
By renaming the debugger internally in Firefox’s source code, we successfully bypassed JavaScript anti-debugging techniques while maintaining full debugging functionality. Unlike simply disabling breakpoints—an approach that limits further analysis—this method allows uninterrupted debugging without triggering protections.
Edit: 10/02/25
A friend needed a compiled version for Intel Mac, so I cross compiled it.
For detailed documentation, refer to: 🔗 Firefox Cross-Compilation Guide
I edited the .mozconfig file and added the following lines:
ac_add_options --target=x86_64-apple-darwin
ac_add_options --enable-bootstrap
After recompiling, I successfully built an Intel Mac version!
Download Pre-Compiled Versions
For convenience, I’ve made the modified versions of Firefox Nightly available for macOS:
🔹 Apple Silicon (ARM64) Version: 📥 Download Nightly_aarch64.tar.xz
🔹 Intel Mac (x86_64) Version: 📥 Download Nightly_x86_64.tar.xz