Skip to main content
This guide covers common issues you may encounter and their solutions.

Installation Issues

Node.js Version Mismatch

Symptom: Errors when running npm install or executing scripts.Solution: Use the correct Node.js version specified in .nvmrc:
nvm install $(cat .nvmrc) && nvm use
The project requires Node.js LTS (v22.13.0 at time of writing).

Python Dependencies Failed

Symptom: Error installing mitmproxy or other Python dependencies.Solution: Create a fresh conda environment:
source new-conda-environment.sh
If you skipped creating a new environment:
./python-dependencies.sh
Requirements:
  • miniforge/miniconda installed
  • Python 3.12

npm Update Required

Symptom: Package installation warnings or errors.Solution: Update npm globally:
npm update -g npm
Then reinstall dependencies:
rm -rf node_modules package-lock.json
npm install

mitmproxy Issues

mitmproxy Not Starting

Symptom: Error when running ./mitmproxy.sh.Solutions:
  1. Verify mitmproxy is installed:
which mitmproxy
  1. Check Python environment is activated:
conda env list
  1. Ensure port 8080 is not in use:
lsof -i :8080
  1. Run mitmproxy with verbose logging:
mitmproxy -s mitmproxy/src/python/main/download-payload.py -v

Browser Not Using Proxy

Symptom: No traffic visible in mitmproxy, obfuscated code not intercepted.Solutions:macOS:
open -a "Google Chrome" --args \
  --proxy-server=http://localhost:8080 \
  --user-data-dir=$(pwd)/chrome-profile
Verify proxy is working:
  • Navigate to any HTTPS site
  • You should see a certificate warning (first time)
  • mitmproxy should show requests in the console
Common mistakes:
  • Using existing Chrome instance (close all Chrome windows first)
  • Not specifying --user-data-dir (Chrome won’t use proxy without it)
  • Firewall blocking localhost:8080

Certificate Errors

Symptom: Browser shows security warnings, can’t access HTTPS sites.Solution: Install mitmproxy’s certificate:
  1. Start mitmproxy
  2. Navigate to http://mitm.it
  3. Download and install the certificate for your platform
  4. Restart the browser
For Chrome, you may need to explicitly trust the certificate in system settings.

Code Interception Issues

Obfuscated Code Not Captured

Symptom: Output directory empty or missing expected JavaScript files.Diagnostics:
  1. Check mitmproxy is intercepting requests:
# In mitmproxy console, you should see requests to /Api/1/Blob
  1. Verify the filter is working:
# In download-payload.py
self.filter = flowfilter.parse("~u '/Api/1/Blob'")
  1. Check file detection logic:
# The obfuscated code should start with:
obfuscated_start_string = "(function(){ var _0x123a="
Solutions:
  • bet365 may have changed their URL structure - update the filter
  • Obfuscated code signature may have changed - update obfuscated_start_string
  • Clear browser cache and reload

Wrong Code Version Intercepted

Symptom: The intercepted code doesn’t match known patterns.Explanation: bet365 rotates obfuscated code based on:
  • Location (IP address)
  • Time (periodic rotation)
  • User agent
  • Random distribution
Solution:
  1. Save the new version:
python mitmproxy/src/python/save_obfuscated_code.py
  1. Update your transforms to handle the new patterns:
# Compare with previous versions
diff mitmproxy/src/javascript/obfuscated/*.js
  1. All obfuscated versions are tracked in:
mitmproxy/src/javascript/obfuscated/

Deobfuscation Issues

Transform Errors

Symptom: Node.js errors during transformation.Common Causes:
  1. Syntax Error in Input:
# Validate input file
node --check input.js
  1. Transform Bug:
# Enable intermediate output to find which transform fails
node mitmproxy/src/javascript/refactor-obfuscated-code-jscodeshift.js \
  input.js output.js true

# Check deobfuscated-output-0.js, -1.js, -2.js, etc.
  1. Memory Issues:
# Increase Node.js heap size
node --max-old-space-size=4096 \
  mitmproxy/src/javascript/refactor-obfuscated-code-jscodeshift.js \
  input.js output.js

Invalid JavaScript Output

Symptom: Browser errors, or node --check fails.Diagnostics:
  1. Validate each transform step:
for file in deobfuscated-output-*.js; do
    echo "Checking $file"
    node --check "$file" || echo "FAILED: $file"
done
  1. Identify the problematic transform:
# The last valid file shows which transform broke the code
Solutions:
  • Review the failing transform’s logic
  • Check if it handles all edge cases
  • Use AST Explorer to verify replacement patterns
  • Add additional guards to prevent invalid replacements

Variable Renaming Conflicts

Symptom: Code runs but produces incorrect results.Cause: Variable name collision in refactorVariables mapping.Solution:Review the variable mapping in refactor-obfuscated-code-jscodeshift-2.js:
var refactorVariables = {
    '_0x1e16': 'keywords',
    '_0x35ab': 'getKeywordName',
    // Ensure no duplicates in values
};
Run a check:
const values = Object.values(refactorVariables);
const duplicates = values.filter((v, i) => values.indexOf(v) !== i);
console.log('Duplicate mappings:', duplicates);

Runtime Issues

DevTools Detection

Symptom: Website behaves differently when DevTools is open.Explanation: bet365 detects DevTools by checking for:
  • tapeKeywords[27269] changes
  • Timing differences
  • Console API modifications
Workarounds:
  1. Use remote debugging:
chrome --remote-debugging-port=9222 --user-data-dir=./chrome-profile
  1. Monitor via log files instead:
chrome --enable-logging --v=1 --user-data-dir=./chrome-profile
tail -f chrome-profile/chrome_debug.log
  1. Disable detection code in transformed output (educational purposes only)

Webdriver Detection

Symptom: Site blocks access when using Selenium/Playwright.Note: The current implementation does not fully bypass webdriver detection.Alternatives:
  • Use mitmproxy with a real browser session
  • For data scraping, prefer WebSocket connections (more efficient)
  • Future work will focus on WebSocket reverse engineering
Important: Even if webdriver detection is bypassed, scraping via WebSocket is faster and more reliable.

Cache Issues

Symptom: Browser still uses old obfuscated code despite new transforms.Solution:
  1. Clear all cache:
rm -rf chrome-profile/Default/Cache
rm -rf chrome-profile/Default/Code\ Cache
  1. Use Clear Cache extension:
  • Install from Chrome Web Store
  • Bind to keyboard shortcut
  • Clear cache before each test
  1. Disable cache in DevTools:
  • Open DevTools
  • Network tab → Disable cache checkbox
  • (But remember this triggers detection)

Development Workflow Issues

watchexec Not Working

Symptom: Changes to transforms don’t trigger recompilation.Solutions:
  1. Install watchexec:
# macOS
brew install watchexec

# Linux
cargo install watchexec-cli
  1. Verify pattern matching:
watchexec -e js "echo 'file changed'"
# Make a change to any .js file
  1. Check for file system issues:
# macOS: Increase file watch limit
sudo sysctl -w kern.maxfiles=65536
sudo sysctl -w kern.maxfilesperproc=65536

Output Directory Permissions

Symptom: Permission denied errors when intercepting code.Solution:
# Create output directory if missing
mkdir -p output

# Fix permissions
chmod 755 output

# Verify ownership
ls -la output/

Performance Issues

Slow Transformation

Symptom: Browser hangs waiting for transformed code.Optimization strategies:
  1. Disable intermediate output in production:
const outputIntermediateSteps = false;
  1. Profile transforms:
node --prof \
  mitmproxy/src/javascript/refactor-obfuscated-code-jscodeshift.js \
  input.js output.js

node --prof-process isolate-*.log > profile.txt
  1. Pre-compute transformations:
  • Use refactor_script_on_fly = False
  • Manually generate deobfuscated.js once
  • Serve the cached version
  1. Optimize transform logic:
  • Avoid redundant AST traversals
  • Use more specific node queries
  • Cache intermediate results

High Memory Usage

Symptom: FATAL ERROR: Reached heap limit Allocation failedSolutions:
# Increase heap size
node --max-old-space-size=4096 script.js

# Monitor memory usage
node --expose-gc --trace-gc script.js
Consider splitting large obfuscated files into smaller chunks for processing.

Testing Issues

Jest Tests Failing

Symptom: Test suite errors.Solutions:
  1. Verify Babel configuration:
// .babelrc or babel.config.js should exist
{
  "presets": ["@babel/preset-env"]
}
  1. Clear Jest cache:
npx jest --clearCache
npm test
  1. Run specific test:
npx jest refactor-obfuscated-code-jscodeshift-common.test.js

Unknown Issues

Getting Help

If you encounter an issue not covered here:
1

Gather Information

Collect relevant details:
  • Error messages (full stack trace)
  • Node.js version: node --version
  • Python version: python --version
  • Operating system
  • Steps to reproduce
2

Check Recent Changes

bet365 frequently updates their code:
# Check if obfuscated code changed recently
ls -lt mitmproxy/src/javascript/obfuscated/

# Compare with your current code
diff mitmproxy/src/javascript/obfuscated-new-raw.js \
     mitmproxy/src/javascript/obfuscated/<latest>.js
3

Enable Verbose Logging

Get more diagnostic information:
# mitmproxy with verbose output
mitmproxy -s mitmproxy/src/python/main/download-payload.py -v

# Node.js with debugging
node --inspect --inspect-brk script.js
4

Test in Isolation

Narrow down the issue:
# Test individual transform
node mitmproxy/src/javascript/refactor-obfuscated-code-jscodeshift-0.js

# Test with minimal input
echo "void 0" | node transform-test.js

Common Error Messages

”oldString not found in content”

Cause: The Edit tool couldn’t find the exact string to replace. Solution: Check for whitespace differences, ensure you’re reading the file first, and verify the string exists.

”Cannot find module”

Cause: Missing Node.js dependency. Solution:
npm install

“EADDRINUSE: address already in use”

Cause: Port 8080 already in use. Solution:
# Find process using port 8080
lsof -i :8080

# Kill the process
kill -9 <PID>

# Or use different port
mitmproxy -s mitmproxy/src/python/main/download-payload.py -p 8081

“SyntaxError: Unexpected token”

Cause: Invalid JavaScript input or output from transform. Solution: Validate at each step using node --check filename.js

Best Practices for Avoiding Issues

Use Version Control: Keep track of working configurations so you can roll back if something breaks.
Test Incrementally: When adding new transforms, test each one individually before adding to the chain.
Monitor bet365 Changes: Set up automated checks to detect when bet365 updates their obfuscation patterns.
Document Your Changes: Comment your custom transforms and keep notes on what patterns they handle.
Always keep backup copies of working obfuscated code and transforms. bet365’s frequent updates can break functionality.

Build docs developers (and LLMs) love