Внедрился в чужой процесс, получил хендл запроса на сервер, хочу считать страницу в ответ. Перехватываю IRF. Код (Text): char buff[255]; while (true) { if (!OrigInternetReadFile(hFile, buff, sizeof(buff), &dwSize)) // hFile - перехваченный хендл { MessageBox(0, "InternetReadFile", "IRF", 0); goto fck; } if (dwSize == 0) break; buff[dwSize] = 0x00; page += buff; dwReadPtr += dwSize; } Но этот код работает из рук вон плохо. То считает половину страницы и обломается (dwSize == 0), то IRF возвращает 0. В последней мутации =\ вообще после первого вызова IRF возвращает true, но dwSize = 0. Как стабильности добиться? С чем может быть связанна такая ерунда?
А как вызов IRF влияет на хендл? т.е. можно как-то имея хенд прочитать всю страницу, но при этом вернуть хендл так, как будто чтения не было, и след. вызов IRF читал страницу снова?
Ещё вопрос - я перехватил InternetReadFileExA, получил данные - как дать знать пользовательскому коду что ф-я отработала?
не поделитесь паблик сорсом подмены странички под IE? а то сталкиваюсь с некоторыми стихийными и непонятными проблемами, стремясь вывести себя в лидеры гугла =)
Да свои наработки есть, но работает оно через раз по непонятной причине. Заценить бы чужие разработки.
А почему может возникать такая проблема - пишу функцию - заменитель InternetQueryDataAvailable, в ней читаю всю страничку при первом её вызове, возвращаю как доступно весь размер странички. Но после этого хендл этот закрывается, а мне выводится dnserror.htm. InternetReadFile даже не вызывается.
Freecod Перехватывай WSARecv проблем никаких не будет, а если ещё и внимательно посмотришь на неё под дизасмом перехватишь незаметно для rku/gmer.
В функции - переходнике IQDA Код (Text): std::string page=""; //Sleep(1000); DWORD dwSize = 0, dwReadPtr = 0, lpBytesAvailable = 0; char * buff = NULL; while (true) { bool ret = OrInternetQueryDataAvailableA(hFile, &lpBytesAvailable, NULL, NULL); if (ret) { buff = (char *)LocalAlloc(GMEM_FIXED | LMEM_ZEROINIT, lpBytesAvailable+1); if (!OrInternetReadFile(hFile, buff, lpBytesAvailable, &dwSize)) { LocalFree(buff); MessageBox(0, "InternetReadFile", "IRF", 0); return false; } if (dwSize == 0) { LocalFree(buff); break; } buff[dwSize] = 0x00; page += buff; dwReadPtr += dwSize; LocalFree(buff); } } ... dwPgSize = page.size(); *lpdwNumberOfBytesAvailable = dwPgSize; return 1; По логике должно работать. Не работает. Страницу читает, размер возвращает. dnserror.htm в итоге Если снять коммент со Sleep в начале - некоторые страницы робит нормально. Некоторые - опять dnserr Вызывается IQDA, возвращается размер прочитанной страницы (всей) и true, - после этого след. вызов InternetCloseHandle, закрывает мой хендл и на ошибку.
Freecod ИМХО, какой код -- так и работает Вообще в идеале надо выдавать минимальный код, к-рый можно собрать и запустить (а стало быть и отладить). А здесь какой-то ошметок хз чего. std::string а значит что код в отдельной dll? У меня просто все хуки сплайсенгом устанавливаются, не могу позволить такую роскошь . Далнее, зачем вообще ставить Sleep'ы в обработчик функций? Потом, если уж используешь С++, то вместо LocalAlloc/LocalFree предпочтительней использовать std::vector, что-то вроде std::vector<char> v(lpBytesAvailable + 1); InternetReadFile(hFile, &v[0], lpBytesAvailable, &dwSize); std::string page(&v[0]); Также, некошерно втыкать в обработчики MessageBox'ы (скока раз уж об этом талдычили), если уж так хочется делать OutputDebugString и смотри в DebugView. + в прототипе функции стоит BOOL, а значит и обработчик должен возращать FALSE/TRUE, а не false/1. Ну а ошибка конечно же в ... P.S. Никогда не перехватывал InternetQueryDataAvailable, есть предположение: написать тестовую программу к-рая будет скачивать файл с помощью wininet'a и посмотреть что будет если между 2мя вызовами сабжа сделать InternetReadFile. P.S.1. Попробовал делать хук на subj, все ловится, но пораждает глюки. Соб-но а зачем её хукать?
Хорошо. Чхать на InternetReadFile и IQDA. Что использует IE НАД ними? То есть что он наверняка ипользует ещё одну апи что бы получить всю страницу целиком.
я ж тебе сказал что лучше всего перехватывать, и не обязательно что б функция получала всю страницу целиком это можно и вручную сделать.
> и не обязательно всю страницу целиком это можно и вручную сделать. Как предлагаешь это сделать? Проверять каждый "Кусочек" на нужные данные? а если они будут "разрезанны"?