Недокументированные функции; Загрузка 32-х битных DLL в 64-х битный процесс.
Скажите, а невозможность загрузки в 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-х битный. Проще создать новый.
Спасибо, понятно.
Хотелось узнать, не изобретаю ли я велосипед.
Что касается “создать новый процесс” – была такая идея, regsvr32 так и делает
В частности, если речь идёт о inproc COM-сервере в виде 32bit DLL, – нет ли (не планируется ли заведение) некоего 32bit host process (типа svchost.exe) специально для обеспечения межбитной COM-совместимости? Тем более, что у COM уже есть готовые средства межпроцессного маршалинга, изобретать которые заново не интересно…
Обычно для этого используют DllSurrogate.
извините. it’s not a mercy.
зачастую, _только_ недокументированные функции реализуют нужный функционал.
Ну и что? Даже если так, это совсем не оправдывает их использование. Одна из заповедей менеджеров программных (да и не только программных) проектов – “manage your dependencies”. Если срываются сроки поставки компонента, от которого зависит данное приложение – срываются сроки поставки этого приложения. Если нарушается контракт (публичный интерефейс) между прилодением и библиотекой – страдает приложение. А операционная система – это библиотека.
Кроме того, 9 из 10 раз когда звучит это утверждение, это не так. Обычно существует альтернативное решение. Оно кажется дороже в данный момент, но в перспективе это экономия на спичках.
Забыто еще одно применение недок.функций: создание скрытого функционала.
Именно об этом я и говорю. Любая библиотека/программа содержит в себе “скрытый функционал”. В том числе любое приложение с открытым исходным кодом.
К сожалению, не всегда можно найти альтернативу. К примеру, инжект 32х DLL под 32-ой Windows и 64-ой под 64-ой Windows из kernel mode драйвера при создание процесса – проблем нет. А вот как получить из 64-ого драйвера указатель на код который будет вызван после инициализации WOW, чтобы можно было загрузить DLL в процесс?
Единственный известный мне способ получить 32-ый “entry point” это вызвать недокументированное API: ZwQueryInformationProcess c параметром ProcessImageInformation.