![]() |
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]() ![]() ![]() |
|
freezeman |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 175 Регистрация: 21.1.2011 Репутация: нет Всего: нет |
Привет всем!
Подскажите, пожалуйста. Я сделал перехват winapi функции ReadFile и нужно занести файл, который читался этой функцией в ОП. Какой метод будет самым быстрым? Проецирование или виртуальная память? И ещё, после того как я записал файл в память, мне нужно при следующем перехвате ReadFile передать указатель на мой файл в ОП, просто подменив HANDLE у ReadFile... как получить этот HANDLE у файла в ОП? Или все же проецирование использовать?? Я уже запутался, помогите... Это сообщение отредактировал(а) freezeman - 27.3.2012, 20:04 |
|||
|
||||
Akira |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 26.3.2012 Репутация: нет Всего: нет |
Честно, несколько раз перечитывал и не понял что нужно. Выдохни и опиши что ты хочешь хочешь сделать и что хукаешь (импорт или dll). Насколько я понял подмену чтения файла, если так, то открывай файл который будешь подсовывать, как открывать зависит от размера, если несколько килло то нет смысла мапить и прописывай HANDLE своего файла, указатель трогать незачем, буфер уже выделен (или нужно?), а так, проще и правильнее (хуки зло) хукнуть CreateFile.
|
|||
|
||||
freezeman |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 175 Регистрация: 21.1.2011 Репутация: нет Всего: нет |
У меня перехватывается функция ReadFile, я набираю статистику по перехвату/обращению и наиболее часто используемые файлы хочу поместить в ОП. Затем при следующем перехвате, если я определю, что файл уже в ОП, то в перехваченную функцию ReadFile нужно как-то передать "указатель" на этот же файл, но в ОП. Вопроса в общем 2: как лучше заносить файл в ОП и как получить HANDLE этого файла в ОП (чтобы просто подставить в перехваченную ReadFile и все) или можно как-то другим методом это реализовать? |
|||
|
||||
Akira |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 26.3.2012 Репутация: нет Всего: нет |
Решение в лоб - Мапить файл и из проекции заполнять буфер (указатель) размер сколько читать передается. ReadFile не трогать.
|
|||
|
||||
freezeman |
|
||||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 175 Регистрация: 21.1.2011 Репутация: нет Всего: нет |
Спасибо за совет, проверю его завтра..) Добавлено через 6 минут и 44 секунды
Но думаю, что это не очень хорошее решение, желательно каким-нибудь образом HANDLE передать в ReadFIle... Если я просто заполню буфер тупо по параметрам вызова ReadFile, то вернуть системе этот ReadFile не получится без проблем... |
||||||
|
|||||||
freezeman |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 175 Регистрация: 21.1.2011 Репутация: нет Всего: нет |
Подскажите, please!!))
|
|||
|
||||
Akira |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 26.3.2012 Репутация: нет Всего: нет |
Если я просто заполню буфер тупо по параметрам вызова ReadFile, то вернуть системе этот ReadFile не получится без проблем...
Какие еще проблемы? |
|||
|
||||
freezeman |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 175 Регистрация: 21.1.2011 Репутация: нет Всего: нет |
После перехвата функции ReadFile нужно вернуть её системе, модифицированную или нет, а если я просто заполню буфер, то что указывать в указателе на файл (первый параметр - HANDLE), NULL? |
|||
|
||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
в данном случае, совсем не обязательно, можно просто вернуть TRUE -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
freezeman |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 175 Регистрация: 21.1.2011 Репутация: нет Всего: нет |
||||
|
||||
Akira |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 26.3.2012 Репутация: нет Всего: нет |
Например успешно промапил файл и считал то return true если нет,то return false. Примеры работы с проекциями с мотри в MSDN или в гугле - Чтение фала + FileMapping, примеров овер 9000 на всех языках.
|
|||
|
||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
это зависит от твоей конкретной реализации свопа, если перехватывать CreateFile и в нем создавать объект мепирования (CreateFileMapping), как предлагает Akira, то дескриптор этого маппинга и нужно вернуть из CreateFile, в таком случае, на ReadFile нужно вызвать MapViewOfFile со смещением и размером, пришедшими из ReadFile, MapViewOfFile вернет указатель на исходный буфер, вот данные из этого буфера и нужно перекинуть в буфер, пришедший в ReadFile и вернуть TRUE, конечно, если MapViewOfFile вернет NULL, ReadFile должен вернуть FALSE, соответственно только на CloseHandle, нужно соответственно закрыть дескриптор исходного файла вот и вся работа по твоей задаче, замечу только, что система такой хук не перварит без дополнительного фильтра, который будет отсеивать процессы, работающие с драйверами устройств, так что не стоит его внедрять в автозагрузку, чревато -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
freezeman |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 175 Регистрация: 21.1.2011 Репутация: нет Всего: нет |
Понятно, а если так реализовать: у меня набирается статистика по обращениям к файлам, затем по алгоритму выбираются файлы, которые нужно поместить в ОП, а после очередного перехвата ReadFile, если этот файл, к которому идет обращение функцией ReadFile, занесен в ОП, то считать его из ОП. Это было общее описание задачи. Если я на этапе копирования файла в ОП, сделаю проекцию и назову её по имени файла+какие-нибудь доп. атрибуты, а когда произойдет след перехват я проверю сущ ли такая проекция, если да, то заполню буфер как вы описали, если нет просто верну ReadFile до перехвата... И ещё при проекции скорость чтения из неё так как из ОП или как с жесткого диска?? |
|||
|
||||
Akira |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 26.3.2012 Репутация: нет Всего: нет |
Можно и из ОП раз так хочется (только где столько памяти взять?
![]() |
|||
|
||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
значит нужно завести список таких файлов и на ReadFile искать эти данные в нем, вроде же все очевидно, можно сделать так: 1. перехватываем CreateFile: - проходим по списку files, ищем по имени запись файла - нашли - возвращаем его индекс (или его уникальный номер) - не нашли - создали такую запись, открыли файл и вернули индекс новой записи(или ее уникальный номер) 2. перехватываем ReadFile: - переходим в списке files к записи файла (в первом параметре, соответственно будет индекс или уникальный номер этой записи) - не нашли - передали параметр в реальную ReadFile - нашли - расчитываем его статистику, сохраняем ее результаты в записи - если требуется отобразить файл в память, создаем отображение, сохраняем дескриптор в записи - если требуется прочитать отображение, делаем это по схеме постом выше, используя дескриптор отображения, он же уже находится в записи - если требуется прочитать файл напрямую, делаем это, передав параметры в реальную ReadFile, дескриптор файла ведь там же 3. перехватываем CloseHandle: - переходим в списке files к записи файла (в первом параметре, соответственно будет индекс или уникальный номер этой записи) - не нашли - передали параметр в реальную CloseHandle - нашли - закрыли открытые дескрипторы, удалили запись
при такой проекции, скорость чтения из нее может оказаться самым незначительным местом, особенно, если файлов будет много или если время анализа и подсчета статистики будет сильно перекрывать время чтения если при этом будет слишком много мелких файлов, любая проекция будет невыгодна, независимо от того медленная она или быстрая -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
freezeman |
|
||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 175 Регистрация: 21.1.2011 Репутация: нет Всего: нет |
Уффф... для вас, для кого-нибудь ещё на форуме это, конечно, не сложно... Я программист .NET и с WINAPI не работал, пишу сейчас на С++ и параллельно изучаю особенности языка...
У меня в этом то и дело, что файлов маленьких будет много, а общий размер я буду выделять и, если сумма объёмов этих файлов превышает ограничение, то они просто не учитываются, возвращаются как есть... Перехват у меня есть функции ReadFile, через проекцию сведения о перехваченном файле передаются в мою службу, где там обрабатываются, принимается решение заносить их в ОП или нет, когда занес группу файлов в ОП, я планировал сделать проекцию (для межпроцессного взаимодействия), где хранил сведения о уже занесенных файла в ОП...Когда произошел перехват вновь, открывается эта проекция и проверяет на наличие этого файла в ОП... ну дальше понятно, что я должен считать его с ОП... но как это сделать, как это реализовать....не знаю(( И не совсем подходит описанная схема...Моожет через кучу, заносить туда, а потом, как писал Akira, считать в буффер и все?? |
||||
|
|||||
Akira |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 26.3.2012 Репутация: нет Всего: нет |
Как читать особой разницы нет, реализация примерно одинакова. Почитай про работу с указателями. Хранить, если много параметров которые надо хранить то можно завести структуру и сделать масив. Например, как то так
struct Save { char name[MAX_PATH]; void* ptr }; А в память грузи так, как тебе нравится. Функция что бы получить из HANDLE имя - NtQueryObject(hFileHandle,ObjectNameInformation,(PVOID)lpBuffer, size, &ret); Это сообщение отредактировал(а) Akira - 28.3.2012, 18:23 |
|||
|
||||
freezeman |
|
||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 175 Регистрация: 21.1.2011 Репутация: нет Всего: нет |
Получил имя из HANDLE чуть-чуть по другому, и передаю тоже в структуре массив TCHAR, но при передаче, почему-то путь ограничивается 18 символами, хотя в момент преобразования HANDEL в путь к файлу он бывает корректен.
То есть сначала загрузить, а потом просто прочитать из памяти, как вы описывали ранее и вернуть в случае успеха TRUE... буду пробовать, спасибо большое! |
||||
|
|||||
Akira |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 26.3.2012 Репутация: нет Всего: нет |
но при передаче, почему-то путь ограничивается 18 символами
Мб проблема в типах (WCHAR) покажи код получения имени. Add: freezeman Если не кто не ответит то завтра напишу ибо я уже иду на вторые сутки без сна так что проблема отлечить int от char. Это сообщение отредактировал(а) Akira - 28.3.2012, 22:10 |
|||
|
||||
freezeman |
|
||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 175 Регистрация: 21.1.2011 Репутация: нет Всего: нет |
В тестовом примере ставлю точку останова, проверяю и все нормально, но когда передаю через проекцию передает только первые 18 символов... Код получения путь к файлу по его HANDLE:
Скорее всего дело в типе, может получать не в массиве TCHAR, а просто в массиве char? Это сообщение отредактировал(а) freezeman - 28.3.2012, 20:34 |
||||
|
|||||
freezeman |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 175 Регистрация: 21.1.2011 Репутация: нет Всего: нет |
А как узнать какие именно данные будут считываться, какая часть файла?
Можно ли получить из параметров readfile? Я подумал, что при вызове системой функции ReadFile считывается определенный блок из файла, но в параметрах кроме количества толком ничего нет, как узнать что именно читается? Это сообщение отредактировал(а) freezeman - 30.3.2012, 10:03 |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
Если файл был открыт в OVERLAPPED режиме, то в структуре overlapped (последний параметр) передается смещение, откуда читать. Иначе чтение производится с текущей позиции. Ее можно отслеживать самому, или запросить у системы (через SetFilePointer(handle,0,NULL,FILE_CURRENT) ) |
|||
|
||||
Akira |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 26.3.2012 Репутация: нет Всего: нет |
freezeman
А зачем ты путь конвертируешь? В этот нет нужды, да и в хукнутой функции это точно не нужно делать. |
|||
|
||||
freezeman |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 175 Регистрация: 21.1.2011 Репутация: нет Всего: нет |
А как я узнаю, какой именно файл читает ReadFile и есть ли он у меня в памяти... ведь HANDLE не будет при следующем обращении совпадать... |
|||
|
||||
Akira |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 26.3.2012 Репутация: нет Всего: нет |
Я об этом - QueryDosDevice достаточно этого - GetMappedFileName
Конвертирование нужно что бы из этого \Device\HarddiskVolume1\Temp\ сделать C:\Temp в твоем случае это излишне. Это сообщение отредактировал(а) Akira - 30.3.2012, 15:44 |
|||
|
||||
freezeman |
|
||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 175 Регистрация: 21.1.2011 Репутация: нет Всего: нет |
Проверю... Подскажите как мне заполнить буфер, который указан в перехваченной функции ReadFile... Вот алгоритм: 1 создать однонаправленный динамический список, загрузить туда файлы, отфильтрованные по алгоритму 2 проверить в перехваченной ReadFile на наличие этого файла в моем динамическом списке 3 если файл в памяти, то нужно заполнить буфер со смещением overlapped 4 иначе просто вернуть ReadFile системе. Подскажите, пожалуйста, как реализовать 3 пункт, как заполнить буфер со смещением? Добавлено через 53 секунды
Спасибо, отлично... |
||||
|
|||||
Akira |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 26.3.2012 Репутация: нет Всего: нет |
Я же говорил, читай про работу с указателями.
Примерно так char* str = "primer"; void* pout = str; void* pin; memcpy(pin, pout, 4); printf("%s", pin); |
|||
|
||||
freezeman |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 175 Регистрация: 21.1.2011 Репутация: нет Всего: нет |
Спасибо большое! почитаю, разберусь!) |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Системное программирование и WinAPI" | |
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |