Merge pull request #78 from pdalancer/hotfix
Some checks failed
Build and Push Docker Image / build-and-push (push) Has been cancelled
Build and test inv_sig_helper / build (push) Has been cancelled

This commit is contained in:
TheFrenchGhosty 2025-04-23 16:19:14 +02:00 committed by GitHub
commit 5d3c7a4574
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 97 additions and 52 deletions

View file

@ -14,6 +14,7 @@ pub static NSIG_FUNCTION_ARRAYS: &[&str] = &[
];
pub static NSIG_FUNCTION_ENDINGS: &[&str] = &[
r#"=\s*function([\S\s]*?\}\s*return [A-Za-z0-9$]+\[[A-Za-z0-9$]+\[\d+\]\]\([A-Za-z0-9$]+\[\d+\]\)\s*\};)"#,
r#"=\s*function(\(\w\)\s*\{[\S\s]*\{return.[a-zA-Z0-9_-]+_w8_.+?\}\s*return\s*\w+.join\(""\)\};)"#,
r#"=\s*function([\S\s]*?\}\s*return \w+?\.join\([^)]+\)\s*\};)"#,
r#"=\s*function([\S\s]*?\}\s*return [\W\w$]+?\.call\([\w$]+?,\"\"\)\s*\};)"#,
@ -21,9 +22,14 @@ pub static NSIG_FUNCTION_ENDINGS: &[&str] = &[
pub static REGEX_SIGNATURE_TIMESTAMP: &Lazy<Regex> = regex!("signatureTimestamp[=:](\\d+)");
pub static REGEX_SIGNATURE_FUNCTION: &Lazy<Regex> =
regex!(r#"\s*?([a-zA-Z0-9_\$]{1,})=function\([a-zA-Z]{1}\)\{(.{1}=.{1}\.split\([a-zA-Z0-9\-_\$\[\]"]+\)[^\}{]+)return .{1}\.join\([a-zA-Z0-9\-_\$\[\]"]+\)\}"#);
pub static REGEX_HELPER_OBJ_NAME: &Lazy<Regex> = regex!(";([A-Za-z0-9_\\$]{2,})\\...\\(");
pub static REGEX_SIGNATURE_FUNCTION_PATTERNS: &[&str] = &[
r#"\s*?([a-zA-Z0-9_\$]{1,})=function\([a-zA-Z]{1}\)\{(.{1}=.{1}\.split\([a-zA-Z0-9\-_\$\[\]"]+\)[^\}{]+)return .{1}\.join\([a-zA-Z0-9\-_\$\[\]"]+\)\}"#, // old regex
r#"([a-zA-Z0-9_$]{1,})=function\(([a-zA-Z0-9_$]{1})\)\{[^}]*GLOBAL_VAR_NAME\[[^\]]+\][^}]*return [^}]*GLOBAL_VAR_NAME\[[^\]]+\][^}]*\}"#, // new regex
r#"([a-zA-Z0-9_$]{1,})=function\(([a-zA-Z0-9_$]{1})\)\{[^}]*return [^}]*GLOBAL_VAR_NAME\[[^\]]+\][^}]*\}"#, // more general regex
];
// pub static REGEX_SIGNATURE_FUNCTION: &Lazy<Regex> = regex!(r#"\s*?([a-zA-Z0-9_\$]{1,})=function\([a-zA-Z]{1}\)\{(.{1}=.{1}\.split\([a-zA-Z0-9\-_\$\[\]"]+\)[^\}{]+)return .{1}\.join\([a-zA-Z0-9\-_\$\[\]"]+\)\}"#);
pub static REGEX_HELPER_OBJ_NAME: &Lazy<Regex> = regex!(";([A-Za-z0-9_\\$]{2,})(?:\\.|\\[)");
pub static NSIG_FUNCTION_NAME: &str = "decrypt_nsig";
pub static SIG_FUNCTION_NAME: &str = "decrypt_sig";

View file

@ -5,7 +5,7 @@ use regex::Regex;
use crate::{
consts::{
NSIG_FUNCTION_ARRAYS, NSIG_FUNCTION_ENDINGS, NSIG_FUNCTION_NAME, REGEX_HELPER_OBJ_NAME,
REGEX_PLAYER_ID, REGEX_SIGNATURE_FUNCTION, REGEX_SIGNATURE_TIMESTAMP, TEST_YOUTUBE_VIDEO,
REGEX_PLAYER_ID, REGEX_SIGNATURE_FUNCTION_PATTERNS, REGEX_SIGNATURE_TIMESTAMP, TEST_YOUTUBE_VIDEO,
},
jobs::GlobalState,
};
@ -214,66 +214,105 @@ pub async fn fetch_update(state: Arc<GlobalState>) -> Result<(), FetchUpdateStat
break;
}
// Extract signature function name
let sig_function_name = REGEX_SIGNATURE_FUNCTION
.captures(&player_javascript)
.unwrap()
.get(1)
.unwrap()
.as_str();
let mut sig_function_body_regex_str: String = String::new();
sig_function_body_regex_str += &sig_function_name.replace("$", "\\$");
sig_function_body_regex_str += "=function\\([a-zA-Z0-9_]+\\)\\{.+?\\}";
let sig_function_body_regex = Regex::new(&sig_function_body_regex_str).unwrap();
let sig_function_body = sig_function_body_regex
.captures(&player_javascript)
.unwrap()
.get(0)
.unwrap()
.as_str();
// Get the helper object
let helper_object_name = REGEX_HELPER_OBJ_NAME
.captures(sig_function_body)
.unwrap()
.get(1)
.unwrap()
.as_str();
let mut helper_object_body_regex_str = String::new();
helper_object_body_regex_str += "(var ";
helper_object_body_regex_str += &helper_object_name.replace("$", "\\$");
helper_object_body_regex_str += "=\\{(?:.|\\n)+?\\}\\};)";
let helper_object_body_regex = Regex::new(&helper_object_body_regex_str).unwrap();
let helper_object_body = helper_object_body_regex
.captures(&player_javascript)
.unwrap()
.get(0)
.unwrap()
.as_str();
let mut sig_code = String::new();
sig_code += "var ";
sig_code += sig_function_name;
sig_code += ";";
if let Some((global_var, varname, _)) = extract_player_js_global_var(&player_javascript) {
sig_code += &global_var;
sig_code += ";";
debug!("fix sig code global var: {}", global_var);
debug!("fix sig code varname: {}", varname);
let (global_var, varname, _) = extract_player_js_global_var(&player_javascript).unwrap();
if !global_var.is_empty() {
debug!("Found global var for sig: {}", global_var);
debug!("Found varname for sig: {}", varname);
} else {
debug!("No global array variable found in player JS");
debug!("No global var found for sig");
}
sig_code += helper_object_body;
sig_code += sig_function_body;
// Extract signature function name
let mut sig_function_name = String::new();
let mut found_sig_function = false;
for sig_pattern in REGEX_SIGNATURE_FUNCTION_PATTERNS.iter() {
let _sig_pattern = sig_pattern.replace("GLOBAL_VAR_NAME", &regex::escape(&varname));
info!("sig code: {}", sig_code);
debug!("sig pattern: {}", _sig_pattern);
let sig_regex = match Regex::new(&_sig_pattern) {
Ok(r) => r,
Err(e) => {
warn!("Failed to compile signature regex pattern: {}", e);
continue;
}
};
if let Some(cap) = sig_regex.captures(&player_javascript) {
if let Some(m) = cap.get(1) {
sig_function_name = m.as_str().to_string();
found_sig_function = true;
break;
}
}
}
if !found_sig_function {
sig_function_name = format!("sig_function_{}", SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_millis());
info!("No signature function found in player JS, using random name: {}", sig_function_name);
}
let mut sig_code = String::new();
// if sig_function_name is not empty, then we need to extract the function body
if found_sig_function {
debug!("found sig function: {}", sig_function_name);
let mut sig_function_body_regex_str: String = String::new();
sig_function_body_regex_str += &sig_function_name.replace("$", "\\$");
sig_function_body_regex_str += "=function\\([a-zA-Z0-9_]+\\)\\{.+?\\}";
let sig_function_body_regex = Regex::new(&sig_function_body_regex_str).unwrap();
let sig_function_body = sig_function_body_regex
.captures(&player_javascript)
.unwrap()
.get(0)
.unwrap()
.as_str();
// Get the helper object
let helper_object_name = REGEX_HELPER_OBJ_NAME
.captures(sig_function_body)
.unwrap()
.get(1)
.unwrap()
.as_str();
let mut helper_object_body_regex_str = String::new();
helper_object_body_regex_str += "(var ";
helper_object_body_regex_str += &helper_object_name.replace("$", "\\$");
helper_object_body_regex_str += "=\\{(?:.|\\n)+?\\}\\};)";
let helper_object_body_regex = Regex::new(&helper_object_body_regex_str).unwrap();
let helper_object_body = helper_object_body_regex
.captures(&player_javascript)
.unwrap()
.get(0)
.unwrap()
.as_str();
sig_code += "var ";
sig_code += &sig_function_name;
sig_code += ";";
if !global_var.is_empty() {
sig_code += &global_var;
sig_code += ";";
}
sig_code += helper_object_body;
sig_code += sig_function_body;
} else {
// just return empty sig function code with random name
sig_code += "var ";
sig_code += &sig_function_name;
sig_code += ";";
info!("No signature function found in player JS, just returning empty sig function code with random name: {}", sig_function_name);
}
debug!("sig code: {}", sig_code);
// Get signature timestamp
let signature_timestamp: u64 = REGEX_SIGNATURE_TIMESTAMP