IAT memory protection

Тема в разделе "WASM.WIN32", создана пользователем DM, 26 дек 2009.

  1. DM

    DM New Member

    Публикаций:
    0
    Регистрация:
    26 дек 2009
    Сообщения:
    7
    Пытаюсь ставить hook на winapi через import address table. Написал код, протестировал на перехвате CreateFileA в "FAR manager", работает нормально, то есть в алгоритме поиска нужного адреса в IAT проблем быть не должно. Но когда дело дошло до перехвата функций в целевом приложении, получаю access violation при изменении IAT. Попытка изменения режима доступа к памяти ни к чему не приводит.

    Проверяю возможность записи с помощью IsBadWritePtr:

    Код (Text):
    1. IsBadWritePtr((LPVOID)thunkIat->u1.AddressOfData, sizeof(LPVOID))
    Если запись невозможна, то получаю текущие права доступа к памяти

    Код (Text):
    1. VirtualQuery((LPVOID)thunkIat->u1.AddressOfData, &mbiImportPage, sizeof(MEMORY_BASIC_INFORMATION));
    2. dwNewProtectionFlags = mbiImportPage.Protect;
    3. dwNewProtectionFlags &= ~(PAGE_READONLY | PAGE_EXECUTE_READ | PAGE_EXECUTE);
    4. dwNewProtectionFlags |= (PAGE_EXECUTE_READWRITE);
    затем меняю их через VirtualProtect, вызываю дважды, чтобы узнать какие права были применены после первого вызова

    Код (Text):
    1. dwResult = VirtualProtect((LPVOID)thunkIat->u1.AddressOfData, sizeof(LPVOID), dwNewProtectionFlags, &dwOldProtectionFlags);
    2. dwResult = VirtualProtect((LPVOID)thunkIat->u1.AddressOfData, sizeof(LPVOID), dwNewProtectionFlags, &dwOldProtectionFlags);
    Второй вызов VirtualProtect ставит dwOldProtectionFlags в PAGE_EXECUTE_WRITECOPY вместо PAGE_EXECUTE_READWRITE.

    После изменения прав доступа к памяти, вызов IsBadWritePtr возвращает FALSE, как будто я могу писать по заданному адресу. Но когда я пытаюсь изменить IAT, все равно получаю access violation.

    Экспериментировал с вызовом VirtualProtect:

    - если пытаюсь выставить режим PAGE_READWRITE, то получаю access violation при вызове VirtualProtect
    - использовал (mbiImportPage.BaseAddress, mbiImportPage.RegionSize, ...) вместо ((LPVOID)thunkIat->u1.AddressOfData, sizeof(LPVOID), ...), результат тот же

    Не могу найти полезную информацию о PAGE_EXECUTE_WRITECOPY и узнать чем может быть вызвана установка этого режима вместо PAGE_EXECUTE_READWRITE

    Возможно кто-нибудь в курсе чем может быть вызвано access violation ...
     
  2. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    эм... а это точно VA, а не RVA? я просто не разбирался в коде, но на глаз ошибка может быть тут. П.С.: посмотри в ольке, что конкретно передается в виртуалпротект, что находится по переданному адресу, что именно возвращает виртуалпротект и с каким кодом ошибки
     
  3. DM

    DM New Member

    Публикаций:
    0
    Регистрация:
    26 дек 2009
    Сообщения:
    7
    точно, я тестировал на CreateFileA, это указатель на функцию в загруженной DLL. Также проверял в отладчике - адрес находится нормально и соответствует тому, что возвращает GetProcAddress

    если пытаться поставить PAGE_READWRITE, выпадает access violation, если PAGE_EXECUTE_READWRITE, то режим доступа меняется без ошибок, но выставляется PAGE_EXECUTE_WRITECOPY.

    странно также что IsBadWritePtr возвращает FALSE ... проблема именно с доступом к памяти, но я не разбираюсь во всех тонкостях =\
     
  4. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    а ты память точно в нужном приложении меняешь, а не в своем? адреса точно там находишь, а не в своем? не совсем понятна твоя методика

    это не показатель - условия тестирования разных функций в разных процессах могут отличаться в корне
     
  5. DM

    DM New Member

    Публикаций:
    0
    Регистрация:
    26 дек 2009
    Сообщения:
    7
    Я подключил нужную DLL к своему процессу и попытался модифицировать ее таблицу импорта - результат тот же, что и при внедрении в использующий ее процесс, и теперь я имею возможность отлаживать код в студии - все адреса правильные. Имею ввиду, что я уверен в том, что меняю именно то что нужно, проблема в доступе к памяти.
     
  6. spa

    spa Active Member

    Публикаций:
    0
    Регистрация:
    9 мар 2005
    Сообщения:
    2.240
    DM
    отлаживать студией можно и в чужом процессе
     
  7. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    DM
    ничего не могу сказать. Сколько раз пытался писать подобный код - ни разу проблем не было
     
  8. DM

    DM New Member

    Публикаций:
    0
    Регистрация:
    26 дек 2009
    Сообщения:
    7
    Да, у меня при тестировании также не было проблем, ситуация характерна для конкретной DLL независимо от приложения которое ее использует ... Сейчас начал постепенно разбираться - если изменять режим доступа для всей таблицы IAT, то изменение адреса становится возможным. Тем не менее, если кто в курсе подобного вопроса, поделитесь деталями плиз =)
     
  9. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    WRITECOPY означает, что вместо общей копии процессу выдается частная копия страницы. Короче говоря есть один набор физических страниц, где лежат код и данные загруженной длл. Они проецируются во все процессы только на чтение и исполнение. Если хотят проецировать на запись, то процессу выделяют свою личную копию страницы, где можно вносить изменения не трогая общую копию. Это есть в руссиновиче.

    MSoft, в памяти это поле уже не AddressOfData, а называется Function и содержит точку входа функции. Автор просто выбрал неверное имя из union'а.

    DM
    Вообще странно. Покажи код
     
  10. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    DM
    >dwNewProtectionFlags &= ~(PAGE_READONLY | PAGE_EXECUTE_READ | PAGE_EXECUTE);
    >dwNewProtectionFlags |= (PAGE_EXECUTE_READWRITE);
    Мы бы так не стали делать. Взгляни на значения этих констант – их нижний байт не есть какой-нибудь сорт маски же. Ты контролируешь значение "dwResult" после вызова VirtualProtect с такими атрибутами защиты? Скорее всего функция изначально возвращает FALSE в твоём случае.
    Хотя, опять-таки, это не объясняет AV при попытке модифицирования IAT.

    >если пытаюсь выставить режим PAGE_READWRITE, то получаю access violation при вызове VirtualProtect.
    Очень интересно. По идее такого быть не должно. Можно взглянуть на крэшдамп или хотя бы стек вызовов на момент исключения?
     
  11. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Скорее всего автор имел в виду ERROR_ACCESS_VIOLATION ошибку, возвращаемую функцией. Было бы забавно, если бы вызов валился с реальным исключением.
     
  12. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    А-ха. Таки увидели ситуацию, в которой такое может быть:
    DM вызывает VirtualProtect с защитой PAGE_READWRITE для IAT своего процесса. IAT располагается в начале кодовой секции, на той же странице, что и исполняемый код. VirtualProtect успешно отрабатывает, и сразу после возврата возникает исключение — ведь страница с кодом теперь неисполняемая.
     
  13. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Хм. И правда) А я думал это он ошибку имел в виду.

    Автор, жадина, код так и не показал, оставляя другим лишь вариант догадываться до подробностей самому :)
    Пора написать, что настоятельно рекомендуется приводить исходный код сразу в первом посте, когда пишут тему о том, что не могут разобраться в проблеме.
     
  14. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    или чек ВМ на 4? - за услуги экстрасенсов :)
     
  15. DM

    DM New Member

    Публикаций:
    0
    Регистрация:
    26 дек 2009
    Сообщения:
    7
    Я же привел код ... Какой конкретно код нужно выложить ?

    Скорее всего так и есть, непонятно почему в примере советовали использовать PAGE_READWRITE


    Как оказалось использовать IsBadWritePtr уже не стоит, т.к. функция давно obsolete и ничего не гарантирует.
    А VirtualProtect вызывать для всей секции IAT, тогда при втором вызове в dwOldProtectionFlags записывается PAGE_EXECUTE_READWRITE.

    Все же напишите какой нужен. На мой взгляд проблема в одном только вызове VirtualProtect, остальное неважно скорее всего.

    PS

    Не обращайте внимание на &= ~(PAGE_READONLY | PAGE_EXECUTE_READ | PAGE_EXECUTE), переменная здесь обнуляется, я заменил на dwNewProtectionFlags = PAGE_EXECUTE_READWRITE

    При установке PAGE_EXECUTE_READWRITE функция возвращала TRUE
     
  16. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    DM
    >На мой взгляд проблема в одном только вызове VirtualProtect.
    Ага. Видим теперь. Всё просто. Собираешься изменить элемент IAT – необходимо изменять протекцию этого элемента IAT. Не протекцию функции, на которую ссылается элемент IAT.

    Так что действительно – весь код есть, в нужном объёме.
     
  17. DM

    DM New Member

    Публикаций:
    0
    Регистрация:
    26 дек 2009
    Сообщения:
    7
    Хехе, как обычно - много возни из-за ерунды =\
     
  18. DM

    DM New Member

    Публикаций:
    0
    Регистрация:
    26 дек 2009
    Сообщения:
    7
    Всем спасибо, думаю теперь проблем не должно возникнуть.