wininet hooks
От: linkoln  
Дата: 05.04.13 13:54
Оценка:
Hi,
пытаюсь написать либу под ие для мониторинга трафика протекающего. написал. -все работает, вижу все странички, жава скрипты, картинки — ие радуется что все на месте. Но тут, попал на один сайтец
http://gcl.ncl.novostimira.biz/52704/434 с ним както все очень странно выходит...
1. первым делом качаем редирект ответ от сервака на
http://60seconds.com.ua/index.php?page=shop.product_details&category_id=14&flypage=flypage.tpl&product_id=64&option=com_virtuemart&Itemid=118
2. на той страничке есть прописана подгрузка стилей
link rel="stylesheet" href="/components/com_jcomments/tpl/default/style.css?v=12" type="text/css"
как видно она относительна от текущей локации(?)
без моих хуков грузит стиль с 60seconds.com.ua, но как только включаю хуки ИЕ пытается подгрузить стиль с gcl.ncl.novostimira.biz... и + к всему в адресной строке не меняется адресс локации.

как таке может быть? если по логам HttpAnalyzer вижу картину
GET http://gcl.ncl.novostimira.biz/52704/434 - REDIRECT TO  http://60seconds.com.ua/index.php?page=shop.product_details&category_id=14&flypage=flypage.tpl&product_id=64&option=com_virtuemart&Itemid=118
GET  http://60seconds.com.ua/index.php?page=shop.product_details&category_id=14&flypage=flypage.tpl&product_id=64&option=com_virtuemart&Itemid=118
GET http://60seconds.com.ua/modules/mod_callback/tmpl/style.css (один единственный стиль грузим с "правильного" сайта)
//а дальше
GET http://gcl.ncl.novostimira.biz/components/com_jcomments/tpl/default/style.css?v=12 //и получаем в ответ 302 Found, т.к. данный стиль должен был бы грузится с 60seconds.com.ua


смотрю по дебаг принтам со своих хуков — все вроде проходит нормально (не вижу я по крайней мере ничего подозрительного)
поставил бряк на InternetConnect() когда коннестимся мы на "невалидный" хост (gcl.ncl.novostimira.biz вместо 60seconds.com.ua), посмотрел каллстек

021edab8 772733e5 urlmon!CINet::INetAsyncConnect+0x156
021edad0 772632b7 urlmon!CINet::INetAsyncOpen+0xe5
021edae0 7726327e urlmon!CINet::INetAsyncStart+0x1a
021edafc 7dc6c132 urlmon!CINet::Start+0x1db
021edd5c 7dc456d7 mshtml!CDwnBindData::Bind+0x3a7
021edd78 7dc45624 mshtml!NewDwnBindData+0xb9
021edd9c 7dcc5370 mshtml!CDwnLoad::Init+0xc8
021eddb4 7dc47a97 mshtml!CBitsLoad::Init+0x1a
021eddd8 7dc3c257 mshtml!CDwnInfo::SetLoad+0xeb
021eddfc 7dc46ff4 mshtml!CDwnCtx::SetLoad+0x65
021ede18 7dcaf948 mshtml!NewDwnCtx+0x58
021efea0 7dc42bc2 mshtml!CHtmPre::AddDwnCtx+0x162
021efec4 7dc411bc mshtml!CHtmPre::SpecialToken+0x30f
021eff14 7dc408ef mshtml!CHtmPre::DoTokenizeOneTag+0x821
021eff70 7dc41426 mshtml!CHtmPre::Tokenize+0x807
021eff88 7dc6af6f mshtml!CHtmPre::Exec+0xd5
021eff94 7dc69931 mshtml!CHtmPre::Run+0x13
021effa4 7dcb71b2 mshtml!CDwnTaskExec::ThreadExec+0x98
021effac 7dcb7184 mshtml!CExecFT::ThreadProc+0x28


посмотрел что передаем в urlmon!CINet::Start() — наш кривой адресок, выходит mshtml я заставил запутаться и не понимает она что пора редиректится (не сморя на то что страничку после редиректа + один стиль мы скачали удачно)

мож кто-нибудь подтолкнет в нужном направлении,а то сижу и второй день — просто смотрю на логи и ничего понять не могу.
спасиб!
Re: wininet hooks
От: ononim  
Дата: 05.04.13 15:46
Оценка:
типичный паттерн фикса — убираем максимум хуков пока воспроизводится проблема, потом убираем из оставшихся хуков максимум кода, пока воспроизводится проблема, и если все еще самому непонятна причина — толково пишем на RSDN как устроены и что делают хуки
Как много веселых ребят, и все делают велосипед...
Re[2]: wininet hooks
От: linkoln  
Дата: 05.04.13 19:11
Оценка:
Здравствуйте, ononim,

Выкинуть хуки сразу подумалось, но там кода — необходимый минимум, т.е. если чтото убрать — общая картина перестает полностью работать.
Решил пересобрать логи, пересмотреть по новому и подготовить что-то для поста сюда. Во время подготовки логов было замечено что я упустил один немаловажный момент — INTERNET_STATUS_RESPONSE_RECEIVED в каллбеке. Как его правильно обрабатывать я так и не понял,у меня еррор (ERROR_INTERNET_INCORRECT_HANDLE_STATE) валится при попытке вычитать данные при помощи как InternetReadFile так и pInternetReadFileEx. Читал заметки одного "Хакер"-а_телепата..лучше бы его не читал, а то запутал полностью. Вот как я обрабатываю данное событие:

BOOL
IeReadData (
    IN      PCONNECTION    hConn,
    IN OUT  PULONG         DataSize
    )
{
    ULONG   size;
    BYTE    buff [MAX_PATH];
    PVOID   Buffer;
    ULONG   TotalSize;
    BOOL    result;

    /*
        Read data from wininet
        return TRUE only if all data was received
        otherwise return FALSE
    */

    DPRINT( "<IeReadData BEGIN> for [%X]\n\tInetHandle: %X\n\tStage: %X\n\tDataSize: %X\n\n",
            hConn,
            hConn->InetHandle,
            hConn->Stage,
            *DataSize );

    size = *DataSize;
    Buffer = Alloc( isd,
                    size,
                    NULL,
                    hConn );
    if (!Buffer)
        return 0;

    result = FALSE;
    TotalSize = 0;
    while (TRUE) {

        if (!isd->vpt.pInternetReadFile( hConn->InetHandle, Buffer, size, &size )) {
        
            if (Buffer != buff)
                Free( isd,
                      Buffer,
                      NULL,
                      hConn );
            break;
        }

        if (!size) {
            /* all data has been readed from wininet */
            result = TRUE;
            break;
        }

        TotalSize += size;

        if (Buffer == buff) {

            Buffer = Alloc( isd,
                            size,
                            NULL,
                            hConn );
            if (!Buffer) {

                TotalSize -= size;
                break;
            }

            MemCpy( Buffer,
                    buff,
                    size );
        }

        Buffer = buff;
        size = sizeof( buff );
    }

    DPRINT( "<IeReadData DONE> for [%X]\n\tInetHandle: %X\n\tStage: %X\n\tTotalSize: %X\n\tError: %X\n\n",
            hConn,
            hConn->InetHandle,
            hConn->Stage,
            TotalSize,
            GetLastError() );

    *DataSize = TotalSize;
    return result;
}


VOID
CALLBACK
InternetStatusCallbackHook (
    IN      HINTERNET       hInternet,
    IN      DWORD_PTR       Context,
    IN      DWORD           InternetStatus,
    IN      PVOID           StatusInformation,
    IN      DWORD           StatusInformationLength
    )
{
    PCONNECTION     hConn;
    BOOL            SkipOrigCall;
    
    hConn = SearchConnection( hInternet );
    if (hConn) {

        SkipOrigCall = TRUE;
        switch (InternetStatus) {
        
            case INTERNET_STATUS_RESPONSE_RECEIVED:
                if (StatusInformation && StatusInformationLength == sizeof(DWORD)) {
                    /* try read data from wininet buffer */
                    size = *(PDWORD)StatusInformation;
                    result = IeReadData( hConn,
                                         &size );
                    if (result) {
                        /* all data received - return data to ie */
                        SkipOrigCall = FALSE;
                    }

                } else
                    SkipOrigCall = FALSE;

                break;
        }
        
    } else
        SkipOrigCall = FALSE;
        
    if (!SkipOrigCall)
        ((INTERNET_STATUS_CALLBACK)InternetStatusCallbackOrig)( hInternet,
                                                                   Context,
                                                                InternetStatus,
                                                                StatusInformation,
                                                                StatusInformationLength );
}
Re[2]: wininet hooks
От: linkoln  
Дата: 05.04.13 19:13
Оценка:
*сами заметки забыл прикрутить
bbs.vbstreets.ru/viewtopic.php?f=54&t=40232
предпоследний пост.
Re[3]: wininet hooks
От: jyuyjiyuijyu  
Дата: 06.04.13 07:22
Оценка:
Здравствуйте, linkoln, Вы писали:

странные у вас хуки... вот вы в логи пишите а где GetLastError/SetLastError ?
Re[4]: wininet hooks
От: ononim  
Дата: 06.04.13 11:36
Оценка:
J>странные у вас хуки... вот вы в логи пишите а где GetLastError/SetLastError ?
угу, + еще и не thread-safe'овые
Как много веселых ребят, и все делают велосипед...
Re[4]: wininet hooks
От: linkoln  
Дата: 06.04.13 11:46
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>Здравствуйте, linkoln, Вы писали:


J>странные у вас хуки... вот вы в логи пишите а где GetLastError/SetLastError ?


В данном хуке не вижу смысла устанавливать последний еррор. Чтение, прошу заметить есть
DPRINT( "<IeReadData DONE> for [%X]\n\tInetHandle: %X\n\tStage: %X\n\tTotalSize: %X\n\tError: %X\n\n",
hConn,
hConn->InetHandle,
hConn->Stage,
TotalSize,
GetLastError() );

еще где нужно обрабатывать еррор код — в данном хуке не вижу.

Здравствуйте, ononim, Вы писали:

J>угу, + еще и не thread-safe'овые


прошу прощения, а что тут не thread-safe'овое?
Re[5]: wininet hooks
От: linkoln  
Дата: 06.04.13 11:50
Оценка:
тут малость не все рассказал — Alloc\Free, это мои внутренние функи, которые выделяет\освобождает память в мемори_стриме для данного коннекшина. Сразу не сказал — извиняюсь.
Re[5]: wininet hooks
От: ononim  
Дата: 06.04.13 11:51
Оценка:
L>еще где нужно обрабатывать еррор код — в данном хуке не вижу.
Дело не в том чтоб вы обрабатывали ластеррор, а в том чтобы ваш код обработчика хука его не исказил.

J>>угу, + еще и не thread-safe'овые

L>прошу прощения, а что тут не thread-safe'овое?
Сори, показалось что SkipOrigCall — глобальная переменная. Как выяснилось — она локальная. Мимимизируйте Минимизируйте свой код дальше...
Как много веселых ребят, и все делают велосипед...
Re[5]: wininet hooks
От: linkoln  
Дата: 06.04.13 12:01
Оценка:
O>не thread-safe'овые

виноват, спасибо. введу ReferenceCount на коннекшин. но трабла в отображении не думаю что в этом(
Re[6]: wininet hooks
От: linkoln  
Дата: 06.04.13 12:05
Оценка:
Здравствуйте, ononim, Вы писали:
O>Дело не в том чтоб вы обрабатывали ластеррор, а в том чтобы ваш код обработчика хука его не исказил

поправлю, не учел сие дело. попробую исправить.
Re[7]: wininet hooks
От: linkoln  
Дата: 06.04.13 17:03
Оценка:
подровнял кодез, внедрил наконецто референс_каунт + еррор_коды сохраняю-востанавливаю.
НО это не дал решения моей трабле с
<IeReadData BEGIN> for [3A0FC4]
InetHandle: CC000C
Stage: 0
DataSize: 2FA

<IeReadData DONE> for [3A0FC4]
InetHandle: CC000C
Stage: 0
TotalSize: 0
Error: 2EF3

почему же я не могу вычитать вышеизложенным кодом ни байтика с буффера при каллбеке??
Re[8]: wininet hooks
От: linkoln  
Дата: 06.04.13 17:09
Оценка:
тестанул еще разок, с ретурном при данном каллбеке — тож самое.
я умудрился заставить ИЕ игнорировать редиректы, т.к. пошел на google.com а редирект на google.com.ua не произошел в аддресной строке) хотя подгрузило контент с гугл_украина...
=может я чет с каллбеками недоучитываю..может нужно каллбекать ИЕ при какихто условиях помимо как "вычитал все данные"???
Re[9]: wininet hooks
От: Kubyshev Andrey  
Дата: 08.04.13 03:27
Оценка:
Ну вот ты вычитал все данные в своем коллбеке, а что прочтет оригинальный коллбек ?
Re[10]: wininet hooks
От: linkoln  
Дата: 08.04.13 13:54
Оценка:
Здравствуйте, Kubyshev Andrey, Вы писали:

KA>Ну вот ты вычитал все данные в своем коллбеке, а что прочтет оригинальный коллбек ?


если все вычитать получилось в каллбеке (будь то INTERNET_STATUS_RESPONSE_RECEIVED или INTERNET_STATUS_REQUEST_COMPLETE) — сразу же вызываю калбек оригинальный по этому поводу... Если не вышло сейчас — то пробую закачать еще на хуках InternetQueryDataAvailable | InternetReadFile | InternetReadFileEx, если же там вышло закачать все данные то мы колаем оригинальный прок каллбека и по хуку возвращаем все данные что остались, т.е. если в каллбеке оригинальный прок решит все выкачать — пусть, в хуке тогда уже отдадим что недокачал..
НО суть не в этом — ПОЧЕМУ МНЕ ВОЗВРАЩАЕТ ЕРРОР ПРИ ЧТЕНИИ ДАННЫХ В КАЛЛБЕКЕ?????
INTERNET_STATUS_RESPONSE_RECEIVED — InternetReadFile() возвращает ошибку ERROR_INTERNET_INCORRECT_HANDLE_STATE -почему стет инкоррект, как правильнор вычитвать в этом каллбеке???
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.