Overview
The tape system is a bytecode-like instruction stream that dictates the control flow of the deobfuscated JavaScript. Think of it as a virtual machine where JavaScript functions read instructions from a base64-encoded tape to determine what operations to execute.From README.md:183-184: “The current implementation only reverse engineers the JavaScript component but the control flow JavaScript is dictated by the tape. We will need to reverse engineer the tape for the complete reverse engineering.”
What is the Tape?
The tape is a base64-encoded binary instruction stream that contains:- Function indices to execute
- Execution context information
- Operation parameters
- Control flow instructions
- State manipulation directives
Tape Components
Tape Variables
From the transform pipeline (refactor-obfuscated-code-jscodeshift-2.js:42):
Tape Parameters
From the parameter refactoring (refactor-obfuscated-code-jscodeshift-4.js:14):
Tape Execution Flow
1. Tape Initialization
2. Execution Index Tracking
The tape maintains execution indices that point to the current instruction:3. Function Execution
Tape and Global State Integration
The tape execution system is tightly coupled with the global state:Base64 Decoding
The tape arrives as base64 and must be decoded:Binary String Operations
The tape system includes utilities for binary string manipulation:Tape Keywords
The tape can reference keyword strings stored in a lookup table:mitmproxy/src/javascript/pre-transform-code.js
Keyword Access Pattern
Obfuscated Code Rotation
From README.md:131-140, bet365 rotates their obfuscated code, which includes different tape encodings:The obfuscated code is manually tracked in
mitmproxy/src/javascript/obfuscated/.Factors affecting tape version:- Location (IP address)
- Time (rotates periodically)
String Extraction from Tape
Strings are encoded in the tape and extracted during execution:Function Index Resolution
The tape contains indices to functions that should be executed:Module System
The tape drives a module loading system:Module-Related Variables
Tape-Driven Control Flow
Conditional Execution
The tape determines which branches to execute:Loop Control
Loops are controlled by tape instructions:Error Handling
Error handlers are registered via the tape:Tape Analysis Challenges
Dynamic Decoding
Dynamic Decoding
The tape is decoded at runtime, making static analysis difficult. The base64 encoding changes with each obfuscation rotation.
Context Dependency
Context Dependency
Tape instructions depend on
globalState[35] execution context, which changes frequently during execution.Opaque Operations
Opaque Operations
The meaning of specific byte sequences in the tape is not documented and must be reverse-engineered through observation.
Development Tools
Watchexec Development Loop
From README.md:143-150:Tape Logging
You can log tape operations by instrumenting the deobfuscated code:Future Work
From README.md:189-193:Current Status: Only the JavaScript component is reverse-engineered. The tape format itself remains largely undocumented.Next Steps:
- Reverse engineer tape instruction format
- Document tape opcodes and their meanings
- Build a tape disassembler
- Create tape execution tracer
Related Concepts
- Global State - Runtime state manipulated by tape instructions
- Transform Scripts - How tape-related variables are renamed
- See README.md:183-193 for current limitations and future work
