Здравствуйте, Уважаемые! Пишу на 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. Если у кого есть идеи по обоим или одному из этих двух пунктов, буду признателен!
Посмотрел оба сайта. Дело в том, что современные браузеры обычно просят сервер отсылать им данные в gzip. Так вот на сайте http://www.kurort.ru/ данные отправляются все равно в чистом виде, в то время как на http://jimm2009.ru/ в сжатом. Вы должны разобраться, возвращает ли функция, которую вы хукаете данные в точно таком виде, в котором получила их от сервера, или же разжимает их перед этим. Если второй вариант, - тогда нужно искать ошибку в другом. Так ТС ведь написал, что он хукает.
Про номер раз смотри у мну здесь -->клац<--. Там исходник для Chrome, FF, IE. Такая же проблема и у Chrome, проста надо отлавливать следующий POST после авторизации. Про подмену чел подробно разжевал там -->Идти туда<-- . Ну и конечно смотри сорцы дятьки Зеуса. Благо валяются везде и механизм браузеров не изменился.
2 Mentaless: Ну нифига тут про подмену и не подробно. Вот именно, что пара слов. Практически ничего из этой заметки не почерпнул. По поводу первого моего вопроса ща посмотрю, уже качаю исходники.
Посмотрел исходники, ничего особенного там нет, что наставило бы меня на путь истинный в том, что касается отлавливания POST-запросов в IE. Перехватывается только HttpSendRequestA, и если lpOptionak не NULL, тогда заголовки и переменные пишутся в лог. У меня практически так же. Попробовал заразить ие инжектором, вроде прога написала что успешно. Но лог так и не создался. К сожалению, инжектор написан на вижуал бэйсике, а я им не пользуюсь, так как не люблю. Поэтому отладить не могу. Ну ведь и не написано, что инжектор работает с IE.
Ну тады Зри в корень Зевса! Уж там точно должно работать. Какой ослик юзаешь? У меня например на 6-ом free-lance отказывается авторизовываться, а с внедрёным модулем вообще повисает. Работает и с ослом. P.S. Проект не забудь пересобрать.
Осел - это IE? Ты имеешь ввиду, что инжектор и с ним работает? У меня седьмой. Зевс мне много где советовали, да я и начал свою работу с его изучения. Но там, к сожалению, код очень навороченный, черт ногу сломит Пока ничего оттуда не почерпнул, но может, гляну еще разок. Так что, и лог у тебя ведется? C:\test.txt?
Именно так. IE-осёл, а лог C:\test.txt У тебя отображаются файлы и папки с атрибутом "скрытые"? И попробуй заюзать на ФФ и Chrome если не трудно. Попозже напишу что-нибуть на тему подмены.
У меня возник еще один вопрос. Пока подмена у меня делается в Firefox только каждом чанке данных, независимо от других для данного запроса. Это не есть гут, так как из-за того что длина исходных данных и данных с выполненой подменой может различаться, данные местами могут съехать, что-то перекрыть и т.п. Кроме того, меня надоумили, что некоторые сайты могут возвращать тексты страниц в gzip, и чтобы получить доступ к исходным данным, мне надо сделать их декомпрессию, а это возможно только если я свяжу все чанки для одного запроса воедино. Поэтому вопрос такой: как мне вычислить, какие куски данных, возвращаемых функцией PR_Read, относятся к одному запросу, а какие - нет? Как-то на основе структуры fd, певого параметра этой функции, но как именно?
Можно воспользоваться динамическим массивом, потоком данных или еще чем то подобным. Нужно организовать свою структуру, в которой хранить такие данные: 1) fd; 2) указатель на данные, полученные с помощью PR_Read; 3) размер данных. Далее, когда получаем новые данные, нужно просмотреть полностью список fd в потоке данных, и если текущий fd там уже присутствует, то записать только что полученные данные в конец полученных ранее и оновить размер данных, если fd еще нету в нашем потоке, то нужно просто выделить память для полученных данных, сохранить эти данные и их размер.
Спасибо, но я не спрашивал, как мне организовывать работу с данными. Вы не поняли моего вопроса. Меня интересует именно, как мне связывать разные куски данных вместе, на основе какого значения. Сам адрес fd - по-моему, это плохой показатель. Он может повторяться для разных запросов, я проверял.
Я думаю, что fd может повторяться для разных запросов тогда, когда используеться Code: Connection: Keep-Alive но данные должны приходить все равно последовательно. Как именно связать куски данных вместе? Как уже говорил, нужно записать первый кусок в поток данных. Далее находить его и изменять размер выделенной виртуальной памяти. Все сводиться к работе с функциями вида VirtualAlloc или подобных.
Опять-таки, я не спрашиваю, как мне работать с памятью, с данными. Можно ли положиться на fd? Допустим, он оказался одинаков для двух разных запросов, пусть они и выполнялись последовательно. Тогда программа свяжет эти совершенно посторонние куски вместе и обработает как одно целое. А такое надо исключить.
Скорее всего, на fd можно положиться. Чтобы различить разные запросы, или даже правильнее сказать, чтобы проверить, можно ли добавлять следующую часть к предыдущим, нужно из первых частей взять значение Content-Length, которое указывает на размер тела ответа. Далее после заголовка считывать столько байт, сколько было указано в Content-Length и соеденить все куски. Получим полный ответ от сервера. Если значения Content-Length нету, то надо проверить значение поля Transfer-Encoding. Если оно равняеться chuncked, то нужно считывать ответ от сервера и записывать его к уже полученным частям до тех пор, пока следующий chunk не будет равняться нулю. Если все таки и Transfer-Encoding в заголовках сервера отсутствует, то нужно читать и записывать в один поток данных до тех пор, пока сервер не закроет соединение сам. Это примерный алгоритм. Надеюсь, то, что надо.