This guide covers the day-to-day development workflow for working with bet365-re-js, from making changes to testing and debugging.
Quick Start Development Loop
The most efficient workflow for developing new transformations:
Set up automatic recompilation
Use watchexec to automatically run transformations when you save files: watchexec -e js "touch mitmproxy/src/python/download-payload.py && \
node mitmproxy/src/javascript/refactor-obfuscated-code-jscodeshift.js \
mitmproxy/src/javascript/obfuscated-original.js \
mitmproxy/src/javascript/deobfuscated-output.js && \
node mitmproxy/src/javascript/pre-transform-code.js"
This watches for changes in any *.js file (except obfuscated-original.js and deobfuscated.js) and automatically recompiles.
Edit transformation scripts
Open your preferred editor and modify transformation scripts in: mitmproxy/src/javascript/refactor-obfuscated-code-jscodeshift-*.js
Each time you save, watchexec automatically runs the transformation.
Check the output
Review the generated output: code mitmproxy/src/javascript/deobfuscated-output.js
Or diff against expected output: diff deobfuscated-output.js expected-output.js
This workflow eliminates the need to manually run the transformation command after every change, significantly speeding up development.
Project Structure
Understanding the project layout helps you navigate efficiently:
bet365-re-js/
├── mitmproxy/
│ └── src/
│ ├── python/
│ │ ├── main/
│ │ │ └── download-payload.py # Main interception script
│ │ ├── save_obfuscated_code.py # Save intercepted code
│ │ ├── requirements.txt # Python dependencies
│ │ └── tests/ # Python/Playwright tests
│ └── javascript/
│ ├── refactor-obfuscated-code-jscodeshift.js # Entry point
│ ├── refactor-obfuscated-code-jscodeshift-*.js # Transformations
│ ├── refactor-obfuscated-code-jscodeshift-*.test.js # Tests
│ ├── pre-transform-code.js # Injected before deobfuscated code
│ ├── post-transform-code.js # Injected after deobfuscated code
│ ├── obfuscated/ # Historical obfuscated versions
│ ├── obfuscated-original.js # Your working copy
│ └── deobfuscated-output.js # Generated output
├── output/ # Intercepted files (gitignored)
├── chrome-profile/ # Chrome user data (gitignored)
├── package.json # Node.js dependencies
├── mitmproxy.sh # Start proxy script
├── new-conda-environment.sh # Python env setup
└── python-dependencies.sh # Install Python deps
Common Development Tasks
Testing Your Changes
Run All Tests
Run Specific Test
Watch Mode
npm test
# Runs all Jest tests for transformation scripts
Create the transformation script
touch mitmproxy/src/javascript/refactor-obfuscated-code-jscodeshift-11.js
Template structure: const transform = ( ast , j ) => {
// Your transformation logic here
return ast ;
};
module . exports = transform ;
Create a test file
touch mitmproxy/src/javascript/refactor-obfuscated-code-jscodeshift-11.test.js
Template: const transform = require ( './refactor-obfuscated-code-jscodeshift-11' );
const testUtil = require ( './refactor-obfuscated-code-jscodeshift-test-util' );
describe ( 'Transformation 11' , () => {
it ( 'should handle new obfuscation pattern' , () => {
const input = `/* obfuscated code */` ;
const expected = `/* deobfuscated code */` ;
const result = testUtil . applyTransform ( transform , input );
expect ( result ). toBe ( expected );
});
});
Import into the chain
Edit refactor-obfuscated-code-jscodeshift-chained.js to include your transformation: const transform11 = require ( './refactor-obfuscated-code-jscodeshift-11' );
// Add to the chain
ast = transform11 ( ast , j );
Test the change
npm test -- refactor-obfuscated-code-jscodeshift-11.test.js
Working with Obfuscated Code Versions
The project tracks multiple versions of bet365’s obfuscated code:
# List all saved versions
ls -lht mitmproxy/src/javascript/obfuscated/
# Compare two versions
diff -u mitmproxy/src/javascript/obfuscated/2024-01-15.js \
mitmproxy/src/javascript/obfuscated/2024-02-01.js
# Test against a specific version
node mitmproxy/src/javascript/refactor-obfuscated-code-jscodeshift.js \
mitmproxy/src/javascript/obfuscated/2024-01-15.js \
test-output.js
Keeping historical versions helps ensure your transformations work across different obfuscation patterns and don’t introduce regressions.
AST Explorer
For prototyping transformations: https://astexplorer.net/
Paste obfuscated JavaScript in the left pane
Select Parser: recast or esprima
Select Transform: jscodeshift
Write your transformation in the bottom pane
See results in real-time
For formatting obfuscated code: https://unminify.com/
This formatter handles comma operators particularly well, which bet365 uses extensively in their obfuscation.
Debugging Chrome Output
When running Chrome with --enable-logging --v=1, view console output without opening DevTools:
# View raw logs
tail -f ./chrome-profile/chrome_debug.log
# Filter for JSON output from injected code
tail -f ./chrome-profile/chrome_debug.log | \
sed -En "s/.*inside.* \\ ]: (.*) \" , source: \(3\)/\1/p"
Opening DevTools triggers bet365’s anti-debugging measures. The tapeKeywords[27269]: "" value is set when DevTools is open, which may alter behavior.
Running the Full Pipeline
End-to-End Test
Test the complete interception and deobfuscation workflow:
Launch proxied browser
open -a "Google Chrome" --args \
--proxy-server=http://localhost:8080 \
--user-data-dir=$( pwd )/chrome-profile
Navigate and verify
Go to https://www.bet365.com
Check mitmproxy logs for “Intercepting response”
Verify files appear in output/
Check that -sent- files contain deobfuscated code
Debugging Failed Deobfuscation
If the deobfuscation fails:
Check Received Files
Check Deobfuscated Files
Check for Errors
ls -lht output/ * -received- * .js | head -5
head -50 output/[latest]-received-0.js
# Verify the obfuscated code was intercepted correctly
Best Practices
Code Organization
Keep transformations focused : Each refactor-obfuscated-code-jscodeshift-*.js file should handle one specific obfuscation pattern. This makes debugging easier.
Version Control
# Before making changes, save the current obfuscated version
cp mitmproxy/src/javascript/obfuscated-new-raw.js \
mitmproxy/src/javascript/obfuscated/ $( date +%Y-%m-%d ) .js
# Commit with descriptive messages
git add mitmproxy/src/javascript/refactor-obfuscated-code-jscodeshift-11.js
git commit -m "Add transformation for new string encoding pattern"
Testing Strategy
Unit tests - Test individual transformations with *.test.js files
Integration tests - Test the full transformation chain with real obfuscated samples
Regression tests - Test against historical obfuscated versions
# Run against all historical versions
for file in mitmproxy/src/javascript/obfuscated/*.js ; do
echo "Testing $file "
node mitmproxy/src/javascript/refactor-obfuscated-code-jscodeshift.js \
" $file " \
"test-output-$( basename $file )" && echo "✓ PASS" || echo "✗ FAIL"
done
Transformations run on every intercepted request in real-time. Keep them efficient to avoid slowing down the browser experience.
Profile transformation performance:
time node mitmproxy/src/javascript/refactor-obfuscated-code-jscodeshift.js \
mitmproxy/src/javascript/obfuscated-original.js \
/dev/null
Continuous Integration (Future)
The project plans to implement CI/CD to:
Automatically detect when bet365 updates their obfuscated code
Run regression tests against new versions
Alert when transformations break
Maintain a backup deobfuscation script
This is a planned feature mentioned in the README but not yet implemented.
Troubleshooting Common Issues
watchexec not found
# macOS
brew install watchexec
# Linux
sudo apt install watchexec # Debian/Ubuntu
# or check your distribution's package manager
Node version mismatch
nvm use
# Automatically switches to the version in .nvmrc (v22.15.0)
If you see “SyntaxError” in the output:
Check if the input file is valid JavaScript
Verify you’re using the correct jscodeshift API
Test in AST Explorer first
Add error handling to your transformation
Python/Node environment conflicts
Ensure you’re in the correct environments:
# Check Python env
conda env list # Should show * next to bet365-re-js
# Check Node version
node --version # Should be v22.15.0
Next Steps
Review existing transformation scripts in mitmproxy/src/javascript/
Experiment with AST Explorer to understand code patterns
Try intercepting live traffic from bet365
Contribute new transformations when obfuscation patterns change