fix: keep JS context when deobfuscating

This commit is contained in:
ThetaDev 2023-02-04 16:15:35 +01:00
parent 1d56b9c9a0
commit 79446bed1c
4 changed files with 94 additions and 83 deletions

View file

@ -708,15 +708,16 @@ impl RustyPipe {
/// Instantiate a new deobfuscator from either cached or extracted YouTube JavaScript code.
async fn get_deobf(&self) -> Result<Deobfuscator, Error> {
// Write lock here to prevent concurrent tasks from fetching the same data
let mut deobf = self.inner.cache.deobf.write().await;
let mut deobf_data = self.inner.cache.deobf.write().await;
match deobf.get() {
Some(deobf) => Ok(Deobfuscator::from(deobf.to_owned())),
match deobf_data.get() {
Some(deobf_data) => Ok(Deobfuscator::new(deobf_data.clone())?),
None => {
log::debug!("getting deobfuscator");
let new_deobf = Deobfuscator::new(self.inner.http.clone()).await?;
*deobf = CacheEntry::from(new_deobf.get_data());
drop(deobf);
let data = DeobfData::download(self.inner.http.clone()).await?;
let new_deobf = Deobfuscator::new(data.clone())?;
*deobf_data = CacheEntry::from(data);
drop(deobf_data);
self.store_cache().await;
Ok(new_deobf)
}

View file

@ -612,19 +612,20 @@ mod tests {
use std::{fs::File, io::BufReader};
use path_macro::path;
use rstest::rstest;
use rstest::{fixture, rstest};
use super::*;
use crate::deobfuscate::DeobfData;
static DEOBFUSCATOR: Lazy<Deobfuscator> = Lazy::new(|| {
Deobfuscator::from(DeobfData {
js_url: "https://www.youtube.com/s/player/c8b8a173/player_ias.vflset/en_US/base.js".to_owned(),
sig_fn: "var oB={B4:function(a){a.reverse()},xm:function(a,b){a.splice(0,b)},dC:function(a,b){var c=a[0];a[0]=a[b%a.length];a[b%a.length]=c}};var Vva=function(a){a=a.split(\"\");oB.dC(a,42);oB.xm(a,3);oB.dC(a,48);oB.B4(a,68);return a.join(\"\")};function deobfuscate(a){return Vva(a);}".to_owned(),
nsig_fn: "Ska=function(a){var b=a.split(\"\"),c=[-1505243983,function(d,e){e=(e%d.length+d.length)%d.length;d.splice(-e).reverse().forEach(function(f){d.unshift(f)})},\n-1692381986,function(d,e){e=(e%d.length+d.length)%d.length;var f=d[0];d[0]=d[e];d[e]=f},\n-262444939,\"unshift\",function(d){for(var e=d.length;e;)d.push(d.splice(--e,1)[0])},\n1201502951,-546377604,-504264123,-1978377336,1042456724,function(d,e){for(e=(e%d.length+d.length)%d.length;e--;)d.unshift(d.pop())},\n711986897,406699922,-1842537993,-1678108293,1803491779,1671716087,12778705,-718839990,null,null,-1617525823,342523552,-1338406651,-399705108,-696713950,b,function(d,e){e=(e%d.length+d.length)%d.length;d.splice(0,1,d.splice(e,1,d[0])[0])},\nfunction(d,e){e=(e%d.length+d.length)%d.length;d.splice(e,1)},\n-980602034,356396192,null,-1617525823,function(d,e,f){var h=f.length;d.forEach(function(l,m,n){this.push(n[m]=f[(f.indexOf(l)-f.indexOf(this[m])+m+h--)%f.length])},e.split(\"\"))},\n-1029864222,-641353250,-1681901809,-1391247867,1707415199,-1957855835,b,function(){for(var d=64,e=[];++d-e.length-32;)switch(d){case 58:d=96;continue;case 91:d=44;break;case 65:d=47;continue;case 46:d=153;case 123:d-=58;default:e.push(String.fromCharCode(d))}return e},\n-1936558978,-1505243983,function(d){d.reverse()},\n1296889058,-1813915420,-943019300,function(d,e,f){var h=f.length;d.forEach(function(l,m,n){this.push(n[m]=f[(f.indexOf(l)-f.indexOf(this[m])+m+h--)%f.length])},e.split(\"\"))},\n\"join\",b,-2061642263];c[21]=c;c[22]=c;c[33]=c;try{c[3](c[33],c[9]),c[29](c[22],c[25]),c[29](c[22],c[19]),c[29](c[33],c[17]),c[29](c[21],c[2]),c[29](c[42],c[10]),c[1](c[52],c[40]),c[12](c[28],c[8]),c[29](c[21],c[45]),c[1](c[21],c[48]),c[44](c[26]),c[39](c[5],c[2]),c[31](c[53],c[16]),c[30](c[29],c[8]),c[51](c[29],c[6],c[44]()),c[4](c[43],c[1]),c[2](c[23],c[42]),c[2](c[0],c[46]),c[38](c[14],c[52]),c[32](c[5]),c[26](c[29],c[46]),c[26](c[5],c[13]),c[28](c[1],c[37]),c[26](c[31],c[13]),c[26](c[1],c[34]),\nc[46](c[1],c[32],c[40]()),c[26](c[50],c[44]),c[17](c[50],c[51]),c[0](c[3],c[24]),c[32](c[13]),c[43](c[3],c[51]),c[0](c[34],c[17]),c[16](c[45],c[53]),c[29](c[44],c[13]),c[42](c[1],c[50]),c[47](c[22],c[53]),c[37](c[22]),c[13](c[52],c[21]),c[6](c[43],c[34]),c[6](c[31],c[46])}catch(d){return\"enhanced_except_gZYB_un-_w8_\"+a}return b.join(\"\")};function deobfuscate(a){return Ska(a);}".to_owned(),
sts: "19201".to_owned(),
})
});
#[fixture]
fn deobf() -> Deobfuscator {
Deobfuscator::new(DeobfData {
js_url: "https://www.youtube.com/s/player/c8b8a173/player_ias.vflset/en_US/base.js".to_owned(),
sig_fn: "var oB={B4:function(a){a.reverse()},xm:function(a,b){a.splice(0,b)},dC:function(a,b){var c=a[0];a[0]=a[b%a.length];a[b%a.length]=c}};var Vva=function(a){a=a.split(\"\");oB.dC(a,42);oB.xm(a,3);oB.dC(a,48);oB.B4(a,68);return a.join(\"\")};var deobf_sig=Vva;".to_owned(),
nsig_fn: "Ska=function(a){var b=a.split(\"\"),c=[-1505243983,function(d,e){e=(e%d.length+d.length)%d.length;d.splice(-e).reverse().forEach(function(f){d.unshift(f)})},\n-1692381986,function(d,e){e=(e%d.length+d.length)%d.length;var f=d[0];d[0]=d[e];d[e]=f},\n-262444939,\"unshift\",function(d){for(var e=d.length;e;)d.push(d.splice(--e,1)[0])},\n1201502951,-546377604,-504264123,-1978377336,1042456724,function(d,e){for(e=(e%d.length+d.length)%d.length;e--;)d.unshift(d.pop())},\n711986897,406699922,-1842537993,-1678108293,1803491779,1671716087,12778705,-718839990,null,null,-1617525823,342523552,-1338406651,-399705108,-696713950,b,function(d,e){e=(e%d.length+d.length)%d.length;d.splice(0,1,d.splice(e,1,d[0])[0])},\nfunction(d,e){e=(e%d.length+d.length)%d.length;d.splice(e,1)},\n-980602034,356396192,null,-1617525823,function(d,e,f){var h=f.length;d.forEach(function(l,m,n){this.push(n[m]=f[(f.indexOf(l)-f.indexOf(this[m])+m+h--)%f.length])},e.split(\"\"))},\n-1029864222,-641353250,-1681901809,-1391247867,1707415199,-1957855835,b,function(){for(var d=64,e=[];++d-e.length-32;)switch(d){case 58:d=96;continue;case 91:d=44;break;case 65:d=47;continue;case 46:d=153;case 123:d-=58;default:e.push(String.fromCharCode(d))}return e},\n-1936558978,-1505243983,function(d){d.reverse()},\n1296889058,-1813915420,-943019300,function(d,e,f){var h=f.length;d.forEach(function(l,m,n){this.push(n[m]=f[(f.indexOf(l)-f.indexOf(this[m])+m+h--)%f.length])},e.split(\"\"))},\n\"join\",b,-2061642263];c[21]=c;c[22]=c;c[33]=c;try{c[3](c[33],c[9]),c[29](c[22],c[25]),c[29](c[22],c[19]),c[29](c[33],c[17]),c[29](c[21],c[2]),c[29](c[42],c[10]),c[1](c[52],c[40]),c[12](c[28],c[8]),c[29](c[21],c[45]),c[1](c[21],c[48]),c[44](c[26]),c[39](c[5],c[2]),c[31](c[53],c[16]),c[30](c[29],c[8]),c[51](c[29],c[6],c[44]()),c[4](c[43],c[1]),c[2](c[23],c[42]),c[2](c[0],c[46]),c[38](c[14],c[52]),c[32](c[5]),c[26](c[29],c[46]),c[26](c[5],c[13]),c[28](c[1],c[37]),c[26](c[31],c[13]),c[26](c[1],c[34]),\nc[46](c[1],c[32],c[40]()),c[26](c[50],c[44]),c[17](c[50],c[51]),c[0](c[3],c[24]),c[32](c[13]),c[43](c[3],c[51]),c[0](c[34],c[17]),c[16](c[45],c[53]),c[29](c[44],c[13]),c[42](c[1],c[50]),c[47](c[22],c[53]),c[37](c[22]),c[13](c[52],c[21]),c[6](c[43],c[34]),c[6](c[31],c[46])}catch(d){return\"enhanced_except_gZYB_un-_w8_\"+a}return b.join(\"\")};var deobf_nsig=Ska;".to_owned(),
sts: "19201".to_owned(),
}).unwrap()
}
#[rstest]
#[case::desktop("desktop")]
@ -632,13 +633,13 @@ mod tests {
#[case::tv_html5_embed("tvhtml5embed")]
#[case::android("android")]
#[case::ios("ios")]
fn map_player_data(#[case] name: &str) {
fn map_player_data(#[case] name: &str, deobf: Deobfuscator) {
let json_path = path!("testfiles" / "player" / format!("{name}_video.json"));
let json_file = File::open(json_path).unwrap();
let resp: response::Player = serde_json::from_reader(BufReader::new(json_file)).unwrap();
let map_res = resp
.map_response("pPvd8UxmSbQ", Language::En, Some(&DEOBFUSCATOR))
.map_response("pPvd8UxmSbQ", Language::En, Some(&deobf))
.unwrap();
assert!(
@ -660,14 +661,14 @@ mod tests {
});
}
#[test]
fn cipher_to_url() {
#[rstest]
fn cipher_to_url(deobf: Deobfuscator) {
let signature_cipher = "s=w%3DAe%3DA6aDNQLkViKS7LOm9QtxZJHKwb53riq9qEFw-ecBWJCAiA%3DcEg0tn3dty9jEHszfzh4Ud__bg9CEHVx4ix-7dKsIPAhIQRw8JQ0qOA&sp=sig&url=https://rr5---sn-h0jelnez.googlevideo.com/videoplayback%3Fexpire%3D1659376413%26ei%3Dvb7nYvH5BMK8gAfBj7ToBQ%26ip%3D2003%253Ade%253Aaf06%253A6300%253Ac750%253A1b77%253Ac74a%253A80e3%26id%3Do-AB_BABwrXZJN428ZwDxq5ScPn2AbcGODnRlTVhCQ3mj2%26itag%3D251%26source%3Dyoutube%26requiressl%3Dyes%26mh%3DhH%26mm%3D31%252C26%26mn%3Dsn-h0jelnez%252Csn-4g5ednsl%26ms%3Dau%252Conr%26mv%3Dm%26mvi%3D5%26pl%3D37%26initcwndbps%3D1588750%26spc%3DlT-Khi831z8dTejFIRCvCEwx_6romtM%26vprv%3D1%26mime%3Daudio%252Fwebm%26ns%3Db_Mq_qlTFcSGlG9RpwpM9xQH%26gir%3Dyes%26clen%3D3781277%26dur%3D229.301%26lmt%3D1655510291473933%26mt%3D1659354538%26fvip%3D5%26keepalive%3Dyes%26fexp%3D24001373%252C24007246%26c%3DWEB%26rbqsm%3Dfr%26txp%3D4532434%26n%3Dd2g6G2hVqWIXxedQ%26sparams%3Dexpire%252Cei%252Cip%252Cid%252Citag%252Csource%252Crequiressl%252Cspc%252Cvprv%252Cmime%252Cns%252Cgir%252Cclen%252Cdur%252Clmt%26lsparams%3Dmh%252Cmm%252Cmn%252Cms%252Cmv%252Cmvi%252Cpl%252Cinitcwndbps%26lsig%3DAG3C_xAwRQIgCKCGJ1iu4wlaGXy3jcJyU3inh9dr1FIfqYOZEG_MdmACIQCbungkQYFk7EhD6K2YvLaHFMjKOFWjw001_tLb0lPDtg%253D%253D";
let mut last_nsig: [String; 2] = ["".to_owned(), "".to_owned()];
let map_res = map_url(
&None,
&Some(signature_cipher.to_owned()),
&DEOBFUSCATOR,
&deobf,
&mut last_nsig,
);
let (url, throttled) = map_res.c.unwrap();

View file

@ -3,7 +3,6 @@ use once_cell::sync::Lazy;
use regex::Regex;
use reqwest::Client;
use serde::{Deserialize, Serialize};
use std::result::Result::Ok;
use crate::{error::DeobfError, util};
@ -11,6 +10,7 @@ type Result<T> = core::result::Result<T, DeobfError>;
pub struct Deobfuscator {
data: DeobfData,
ctx: quick_js::Context,
}
#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq)]
@ -21,8 +21,8 @@ pub struct DeobfData {
pub sts: String,
}
impl Deobfuscator {
pub async fn new(http: Client) -> Result<Self> {
impl DeobfData {
pub async fn download(http: Client) -> Result<Self> {
let js_url = get_player_js_url(&http).await?;
let player_js = get_response(&http, &js_url).await?;
@ -33,21 +33,46 @@ impl Deobfuscator {
let sts = get_sts(&player_js)?;
Ok(Self {
data: DeobfData {
js_url,
nsig_fn,
sig_fn,
sts,
},
js_url,
sig_fn,
nsig_fn,
sts,
})
}
}
impl Deobfuscator {
pub fn new(data: DeobfData) -> Result<Self> {
let ctx =
quick_js::Context::new().or(Err(DeobfError::Other("could not create QuickJS rt")))?;
ctx.eval(&data.sig_fn)?;
ctx.eval(&data.nsig_fn)?;
Ok(Self { data, ctx })
}
pub fn deobfuscate_sig(&self, sig: &str) -> Result<String> {
deobfuscate_sig(sig, &self.data.sig_fn)
let res = self.ctx.call_function(DEOBF_SIG_FUNC_NAME, vec![sig])?;
res.as_str().map_or(
Err(DeobfError::Other("sig deobfuscation func returned null")),
|res| {
log::debug!("deobfuscated sig");
Ok(res.to_owned())
},
)
}
pub fn deobfuscate_nsig(&self, nsig: &str) -> Result<String> {
deobfuscate_nsig(nsig, &self.data.nsig_fn)
let res = self.ctx.call_function(DEOBF_NSIG_FUNC_NAME, vec![nsig])?;
res.as_str().map_or(
Err(DeobfError::Other("nsig deobfuscation func returned null")),
|res| {
log::debug!("deobfuscated nsig");
Ok(res.to_owned())
},
)
}
pub fn get_sts(&self) -> String {
@ -59,13 +84,8 @@ impl Deobfuscator {
}
}
impl From<DeobfData> for Deobfuscator {
fn from(data: DeobfData) -> Self {
Self { data }
}
}
const DEOBFUSCATION_FUNC_NAME: &str = "deobfuscate";
const DEOBF_SIG_FUNC_NAME: &str = "deobf_sig";
const DEOBF_NSIG_FUNC_NAME: &str = "deobf_nsig";
fn get_sig_fn_name(player_js: &str) -> Result<String> {
static FUNCTION_REGEXES: Lazy<[FancyRegex; 6]> = Lazy::new(|| {
@ -83,8 +103,8 @@ fn get_sig_fn_name(player_js: &str) -> Result<String> {
.ok_or(DeobfError::Extraction("deobf function name"))
}
fn caller_function(fn_name: &str) -> String {
format!("var {DEOBFUSCATION_FUNC_NAME}={fn_name};")
fn caller_function(mapped_name: &str, fn_name: &str) -> String {
format!("var {mapped_name}={fn_name};")
}
fn get_sig_fn(player_js: &str) -> Result<String> {
@ -125,19 +145,9 @@ fn get_sig_fn(player_js: &str) -> Result<String> {
.unwrap()
.as_str();
Ok(helper_object.to_owned() + &deobfuscate_function + &caller_function(&dfunc_name))
}
fn deobfuscate_sig(sig: &str, sig_fn: &str) -> Result<String> {
let context =
quick_js::Context::new().or(Err(DeobfError::Other("could not create QuickJS rt")))?;
context.eval(sig_fn)?;
let res = context.call_function(DEOBFUSCATION_FUNC_NAME, vec![sig])?;
res.as_str().map_or(
Err(DeobfError::Other("sig deobfuscation func returned null")),
|res| Ok(res.to_owned()),
)
Ok(helper_object.to_owned()
+ &deobfuscate_function
+ &caller_function(DEOBF_SIG_FUNC_NAME, &dfunc_name))
}
fn get_nsig_fn_name(player_js: &str) -> Result<String> {
@ -240,19 +250,7 @@ fn get_nsig_fn(player_js: &str) -> Result<String> {
let offset = player_js.find(&function_base).unwrap_or_default();
extract_js_fn(&player_js[offset..], &function_name)
.map(|s| s + ";" + &caller_function(&function_name))
}
fn deobfuscate_nsig(sig: &str, nsig_fn: &str) -> Result<String> {
let context =
quick_js::Context::new().or(Err(DeobfError::Other("could not create QuickJS rt")))?;
context.eval(nsig_fn)?;
let res = context.call_function(DEOBFUSCATION_FUNC_NAME, vec![sig])?;
res.as_str().map_or(
Err(DeobfError::Other("nsig deobfuscation func returned null")),
|res| Ok(res.to_owned()),
)
.map(|s| s + ";" + &caller_function(DEOBF_NSIG_FUNC_NAME, &function_name))
}
async fn get_player_js_url(http: &Client) -> Result<String> {
@ -300,14 +298,15 @@ fn get_sts(player_js: &str) -> Result<String> {
mod tests {
use super::*;
use path_macro::path;
use test_log::test;
use rstest::{fixture, rstest};
static TEST_JS: Lazy<String> = Lazy::new(|| {
let js_path = path!("testfiles" / "deobf" / "dummy_player.js");
std::fs::read_to_string(js_path).unwrap()
});
const N_DEOBF_FUNC: &str = r#"Vo=function(a){var b=a.split(""),c=[function(d,e,f){var h=f.length;d.forEach(function(l,m,n){this.push(n[m]=f[(f.indexOf(l)-f.indexOf(this[m])+m+h--)%f.length])},e.split(""))},
const SIG_DEOBF_FUNC: &str = r#"var qB={w8:function(a){a.reverse()},EC:function(a,b){var c=a[0];a[0]=a[b%a.length];a[b%a.length]=c},Np:function(a,b){a.splice(0,b)}};var Rva=function(a){a=a.split("");qB.Np(a,3);qB.w8(a,41);qB.EC(a,55);qB.Np(a,3);qB.w8(a,33);qB.Np(a,3);qB.EC(a,48);qB.EC(a,17);qB.EC(a,43);return a.join("")};var deobf_sig=Rva;"#;
const NSIG_DEOBF_FUNC: &str = r#"Vo=function(a){var b=a.split(""),c=[function(d,e,f){var h=f.length;d.forEach(function(l,m,n){this.push(n[m]=f[(f.indexOf(l)-f.indexOf(this[m])+m+h--)%f.length])},e.split(""))},
928409064,-595856984,1403221911,653089124,-168714481,-1883008765,158931990,1346921902,361518508,1403221911,-362174697,-233641452,function(){for(var d=64,e=[];++d-e.length-32;){switch(d){case 91:d=44;continue;case 123:d=65;break;case 65:d-=18;continue;case 58:d=96;continue;case 46:d=95}e.push(String.fromCharCode(d))}return e},
b,158931990,791141857,-907319795,-1776185924,1595027902,-829736173,function(d,e){e=(e%d.length+d.length)%d.length;d.splice(0,1,d.splice(e,1,d[0])[0])},
-1274951142,function(){for(var d=64,e=[];++d-e.length-32;){switch(d){case 91:d=44;continue;case 123:d=65;break;case 65:d-=18;continue;case 58:d=96;continue;case 46:d=95}e.push(String.fromCharCode(d))}return e},
@ -319,7 +318,18 @@ null,497372841,-1912651541,function(d,e){d.push(e)},
function(d,e){e=(e%d.length+d.length)%d.length;d.splice(-e).reverse().forEach(function(f){d.unshift(f)})},
function(d,e){e=(e%d.length+d.length)%d.length;var f=d[0];d[0]=d[e];d[e]=f}];
c[30]=c;c[40]=c;c[46]=c;try{c[43](c[34]),c[45](c[40],c[47]),c[46](c[51],c[33]),c[16](c[47],c[36]),c[38](c[31],c[49]),c[16](c[11],c[39]),c[0](c[11]),c[35](c[0],c[30]),c[35](c[4],c[17]),c[34](c[48],c[7],c[11]()),c[35](c[4],c[23]),c[35](c[4],c[9]),c[5](c[48],c[28]),c[36](c[46],c[16]),c[4](c[41],c[1]),c[4](c[16],c[28]),c[3](c[40],c[17]),c[9](c[8],c[23]),c[45](c[30],c[4]),c[50](c[3],c[28]),c[36](c[51],c[23]),c[14](c[0],c[24]),c[14](c[35],c[1]),c[20](c[51],c[41]),c[15](c[8],c[0]),c[31](c[35]),c[29](c[26]),
c[36](c[8],c[32]),c[20](c[25],c[10]),c[2](c[22],c[8]),c[32](c[20],c[16]),c[32](c[47],c[49]),c[1](c[44],c[28]),c[39](c[16]),c[32](c[42],c[22]),c[46](c[14],c[48]),c[26](c[29],c[10]),c[46](c[9],c[3]),c[32](c[45])}catch(d){return"enhanced_except_85UBjOr-_w8_"+a}return b.join("")};var deobfuscate=Vo;"#;
c[36](c[8],c[32]),c[20](c[25],c[10]),c[2](c[22],c[8]),c[32](c[20],c[16]),c[32](c[47],c[49]),c[1](c[44],c[28]),c[39](c[16]),c[32](c[42],c[22]),c[46](c[14],c[48]),c[26](c[29],c[10]),c[46](c[9],c[3]),c[32](c[45])}catch(d){return"enhanced_except_85UBjOr-_w8_"+a}return b.join("")};var deobf_nsig=Vo;"#;
#[fixture]
fn deobf() -> Deobfuscator {
Deobfuscator::new(DeobfData {
js_url: String::default(),
sig_fn: SIG_DEOBF_FUNC.to_owned(),
nsig_fn: NSIG_DEOBF_FUNC.to_owned(),
sts: String::default(),
})
.unwrap()
}
#[test]
fn t_get_sig_fn_name() {
@ -330,17 +340,13 @@ c[36](c[8],c[32]),c[20](c[25],c[10]),c[2](c[22],c[8]),c[32](c[20],c[16]),c[32](c
#[test]
fn t_get_sig_fn() {
let dcode = get_sig_fn(&TEST_JS).unwrap();
assert_eq!(
dcode,
r#"var qB={w8:function(a){a.reverse()},EC:function(a,b){var c=a[0];a[0]=a[b%a.length];a[b%a.length]=c},Np:function(a,b){a.splice(0,b)}};var Rva=function(a){a=a.split("");qB.Np(a,3);qB.w8(a,41);qB.EC(a,55);qB.Np(a,3);qB.w8(a,33);qB.Np(a,3);qB.EC(a,48);qB.EC(a,17);qB.EC(a,43);return a.join("")};var deobfuscate=Rva;"#
);
assert_eq!(dcode, SIG_DEOBF_FUNC);
}
#[test]
fn t_deobfuscate_sig() {
let dcode = get_sig_fn(&TEST_JS).unwrap();
let deobf = deobfuscate_sig("GOqGOqGOq0QJ8wRAIgaryQHfplJ9xJSKFywyaSMHuuwZYsoMTAvRvfm51qIGECIA5061zWeyfMPX9hEl_U6f9J0tr7GTJMKyPf5XNrJb5fb5i", &dcode).unwrap();
assert_eq!(deobf, "AOq0QJ8wRAIgaryQHmplJ9xJSKFywyaSMHuuwZYsoMTfvRviG51qIGECIA5061zWeyfMPX9hEl_U6f9J0tr7GTJMKyPf5XNrJb5f");
#[rstest]
fn t_deobfuscate_sig(deobf: Deobfuscator) {
let dsig = deobf.deobfuscate_sig("GOqGOqGOq0QJ8wRAIgaryQHfplJ9xJSKFywyaSMHuuwZYsoMTAvRvfm51qIGECIA5061zWeyfMPX9hEl_U6f9J0tr7GTJMKyPf5XNrJb5fb5i").unwrap();
assert_eq!(dsig, "AOq0QJ8wRAIgaryQHmplJ9xJSKFywyaSMHuuwZYsoMTfvRviG51qIGECIA5061zWeyfMPX9hEl_U6f9J0tr7GTJMKyPf5XNrJb5f");
}
#[test]
@ -361,6 +367,7 @@ c[36](c[8],c[32]),c[20](c[25],c[10]),c[2](c[22],c[8]),c[32](c[20],c[16]),c[32](c
#[test]
fn t_extract_js_fn_eviljs() {
// Evil JavaScript code containing braces within strings and regular expressions
let base_js = "Wka = function(d){var x = [/,,/,913,/(,)}/,\"abcdef}\\\"\",];var y = 10/2/1;return x[1][y];}//some={}random-padding+;";
let res = extract_js_fn(base_js, "Wka").unwrap();
assert_eq!(
@ -372,7 +379,7 @@ c[36](c[8],c[32]),c[20](c[25],c[10]),c[2](c[22],c[8]),c[32](c[20],c[16]),c[32](c
#[test]
fn t_get_nsig_fn() {
let res = get_nsig_fn(&TEST_JS).unwrap();
assert_eq!(res, N_DEOBF_FUNC);
assert_eq!(res, NSIG_DEOBF_FUNC);
}
#[test]
@ -381,9 +388,9 @@ c[36](c[8],c[32]),c[20](c[25],c[10]),c[2](c[22],c[8]),c[32](c[20],c[16]),c[32](c
assert_eq!(res, "19187")
}
#[test]
fn t_deobfuscate_nsig() {
let res = deobfuscate_nsig("BI_n4PxQ22is-KKajKUW", N_DEOBF_FUNC).unwrap();
#[rstest]
fn t_deobfuscate_nsig(deobf: Deobfuscator) {
let res = deobf.deobfuscate_nsig("BI_n4PxQ22is-KKajKUW").unwrap();
assert_eq!(res, "nrkec0fwgTWolw");
}
@ -398,7 +405,8 @@ c[36](c[8],c[32]),c[20](c[25],c[10]),c[2](c[22],c[8]),c[32](c[20],c[16]),c[32](c
#[test]
fn t_update() {
let client = Client::new();
let deobf = tokio_test::block_on(Deobfuscator::new(client)).unwrap();
let deobf_data = tokio_test::block_on(DeobfData::download(client)).unwrap();
let deobf = Deobfuscator::new(deobf_data).unwrap();
let deobf_sig = deobf.deobfuscate_sig("GOqGOqGOq0QJ8wRAIgaryQHfplJ9xJSKFywyaSMHuuwZYsoMTAvRvfm51qIGECIA5061zWeyfMPX9hEl_U6f9J0tr7GTJMKyPf5XNrJb5fb5i").unwrap();
println!("{deobf_sig}");

View file

@ -28,6 +28,7 @@ use rustypipe::param::{
#[case::tv_html5_embed(ClientType::TvHtml5Embed)]
#[case::android(ClientType::Android)]
#[case::ios(ClientType::Ios)]
#[test_log::test]
fn get_player_from_client(#[case] client_type: ClientType) {
let rp = RustyPipe::builder().strict().build();
let player_data =