Kezdjük azzal, hogy a tecső állítólag HTTP/3 over QUIC kapcsolat esetén tojik a throttle signature-re (#1, #2), amivel az a baj, hogy ezt a setupot sem a youtube-dl
/yt-dlp
/egyéb Pythonos YT extractorok, sem az MPV/VLC/whatever nem fogja egyhamar adni (ez a felállás kb. Chrome/Firefox-only (+ Safari experimental): QUIC, HTTP/3), tehát erre bazírozni tökéletes zsákutca. (Nem, én hiába is implementálnám a YTFE-ben, mert nem az játtsza le a videókat.) A kugli amúgy is elmehetne a vérbe a QUIC erőltetésével, de ez mellékes; akit érdekel, itt egy link: https://medium.com/codavel-blog/quic-vs-tcp-tls-and-why-quic-is-not-the-next-big-thing-d4ef59143efd
Megnéztem azt is, hogy a yt-dlp
hogy oldotta meg, de ők kb. behúztak egy JS interpretert a játékba, aztán szíjon gázt a kugli...egyébként nem tudom őket hibáztatni a dologért, csak így a Python mellett még a JS-t is futtatniuk kell majd...
Belemélyedtem a Kodi megoldásának a tanulmányozásába (#1, #2). Ez zéró Python tudás mellett nem volt olyan egyszerű, de szerencsére kommentelték a forrást, így az gyorsan kiderült, hogy ők megkeresik az érintett függvényt, majd szétdobják funkciókra és wrappelik Pythonos megfelelőkre...azaz tkp. majdhogynem ugyanazt csinálták, mint én a múltkor a signatureCipher
visszafejtésénél. Ez már gyorsan rávezetett a megoldás felé vezető útra: fogtam a tecső player kódját, majd rákerestem benne a reverse()
függvényre, majd némi keresgetés/analizálgatás/scriptelgetés után kipakoltam a legvalószínűbbnek látszó függvényt egy külön fájlba, aztán kinyitottam egy tecső videót a YTFE-vel, kiszedtem egy közvetlen linket, majd az URL-ben lévő cipherelt n
paraméterre ráeresztettem a frissen kiberhelt függvényt nodejs
segítségével. Visszahelyettesítés után kinyitottam a kapott linket MPV-ben és láss csodát, annyi lett a throttle-nak, lehetett normálisan nézni a full HD-s videót.
Eddig a jó hírek, de most jön a fekete leves. Az ominózus függvény ugyanis így néz ki:
qha = function(a) {
var b = a.split(""),
c = [-470482026, -691770757, function(d, e) {
e = (e % d.length + d.length) % d.length;
d.splice(-e).reverse().forEach(function(f) {
d.unshift(f)
})
},
b, 258876269, -1426380890, 318754300, -68090711, -2064438462, -1886316521, 1913911047, 1635047330,
function(d, e) {
e = (e % d.length + d.length) % d.length;
d.splice(-e).reverse().forEach(function(f) {
d.unshift(f)
})
},
-1815897225, 1940621629, -714586149, -1723898467, null, 778601498, 2145333248, 1245726977, 1952270083, 268207944, 244274044, null,
function(d, e) {
e = (e % d.length + d.length) % d.length;
d.splice(0, 1, d.splice(e, 1, d[0])[0])
},
null, -762271981, 604636391, 1087224318, -931565987, -338396815,
function(d, e) {
for (e = (e % d.length + d.length) % d.length; e--;) d.unshift(d.pop())
},
2126741474,
function(d) {
for (var e = d.length; e;) d.push(d.splice(--e, 1)[0])
},
-1874551858, -1238260579, 498106911, 1913911047, -1951114300, -504396507, b, 344510945, 905306344, b,
function(d, e) {
e = (e % d.length + d.length) % d.length;
var f = d[0];
d[0] = d[e];
d[e] = f
},
909033134, 1027812119, 1686673079,
function(d, e) {
d.push(e)
},
-1902376100,
function(d, e) {
e = (e % d.length + d.length) % d.length;
d.splice(e, 1)
},
"push",
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))
}
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(""))
}
];
c[17] = c;
c[24] = c;
c[26] = c;
try {
c[45](c[17], c[38]), c[12](c[44], c[29]), c[45](c[26], c[0]), c[51](c[41], c[13]), c[12](c[41], c[27]), c[12](c[26], c[11]), c[39](c[17], c[49]), c[9](c[38], c[47]), c[26](c[40], c[0]), c[7](c[8], c[44]), c[14](c[54], c[0]), c[18](c[3], c[25]), c[7](c[33], c[36]), c[15](c[19], c[14]), c[7](c[19], c[9]), c[7](c[6], c[12]), c[41](c[33], c[35]), c[7](c[40], c[5]), c[50](c[42]), c[13](c[14], c[17]), c[6](c[35], c[51]), c[26](c[48], c[50]), c[26](c[35], c[0]), c[6](c[21], c[46]), c[15](c[21], c[42]), c[1](c[2], c[43]), c[15](c[2],
c[31]), c[1](c[21], c[25]), c[22](c[30], c[17]), c[15](c[44], c[46]), c[22](c[44], c[11]), c[22](c[23], c[38]), c[1](c[23], c[14]), c[35](c[23], c[44]), c[11](c[53], c[20]), c[9](c[51]), c[31](c[51], c[28]), c[18](c[51], c[35]), c[46](c[53], c[6]), c[52](c[51], c[49]), c[11](c[53], c[15])
} catch (d) {
return "enhanced_except_75MBkOz-_w8_" + a
}
return b.join("")
};
Na, most, ezt visszafejteni még nem olyan nehéz, meg ugyanezt leimplementálni Pascalban sem, de itt nem egyszerűen ezt kell leimplementálni, hanem tkp. egy értelmezőt kellene írni, ami felismeri, hogy ezekből a műveletekből mit és mikor kell végrehajtani. Azaz fel kell, hogy ismerje, hogy a c
tömb egyes elemei mit csinálnak, majd utána a try
blokkban lévő a c
tömb indexeivel meghatározott műveletsorozatot végre kell hajtania. (Külön fun lesz, hogy a c
tömbbe a kugli a definíció és a műveletsor közt a tömb pár eleme helyére bekopírozza magát a tömböt még egyszer...)
A másik megoldás az, ami már tkp. készen is van (ill. a pár soros kísérleti PHP kódot még át kéne ültetni Pascalba), csak ahhoz nodejs
kell. A kísértés erős, de a hányinger egyelőre erősebb. :P
Úgyhogy látszik már a fény az alagút végén (de miért dudál?!), aztán, ha sikerül, akkor megint menni fog rendesen a tecső, amíg a kugli megint ki nem talál valamit...
- TCH blogja
- A hozzászóláshoz be kell jelentkezni
Hozzászólások
Amúgy ez a küzdelem mire jó? Úgyis mindig elromlik minden módszer, nem? És mindez a reklámok miatt, vagy miért?
- A hozzászóláshoz be kell jelentkezni
De előtte hosszú hónapokig jó. A kugli által eltört dolgok javítása nem tart annyi ideig. Nem a reklámok miatt van (elsősorban), azok nekem browserből sem voltak. Ez azért van, mert a tecső felülete teljesen használhatatlanná vált. Nem csak azért, mert az, ahogy működik az minden csak nem használható, de mellette még a jávaszkript miatt felzabálja a gépet reggelire; egy full HD video lejátszása nálam kb. a CPU 5%-át eszi meg (MPV-ből), még a ventilátorok sem pörögnek fel, viszont maga a tecső, browserből úgy eszi meg a CPU 30-40%-át, hogy pár kép, egyszínű négyzet és némi szöveg kirakása a feladat és úgy bőgeti a ventilátorokat, hogy a szomszéd galaxisban is hallatszik. Jávaszkript. A legelső kiadott YTFE-nél kifejtettem kicsit részletesebben.
- A hozzászóláshoz be kell jelentkezni
Gratula a visszafejtéshez. Tényleg hányinger, amit a yt csinál. Érthetetlen.
"Jegyezze fel a vádhoz - utasította Metcalf őrnagy a tizedest, aki tudott gyorsírni. - Tiszteletlenül beszélt a feljebbvalójával, amikor nem pofázott közbe."
- A hozzászóláshoz be kell jelentkezni
Még nincs teljesen visszafejtve, de köszi. :)
Múltkor is volt téma, nekem is érthetetlen volt, mert egyszerűen megkerülhető védelem volt, de Mcsiv és bra-ket rámutatott, hogy nem is engem akar megfogni a kugli... Mondjuk ez már egy fokkal komolyabb védelem, de ez is kijátszható.
- A hozzászóláshoz be kell jelentkezni
Ügyes.
Viszont eljön majd az idő, amikor a G webassembly-ben tolja le a hókuszpókuszát a böngészőbe. Azt keményebb lesz visszafejteni.
- A hozzászóláshoz be kell jelentkezni
Kösz.
Egy kis disassemblytől nem fogok megijedni. :P
Vagy egy WASM VM megírásától, ha máshogy nem megy. :P
- A hozzászóláshoz be kell jelentkezni
Na, örömmel jelentem, hogy ebben a percben sikerült végképp kibogozni ezt a szart; a kísérleti PHP-s decipherelő ugyanazt adja vissza, mint a nodejs
-sel futtatott eredeti kuglis-jávaszkriptes. Még át kell írni Pascalba, utána búcsút inthetünk a throttle-nek. (Aztán jöhet a következő szívatás.)
- A hozzászóláshoz be kell jelentkezni
> A másik megoldás az, ami már tkp. készen is van (ill. a pár soros kísérleti PHP kódot még át kéne ültetni Pascalba), csak ahhoz nodejs
kell.
nem világos mihez használod használnád pontosan a nodejst, de én eddig ha js-hez kellett nyúlnom megúsztam a Bellard-fél quickjs-sel. Nem tudom a te céljaidnak megfelelne-e
let's go Brandon!
- A hozzászóláshoz be kell jelentkezni
Hú, köszi, így, ha parancssori JS kell, akkor megszabadulhatok a nodejs
sokmegás bloat-jától. Egyébként erre kellett volna csak, hogy miután kipecáztam a kugli örvénylő fostengerének mélyéről a decipher rutint, meghívom valamilyen parancssori JS interpreterrel az n
szignatúrára (szerintem a fentebbi kódot viszi bármilyen ES5-nél későbbi JS VM, úgyhogy biztos megfelelt volna a QuickJS is) és így nem kell deciphert írnom...csak közben már megírtam a deciphert. :P De köszi, jól fog ez jönni máskor is.
- A hozzászóláshoz be kell jelentkezni
nagyon szívesen :)
btw embeddelni is tudod az interpretert, akár a programodban is fel tudod használni, ha megoldható úgy
let's go Brandon!
- A hozzászóláshoz be kell jelentkezni
Az meg még pláne jól jöhet, ha a kugli nagyon bekeményít; most ugyan megint megúsztam - akár külső, akár belső - JS interpreter nélkül, de nem biztos, hogy mindig ilyen szerencsém lesz... A license is megengedi, szóval, ha a kugli előáll egy nap egy olyan cipherrel, ami többszáz kB, akkor tuti az lesz, hogy beágyazom a QuickJS-t. :)
- A hozzászóláshoz be kell jelentkezni
https://github.com/bero1985/besen
itt van ez is, ezt eddig azért nem írtam mert még nem használtam a quickjs-sel ellentétben, de ez a BeRo is jó warekat ír, és ez ráadásul Pascalban van :)
az megkönnyítené ha be kéne ágyazni
let's go Brandon!
- A hozzászóláshoz be kell jelentkezni
Hoppá, ilyen is van? :) Köszi ezt is, ez is még jól jöhet.
Sajnos csak elméletileg lenne könnyebb beágyazni, a gyakorlatban a license (LGPL) miatt ezt egyáltalán nem tudom beágyazni, maximum külső libraryként tudnám használni, dehát úgy akár a QuickJS-t is tudnám, viszont azt tényleg be is tudom ágyazni a programba, csak a wrapper unitot kellene megírnom a fordító által kiköpött objectekhez.
- A hozzászóláshoz be kell jelentkezni