HTTP-граббер

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Homez, 10 Jul 2011.

  1. Homez

    Homez New Member

    Joined:
    8 Jul 2011
    Messages:
    7
    Likes Received:
    0
    Reputations:
    0
    Здравствуйте, Уважаемые! Пишу на C++ HTTP-граббер, инжектищайся в IE и Firefox. Возникли две следующих проблемы:

    1. С IE не удается перхватывать все запросы методом POST. Например, логин на сайте free-lance.ru, С Firefox вроде таких неудач нет, в логе вижу вводимые мной при авторизации логин и пароль. А с IE - нет. Хотя, в то же время, в логе могу наблюдать данные другого POST-запроса. А именно аторизации - нет. Со многими другими сайтами - та же байда. Перехватывал HttpSendRequest и HttpSendRequestEx и ансишной и юникодной версии, а также InternetWriteFile, вроде все учел, не пойму, как некоторые запросы проходят мимо моих хуков? Где я мог допустить оплошность?

    2. Проблемы при замене части содержимого страниц, выдаваемых пользователю браузером. Для примера я сделал подмену заголовка страницы, соответственно, в ее тексте искал тэги <title> и </title> и подменял текст между ними на что-то вроде Hello! Работает почему-то не везде. Я не говорю о тех случаях, когда тэги написаны заглавными буквами, у меня пока поиск без учета регистра, настроен на строчные символы. С сайтом http://www.kurort.ru/ в файрфоксе все нормально, тайтл подменяется. А вот, например, с http://jimm2009.ru/ - уже нет. Хоть тэги и в нижнем регистре, они не находятся и тайтл не заменяется. Такое чувство, что опять-таки, какие-то страницы открываются в обход моих хуков. В файрфоксе я хукнул PR_Read, думая, что этого достаточно. Но вот, опять не все гладко.

    С ие в этом отношении тоже есть проблема. Причем здесь уже несколько по-другому. У ненавистной вебальты тайтл подменяется, если нажимать F5 и не подменяется, если после http://webalta.ru/ в адресной строке нажать энтер. Крайне странно. Были хукнуты InternetReadFile и InternetReadFileEx.

    Если у кого есть идеи по обоим или одному из этих двух пунктов, буду признателен!
     
  2. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Ну раз инжектится, какие функции хукаешь?
     
  3. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    Посмотрел оба сайта. Дело в том, что современные браузеры обычно просят сервер отсылать им данные в gzip. Так вот на сайте http://www.kurort.ru/ данные отправляются все равно в чистом виде, в то время как на http://jimm2009.ru/ в сжатом. Вы должны разобраться, возвращает ли функция, которую вы хукаете данные в точно таком виде, в котором получила их от сервера, или же разжимает их перед этим. Если второй вариант, - тогда нужно искать ошибку в другом.
    Так ТС ведь написал, что он хукает.
     
  4. Mentaless

    Mentaless New Member

    Joined:
    9 Jul 2011
    Messages:
    4
    Likes Received:
    1
    Reputations:
    0
    Про номер раз смотри у мну здесь -->клац<--.
    Там исходник для Chrome, FF, IE. Такая же проблема и у Chrome, проста надо отлавливать следующий POST после авторизации.

    Про подмену чел подробно разжевал там -->Идти туда<-- .

    Ну и конечно смотри сорцы дятьки Зеуса. Благо валяются везде и механизм браузеров не изменился.
     
  5. Homez

    Homez New Member

    Joined:
    8 Jul 2011
    Messages:
    7
    Likes Received:
    0
    Reputations:
    0
    2 Mentaless:
    Ну нифига тут про подмену и не подробно. Вот именно, что пара слов. Практически ничего из этой заметки не почерпнул.

    По поводу первого моего вопроса ща посмотрю, уже качаю исходники.
     
    #5 Homez, 11 Jul 2011
    Last edited: 11 Jul 2011
  6. Homez

    Homez New Member

    Joined:
    8 Jul 2011
    Messages:
    7
    Likes Received:
    0
    Reputations:
    0
    Посмотрел исходники, ничего особенного там нет, что наставило бы меня на путь истинный в том, что касается отлавливания POST-запросов в IE. Перехватывается только HttpSendRequestA, и если lpOptionak не NULL, тогда заголовки и переменные пишутся в лог. У меня практически так же.

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

    Ну ведь и не написано, что инжектор работает с IE.
     
    #6 Homez, 11 Jul 2011
    Last edited: 11 Jul 2011
  7. Mentaless

    Mentaless New Member

    Joined:
    9 Jul 2011
    Messages:
    4
    Likes Received:
    1
    Reputations:
    0
    Ну тады Зри в корень Зевса! Уж там точно должно работать.

    Какой ослик юзаешь? У меня например на 6-ом free-lance отказывается авторизовываться, а с внедрёным модулем вообще повисает.

    Работает и с ослом.

    P.S. Проект не забудь пересобрать.
     
    #7 Mentaless, 11 Jul 2011
    Last edited: 11 Jul 2011
  8. Homez

    Homez New Member

    Joined:
    8 Jul 2011
    Messages:
    7
    Likes Received:
    0
    Reputations:
    0
    Осел - это IE? Ты имеешь ввиду, что инжектор и с ним работает? У меня седьмой.

    Зевс мне много где советовали, да я и начал свою работу с его изучения. Но там, к сожалению, код очень навороченный, черт ногу сломит:( Пока ничего оттуда не почерпнул, но может, гляну еще разок.

    Так что, и лог у тебя ведется? C:\test.txt?
     
  9. Mentaless

    Mentaless New Member

    Joined:
    9 Jul 2011
    Messages:
    4
    Likes Received:
    1
    Reputations:
    0
    Именно так. IE-осёл, а лог C:\test.txt У тебя отображаются файлы и папки с атрибутом "скрытые"?
    И попробуй заюзать на ФФ и Chrome если не трудно.


    Попозже напишу что-нибуть на тему подмены.
     
  10. Homez

    Homez New Member

    Joined:
    8 Jul 2011
    Messages:
    7
    Likes Received:
    0
    Reputations:
    0
    У меня возник еще один вопрос. Пока подмена у меня делается в Firefox только каждом чанке данных, независимо от других для данного запроса. Это не есть гут, так как из-за того что длина исходных данных и данных с выполненой подменой может различаться, данные местами могут съехать, что-то перекрыть и т.п. Кроме того, меня надоумили, что некоторые сайты могут возвращать тексты страниц в gzip, и чтобы получить доступ к исходным данным, мне надо сделать их декомпрессию, а это возможно только если я свяжу все чанки для одного запроса воедино. Поэтому вопрос такой: как мне вычислить, какие куски данных, возвращаемых функцией PR_Read, относятся к одному запросу, а какие - нет? Как-то на основе структуры fd, певого параметра этой функции, но как именно?
     
  11. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    Можно воспользоваться динамическим массивом, потоком данных или еще чем то подобным. Нужно организовать свою структуру, в которой хранить такие данные:

    1) fd;
    2) указатель на данные, полученные с помощью PR_Read;
    3) размер данных.

    Далее, когда получаем новые данные, нужно просмотреть полностью список fd в потоке данных, и если текущий fd там уже присутствует, то записать только что полученные данные в конец полученных ранее и оновить размер данных, если fd еще нету в нашем потоке, то нужно просто выделить память для полученных данных, сохранить эти данные и их размер.
     
  12. Homez

    Homez New Member

    Joined:
    8 Jul 2011
    Messages:
    7
    Likes Received:
    0
    Reputations:
    0
    Спасибо, но я не спрашивал, как мне организовывать работу с данными. Вы не поняли моего вопроса. Меня интересует именно, как мне связывать разные куски данных вместе, на основе какого значения. Сам адрес fd - по-моему, это плохой показатель. Он может повторяться для разных запросов, я проверял.
     
  13. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    Я думаю, что fd может повторяться для разных запросов тогда, когда используеться
    Code:
    Connection: Keep-Alive
    но данные должны приходить все равно последовательно.
    Как именно связать куски данных вместе? Как уже говорил, нужно записать первый кусок в поток данных. Далее находить его и изменять размер выделенной виртуальной памяти. Все сводиться к работе с функциями вида VirtualAlloc или подобных.
     
  14. Homez

    Homez New Member

    Joined:
    8 Jul 2011
    Messages:
    7
    Likes Received:
    0
    Reputations:
    0
    Опять-таки, я не спрашиваю, как мне работать с памятью, с данными. Можно ли положиться на fd? Допустим, он оказался одинаков для двух разных запросов, пусть они и выполнялись последовательно. Тогда программа свяжет эти совершенно посторонние куски вместе и обработает как одно целое. А такое надо исключить.
     
  15. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    Скорее всего, на fd можно положиться. Чтобы различить разные запросы, или даже правильнее сказать, чтобы проверить, можно ли добавлять следующую часть к предыдущим, нужно из первых частей взять значение Content-Length, которое указывает на размер тела ответа. Далее после заголовка считывать столько байт, сколько было указано в Content-Length и соеденить все куски. Получим полный ответ от сервера. Если значения Content-Length нету, то надо проверить значение поля Transfer-Encoding. Если оно равняеться chuncked, то нужно считывать ответ от сервера и записывать его к уже полученным частям до тех пор, пока следующий chunk не будет равняться нулю. Если все таки и Transfer-Encoding в заголовках сервера отсутствует, то нужно читать и записывать в один поток данных до тех пор, пока сервер не закроет соединение сам. Это примерный алгоритм. Надеюсь, то, что надо.