Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 01.07.2017, 07:18
and.enk and.enk вне форума
Прохожий
 
Регистрация: 22.02.2017
Сообщения: 11
Версия Delphi: Delphi 2010
Репутация: 10
По умолчанию Закодированный ответ JSON от wordstat.yandex.ru

Хочу написать парсер ключевых слов из вордстата яндекса на Delphi, авторизовался, сохранил все куки, отправляю запрос с ключевым словом по которому хочу получить выборку и тут мне приходит JSON ответ в две строки, одна строка длинной 30+ тыс символов вот ее начало, небольшой кусочек:

PHP код:
{"data":"hX8L^^\u0002@[ZUN\\r[\\A\\6V\u0017\fq\u0012\u0004VLGD\\\\LdVVQD\u0003\u0003D\u0004opvStiPGkQ\rLt\u00074P;\u0003\u0018>\u0015Y /ktwrK/OEv`\u000eEWo\u0013g\u0005VMr<|\u0010nDJriwev\u0016'`.QG#]nush\u0006`o\u0017ZD.vT\u000b\\M\u0016qO)J\u001dwGcxg\u0012\u0016Cb\u000e#ki\u00014Dd1bm24\\\u0010Z\u0010%\biwbnoWT0J\u0010 !PshGuTG}V\u0014vq\u0013t\u0003\u001ctuJ>YI.T\n\u0006o\u0015\u0012\u0018dY@TYYA\u0010c\u0005\u0004\u0007\u001c\u0007u\u001c\u0000\nFRV]\u000e_BD\u0005\u001cpw `~PP|Qk[\u0005\u0010j\u000 

И вторая строка это какая то функция чтобы убрать все лишние символы и привести к нормальному виду, оно же должно быть такого вида, да?

PHP код:
\u0010c\u0005\u0004\u0007\u001c\u0007u\u001c 

Вот вся функция:

PHP код:
"key":"var f86 = function(v920){var t844=\"f6ae94e65\";var tv835=v920;return function(v920){return t844.concat(v920.concat(tv835))}(\"2bf\")};f86(\"426aa0d\".split('').reverse().join('').split('').reverse().join('').concat(13407^131027).substr(1))"

Смотрел снифером аналоги парсеров вордстата и видел что там точно такие же POST запросы и ответ приходит точно такой же, значит они как то переводят данные в читабельный вид, ковыряю эти две строчки второй день очень нужна помощь.

В приложении txt файл с полным JSON ответом от wordstat.yandex
Вложения
Тип файла: txt POST.txt (37.3 Кбайт, 2 просмотров)
Ответить с цитированием
  #2  
Старый 01.07.2017, 17:46
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Если не ошибаюсь, очпохоже что ответ на питоне приходит, попробовал расшифровать немного с помощью
Код:
//Функция выполняет преобразование вида:
//'\u0421\u043a\u0430\u0439\u0440\u0438\u043c' -> WideString('Скайрим').
function UStrToWideStr(const aUStr : AnsiString) : WideString;
var
  i, j, Len : Integer;
begin
  Len := Length(aUStr) div 6;
  SetLength(Result, Len);
  j := 3;
  for i := 1 to Len do begin
    Result[i] := WideChar( StrToInt('$' + Copy(aUStr, j, 2)) shl 8
      + StrToInt('$' + Copy(aUStr, j + 2, 2)) );
    Inc(j, 6);
  end;
end;
на выходе псвевдографика вылазит
Ответить с цитированием
  #3  
Старый 01.07.2017, 18:55
and.enk and.enk вне форума
Прохожий
 
Регистрация: 22.02.2017
Сообщения: 11
Версия Delphi: Delphi 2010
Репутация: 10
По умолчанию

Я вот думаю может тут и вовсе не нужно ничего декодировать...
Почему когда смотришь исходной код с результатами в нём нет ключевых фраз, а если сделать "исследовать элемент" и в инспекторе посмотреть, то в нём можно найти всю разметку и все ключевые фразы, правда русские символы прописаны вот в таком виде %D1%81 но это не беда, беда получить этот DOM код в Delphi

Код:
<a class="b-link b-phrase-link__link" href="/#!/?words=%D1%81%D0%BA%D0%B0%D1%87%D0%B0%D1%82%D1%8C">скачать</a>

Последний раз редактировалось and.enk, 01.07.2017 в 18:57.
Ответить с цитированием
  #4  
Старый 01.07.2017, 22:27
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

1) Заходим на страницу яндекс вордстата.
2) Открываем консоль (ctrl+shift+i в хроме).
3) Что-нибудь вводим в строке яндекса, чтоб инициировать запрос.
4) На вкладке консоли "Network" видим ответ примерно того вида, что в первом посте. Там JSON с полями data и key.
5) Находим в коде страницы люто обфусцированный Javascript. Впору бы загрустить (копать 20к строк обфусцированного кода на JS - то еще удовольствие), однако замечаем, что в этом коде только один раз встречается операция XOR (которая есть почти в любом шифровании).
6) Понимаем, что этот XOR - и есть расшифровка. Ручками деобфусцируем код и получаем что-то вроде этого:
PHP код:
var rkey navigator.userAgent.substr(025) + ($["cookie"]("fuid01") || "") + eval(response.key);
var 
result "";
for (var 
0response.data.lengthi++)
    
result result String.fromCharCode(response.data.charCodeAt(i) ^ rkey.charCodeAt(rkey.length))
result decodeURIComponent(result); 
7) Видно, что в расшифровке используется user-agent, cookie с названием fuid01 (если есть, иначе пустая строка) и eval от поля "key" в ответе сервера. А дальше банальный XOR с ключом.
8) Пишем в консоли var response = <ответ сервера>
9) Вставляем в консоль этот код расшифровки, нам печатается результат:
PHP код:
"{"content":{"currentPage":"1","lastUpdate":"Последнее обновление01.07.2017","regions":"","hasNextPage":"yes","includingPhrases":{"info":["  ... <И ТАК ДАЛЕЕ
10) ???
11) PROFIT
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 01.07.2017 в 22:42.
Ответить с цитированием
Этот пользователь сказал Спасибо Bargest за это полезное сообщение:
and.enk (02.07.2017)
  #5  
Старый 02.07.2017, 21:54
and.enk and.enk вне форума
Прохожий
 
Регистрация: 22.02.2017
Сообщения: 11
Версия Delphi: Delphi 2010
Репутация: 10
По умолчанию

Спасибо, мне это помогло, правда пришлось подставить response.key и response.data руками в переменные и заменить, почему то у меня в хроме response.length = 0, хотя куки находит... Или я что то с Response не то делал, первый раз с JS в консоле сталкиваюсь.

Главное увидел в браузере расшифрованный текст и это радует.

Вопрос теперь в другом, как лучше всего выполнить функцию которая приходит в ответе сервера из поля key? Я видел она генерирует какой то набор символов, который нужен чтобы дополнить ключ для расшифровки текста из поля data.

В гугле нашёл что функцию eval можно выполнить с помощью TEvaluator из JEDI Code Library или выполнить JS через TwebBrouser, но с TwebBrouser не хочется...
Ответить с цитированием
  #6  
Старый 03.07.2017, 21:15
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Поискать примеры через какой-нибудь ScriptControl.
Предлагают так:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  ScriptControl: Variant;
  Value: Variant;
begin
  ScriptControl := CreateOleObject('ScriptControl');
  ScriptControl.SitehWnd := Handle;
  ScriptControl.Language := 'JScript';

  Value := ScriptControl.Eval('new Date();'); // сюда впихать response.key
  ShowMessage(VarToStr(Value));
end;
(не проверял)
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
Этот пользователь сказал Спасибо Bargest за это полезное сообщение:
and.enk (05.07.2017)
  #7  
Старый 05.07.2017, 21:57
and.enk and.enk вне форума
Прохожий
 
Регистрация: 22.02.2017
Сообщения: 11
Версия Delphi: Delphi 2010
Репутация: 10
По умолчанию

Добрался сегодня до компа наконец-то..

Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  ScriptControl: Variant;
  Value: Variant;
begin
  ScriptControl := CreateOleObject('ScriptControl');
  ScriptControl.SitehWnd := Handle;
  ScriptControl.Language := 'JScript';
 
  Value := ScriptControl.Eval('new Date();'); // сюда впихать response.key
  ShowMessage(VarToStr(Value));
end;

Код полностью рабочий, генерируется недостающий кусочек для ключа расшифровки

В консоле хрома у меня получилось расшифровать закодированный текст вашим кодом, пробовал в делфи расшифровать этим кодом

Код:
var
  key, text, longkey, result: string;
  i: integer;
  toto, c: char;
begin
  for i := 0 to (length(text) div length(key)) do
    longkey := longkey + key;
  for i := 1 to length(text) do
  begin
    toto := chr((ord(text[i]) xor ord(longkey[i]))); // XOR алгоритм
    result := result + toto;
  end;
end;


ничего не получилось, как вот этот кусочек строки нужно прописать в Delphi

Код:
result = result + String.fromCharCode(response.data.charCodeAt(i) ^ rkey.charCodeAt(i % rkey.length))
Ответить с цитированием
  #8  
Старый 05.07.2017, 23:17
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Видимо key неверный. User-Agent надо брать тот же, с которым идет запрос к серверу, а точнее первые 25 его символов. Опять же, если выполнить navigator.userAgent.substr(0, 25) в хроме, то можно увидеть "Mozilla/5.0 (Windows NT 1".
А далее легко - как-нибудь так:
Код:
for i := 1 to length(text) do
    text[i] := chr(ord(text[i]) xor ord(key[((i-1) mod length(key)) + 1]));
Ну и не забыть, что приходящая строка содержит escape-символы. При вставке в консоль хрома ответа сервера они сами unescape'ятся. Чтобы в делфе точно корректно получить строку, лучше вытаскивать data из ответа сервера через какой-нибудь dbxjson, он должен все эти escape-символы конвертировать. А в новых делфях так вообще JSON-парсер уже засунули в стандартные библиотеки.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 05.07.2017 в 23:23.
Ответить с цитированием
  #9  
Старый 06.07.2017, 08:31
and.enk and.enk вне форума
Прохожий
 
Регистрация: 22.02.2017
Сообщения: 11
Версия Delphi: Delphi 2010
Репутация: 10
По умолчанию

С ключом для расшифровки я разобрался, я вставляю в консоль хрома ваш код выше со своими данными, т.е. там уже стоит готовый кей и текст который им зашифрован, всё расшифровывается без проблем, но когда я подставляю те же самые текст и кей

Код:
for i := 1 to length(text) do
  begin
    text[i] := chr(ord(text[i]) xor ord(key[((i-1) mod length(key)) + 1]));
    result := result + text[i];
  end;
   memo17.Text:=result;

мне приходит вот такой результат
Код:
%7B%22=Z 
такой же как и вчера...

В приложении скидываю код, если его вставить в консоль хрома и нажать enter всё расшифруется, а Delphi не хочет
Вложения
Тип файла: txt code.txt (36.2 Кбайт, 2 просмотров)
Ответить с цитированием
  #10  
Старый 06.07.2017, 20:30
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Всё работает.
Код:
{тут объявлена DecodeBase64}
var rkey: string;
	ttext: string;
	i: integer;
begin
	rkey := 'Mozilla/5.0 (Windows NT 6595d22397c0b1998.VO1MmJfamekbMplQO3URqsOY-fp5VDKdVYPfZLAQUIz85hA2Aod_OJ7Vz5cVtSuUXaMoByuHOA3VWwNKP_d_RVXBg34uVCCyvY1D9AbxwDqJ5HjCy91NgAQbjM-k5WIc87a9ad7bee75';
	ttext := 'aFg4TF5eAkBbWlVOXHJbXEFcNlYXDHESBFZMRxZXXEdpVgRVRwMLHAtvc30DfEh4VERfJk5QfxwNIjtmJTYQByp8H1RVBhdheVZzHWBDYwpkFWVsOH0Q';
	ttext := DecodeBase64(ttext);
	for i := 1 to length(ttext) do
        ttext[i] := chr(ord(ttext[i]) xor ord(rkey[((i-1) mod length(rkey)) + 1]));
    WriteLn(ttext);
end.
Вывод:
Цитата:
%7B%22content%22%3A%7B%22currentPage%22%3A%221%22% 2C%22lastUpdate%22%3A%22%D0%9F%D0%BE%
Это формат URL-Encode. Его после придется раскодировать (url decode).
В примере я расшифровал только начало текста, чтобы не писать километровую строку.
Поскольку в онлайн-компиляторе паскаля нету никакого unescape или парсера json, я предварительно сделал unescape javascript'ом и перевел в base64, а в примере использовал раскодирование из base64 (делфи нет под рукой).
В предыдущем сообщении я не просто так писал про
Цитата:
Ну и не забыть, что приходящая строка содержит escape-символы.
Escape-последовательности - это например \u0002 или \r из твоего ответа сервера. Это текстовое представление "символов" (на самом деле просто байтов), которые невозможно ввести с клавиатуры или напечатать. Ты их не раскодируешь, ты даешь эти \u0002 как будто это текст '\u0002', а на самом деле это просто число 2.
Тебе, соответственно, нужно либо найти способ сделать unescape строки ttext в делфи, либо не парить себе мозги и использовать для вытаскивания строки из ответа сервера готовый JSON-парсер, который есть в новых делфях. В прошлом же сообщении я кидал ссылки на документацию про этот JSON-парсер.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 06.07.2017 в 20:37.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 20:17.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter