1

Тема: Decrunching fmovies.is

Тема создана для переноса сообщений, касающихся ресурса  fmovies.is (fmovies.se, ...)

Sony Bravia KDL-32CX523

2

Re: Decrunching fmovies.is

Сообщники!
Нашел вот такой ресурс с, вроде бы, честным 720p, проверил на нескольких потоках.
https://fmovies.se/film/billions-2.qxmjv
вот только запутался я в их скриптах, я так понял они должны генерировать div'ы, один из которых будет "video" и будет содержать заветный srс на поток. Никак не могу понять который из них...

video{ LG&Samsung<-(lan)->HMS<-(vpn)->Neutron s8&note8 }audio

3

Re: Decrunching fmovies.is

slim8020, что это за сайт такой, который содержит последние серии свежих сериалов, а отдаёт ссылку на поток, которая сильно знакомого вида:
ht_ps://redirector.googlevideo.com/videoplayback?id=b5e1a0de46ecdc9a&itag=18&source=webdrive&requiressl=yes&ttl=transient&mm=30&mn=sn-5hnednel&ms=nxu&mv=m&pl=36&mime=video/mp4&lmt=1487434781132897&mt=1487687807&ip=2a00:1768:2001:2::1f&ipbits=128&expire=1487702281&sparams=ip%2Cipbits%2Cexpire%2Cid%2Citag%2Csource%2Crequiressl%2Cttl%2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Cmime%2Clmt&signature=9B0854BD16725FA4734E372124049FE91141F584.9034B5FD308E2DA80573058958048F944AD980E2&key=ck2&app=explorer&xmi=50

Капец, это ж видео с youtube?
Да, качество, похоже, 720. Субтитры английские прилагаются.

А загадки разгадывать - откуда ссылки берутся и как расшифровать, так это моё любимое дело. Прям спасибо за интересный квест.
В общем, там код JS жутко обфусцирован и главный вопрос, как в ссылке:
ht_ps://fmovies.se/ajax/episode/info?ts=1487689200&_=8520&id=j2z3p4&update=0
Значение _=8520 получить. Ибо это токен, который зависит от всех параметров, типа подписи запроса.

В общем, развлечение на вечер (а мне работать надо).

P.S.: Там источники разные. Не только с googlevideo (на сайте как "Server F2"), но и с Openload.co (https://openload.co/embed/--NvddZFdlM/).
"Server F1" всегда не доступен был.

С оpenload тоже развлечения предстоят. В общем, боги шифрования. Это вызов.

Sony Bravia KDL-32CX523

4 (2017.02.22 00:02:25 отредактировано baat)

Re: Decrunching fmovies.is

WendyH пишет:

В общем, боги шифрования. Это вызов.

а не проще на ютубе искать?.. или поиск это не выдаст?..

5 (2017.02.23 11:40:49 отредактировано WendyH)

Re: Decrunching fmovies.is

Я разобрался с fmovies.se.
Для каждого параметра нужно подсчитывать значение подписи. Все значения суммируются.

Чтобы сделать запрос на fmovies.se/ajax/episode/info?ts=1487689200&_=8520&id=j2z3p4
а потом что-то вроде
fmovies.se/grabber-api/?ts=1487757600&_=1550755&id=olm748&token=<blabla>&options=<blabla>&mobile=0

Нужно установить значения:
ts - timestamp округлённое до часов с учётом того, что сервер находится в Америке и должно учитываться смещение по Гринвичу (это -12 часов от московского времени).
_ - это суммарное значение подписи параметров "ts" и "id".

+ Вот такая функция на C++Script получилась
///////////////////////////////////////////////////////////////////////////////
// Подсчёт значения подписи конкретного имени и значения параметра
int CalcSignature(string name, string val) {
  int n, r, i, nTmp, o; Variant a[256];
  for (i=0; i<256; i++) a[i]=i;
  for (i=0, n=0; i<256; i++) {
    n = (n + a[i] + Ord(name[i % Length(name) + 1])) % 256;
    nTmp = a[i];
    a[i] = a[n];
    a[n] = nTmp;
  }
  for (i=0, n=0, r=0; i<Length(val); i++) {
    r = (r + 1   ) % 256;
    n = (n + a[r]) % 256;
    nTmp = a[r];
    a[r] = a[n];
    a[n] = nTmp;
    o += Ord(val[i+1]) ^ (a[(a[r]+a[n]) % 256] * i + i);
  }    
  return o;
}

Чтобы заценить, с чем пришлось работать, вот изначальный распакованный скрипт на JS (тот самый участок):

+ открыть спойлер
function n(t, e) {
    var i, n, r, a, s, o;
    for (i = [], n = +yn, a = yn - 0, s = yn - 0; s < +(Sk + nk); s++) i[s] = s;
    for (s = +yn; s < Sk + nk - 0; s++) n = (n + i[s] + t[iN.P(+(Jl + JD))](iN.A(s, t[iN[lk](+(Jl + uk))]))) % (Sk + nk - 0), r = i[s], i[s] = i[n], i[n] = iN.g(r);
    for (s = yn - 0, n = +yn, o = +yn; o < e[iN.P(+(Jl + QD))]; o++) s = iN.O(iN.h(s, 1 * Jl), +(QD + ek + nk)), n = iN[HC]((n + i[s]) % +(QD + Ck)), r = i[s], i[s] = i[n], i[n] = r, a += e[iN.T(+(Jl + JD))](o) ^ i[iN.R(i[s], i[n]) % +wk] * o + o;
    return a
}

function r(t) {
    for (var e = - +(Pk + Ak + Mk), i = 1 * (UD + xk + Gk + yn), r = +QD, a = +Jl; iN.A9(a[u](), a[u]()[S], qD + Ik + QD - 0) !== e; a++) {
        for (s in t) t[iN.T(1 * KD)](s) && (o /= iN[Hk](n(s, iN.v(t[s], iN.P(+Ck)))));
        return o
    }
    if (iN.g9(r[u](), r[u]()[S], QD + $k + qD + nk - 0) !== i) {
        var s, o;
        o = +yn;
        for (s in t) t[iN.T(qD - 0)](s) && (o += iN[Hk](n(s, iN.v(t[s], iN.P(Jl + ek | 0)))))
    }
    return o
}

Вот из такого вот ... э.. кода пришлось делать свою функцию. Но одно из самых сложных было просто найти этот нужный кусок.

Получился вот такой вот PHP скрипт:

+ открыть спойлер
<?php
ini_set("log_errors", 1); ini_set("error_log", $_SERVER['SCRIPT_FILENAME'].".log"); ini_set('error_reporting', E_ALL); ini_set("display_errors", 1);

$url     = isset($_REQUEST['url']) ? $_REQUEST['url'] : ""; // url like https://fmovies.se/film/fare.prln6/olm748

if (!$url) die("No film url in parameters.");

$cookies = array();
$headers = "Accept-Encoding: gzip, deflate\r\n" .
           "Accept: application/json, text/javascript, */*; q=0.01\r\n" .
           "Referer: https://fmovies.se/\r\n" .
           "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36\r\n";

if (!preg_match('#.*/(\w+)#', $url, $m)) die("Epic fail. No video ID in url.");
$ID   = $m[1]; // Video ID

// Узнаём timestamp из загруженной страницы
$data = LoadPage($url, "GET", $headers);
if (!preg_match('#data-ts="(\d+)"#', $data, $m)) die("Epic fail. Not timestamp in loaded page.");
$timestamp = $m[1];

// Загружаем json информацию об источнике
$url  = SignUrl("https://fmovies.se/ajax/episode/info?id=".$ID, $timestamp); // Подпись ссылки
$data = LoadPage($url, "GET", $headers);
$answ = json_decode($data, true);

if (isset($answ["grabber"])) {
    $url = $answ["grabber"];
    if (isset($answ["params"])) {
        $url .= "?".http_build_query($answ["params"]);
    }
    // Если есть прямая ссылка на видео - загружаем json данные о ней
    if ($answ["type"]=="direct") {
        $url  = SignUrl($url, $timestamp); // Подпись ссылки
        $data = LoadPage($url, "GET", $headers);
        $answ = json_decode($data, True);
        if (isset($answ["data"])) {
            $files = $answ["data"];
            $data = $files[count($files)-1]["file"];
        }
    }
} else {
    echo '{url:"'.$url.'"}';
}

echo $data;

///////////////////////////////////////////////////////////////////////////////
// Получение страницы с указанными методом и заголовками
function LoadPage($url, $method, $headers, $data='') {
    global $cookies;

    // Если есть кукисы - добавляем их значения в HTTP заголовки
    $coo = "";
    foreach($cookies as $key => $val) $coo .= $key."=".urlencode($val)."; ";
    if ($coo) $headers .= "Cookie: $coo\r\n";

    $options = array();
    $options['http'] = array('method' => $method ,
                             'header' => $headers,
                             'content'=> $data   );
    $context = stream_context_create($options);
    $page    = file_get_contents($url, false, $context);
    // Перебираем HTTP заголовки ответа, чтобы установить кукис
    foreach($http_response_header as $c => $h) {
        if (stristr($h, 'content-encoding') and stristr($h, 'gzip')) {
            $page = gzdecode($page);
        } else if (preg_match('#^Set-Cookie:\s*([^;]+)#', $h, $matches)) {
            parse_str($matches[1], $tmp);
            $cookies += $tmp;
        }
    }
    return $page;
}

////////////////////////////////////////////////////////////////////
// Подпись ссылки (добавление ts и _)
function SignUrl($url, $timestamp) {
    $parameters = "";
    if (preg_match("#^(.*?)\?(.*)#", $url, $m)) {
        $url        = $m[1];
        $parameters = $m[2];
    }
    $signature = CalcSignature("ts", "".$timestamp);
    parse_str($parameters, $array);
    foreach ($array as $key => $value) {
        $signature += CalcSignature($key, $value);
    }
    return $url."?ts=".$timestamp."&_=".$signature."&".$parameters;
}

////////////////////////////////////////////////////////////////////
// Подсчёт значения подписи конкретного имени и значения параметра
function CalcSignature($name, $val) {
    $o = 0;
    $a = array(256);
    for ($i=0; $i<256; $i++) $a[$i]=$i;
    for ($i=0, $n=0; $i<256; $i++) {
      $n = ($n + $a[$i] + Ord($name[$i % strlen($name)])) % 256;
      $tmp   = $a[$i];
      $a[$i] = $a[$n];
      $a[$n] = $tmp;
    }
    for ($i=0, $n=0, $r=0; $i<strlen($val); $i++) {
      $r = ($r + 1     ) % 256;
      $n = ($n + $a[$r]) % 256;
      $tmp   = $a[$r];
      $a[$r] = $a[$n];
      $a[$n] = $tmp;
      $o += Ord($val[$i]) ^ ($a[($a[$r]+$a[$n]) % 256] * $i + $i);
    }    
    return $o;
}

Который вот так вот работает:
http://wonky.lostcut.net/fmovies.php?ur … mjv/j2z3p4

Так что упёртость и упоротость не оставляет шансов для создателей сайтов. )
На самом деле, если бы не крутой отладчик в chrome, фиг бы я разобрался, наверно.

baat пишет:

а не проще на ютубе искать?.. или поиск это не выдаст?..

Нет. Тут вопрос в другом - в том, что неправомерный контент находится на серверах компании известной как одной из самых активно борящейся с таким контентом.

slim8020, не смотрел openload.co? Я даже не приступал. Там тоже развлечения с раскодировкой предстоят, как я понял.

UPDATE: Обновил скрипт, оказывается вычислять timestamp была плохая идея. Надёжней брать из загруженной страницы видео. Это значение там есть. Поэтому переделал и обновил скрипт.

Sony Bravia KDL-32CX523
Спасибо сказали: kliopa1002

6

Re: Decrunching fmovies.is

WendyH, openload.co не смотрел. Я пытался скриптом запустить ie, c отключенными картинками, и с добавленным в надёжные узлы fmovies.se, чтоб после загрузки сразу вытащить ссылку на видео... пока не вышло

video{ LG&Samsung<-(lan)->HMS<-(vpn)->Neutron s8&note8 }audio

7

Re: Decrunching fmovies.is

Openload.co повержен.

Функция раскодирования зашифрованных данных написана. Закодированные данные есть в html странице openload.co/embed/--NvddZFdlM/ в:

<div style="display:none;">
  <span id="wRdOAuzXK0">7D4500d5275h5380L7931W7931k2190Q6336R4220i4352l6468B3156A2104I3321U6360g2266H6462C3255n2148J4460o3261m3177V2118F3321N2118X4228O5315G6582K5420c3159e3159Y4212S6378E1107M1056f6330Z7448P3189T4224b3174j7903</span>
  <span id="streamurl">HERE IS THE LINK</span>
</div>

В первом span - нужные зашифрованные данные.
Во втором span после отработки js скриптов появляется значение, типа "--NvddZFdlM~1488110004~2.93.0.0~_iavnA5k".
После чего полная ссылка на поток выглядит вот так:
"ht_ps://openload.co/stream/--NvddZFdlM~1488110004~2.93.0.0~_iavnA5k?mime=true".

Вот функции на C++Script для получения ссылки на медиа-поток из ссылок вида https://openload.co/embed/ceKFetMsUPM/

+ открыть спойлер
///////////////////////////////////////////////////////////////////////////////
// Получение ссылки на медиа-поток с сайта openload.co
void GetLink_Openload(string sLink) {
  string sHtml, sData, sStream;
  
  sHtml = HmsDownloadURL(sLink, 'Referer: '+mpFilePath, true);
  if (!HmsRegExMatch('<div[^>]+style="display:none;">\\s*<span.*?>(.*?)<', sHtml, sData)) {
    HmsLogMessage(2, mpTitle+": Невозможно найти зашифрованные данные сайта openload.co.");
    return;
  }
  sStream = OpenloadDecode(sData);
  MediaResourceLink = 'https://openload.co/stream/'+sStream+'?mime=true';
}

///////////////////////////////////////////////////////////////////////////////
// Декодирование данных сайта openload.co
string OpenloadDecode(string sEncoded) {
  string sResult; int i, a, _, d, e, w, nbufLen;
  if (sEncoded=="") return;
  nbufLen = Int((Length(sEncoded)-1)/5);
  sResult = PadRight("", nbufLen, ' ');
  w = StrToIntDef(sEncoded[1], 0);
  for (d=1; d<Length(sEncoded); d+=5) {
    i = Ord(sEncoded[d+1]);
    if      (i <= 90) e = i - 65;
    else if (i >= 97) e = i - 72;
    else              e = 0;
    _ = StrToIntDef(Copy(sEncoded, d+2, 1), 0);
    a = StrToIntDef(Copy(sEncoded, d+3, 3), 0);
    sResult[e+1] = Chr(Int(a/_) - w);
  }
  return sResult;
}

Как я понимаю, закодированные данные на странице содержат в себе типа хеша или подписи, который привязан к IP. Поэтому скрипт на стороннем сервере для получения таких ссылок сделать можно, но бесполезно:

+ Скрипт для openload.co на PHP
<?php ini_set("log_errors", 1); ini_set("error_log", $_SERVER['SCRIPT_FILENAME'].".log"); ini_set('error_reporting', E_ALL); ini_set("display_errors", 1);

$ID      = isset($_REQUEST['id']) ? $_REQUEST['id'] : ""; // film ID in url like https://openload.co/embed/--NvddZFdlM/

if (!$ID) die("No film id in parameters.");

$cookies = array();
$headers = "Accept-Encoding: gzip, deflate\r\n" .
           "Accept: application/json, text/javascript, */*; q=0.01\r\n" .
           "Referer: https://fmovies.se/\r\n" .
           "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36\r\n";

// Загружаем страницу фильма
$data    = LoadPage("https://openload.co/embed/$ID/", "GET", $headers);

// Ищем в HTML коде зашифрованные данные для потока
if (!preg_match('#<div[^>]+style="display:none;">\s*<span.*?>(.*?)<#s', $data, $m)) die("Epic fail. No encoded text found.");

// Расшифровываем
$decoded = OpenloadDecode($m[1]);
$url     = "https://openload.co/stream/$decoded?mime=true";

// Попробуем получить ссылку редиректа
$context = stream_context_create(array('http'=>array('follow_location' => false)));
$page    = file_get_contents($url, false, $context);
// Ищем в полученных заголовках значение Location
foreach($http_response_header as $c => $h) {
    if (preg_match('#^Location:\s*([^\r\n]+)#', $h, $m)) {
        $url = $m[1];
        break;
    }
}

echo $url;

///////////////////////////////////////////////////////////////////////////////
// Декодирование данных сайта openload.co
function OpenloadDecode($encoded) {
    if (!$encoded) return;
    $bufLen = (strlen($encoded)-1)/5;
    $result = str_pad("", $bufLen, ' ');
    $w = intval($encoded[0]);
    for ($d=1; $d < strlen($encoded); $d+=5) {
        $i = ord($encoded[$d]);
        if      ($i <= 90) $e = $i - 65;
        else if ($i >= 97) $e = $i - 72;
        else               $e = 0;
        $_ = intval(substr($encoded, $d+1, 1));
        $a = intval(substr($encoded, $d+2, 3));
        $result[$e] = chr(($a/$_) - $w);
    }
    return $result;
}

///////////////////////////////////////////////////////////////////////////////
// Получение страницы с указанными методом и заголовками
function LoadPage($url, $method, $headers, $data='') {
    global $cookies;

    // Если есть кукисы - добавляем их значения в HTTP заголовки
    $coo = "";
    foreach($cookies as $key => $val) $coo .= $key."=".urlencode($val)."; ";
    if ($coo) $headers .= "Cookie: $coo\r\n";

    $options = array();
    $options['http'] = array('method' => $method ,
                             'header' => $headers,
                             'content'=> $data   );
    $context = stream_context_create($options);
    $page    = file_get_contents($url, false, $context);
    // Перебираем HTTP заголовки ответа, чтобы установить кукис
    foreach($http_response_header as $c => $h) {
        if (stristr($h, 'content-encoding') and stristr($h, 'gzip')) {
            $page = gzdecode($page);
        } else if (preg_match('#^Set-Cookie:\s*([^;]+)#', $h, $matches)) {
            parse_str($matches[1], $tmp);
            $cookies += $tmp;
        }
    }
    return $page;
}

Но полученные ссылки на другом сервере не будут проигрываться на клиенте с другим IP.
http://wonky.lostcut.net/openload.php?id=--NvddZFdlM

Так что можно писать подкаст для fmovies.se.

Sony Bravia KDL-32CX523

8

Re: Decrunching fmovies.is

Ко мне обратились зарубежные друзья с просьбой посмотреть защиту fmovies, которая сменилась.

На странице фильма есть ссылки на источники "Server F2", в конце ссылки есть ID видео.

ht_ps://fmovies.is/film/the-expanse-2.qxm3n/n89qkm

В коде html можно найти значение ts (timestamp) в  свойстве "data-ts" тега "body".

Этот ts нужен для подписывания всех url, которые вызываются через метод ajax объекта jQuery. Перед вызовом запроса в метод ajaxPrefilter добавляется вызов функции подписывания ссылок - добавляется параметр ts и знак подчёркивания _, значение которого - это и есть вычисленная подпись всех параметров в ссылке.

Функции в JavaScript коде запакованы и обфусцированы, находятся в едином файле /assets/min/public/all.js
Который можно распаковать через jsbeautifier.org.

Для того, чтобы можно было ставить точки прерывания на функции вычисления подписи, можно сохранить веб страницу локально на диск и заменить подгружаемый локально js скрипт на распакованный. При этом такая страница работать не будет но попытки обращения ajax будут, которые браузер будет блокировать с сообщением:
XMLHttpRequest cannot load file:///D:/user/ajax/menu-bar?ts=1500184800&_=1743. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

Т.е. не давать делать запрос на другой домен. Но нам и не нужно. Нам нужно только посмотреть, как именно формируется значение параметра _.
И мы можем поставить точки останова в скрипте и посмотреть пошагово, как выполняется этот подсчёт.
Пользователь Clonex даже дал наводку на место, где этот подсчёт, вероятно, делается. Это около строк с 10656 по 10709. Достаточно расставить там точки останова и посмотреть как идут вычисления. И переписать эти вычисления на своём языке, который хотим использовать.

На данный момент, нам интересен такой участок распакованного js кода:

+ открыть спойлер
        function(t, e, i) {
            "use strict";

            function n() {
                return eD
            }

            function r(t) {
                var e, i = iD,
                    n = {};
                if (t[ed][l](cd) > -1)
                    do e = i[re](t[ed]), e && (n[e[1]] = decodeURIComponent(e[2] || T)[b](nD, J)); while (e);
                if (t[Vr])
                    do e = i[re](t[Vr]), e && (n[e[1]] = decodeURIComponent(e[2] || T)[b](nD, J)); while (e);
                return n
            }

            function a(t, e) {
                var i, n = 0;
                for (i = 0; i < Math[K](t[S], e[S]); i++) n += i < e[S] ? e[rD](i) : 0, n += i < t[S] ? t[rD](i) : 0;
                return Number(n)[u](16)
            }

            function s(t) {
                var e, i = 0;
                for (e = 0; e < t[S]; e++) i += t[rD](e) * e;
                return i
            }

            function o(t) {
                var i, r, o = s(n()),
                    l = {},
                    u = {};
                u[m] = T + y, r = e[x](!0, {}, t, u);
                for (i in r) Object[g][c][b](r, i) && (o += s(a(n() + i, r[i])));
                return l[m] = y, l[h] = o, l
            }

            function d(t, e) {
                var i, n = T;
                for (i in e) Object[g][c][b](e, i) && (n += ud + i + Mt + e[i]);
                return t + (t[l](cd) < 0 ? cd : ud) + n[YH](1)
            }
            var p = e(Ir),
                f = Zk,
                h = fp,
                m = tD,
                v = ed,
                y = p[Vr](m);
            e[f](function(t) {
                var e = o(r(t));
                t[v] = d(t[v], e)
            })
        }(t, t.jQuery, t.FW),

Функция "o" сначала подсчитывает значение с указанной переменной, которая возвращается функцией n и это всегда (пока) значение "bLeqpV" с помощью функции s. Потом подсчитывается значение ts через функцию "a", добавляя к имени параметра всё то же значение "bLeqpV" в самое начало.

После переписывания и упрощения до одной функции, получилось вот такая функция подсчёта на PHP:

+ открыть спойлер
<?php
ini_set("log_errors", 1); ini_set("error_log", $_SERVER['SCRIPT_FILENAME'].".log"); ini_set('error_reporting', E_ALL); ini_set("display_errors", 1);

$url     = isset($_REQUEST['url']) ? $_REQUEST['url'] : ""; // url like https://fmovies.is/film/fare.prln6/olm748

if (!$url) die("No film url in parameters.");

$cookies = array();
$headers = "Accept-Encoding: gzip, deflate\r\n" .
           "Accept: application/json, text/javascript, */*; q=0.01\r\n" .
           "Referer: https://fmovies.is/\r\n" .
           "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36\r\n";

if (!preg_match('#.*/(\w+)#', $url, $m)) die("Epic fail. No video ID in url.");
$ID   = $m[1]; // Video ID

// Get timestamp from loaded page
$data = LoadPage($url, "GET", $headers);
if (!preg_match('#data-ts="(\d+)"#', $data, $m)) die("Epic fail. Not timestamp in loaded page.");
$timestamp = $m[1];

// Get json info about sources
$url  = SignUrl("https://fmovies.is/ajax/episode/info?id=".$ID, $timestamp); // add singnature _=...&ts=...
$data = LoadPage($url, "GET", $headers);
$answ = json_decode($data, true);

if (isset($answ["grabber"])) {
    $url = $answ["grabber"];
    if (isset($answ["params"])) {
        $url .= "?".http_build_query($answ["params"]);
    }
    // If exists direct link - get data for this
    if ($answ["type"]=="direct") {
        $url  = SignUrl($url, $timestamp); // add signature to parameters
        $data = LoadPage($url, "GET", $headers);
        $answ = json_decode($data, True);
        if (isset($answ["data"])) {
            $files = $answ["data"];
            $data = $files[count($files)-1]["file"];
        }
    }
} else {
    echo '{url:"'.$url.'"}';
}

echo $data;

///////////////////////////////////////////////////////////////////////////////
// Load page with specific method and headers
function LoadPage($url, $method, $headers, $data='') {
    global $cookies;

    // If exists cookies - add it to HTTP headers
    $coo = "";
    foreach($cookies as $key => $val) $coo .= $key."=".urlencode($val)."; ";
    if ($coo) $headers .= "Cookie: $coo\r\n";

    $options = array();
    $options['http'] = array('method' => $method ,
                             'header' => $headers,
                             'content'=> $data   );
    $context = stream_context_create($options);
    $page    = file_get_contents($url, false, $context);
    // Get cookies from HTTP answer headers
    foreach($http_response_header as $c => $h) {
        if (stristr($h, 'content-encoding') and stristr($h, 'gzip')) {
            $page = gzdecode($page);
        } else if (preg_match('#^Set-Cookie:\s*([^;]+)#', $h, $matches)) {
            parse_str($matches[1], $tmp);
            $cookies += $tmp;
        }
    }
    return $page;
}

////////////////////////////////////////////////////////////////////
// Add signature to url (add params ts and _)
function SignUrl($url, $timestamp) {
    $parameters = "";
    if (preg_match("#^(.*?)\?(.*)#", $url, $m)) {
        $url        = $m[1];
        $parameters = $m[2];
    }
    // sign the url
    $signature = CalcSignature("", "");
    $signature += CalcSignature("ts", "".$timestamp);
    parse_str($parameters, $array);
    foreach ($array as $key => $value) {
        $signature += CalcSignature($key, $value);
    }
    return $url."?ts=".$timestamp."&_=".$signature."&".$parameters;
}

////////////////////////////////////////////////////////////////////
// Calculate the signature of parameter
function CalcSignature($name, $val) {
  $name = "bLeqpV" . $name; // value: eD = "bLeqpV", line: 1942

  // function a() line: 10673 (upacked) file: /assets/min/public/all.js?596aac49
  if ($val) {
    $n = 0;
    for ($i=0; $i < max(strlen($name), strlen($val)); $i++) {
      $n += ($i < strlen($name)) ? ord($name[$i]) : 0; // charCodeAt
      $n += ($i < strlen($val )) ? ord($val [$i]) : 0; // charCodeAt
    }
    $name = dechex($n); // int to hex (with lowercase liters)
  }

  // function s() line: 10679 (upacked) file: /assets/min/public/all.js?596aac49
  $i = 0;
  for ($e=0; $e < strlen($name); $e++) {
    //$i += ord($name[$e]) * $e + $e;
    $i += ord($name[$e]) * $e;
  }
  return $i;
}

Проверка:
http://wonky.lostcut.net/fmovies.php?ur … m3n/n89qkm

Sony Bravia KDL-32CX523