Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2009.08.23;
Скачать: [xml.tar.bz2];

Вниз

AppInit_Dll - механизм работы.   Найти похожие ветки 

 
Riply ©   (2008-07-04 23:41) [0]

Здравствуйте !
Подскажите, пожалуйста, каким образом подгружаются библиотеки из AppInit_Dll ?
Интересует не как подгрузить с помощью ключа, а сам механизм.
Например, один из вариантов:
Создается Suspended процесс.
В нем создается нить, загружающая Dll-ку.
Процесс будится.
Но это домыслы, а как все реализовано "на самом деле" ?


 
Игорь Шевченко ©   (2008-07-05 13:38) [1]


> а сам механизм.


Сам механизм прост - LoadLibrary.

Каждый процесс, загружающий какие-либо DLL, вызывает при этом DllEntryPoint от этих DLL, надеюсь, этот механизм не надо пояснять ?

В процессе выполнения DllEntryPoint выполняются какие-либо действия. В частности, одним из действий в DllEntryPoint у user32.dll является сканирование ключа реестра AppInit_Dll и загрузка всех перечисленных в нем Dll в память процесса (и вызов их инициализации).

Если приложение не использует user32.dll, то никакие AppInit_Dll в его адресное пространство не загрузятся (например, в SMSS.EXE ничего не загружается, а вот в WinLogon.EXE - загружается)

На самом деле все немного хитрее происходит, но суть примерно такая.


 
Riply ©   (2008-07-05 14:54) [2]

> [1] Игорь Шевченко ©   (05.07.08 13:38)

Спасибо.


 
Игорь Шевченко ©   (2008-07-05 17:05) [3]


> На самом деле все немного хитрее происходит


На самом деле в этом еще участвует процесс csrss.exe, к которому user32.dll обращается в процессе инициализации.


 
Riply ©   (2008-07-05 17:28) [4]

> [3] Игорь Шевченко ©   (05.07.08 17:05)
> На самом деле в этом еще участвует процесс csrss.exe, к которому user32.dll обращается в процессе инициализации.

А он зачем понадобился ?
Вроде в [1] Игорь Шевченко © все и без него неплохо получается.
Или там какая-нибудь таблица Handl`ов ?


 
Игорь Шевченко ©   (2008-07-05 20:46) [5]

Riply ©   (05.07.08 17:28) [4]

Процедурам в user32.dll нужен адрес разделяемой области Win32 (в частности, там находятся все-все Handles подсистемы Win32, относящиеся к окнам, меню, хукам, все, кроме GDI - у GDI своя таблица). Адрес этой разделяемой области формирует (для каждого процесса) ядерная часть подсистемы Win32 - win32k.sys, для того, чтобы она сформировала, ее надо вызывать. Вызывается она внутри CSRSS, а DllEntryPoint от user32 соединяется с процессом csrss, запрашивая инициализацию всего-всего.
Зачем так сделано - очевидно, к моменту загрузки AppInit_DLL структуры процесса относящиеся к подсистеме Win32, должны быть должным образом проинциализированы, иначе будет невозможно даже зарегистрировать оконный класс (чем по логике MS должны заниматься DLL, перечисленные в AppInit_DLL).


 
Сергей М. ©   (2008-07-05 21:11) [6]


> библиотеки из AppInit_Dll


Из какой такой дыры они выскакивают ? Что еще за AppInit_Dll ?)


 
Riply ©   (2008-07-05 21:36) [7]

> [6] Сергей М. ©   (05.07.08 21:11)
> Из какой такой дыры они выскакивают ? Что еще за AppInit_Dll ?)

Sorry. Допустила ошибку (писала по памяти).
Првавильное имя: AppInit_DLLs
Это из HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows


 
Игорь Шевченко ©   (2008-07-05 21:37) [8]


> Из какой такой дыры они выскакивают ? Что еще за AppInit_Dll
> ?)


да ладно тебе буквоедствовать :)


 
Игорь Шевченко ©   (2008-07-05 21:38) [9]

Кстати, на самом деле процесс еще более хитрый - точка входа в user32.dll, которая загружает эти DLL, вызывается для каждого потока. Она так и называется ClientThreadSetup


 
Riply ©   (2008-07-05 21:53) [10]

> [5] Игорь Шевченко ©   (05.07.08 20:46)
> [9] Игорь Шевченко ©   (05.07.08 21:38)
> Кстати, на самом деле процесс еще более хитрый

Оказывается, иногда, черт страшнее чем его малюют :)
Спасибо.


 
Игорь Шевченко ©   (2008-07-05 22:25) [11]

Riply ©   (05.07.08 21:53) [10]

На здоровье. Но у меня встречный вопрос - а с какой целью интересуетесь ?


 
Германн ©   (2008-07-06 00:43) [12]


> Но у меня встречный вопрос - а с какой целью интересуетесь
> ?
>

:))))


 
Riply ©   (2008-07-06 01:34) [13]

> [11] Игорь Шевченко © (05.07.08 22:25)
> Но у меня встречный вопрос - а с какой целью интересуетесь ?

А у Вас все вопросы такие каверзные ? :)
Ну да делать нечего, попробую ответить.
Началось все с того, что мне понадобился класс(структура) в С++, который
инициализируется "самым первым" и последним финализируется.
Один из советов, данных мне, был, примерно, таким:
"код инициализации поместить в DLL-ку, при компиляции указать на необходимость загрузки этой DLL первой
не знаю как это реализовано в PE, но в Linux через DT_FLAGS=initfirst в секции .dynamic *.so файла
думаю, в PE как-то аналогично"

Осознав, что я ничерта в этом не понимаю, решила попробовать разобраться и полезла в дебри загрузки :)
Т.е. понадобились ответы на следующие вопросы:
Является ли этот путь тем, кем стоит заниматься ?
Если да, то как это реализовать ?
Какие ограничения при этом накладываются на нашу Dll-ку ?
(Просто вспомнила, что загрузка через AppInit_DLLs накладывает на Dll серьезные ограничения,
которые удалось обойти только через создание доп. Dll - загрузчика (она то и прописывается в AppInit_DLLs),
которая только и делает, что при помощи QueueUserAPC загружает "настоящую" библиотеку).
Ну а раз так, то не помешало бы понимать, что же там происходит "на самом деле".
Вот так мы и скатились до такой жизни :)


 
Riply ©   (2008-07-06 01:36) [14]

> [12] Германн ©   (06.07.08 00:43)
> :))))

Не вижу ничего смешного :)))


 
Германн ©   (2008-07-06 01:48) [15]


> Riply ©   (06.07.08 01:36) [14]
>
> > [12] Германн ©   (06.07.08 00:43)
> > :))))
>
> Не вижу ничего смешного :)))
>

Ну тогда :((((
Увы нет смайлика, который в полной мере отображал бы чувства, возникающие при чтении твоих постов.


 
Riply ©   (2008-07-06 01:53) [16]

> [15] Германн ©   (06.07.08 01:48)
> Ну тогда :((((

Эт еще хуже :)
Риторический вопрос: и куда делись ветки, где можно пофлудить ?
Здесь боюсь - могут зарезать ветку раньше, чем я получу ответы :)


 
Германн ©   (2008-07-06 02:39) [17]


> Риторический вопрос: и куда делись ветки, где можно пофлудить
> ?

Так ни куда они не делись. Где они были, там и остались.


 
Riply ©   (2008-07-06 02:43) [18]

> [17] Германн ©   (06.07.08 02:39)
> Так ни куда они не делись. Где они были, там и остались.

А я уж который день (ночь) ищу и не могу найти.
Везде, вроде, не флудят, а говорят "по теме".
А то я бы с удовольствием подключилась :)


 
Германн ©   (2008-07-06 03:03) [19]


> Riply ©   (06.07.08 02:43) [18]
>
> > [17] Германн ©   (06.07.08 02:39)
> > Так ни куда они не делись. Где они были, там и остались.
>
>
> А я уж который день (ночь) ищу и не могу найти.
> Везде, вроде, не флудят, а говорят "по теме".
> А то я бы с удовольствием подключилась :)
>

Обратись ко мне на почту.
Или вспомни  арифметику. :)


 
guav ©   (2008-07-06 12:02) [20]

Можно сказать, что все статически импортированные dll загрузятся до кода ехе, однако с порядком их загрузки сложнее. Так, в своей DllMain не рекомендуют вызывать код работы с реестром, потому что advapi32.dll может быть загружена и позже (здесь  http://www.microsoft.com/whdc/driver/kernel/DLL_bestprac.mspx ).

Теперь по сути. Для dll здесть http://support.microsoft.com/kb/94248 в Section 2 описана возможность объявить точку входа в dll не как DllMain, а как DllEntryPoint, при этом инициализация CRT и вызов конструкторов глобальных объектов будет делаться явным вызовом _CRT_INIT. Разумеется, можно что-то своё сделать до _CRT_INIT, не используя при этом CRT.
ДУмаю что-то подобное возможно и для ехе.


 
guav ©   (2008-07-06 12:06) [21]

http://msdn.microsoft.com/en-us/library/f9t8842e(VS.71).aspx
The function must be defined with the __stdcall calling convention. The parameters and return value must be defined as documented in the Win32 API for WinMain (for an .exe file) or DllEntryPoint (for a DLL). It is recommended that you let the linker set the entry point so that the C run-time library is initialized correctly, and C++ constructors for static objects are executed.
Насколько я понял, можно не сделать то что recomended и инициализировать CRT явно.


 
Игорь Шевченко ©   (2008-07-06 14:26) [22]


> Началось все с того, что мне понадобился класс(структура)
> в С++, который
> инициализируется "самым первым" и последним финализируется.
>


AppInit_DLLs для этого не подходит



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2009.08.23;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.008 c
2-1245739359
dmitry_12_08_73
2009-06-23 10:42
2009.08.23
Как скопировать окно с AlphaBlend = true?


2-1245681294
marantz85
2009-06-22 18:34
2009.08.23
Как переписать данные из динамического массива в memorystream?


2-1245733905
Tornado
2009-06-23 09:11
2009.08.23
Копирование файлов


15-1245911928
desc
2009-06-25 10:38
2009.08.23
Не получается "слиять" два поля... Postgres


2-1245838548
Uno-84
2009-06-24 14:15
2009.08.23
Отрисовка ProgressBar в ListView





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский