[vlc-commits] [Git][videolan/vlc][master] 3 commits: youtube.lua: simplify "n" descrambling compound transformation

Hugo Beauzée-Luyssen (@chouquette) gitlab at videolan.org
Tue Nov 16 08:31:28 UTC 2021



Hugo Beauzée-Luyssen pushed to branch master at VideoLAN / VLC


Commits:
174e12b3 by Pierre Ynard at 2021-11-16T08:18:00+00:00
youtube.lua: simplify "n" descrambling compound transformation

Newly observed transformations reveal that the uncertain character
code variable used as constant offset, really isn't one and is simply
supposed to be the alphabet's length. Thus even more so, it is a no-op
on the alphabet's algebraic modulo group, and probably just an artifact
of how modulo of negative numbers is handled in javascript. Simplify it
away.

- - - - -
fd2e937f by Pierre Ynard at 2021-11-16T08:18:00+00:00
youtube.lua: "n" descrambling transformations with two extra arguments

A new standalone compound transformation, taking its Base64 alphabet
as extra input argument, has revealed itself. We support parsing and
passing this one more argument from the script section.

Technically this last argument can be a function or rather the result
of its call, but with no argument, we know what's always returned, and
don't need to treat it as a function. This is less clean but simpler and
will do for now.

- - - - -
7f6614cb by Pierre Ynard at 2021-11-16T08:18:00+00:00
youtube.lua: add "n" descrambling split compound transformations

A new variant of compound transformation has the Base64 alphabet
generation and the compounding itself as two separate data array
elements, contrary to what was observed so far. Add support for those.

Fixes #26285

- - - - -


1 changed file:

- share/lua/playlist/youtube.lua


Changes:

=====================================
share/lua/playlist/youtube.lua
=====================================
@@ -158,12 +158,14 @@ function n_descramble( nparam, js )
         return len
     end
 
-    -- Common routine shared by the compound transformations,
-    -- compounding the "n" parameter with an input string,
-    -- character by character using a Base64 alphabet.
-    -- d.forEach(function(l,m,n){this.push(n[m]=h[(h.indexOf(l)-h.indexOf(this[m])+m-32+f--)%h.length])},e.split(""))
-    local compound = function( ntab, str, alphabet, charcode )
-        if ntab ~= n or type( str ) ~= "string" then
+    -- Shared core section of compound transformations: it compounds
+    -- the "n" parameter with an input string, character by character,
+    -- using a Base64 alphabet as algebraic modulo group.
+    -- 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(""))
+    local compound = function( ntab, str, alphabet )
+        if ntab ~= n or
+           type( str ) ~= "string" or
+           type( alphabet ) ~= "string" then
             return true
         end
         local input = {}
@@ -181,7 +183,7 @@ function n_descramble( nparam, js )
             if ( not pos1 ) or ( not pos2 ) then
                 return true
             end
-            local pos = ( pos1 - pos2 + charcode - 32 ) % len
+            local pos = ( pos1 - pos2 ) % len
             local newc = string.sub( alphabet, pos + 1, pos + 1 )
             ntab[i] = newc
             table.insert( input, newc )
@@ -271,27 +273,55 @@ function n_descramble( nparam, js )
                 "^[^}]-d%.unshift%(f%)}%)},",
             }
         },
-        -- Compound transformations first build a variation of a
-        -- Base64 alphabet, then in a common section, compound the
-        -- "n" parameter with an input string, character by character.
+        -- Here functions with no arguments are not really functions,
+        -- they're constants: treat them as such. These alphabets are
+        -- passed to and used by the compound transformations.
+        alphabet1 = {
+            func = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_",
+            match = {
+                -- 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}
+                "^function%(%){[^}]-case 58:d=96;",
+            }
+        },
+        alphabet2 = {
+            func = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",
+            match = {
+                -- function(){for(var d=64,e=[];++d-e.length-32;)switch(d){case 46:d=95;default:e.push(String.fromCharCode(d));case 94:case 95:case 96:break;case 123:d-=76;case 92:case 93:continue;case 58:d=44;case 91:}return e}
+                "^function%(%){[^}]-case 58:d%-=14;",
+                "^function%(%){[^}]-case 58:d=44;",
+            }
+        },
+        -- Compound transformations are based on a shared core section
+        -- that compounds the "n" parameter with an input string,
+        -- character by character, using a variation of a Base64
+        -- alphabet as algebraic modulo group.
+        compound = {
+            func = compound,
+            match = {
+                -- 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(""))}
+                "^function%(d,e,f%)",
+            }
+        },
+        -- These compound transformation variants first build their
+        -- Base64 alphabet themselves, before using it.
         compound1 = {
             func = function( ntab, str )
-                return compound( ntab, str, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_", 96 )
+                return compound( ntab, str, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_" )
             end,
             match = {
                 -- function(d,e){for(var f=64,h=[];++f-h.length-32;)switch(f){case 58:f=96;continue;case 91:f=44;break;case 65:f=47;continue;case 46:f=153;case 123:f-=58;default:h.push(String.fromCharCode(f))} [ compound... ] }
-                "^[^}]-case 58:f=96;",
+                "^function%(d,e%){[^}]-case 58:f=96;",
             }
         },
         compound2 = {
             func = function( ntab, str )
-                return compound( ntab, str,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_", 96 )
+                return compound( ntab, str,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" )
             end,
             match = {
                 -- function(d,e){for(var f=64,h=[];++f-h.length-32;){switch(f){case 58:f-=14;case 91:case 92:case 93:continue;case 123:f=47;case 94:case 95:case 96:continue;case 46:f=95}h.push(String.fromCharCode(f))} [ compound... ] }
                 -- function(d,e){for(var f=64,h=[];++f-h.length-32;)switch(f){case 46:f=95;default:h.push(String.fromCharCode(f));case 94:case 95:case 96:break;case 123:f-=76;case 92:case 93:continue;case 58:f=44;case 91:} [ compound... ] }
-                "^[^}]-case 58:f%-=14;",
-                "^[^}]-case 58:f=44;",
+                "^function%(d,e%){[^}]-case 58:f%-=14;",
+                "^function%(d,e%){[^}]-case 58:f=44;",
             }
         },
         -- Fallback
@@ -333,7 +363,9 @@ function n_descramble( nparam, js )
 
             -- Compounding functions use a subfunction, so we need to be
             -- more specific in how much parsed data we consume.
-            if el == trans.compound1.func or el == trans.compound2.func then
+            if el == trans.compound.func or
+               el == trans.compound1.func or
+               el == trans.compound2.func then
                 datac = string.match( datac, '^.-},e%.split%(""%)%)},(.*)$' )
             else
                 datac = string.match( datac, "^.-},(.*)$" )
@@ -395,20 +427,22 @@ function n_descramble( nparam, js )
     -- the "n" parameter array as first argument, and often input data
     -- as a second argument. We parse and emulate those calls to follow
     -- the descrambling script.
-    -- c[40](c[14],c[2]),c[25](c[48]),c[21](c[32],c[23]), [...]
-    for ifunc, itab, iarg in string.gmatch( script, "c%[(%d+)%]%(c%[(%d+)%]([^)]-)%)" ) do
-        iarg = string.match( iarg, ",c%[(%d+)%]" )
+    -- c[40](c[14],c[2]),c[25](c[48]),c[14](c[1],c[24],c[42]()), [...]
+    for ifunc, itab, args in string.gmatch( script, "c%[(%d+)%]%(c%[(%d+)%]([^)]-)%)" ) do
+        local iarg1 = string.match( args, "^,c%[(%d+)%]" )
+        local iarg2 = string.match( args, "^,[^,]-,c%[(%d+)%]" )
 
         local func = data[tonumber( ifunc ) + 1]
         local tab = data[tonumber( itab ) + 1]
-        local arg = iarg and data[tonumber( iarg ) + 1]
+        local arg1 = iarg1 and data[tonumber( iarg1 ) + 1]
+        local arg2 = iarg2 and data[tonumber( iarg2 ) + 1]
 
         -- Uncomment to debug transformation chain
-        --vlc.msg.dbg( '"n" parameter transformation: '..prd( func ).."("..prd( tab )..( arg ~= nil and ( ", "..prd( arg, tab ) ) or "" )..") "..ifunc.."("..itab..( iarg and ( ", "..iarg ) or "" )..")" )
+        --vlc.msg.err( '"n" parameter transformation: '..prd( func ).."("..prd( tab )..( arg1 ~= nil and ( ", "..prd( arg1, tab ) ) or "" )..( arg2 ~= nil and ( ", "..prd( arg2, tab ) ) or "" )..") "..ifunc.."("..itab..( iarg1 and ( ", "..iarg1 ) or "" )..( iarg2 and ( ", "..iarg2 ) or "" )..")" )
         --local nprev = table.concat( n )
 
         if type( func ) ~= "function" or type( tab ) ~= "table"
-            or func( tab, arg ) then
+            or func( tab, arg1, arg2 ) then
             vlc.msg.dbg( "Invalid data type encountered during YouTube video throttling parameter descrambling transformation chain, aborting" )
             vlc.msg.dbg( "Couldn't descramble YouTube throttling URL parameter: data transfer will get throttled" )
             vlc.msg.err( "Couldn't process youtube video URL, please check for updates to this script" )



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/8d50e2be0c7c117344b34b36f634880748a0a1dd...7f6614cbafb76e19257551a833375642a7dc3949

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/8d50e2be0c7c117344b34b36f634880748a0a1dd...7f6614cbafb76e19257551a833375642a7dc3949
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list