diff --git a/HeuristicAnalyser.php b/HeuristicAnalyser.php index e1dbbce..9e55118 100644 --- a/HeuristicAnalyser.php +++ b/HeuristicAnalyser.php @@ -361,6 +361,14 @@ public function processContent() $this->variables->concatenateVars($key); } + foreach ( $this->tokens as $key => $_current_token ) { + $this->variables->replaceArrayVars($key); + } + + foreach ( $this->tokens as $key => $_current_token ) { + $this->strings->concatenateComplexStrings($key); + } + foreach ( $this->tokens as $key => $_current_token ) { $this->variables->replaceVars($key); } diff --git a/Modules/Transformations.php b/Modules/Transformations.php index 3f8a094..9ac81a3 100644 --- a/Modules/Transformations.php +++ b/Modules/Transformations.php @@ -44,8 +44,7 @@ public function decodeData($_key) $data = base64_decode((string)$this->tokens->next2->value); break; case 'urldecode': - $data = urldecode((string)$this->tokens->next2->value); - break; + return $this->transformUrlDecodeIntoTokens((string)$this->tokens->next2->value); case 'rawurldecode': $data = rawurldecode((string)$this->tokens->next2->value); break; @@ -152,4 +151,30 @@ private function transformHexStringIntoTokens($hex_string) //hex2bin failed return false; } + + /** + * Transform URL-encoded string into tokens. + * @param string $url_encoded_string + * @return bool + */ + private function transformUrlDecodeIntoTokens($url_encoded_string) + { + if (is_string($url_encoded_string)) { + $decoded_data = @urldecode($url_encoded_string); + + // Unset unnecessary tokens + $this->tokens->unsetTokens('next1', 'next2', 'next3'); + + // Add new token with the decoded data + $this->tokens['current'] = new Token( + 'T_CONSTANT_ENCAPSED_STRING', + $decoded_data, + $this->tokens->current->line, + $this->tokens->current->key + ); + + return true; + } + return false; + } } diff --git a/Modules/Variables.php b/Modules/Variables.php index a6f5976..4008c3d 100644 --- a/Modules/Variables.php +++ b/Modules/Variables.php @@ -455,6 +455,14 @@ public function concatenateVars($_key) return false; } + /** + * Replaces the current variable token with its value if it's a simple variable or a function call. + * This function searches for the first declaration of the variable and replaces the current token + * with the value found in that declaration. + * + * @param int $_key The key of the current token in the token array. + * @return void + */ public function replaceVars($_key) { if ( $this->tokens->current->type === 'T_VARIABLE' ) { @@ -462,7 +470,7 @@ public function replaceVars($_key) $var_first_declaration = $this->tokens->searchForward(0, (string)$this->tokens->current->value); // 10 if ( ! $var_first_declaration ) { - return false; + return; } $var_expression = $this->tokens->getRange( @@ -477,6 +485,42 @@ public function replaceVars($_key) } } + /** + * Replaces the current array variable token with its specific element value. + * This function checks if the next token is an array access and then replaces the current token + * with the value of the specified array element. + * + * @param int $_key The key of the current token in the token array. + * @return void + */ + public function replaceArrayVars($_key) + { + + if ( $this->tokens->current->type === 'T_VARIABLE' ) { + if ( $this->tokens->next1->value === '[' && $this->tokens->next2->type === 'T_LNUMBER') { + $var_first_declaration = $this->tokens->searchForward(0, (string)$this->tokens->current->value); // 10 + + if ( ! $var_first_declaration ) { + return; + } + + $var_expression = $this->tokens->getRange( + $this->tokens[$var_first_declaration][3], + $this->tokens->searchForward($this->tokens[$var_first_declaration][3], ';') - 1 + ); + + $this->tokens['current'] = new Token( + 'T_CONSTANT_ENCAPSED_STRING', + '\'' . trim($var_expression[2][1][$this->tokens->next2->value + 1], '\'\"') . '\'', + $this->tokens->current->line, + $this->tokens->current->key + ); + + $this->tokens->unsetTokens('next1', 'next2', 'next3'); + } + } + } + /** * Replace variables with its content *