InternetReadFileEx

Тема в разделе "WASM.WIN32", создана пользователем JuliaSmit, 3 янв 2009.

  1. JuliaSmit

    JuliaSmit New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2008
    Сообщения:
    13
    Доброво времени суток, не могу понять как правельно считать данные из буфера InternetReadFileEx пробовал так

    Код (Text):
    1. type
    2. far_jmp = packed record
    3.   PuhsOp: byte;
    4.   PushArg: pointer;
    5.   RetOp: byte;
    6.  end;
    7.  
    8.  OldCode = packed record
    9.   One: dword;
    10.   two: word;
    11.  end;
    12.  
    13. var
    14.  
    15.  JmpZwq9: far_jmp;
    16.  OldZwq9: OldCode;
    17.  PtrZwq9: pointer;
    18.  
    19. function TrueInternetReadFileEx(hFile: HINTERNET;  lpBuffersOut: Pointer;
    20.   dwFlags: DWORD; dwContext: DWORD): BOOL; stdcall;
    21. var
    22.  Written:Dword;
    23. begin
    24. WriteProcessMemory(INVALID_HANDLE_VALUE, PtrZwq9,@OldZwq9, SizeOf(OldCode), Written);
    25. Result:= InternetReadFileEx(hFile,lpBuffersOut,dwFlags,dwContext);
    26. WriteProcessMemory(INVALID_HANDLE_VALUE, PtrZwq9,@JmpZwq9, SizeOf(far_jmp), Written);
    27. end;
    28.  
    29.  
    30.  
    31. function NewInternetReadFileEx(hFile: HINTERNET;  lpBuffersOut: Pointer;
    32.   dwFlags: DWORD; dwContext: DWORD): BOOL; stdcall;
    33. var
    34.  Rec:PInternetBuffers;
    35.  F:File of Byte;
    36. begin;
    37. Result:=TrueInternetReadFileEx(hFile,lpBuffersOut,dwFlags,dwContext);
    38. Rec:=lpBuffersOut;
    39.  
    40.  
    41. AssignFile(F,'c:\1.data');
    42. Rewrite(F);
    43. BlockWrite(F,Rec^.lpvBuffer,Rec^.dwBufferLength);
    44. CLoseFile(F);
    45. end;
    46.  
    47.  
    48. Procedure HookInternetReadFileEx;
    49. var
    50.  Written:DWord;
    51.  Lib:Cardinal;
    52. begin
    53. Lib:=GetModuleHandle('wininet.dll');
    54. if Lib=0 then
    55.    Lib:=LoadLibrary('wininet.dll');
    56.  
    57. PtrZwq9  := GetProcAddress(Lib,'InternetReadFileExA');
    58. ReadProcessMemory(INVALID_HANDLE_VALUE, PtrZwq9, @OldZwq9, SizeOf(OldCode), Written);
    59. JmpZwq9.PuhsOp  := $68;
    60. JmpZwq9.PushArg := @NewInternetReadFileEx;
    61. JmpZwq9.RetOp   := $C3;
    62. WriteProcessMemory(INVALID_HANDLE_VALUE, PtrZwq9, @JmpZwq9, SizeOf(far_jmp), Written);
    63. end;
    Пишет полный бред в файл, наверно я не правельно работаю с структурой InternetBuffers. Оснавная задача перехвата изменение данных в js и html при Refresh странице в браузере. Поправте в коде если не сложно в чем моя ощибка, прочитал весь форум на эту тему но ответа на свою проблему не нашел, так что писать читай форум не надо :)... Так же хотелось разобраться с асинхронным режимом Wininet если есть подробные статьи дайте урлы.


    P.S. С Новым Годом. (Заранее спасибо).
     
  2. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
  3. JuliaSmit

    JuliaSmit New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2008
    Сообщения:
    13
    смотрю в InternetReadFile все отлично данные идут без Gzip именно того сайта на катором тестирую. Я думаю все же ощибка в неправельной обработки структуры InternetBuffers.
     
  4. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
  5. JuliaSmit

    JuliaSmit New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2008
    Сообщения:
    13
    Не ужели не кто не сталкивался (((, бросить не могу так как надо делать 100%... По поводу Rewrite то делал мессагебох для паузы и смотрел каждый буфер все равно там бред.

    Тоже без результатнo.


    P.S. Люди помогите очень долго ломаю голову с этой проблемой нету продвижения дальше...
     
  6. djmans

    djmans New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2006
    Сообщения:
    312
    это ансихронная функция, про ансинхронное считывание из wininet, исписано пол инета, ищи.
    тебе нужно прехватывать еще кэлбэк связаный с HINTERNET, и ловить событие получения данных.

    Короче геморой еще тот, и лучше всеже брось затею, там еще много нюансов

    И вообще судя по ReadProcessMemory(INVALID_HANDLE_VALUE, ...) тебе точно нада забить.
     
  7. sambd

    sambd New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2007
    Сообщения:
    60
    JuliaSmit не парень не в ту тему ты полез) брось эту затею

    соглашусь с djmans
    Код (Text):
    1. ReadProcessMemory(INVALID_HANDLE_VALUE, PtrZwq9, @OldZwq9, SizeOf(OldCode), Written);
    2. ...
    3. WriteProcessMemory(INVALID_HANDLE_VALUE, PtrZwq9, @JmpZwq9, SizeOf(far_jmp), Written);
    вообще убило .... на смерть ..
     
  8. JuliaSmit

    JuliaSmit New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2008
    Сообщения:
    13
    Мнда, я думал форумы прогеров создают для общения и помощи ближнему, но после того как выслушал ваши высказывания то понял что большенство форумчан это заевщиеся игоисты. Я понемаю что может я что то незнаю и т.д. но веть можно сказать то то ты делаешь не правельно тебе надо делать так и так, читай то то. А в ответ я услышал только "уууу брось эту затею", не могу я ее бросить придеться делать все равно просто будет дольше и геморнее. Надеялся на ващу помощь теперь понял что большество программистов это игоистичные рожи с высоким самомнением.

    Ну теперь вопросы для тех кто еще не совсем задрал ноздри вверх и дышит ровно.

    1. Почему не верно INVALID_HANDLE_VALUE ?

    Переделал код так:
    Код (Text):
    1. Procedure HookInternetReadFileEx;
    2. var
    3.  Written:DWord;
    4.  Lib:Cardinal;
    5.  PProc:Cardinal;
    6. begin
    7. Lib:=GetModuleHandle('wininet.dll');
    8. if Lib=0 then
    9.    Lib:=LoadLibrary('wininet.dll');
    10.  
    11. PProc:=OpenProcess(PROCESS_ALL_ACCESS, False, GetCurrentProcessID);
    12. PtrZwq9  := GetProcAddress(Lib,'InternetReadFileExA');
    13. ReadProcessMemory(PProc, PtrZwq9, @OldZwq9, SizeOf(OldCode), Written);
    14. JmpZwq9.PuhsOp  := $68;
    15. JmpZwq9.PushArg := @NewInternetReadFileEx;
    16. JmpZwq9.RetOp   := $C3;
    17. WriteProcessMemory(PProc, PtrZwq9, @JmpZwq9, SizeOf(far_jmp), Written);
    18. end;
    Ну работает в любов варианте впринцепи. (Объясните в чем разница).

    2. В чем все же проблема считывания буфера InternetBuffers как я понемаю эта структура содержит в себе указатели на саму себя (Next) и определяет количесво структур параметром (dwBufferTotal).

    INTERNET_BUFFERSA = record
    dwStructSize: DWORD; { used for API versioning. Set to sizeof(INTERNET_BUFFERS) }
    Next: PInternetBuffers; { chain of buffers }
    lpcszHeader: PAnsiChar; { pointer to headers (may be NULL) }
    dwHeadersLength: DWORD; { length of headers if not NULL }
    dwHeadersTotal: DWORD; { size of headers if not enough buffer }
    lpvBuffer: Pointer; { pointer to data buffer (may be NULL) }
    dwBufferLength: DWORD; { length of data buffer if not NULL }
    dwBufferTotal: DWORD; { total size of chunk, or content-length if not chunked }
    dwOffsetLow: DWORD; { used for read-ranges (only used in HttpSendRequest2) }
    dwOffsetHigh: DWORD;
    end;


    3. По поводу асинхронного режима прочитав статьи так и не понял все сути. Но сделал некоторые выводы (если не прав поправте меня). После вызова функции в асинхронном режиме управление передаеться до выполнения функции, после выполнения происходит вызов CallBack, как я понял различить какая функция заверщилась можно по индентификатору HINTERNET. Если не сложно приведите примитивный пример с InternetSetStatusCallback.

    P.S. Заранее спасибо.

    (Не пишите "брось эту затею", так как мне все равно придеться все это понять и сделать, если тут нету людей кто может помочь то так и напишите).
     
  9. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    JuliaSmit, я тебе кое-что скажу. Большинство посетителей сайта (особенно в Beginners) - ламеры (пишу предупреждение - не обижайтесь и не пишите ответное мнение). Профессиональных прогеров это уже давно достало!!! Им хочется нормальной, интересной беседы. Ламеры для них как детсадовские дети, которые спрашивают - почему нельзя совать пальцы в розетку. А кому отвечать на ламерские вопросы? Ламеры "ничего не знают" и в большинстве - эгоисты и не собираются отвечать на чужие вопросы. Вот и приходится на тупые вопросы отвечать знающим людям, которые посещают сайт не только для своих вопросов но и чтобы отвечать на чужие.
    Так что не говори, пожайлуста, что здесь все - эгоисты. Просто я думаю - ламеры здесь всех достали (кто это читает - не обижайтесь и не говорите своего мнения на этот счет, оно наверняка не совпадает).
     
  10. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    AndreyMust19
    Увы. Совпадает
     
  11. JCronuz

    JCronuz New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2007
    Сообщения:
    1.240
    Адрес:
    Russia
    AndreyMust19 можно подумать все такие разумные, такие как ты
     
  12. mednice

    mednice New Member

    Публикаций:
    0
    Регистрация:
    6 янв 2009
    Сообщения:
    9
    В ишаке еще надо хукать InternetReadFile, через InternetReadFileExA/W она в основном читает при рефреше страницы, или туда попадает всякий ненужный мусор.
    Надо хукать InternetStatusCallback и заменять кальбяк на свой, а старый сохранять, впринципе можно обойтись и без этих извратов, но тогда не будет такого универсального инжетора html кода как зевса и прочих как, если тебе это нужно.
    в какой версии ишака(ie) ты хукаеш InternetReadFileEx?
    7-8 юзают InternetReadFileExW.

    Код (Text):
    1. typedef struct _INTERNET_BUFFERS  {
    2. .......
    3.  LPVOID lpvBuffer;
    4.  DWORD dwBufferLength;
    5. .....
    6. } INTERNET_BUFFERS, * LPINTERNET_BUFFERS;
    Код (Text):
    1. INTERNET_BUFFERSA = record
    2. ...
    3.     lpvBuffer: Pointer;       { [b]pointer to data buffer[/b] (may be NULL) }
    4.     dwBufferLength: DWORD;    { length of data buffer if not NULL }
    5. ...
    6. end;
    Все же написано, данные находятся в lpBuffersOut->lpvBuffer или на твоем "языке" в Rec^.lpvBuffer, длинна буффера lpBuffersOut->dwBufferLength или Rec^.dwBufferLength.
     
  13. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.552
    Адрес:
    Russia
    Эх... горе ты мое...
    JuliaSmit
    Да потому, что эти функции нужны чтобы читать из други процессов данные. Это все равно, что юзать лопату не по назначению.
    Для чтения данных в своем процессе используй обычную memcpy. Подумай над этим хорошенько.
    А то что вы взяли и во втором варианте открыли ваш собственный процесс... Это вверх абсурда. Он и так вам доступен для всего.

    Мне кажется вы скопировали этот код откудато.. Это не ваша разработка. Имхо
     
  14. JuliaSmit

    JuliaSmit New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2008
    Сообщения:
    13
    Вообщем следущее:

    Перехватил функции:

    InternetConnectA
    HttpOpenRequestA
    InternetReadFile
    InternetQueryDataAvailable
    InternetCloseHandle

    Собираю в таблицу все HINTERNET, подменяю данные в InternetReadFile и InternetQueryDataAvailable таким макаром

    1. При вызове InternetQueryDataAvailable при нужном URL (Определяю через HINTERNET) начинаю полностью выкачивать страницу через InternetReadFile (Предварительно сняв перехват) делаю в ней необходимые изменения.
    После продолжаю отдавать результат lpdwNumberOfBytesAvailable измененный под новую страницу теме же кусками что и скачивал. Ставлю обратно перехват InternetReadFile.

    2. В InternetReadFile вместо вызова оригинальной функции начинаю отдавать в буфер lpBuffer куски новой, изменной странице.

    Все это отлично пашет без глюков и т.д. Но есть 2 проблемы.

    1. При перехвате InternetQueryDataAvailable когда я пытаюсь скачивать файл через InternetReadFile между вызовами приходиться делать sleep иначе страница не выкачиваеться полностью (Прерываеться на скачивании после первого или второго вызова возращает 0). Думаю это как то связанно с асинхронным режимом (Хотя вызываю функцию я без всяких CallBack и т.д. пока мне это не понятно).

    2. При Refresh странице вызываеться функция InternetReadFileEx про нее я пытаюсь спросить уже долгое время :)

    P.S. По поводу дискуссии что тут развернулась прошу прощения, я понемаю что форум исключительно для решения проблем а не болталогии.
     
  15. mednice

    mednice New Member

    Публикаций:
    0
    Регистрация:
    6 янв 2009
    Сообщения:
    9
    нда

    вот и решай сам, тебе уже подсказали.
    На форуме данная тема поднималась много раз, самый лучший ответ дал barton в какой то из многочисленных тем про InternetReadFile.
    Все разобрано еще до тебя, осталось поискать и собрать.
     
  16. JuliaSmit

    JuliaSmit New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2008
    Сообщения:
    13
    Вообщем немного понял как работает асинхронный режим в IE, попробую описать. (Если не прав поправте меня).

    Функция InternetSetStatusCallback делает перехватчик на всю сессию (HINTERNET) открытую через InternetOpen и при любом взаимодействии с указателем на сессию вызывает функцию переданную в InternetSetStatusCallback. Передает параметры состоянии сессии через dwInternetStatus по каторым можно определить что происходит в данный момент.

    Код (Text):
    1. Function MyCallBack (HInternet: HINTERNET; dwContext, dwInternetStatus: DWORD;
    2.   lpStatusInfo: Pointer; dwStatusInfoLen: DWORD): HINTERNET; stdcall;
    Я перехватил InternetSetStatusCallback изменил параметры lpfnInternetCallback на свой обработчик (MyCallBack) но после вызова моей функции непонятно что нужно вернуть в результат что бы IE начал отображать страницу нормально. Если не вернуть результат IE оставляет страницу пустой (было уже на формуме но так и не решили эту проблему публично).


    Код (Text):
    1. Function MyCallBack (HInternet: HINTERNET; dwContext, dwInternetStatus: DWORD;
    2.   lpStatusInfo: Pointer; dwStatusInfoLen: DWORD): HINTERNET; stdcall;
    3. begin
    4. MessageBox(0,'CallBack',pchar(IntTostr(dwInternetStatus)),0);
    5. // Result=????
    6. end;
    7.  
    8.  
    9.  
    10. function NewInternetSetStatusCallback(hInet: HINTERNET;
    11.   lpfnInternetCallback: PFNInternetStatusCallback): PFNInternetStatusCallback; stdcall;
    12. var
    13.   Written:Dword;
    14. begin
    15. OldCallBack:=lpfnInternetCallback;
    16. OldHinternet:=hInet;
    17.  
    18. WriteProcessMemory(GetCurrentProcess, PtrZwq9,@OldZwq9, SizeOf(OldCode), Written);
    19. Result:=InternetSetStatusCallback(hInet,@MyCallBack);
    20. WriteProcessMemory(GetCurrentProcess, PtrZwq9,@JmpZwq9, SizeOf(far_jmp), Written);
    21. end;
    Но все же до меня не дошло, необходимо возращать результат в функции обработки каллбека (MyCallBack) или же сам старый каллбак (InternetSetStatusCallback) вызывать повторно со старыми параметрами.

    P.S. Не когда не работал по данной теме, ну теперь необходимо решить эту проблему в кротчайшие сроки, надеюсь на ваше понемание. Вот и пытаюсь понять как и что происходит извените за назойливость ну уж больно надо это решить, да и думаю форумчанам будет интересна эта тема разложенная в подробностях, так как после прочтения форума мало что понятно по данному вопросу.
     
  17. barton

    barton New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2008
    Сообщения:
    164
    Адрес:
    Czechoslovakia
    Этот тред где-то 7ой на wasm)
    Конечно же нужно оповещать старый оригинальный колбек ИЕ (а точнее, urlmon'а) о всех событиях (кроме тех, которые надо завернуть). Как ещё может работать асинхронный режим? АПИ возвращают управление с ERROR_IO_PENDING, а когда выполняют свою работу - вызывают заданый колбек с соответствующими аргументами, только поэтому программа понимает, что действие завершено (к примеру, INTERNET_STATUS_REQUEST_COMPLETE означает, что асинхронный запрос выполнен - чтение странички, отсылка заголовков итд).
    Кстати, для этого придется хранить связь INTERNET HANDLE -- session callback. Т.к. хендл, который присылается в колбек - может быть хендлом SESSION (InternetOpen), CONNECTION (InternetConnect) и REQUEST (XxxOpenRequest). Я для этого строил свой список. Асинхронный/нет режим задается через dwFlags флагом INTERNET_FLAG_ASYNC в InternetOpen и меняется ещё там как-то через InternetSetOption.

    InternetReadFileEx ИЕ юзает (так решили разработчики, хотя не особо ясно зачем) все элементы на странице (картинки) и саму страницу при рефреше. Причем это выясняно путем науч.тыка и является только фактом для ие5,ие6,ие7, не более.
    Сразу совет - лучше не смотреть на версию а хукать все АПИ, которые могут быть использованы, список в MSDN. Иначе потом будет выяснятся, что на другой версии ИЕ лаг, fixed-нашелся на другой версии лаг итд.
    Все равно для полноценной работы ещё придется очень много чего реализовать.
     
  18. JuliaSmit

    JuliaSmit New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2008
    Сообщения:
    13
    Что про поводу InternetReadFileEx разобрался на самом деле не понятный мне глюк с памятью. Решил так наверно все же это кривой Delphi

    Код (Text):
    1. function NewInternetReadFileEx(hFile: HINTERNET;  lpBuffersOut: Pointer;
    2.   dwFlags: DWORD; dwContext: DWORD): BOOL; stdcall;
    3. var
    4.  Rec:PInternetBuffersA;
    5.  Buffer:Pointer;
    6.  F:File of Byte;
    7.  
    8. begin;
    9. Result:=TrueInternetReadFileEx(hFile,lpBuffersOut,dwFlags,dwContext);
    10. Rec:=lpBuffersOut;
    11. GetMem(Buffer,Rec^.dwBufferLength);
    12. CopyMemory(Buffer,Rec^.lpvBuffer,Rec^.dwBufferLength);
    13.  
    14. AssignFile(F,'c:\1.data');
    15. if FileExists('c:\1.data') then
    16. begin
    17. Reset(F);
    18. Seek(f,FileSize(F));
    19. end else
    20. Rewrite(F);
    21. BlockWrite(F,Buffer^,Rec^.dwBufferLength);
    22. CLoseFile(F);
    23. end;
    Причем я не виже особой разницы в плане чтения памяти с прошлым вариантом:

    Код (Text):
    1. function NewInternetReadFileEx(hFile: HINTERNET;  lpBuffersOut: Pointer;
    2.   dwFlags: DWORD; dwContext: DWORD): BOOL; stdcall;
    3. var
    4.  Rec:PInternetBuffers;
    5.  F:File of Byte;
    6. begin;
    7. Result:=TrueInternetReadFileEx(hFile,lpBuffersOut,dwFlags,dwContext);
    8. Rec:=lpBuffersOut;
    9.  
    10.  
    11. AssignFile(F,'c:\1.data');
    12. Rewrite(F);
    13. BlockWrite(F,Rec^.lpvBuffer,Rec^.dwBufferLength);
    14. CLoseFile(F);
    15. end;
    Всем спасибо буду разбераться дальше.
     
  19. djmans

    djmans New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2006
    Сообщения:
    312
    ..
    Result:=TrueInternetReadFileEx(hFile,lpBuffersOut,dwFlags,dwContext);
    =>> после возврата из асинхронной функции у тебя еше нет данных в буфере.

    здесь делается примерно так if(GetLastError() == ERROR_IO_PENDING)WaitForSingleObject(hReadEvent, INFINITE); , где hReadEvent допустим созданное тобой событие(CreateEvent), которое сигнализирует (SetEvent) в в твоем кэллбэке.

    и вот после срабатывания ожидания, ты спокойно дальше выполняеш свой код.

    Rec:=lpBuffersOut;

    ..


    PS: Почитай про синхронизацию потоков.
     
  20. JuliaSmit

    JuliaSmit New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2008
    Сообщения:
    13
    Подведем итоги:

    После всего пересказанного и высказанного получил нужную информацию и смог решить почти все текущие проблемы. Хотелось бы выразить благодарность barton,djmans за совету по делу.

    Что косаеться поста
    Во первых что бы отвечать на чьи то вопросы необходимо дойти до нормального уровня программирования, что бы не отвечать тупостью "Брось эту тему" или "Читай форум МСДН там все написанно", лично я не дошел до того уровня.

    Ну а вообщем некоторые ваши ответы мне очень помогли, огромное вам спасибо, надеюсь на дальнейшее взаимопонимание.