Недокументированные функции; Загрузка 32-х битных DLL в 64-х битный процесс.

February 28th, 2008

Вопрос:

Скажите, а невозможность загрузки в 64bit-процесс 32bit DLL – фатальна, или же возможны какие-то хаки, недокументированные обходные пути?

Отвечаю здесь, так как ответ получился слушком длинным.

Во-первых, про любые недокументированные возможности меня спрашивать бесполезно. Даже если такая возможность существует, я всё равно о ней не расскажу. Этому есть несколько причин, включая очевидные вещи вроде NDA, законе об авторском праве и т.д. Еще одна причина, почему я не горю желанием это делать, – это то, что раскрывая детали реализации того или иного компонента, я тем самым лишаю этот компонент возможности развиваться и улучшатся в следующих версиях.

Почему так? Приведу пример. Создавая класс, разработчик задаёт каждому его члену определённый уровень доступа:

  • public – для членов класса, составляющих публичный интерфейс класса;
  • protected – для членов класса, определяющих внутренний интерфейс класса;
  • private – для членов, являющихся деталями реализации класса, о которых остальным знать не положено.

Сокрытие части функциональности класса облегчает будущие исправления и добавление новой функциональности, так как код может быть изменен при условии, что публичный интерфейс не изменяется. Windows, как и любой другой продукт, никак не отличается от класса в этом плане.

Недокументированные возможности существуют. Причины из недокументированности ровно те же самые, что и причины для существования private и protected членов класса. И если я (или другой инсайдер) поделиться с Интернетом описанием какой-либо недокументированной функции, то эта функция мигом становиться частью публичного интерфейса, так как появляются приложения, использующие эту функцию. Шишки за то, что такая программа перестаёт работать в следующей версии Windows, естественно сыпятся на авторов Windows.

Во-вторых, про загрузку 32-х битной DLL в 64-х битный процесс. Это можно сделать, если при вызове LoadLibraryEx указать флаг LOAD_LIBRARY_AS_DATAFILE. Это позволяет загрузить ресурсы, хранящиеся в этой DLL, но не позволяет выполнять код в DLL.

Если же нужно загрузить 32-х битную DLL в 64-х битный и выполнить код из неё, то это невозможно в принципе. Для этого нужно загрузить и проинициализировать Wow64, не говоря уже о структурах в ядре. Короче нужно будет на ходу превратить процесс в 32-х битный. Проще создать новый. :-)

, , ,

  1. alex
    February 29th, 2008 at 02:02 | #1

    Спасибо, понятно.
    Что касается “создать новый процесс” – была такая идея, regsvr32 так и делает :) Хотелось узнать, не изобретаю ли я велосипед.

    В частности, если речь идёт о inproc COM-сервере в виде 32bit DLL, – нет ли (не планируется ли заведение) некоего 32bit host process (типа svchost.exe) специально для обеспечения межбитной COM-совместимости? Тем более, что у COM уже есть готовые средства межпроцессного маршалинга, изобретать которые заново не интересно…

  2. February 29th, 2008 at 13:44 | #3

    извините. it’s not a mercy.
    зачастую, _только_ недокументированные функции реализуют нужный функционал.

    • March 1st, 2008 at 23:00 | #4

      _только_ недокументированные функции реализуют нужный функционал.

      Ну и что? Даже если так, это совсем не оправдывает их использование. Одна из заповедей менеджеров программных (да и не только программных) проектов – “manage your dependencies”. Если срываются сроки поставки компонента, от которого зависит данное приложение – срываются сроки поставки этого приложения. Если нарушается контракт (публичный интерефейс) между прилодением и библиотекой – страдает приложение. А операционная система – это библиотека.

      Кроме того, 9 из 10 раз когда звучит это утверждение, это не так. Обычно существует альтернативное решение. Оно кажется дороже в данный момент, но в перспективе это экономия на спичках.

  3. Neandertalets
    March 16th, 2008 at 23:47 | #5

    Забыто еще одно применение недок.функций: создание скрытого функционала.

    • March 17th, 2008 at 08:29 | #6

      Именно об этом я и говорю. Любая библиотека/программа содержит в себе “скрытый функционал”. В том числе любое приложение с открытым исходным кодом.

  4. January 29th, 2009 at 05:42 | #7

    Кроме того, 9 из 10 раз когда звучит это утверждение, это не так. Обычно существует альтернативное решение. Оно кажется дороже в данный момент, но в перспективе это экономия на спичках.

    К сожалению, не всегда можно найти альтернативу. К примеру, инжект 32х DLL под 32-ой Windows и 64-ой под 64-ой Windows из kernel mode драйвера при создание процесса – проблем нет. А вот как получить из 64-ого драйвера указатель на код который будет вызван после инициализации WOW, чтобы можно было загрузить DLL в процесс?
    Единственный известный мне способ получить 32-ый “entry point” это вызвать недокументированное API: ZwQueryInformationProcess c параметром ProcessImageInformation.

  1. No trackbacks yet.
Comments are closed.