-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
According to the ECMAScript specification, running a JavaScript program class x { static { const x = { x } = 0 ; } } is expected to result in ReferenceError but after obfuscating the JavaScript program, it results in TypeError.
Expected Behavior
Running the following JavaScript code using Node.js results in ReferenceError.
class x { static { const x = { x } = 0 ; } }Current Behavior
However, as shown below, running the obfuscated code using Node.js results in TypeError.
Obfuscated code
class x{static{const _0x2340e4={x}=0x0;}}In summary, obfuscated code results in TypeError, because obfuscator have renamed constant variable in class static block. (e.g. x to _0x2340e4)
- Original code and obfuscated code both evaluates
{ x } = 0and{x}=0x0to initializexinx = { x } = 0and_0x2340e4in_0x2340e4={x}=0x0. - When resolving
xin{x}, the original code resolves toxinconst xand the obfuscated code resolves toxinclass x. - In case of the original code,
ReferenceErrorexception arises because it tries to set mutable binding for uninitializedx, which refers toconst x.
- In case of the obfuscated code,
- the
TypeErrorexception arises because it tries to change the value of an immutable bindingx, which refers toclass x.
- the
Steps to Reproduce
- Obfuscate the following program using https://obfuscator.io.
- Run the following program using Node.js v18.13.0.
Your Environment
- Obfuscator version used: https://obfuscator.io.
- Node version used: v18.13.0
Stack trace
Minimal working example that will help to reproduce issue
Below is a detailed explanation using ECMAScript specification.
Evaluation of class x { static { const x = { x } = 0 ; } } is done by following algorithms.
1. Operation ClassDefinitionEvaluation of ECMAScript specification
In step 3, the algorithm creates an immutable binding of x.
In step 27, the algorithm initializes the binding of x with F.
In step 31-b, the algorithm calls Call(initializer,receiver).
where initializer represents the const x = { x } = 0 ; and receiver represents the evaluation result of ClassDefinition of x.
2. Operation ClassStaticBlockBody.EvaluateClassStaticBlockBody of the ECMAScript specification
This step evaluates the ClassStaticBlockBody, which represents const x = { x } = 0 ; and creates binding of variables in ClassStaticBlockBody in class environment.
In step 1, the algorithm calls FunctionDeclarationInstantiation(functionObject, <<>>), where functionObject represents the const x = { x } = 0 ;.
This step creates binding of x, which represents the constant variable name const x.
In step 2, the algorithm calls the evaluation of ClassStaticBlockStatementList, where ClassStaticBlockStatementList represents const x = { x } = 0 ;
3. Evaluation of LexicalBinding in ECMAScript specification
LexicalBinding represents x = {x} = 0, and it can be divided into BindingIdentifier x and Initializer = {x} = 0.
This algorithm intends to resolve bindingId and evaluate Initializer to initialize binding at step 5.
Note that binding for the constant variable x is not initialized until it reaches step 5.
In step 4, the algorithm calls the evaluation of Initializer.
4. Evaluation of AssignmentExpression in ECMAScript specification
AssignmentExpression represents {x} = 0, and it can be divided into LeftHandSideExpression {x} and AssignmentExpression 0.
In step 5, the algorithm calls DestructuringAssignmentEvaluation(value) of assignmentPattern, where value represents 0 and assignmentPattern represents {x}.
Then, DestructuringAssignmentEvaluation calls PropertyDestructuringAssignmentEvaluation(value), where value represents 0.
5. Operation AssignmentProperty.PropertyDestructuringAssignmentEvaluation in ECMASCript specification
In step 2, the algorithm resolves x as the constant variable x.
In step 5, the algorithm calls PutValue(V, W), where V represents a reference of the constant variable x and W rerpresents undefined.
Then, PutValue calls SetMutableBinding(N, V, S) of base, where base represents the environment that binding of constant variable x is stored, N represents x, V represents undefined, and S represents True.
6. Operation SetMutableBinding in ECMAScript specification
In step 3, the algorithm throws a ReferenceError exception, because the binding for N, which is x in envRec has not yet been initialized.
In detail, the x in envRec refers the x in const x. Therefore, it has not been initialized.
In comparison, the evaluation of the obfuscated JavaScript program, class x{static{const _0x2340e4={x}=0x0;}}, is similar but different in following steps.
2. Operation ClassStaticBlockBody.EvaluateClassStaticBlockBody of the ECMAScript specification
In step 1, the algorithm creates an immutable binding of _0x2340e4 in class environment.
In step 2, the algorithm calls the evaluation of ClassStaticBlockStatementList, where ClassStaticBlockStatementList represents const _0x2340e4 = { x } = 0x0 ;.
5. Operation AssignmentProperty.PropertyDestructuringAssignmentEvaluation in ECMASCript specification
In step 2, the algorithm resolves x as the class x.
In step 5, the algorithm calls PutValue(V, W), where V represents a reference of the class x.
Then, PutValue calls SetMutableBinding(N, V, S) of base, where base represents the environment that binding of class x is stored.
6. Operation SetMutableBinding in ECMAScript specification
In step 5-b, the algorithm throws a TypeError exception, because the binding for x in envRec is an immutable binding (class binding).
Since this is an attempt to change the value of an immuatble binding, the algorithm throws TypeError exception.









