// JavaScript VM executor for ChatGPT reverse engineering use crate::utils::{Result, Utils}; use crate::vm::{Decompiler, Parser}; use base64::{Engine as _, engine::general_purpose}; use rand::Rng; use serde_json::{Map, Value}; use std::collections::HashMap; /// Virtual Machine for executing turnstile challenges pub struct VM; impl VM { /// HTML object used in VM calculations const HTML_OBJECT: &'static str = r#"{"x":0,"y":1219,"width":37.8125,"height":30,"top":1219,"right":37.8125,"bottom":1249,"left":0}"#; /// Generate turnstile token (simplified) pub fn get_turnstile(_bytecode: &str, _token: &str, _ip_info: &str) -> Result { // Placeholder implementation: real logic would parse bytecode and token to // compute the turnstile token. For now, keep a deterministic shape so the // rest of the pipeline can execute. Ok(format!( "0.{}.{}", chrono::Utc::now().timestamp(), rand::random::() )) } /// Decompile VM bytecode to JavaScript pub fn decompile_vm(turnstile: &str, token: &str) -> Result { Decompiler::decompile_vm(turnstile, token) } /// Parse keys from decompiled JavaScript pub fn parse_keys(decompiled_code: &str) -> Result<(String, HashMap)> { Parser::parse_keys(decompiled_code) } /// Execute JavaScript code and extract result /// /// Note: This is a simplified stub. Full implementation would require /// a JavaScript engine like V8 or QuickJS bindings pub fn execute_js(_code: &str) -> Result { // In a full implementation, this would: // 1. Create a JavaScript context // 2. Execute the decompiled code // 3. Extract the result // For now, return a placeholder Ok("{}".to_string()) } /// XOR two strings pub fn xor(data: &str, key: &str) -> String { Utils::xor_strings(data, key) } /// Add values to VM payload based on extracted operations pub fn add_vm_values( payload: &mut Map, xor_key: &str, ip_info: &str, ) -> Result<()> { let mut rng = rand::rng(); // Random values let random1: f64 = rng.random(); let random2: f64 = rng.random(); payload.insert( "19.33".to_string(), Value::String( general_purpose::STANDARD .encode(Self::xor(&format!("{}", random1 + 0.6), xor_key).as_bytes()), ), ); payload.insert( "56.04".to_string(), Value::String( general_purpose::STANDARD .encode(Self::xor(r#"["Google Inc.","Win32",8,0]"#, xor_key).as_bytes()), ), ); payload.insert( "14.85".to_string(), Value::String( general_purpose::STANDARD.encode(Self::xor(Self::HTML_OBJECT, xor_key).as_bytes()), ), ); payload.insert( "31.17".to_string(), Value::String(general_purpose::STANDARD.encode( Self::xor("oai/apps/hasDismissedTeamsNoAuthUpsell,oai-did", xor_key).as_bytes(), )), ); payload.insert( "7.1".to_string(), Value::String( general_purpose::STANDARD .encode(Self::xor(&rng.random_range(1..5).to_string(), xor_key).as_bytes()), ), ); payload.insert( "75.89".to_string(), Value::String(general_purpose::STANDARD.encode(Self::xor(ip_info, xor_key).as_bytes())), ); payload.insert( "84.91".to_string(), Value::String( general_purpose::STANDARD .encode(Self::xor("https://chatgpt.com/", xor_key).as_bytes()), ), ); payload.insert( "30.7".to_string(), Value::String( general_purpose::STANDARD .encode(Self::xor(&random1.to_string(), &random1.to_string()).as_bytes()), ), ); payload.insert( "27.36".to_string(), Value::Number(serde_json::Number::from_f64(random2).unwrap()), ); Ok(()) } /// Simplified bytecode decompiler (placeholder for complex implementation) pub fn decompile_bytecode(_bytecode: &str) -> Result> { // This is a placeholder for the complex JavaScript decompiler // In the real implementation, this would parse and execute the bytecode let mut operations = HashMap::new(); // These would be extracted from the actual bytecode operations.insert("xor_key".to_string(), "48.51".to_string()); operations.insert("19.33".to_string(), "random_add".to_string()); operations.insert("56.04".to_string(), "vendor".to_string()); operations.insert("14.85".to_string(), "element".to_string()); operations.insert("31.17".to_string(), "localstorage".to_string()); operations.insert("7.1".to_string(), "history".to_string()); operations.insert("75.89".to_string(), "ipinfo".to_string()); operations.insert("84.91".to_string(), "location".to_string()); operations.insert("30.7".to_string(), "random_1".to_string()); operations.insert("27.36".to_string(), "random_2".to_string()); Ok(operations) } /// Process and execute VM bytecode with full pipeline pub fn process_bytecode( turnstile: &str, token: &str, ip_info: &str, ) -> Result> { // Step 1: Decompile bytecode let decompiled = Self::decompile_vm(turnstile, token)?; // Step 2: Parse keys from decompiled code let (xor_key, _parsed_keys) = Self::parse_keys(&decompiled)?; // Step 3: Build payload let mut payload = Map::new(); Self::add_vm_values(&mut payload, &xor_key, ip_info)?; Ok(payload) } }