Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #95, НОЯБРЬ 2006 г.

На пике славы: «взлом» поисковых систем

BUG(O)R

Хакер, номер #095, стр. 095-090-3


Пишем код функции TRecv

function Nrecv(s: TSocket; Buf: pChar; len, flags: Integer): Integer; stdcall;

begin

Trecv(s, buf, len, flags);

asm

pushad

end;

asm

popad

end;

end;

рushad и popad используются для того, чтобы не было проблем. Для незнающих отмечу, что эти команды процессора кладут в стек и восстанавливают оттуда значения всех основных регистров. Поэтому лучше, чтобы все регистры до и после вызова оригинальных функций содержали первоначальные значения. Любые модификации переданных параметров нужно производить в пределах двух ассемблерных вставок.

Грубо говоря, мы установили перехват. Теперь, когда в программе встретился вызов одной из этих четырех функций, мы попадаем в функцию с префиксом «N». Как видно, она принимает те же параметры, что и перехватываемая. В пределах двух ассемблерных вставок мы делаем с этими параметрами все, что душе угодно, а далее вызываем оригинальную функцию (здесь это вызов функций с префиксом «T»).

Далее, чтобы не повторять много раз один и тот же код, стоит сделать следующую оговорку. Когда я буду говорить: «В функцию перехвата send впишем код...», это будет значить, что между строками «end;» и «asm» в функции Nsend нужно вписать какой-либо код.

Теперь давай исследовать запросы и ответы гугла при поиске. При перехвате функций отправки данных (send, WSASend) в полях заголовка среди прочих полей существует поле «Accept-Encoding:deflate, gzip, x-gzip, identity, *;q=0», а это значит, что данные от сервера будут приниматься в сжатом виде и мы не сможем их пропарсить. Как от этого избавиться? Все довольно просто - вместо «gzip» в полях заголовка нужно вписать «none», таким образом, при ответе сервера на запрос данные будут приходить в девственно чистом виде. В функции перехвата send пишем следующий код:

if (pos('Host: www.google.ru', Buf) > 0) or (pos('Host: google.ru', Buf) > 0) then ReplaceGZIP(Buf, len);

А в функции перехвата WSASend - такой код:

if (pos('Host: www.google.ru', lpBuffers.buf) > 0) or (pos('Host: google.ru', lpBuffers.buf) > 0) then ReplaceGZIP(lpBuffers.buf, lpBuffers.len);

Чтобы отсечь запросы к другим сайтам (ведь нам их обрабатывать вовсе не нужно), я ввожу проверку наличия строк «Host: www.google.ru» и «Host: google.ru». Функция ReplaceGZIP - это самописная функция, которая ищет строку «gzip» и заменяет ее строчкой «none»:

function ReplaceGZIP(lpData: pointer; szData: dword): boolean;

begin

for i:=szData downto 0 do

begin

if dword(lpData^) = $70697A67 then dword(lpData^) := $656E6F6E;

inc(dword(lpData));

end;

end;

Вот теперь ответ сервера мы можем спокойно парсить, как любые данные html-формата.

Сделай в поисковике запрос по слову «журнал» и открой html-код страницы. Приглядевшись, ты сможешь четко увидеть структуру отображения результатов поиска, которые условно можно разбить на блоки, например самый первый блок будет следующим:

Назад на стр. 095-090-2  Содержание  Вперед на стр. 095-090-4