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

Вниз

Безопасен ли вызов в DllMain такой функции   Найти похожие ветки 

 
Егорка   (2012-08-24 16:33) [0]

Доброго времени суток. Прочитал много страшного про вызовы из DllMain и так и не понял чего там можно, а чего нет.
Меня интересует только ниже приведенный код. При загрузке DLL нужно извлечь из нее ресурс.
Все вместе это выглядет примерно так так:


library MyLib;

uses
 Windows;

function ExtractResource(const ResName, FileName: string): Boolean;
var
 hNewFile, hResInfo, hResData: THandle;
 dwResSize, dwWritten: Cardinal;
 PRes: Pointer;
begin
 Result := False;
 hResInfo := FindResource(hInstance, CharUpper(PChar(ResName)), RT_RCDATA);
 if hResInfo = 0 then
   Exit;
 dwResSize := SizeOfResource(hInstance, hResInfo);
 hResData := LoadResource(hInstance, hResInfo);
 PRes := LockResource(hResData);
 if Assigned(PRes) then
 begin
   hNewFile := CreateFile(PChar(FileName), GENERIC_WRITE, 0, nil, CREATE_ALWAYS, 0, 0);
   if hNewFile <> INVALID_HANDLE_VALUE then
   begin
     if WriteFile(hNewFile, PRes^, dwResSize, dwWritten, nil) then
Result := dwWritten = dwResSize;
     CloseHandle(hNewFile);
   end;
 end;
end;

function GetLibDir: string;
var
 I: Integer;
 ModuleName: array[0..MAX_PATH] of Char;
begin
 Result := "";
 ZeroMemory(@ModuleName, SizeOf(ModuleName));
 if GetModuleFileName(hInstance, ModuleName, SizeOf(ModuleName)) > 0 then
 begin
   for I := High(ModuleName) downto Low(ModuleName) do
     if ModuleName[I] = "\" then
     begin
       Result := Copy(ModuleName, 0, Succ(I));
       Break;
     end;
 end;
end;

var
 FileName: string;

begin
 FileName := GetLibDir + "myfilename.ext";

 if GetFileAttributes(PChar(FileName)) = DWORD(-1) then
   if not ExtractResource("MyResName", FileName) then
     MessageBox(0, "Не удалось извлечь ресурс", nil, MB_ICONERROR);
end;


 
Егорка   (2012-08-24 16:34) [1]

Вобщем вопрос: можно так делать или нет?


 
Dimka Maslov ©   (2012-08-24 16:46) [2]

Делать можно, но не нужно.


 
bems ©   (2012-08-24 20:49) [3]

MessageBox нельзя, хоть обычно и работает


 
Сергей М. ©   (2012-08-24 22:06) [4]

в DllMain следует остерегаться манипуляций созданием тредов, равно как и иных ОС-объектов (например, образов DLL, впервые динамически загружаемых в АП пространство процесса), создание которых претендует на блокировку таблиц PEB и TEB.


 
Сергей М. ©   (2012-08-24 22:07) [5]


> MessageBox нельзя


Чтой-то вдруг ?


 
sniknik ©   (2012-08-24 22:44) [6]

> Чтой-то вдруг ?
из dll? сообщение с ожиданием нажатия... даже при ошибке, я бы не делал.


 
Rouse_ ©   (2012-08-25 00:31) [7]


> в DllMain следует остерегаться манипуляций созданием тредов,
>  равно как и иных ОС-объектов

Ненаказуемо © :)
А вот воспользоваться DisableThreadLibraryCalls() желательно.
Ну а TEB в динамике залочить - этож я даже не знаю как постараться нужно с учетом библиотеки . Ну точнее знаю, но стандартные компилеры не позволяют прописывать TLS-callback даже с учетом асм-вставок.


 
Rouse_ ©   (2012-08-25 00:36) [8]

Зы, чуть не забыл ответить авторы темы :)
Код нормальный, должен работать, только не привязывай данную бибилотеку статически. На  вызове user32 функций лоадер может терминировать процесс.


 
Егорка   (2012-08-25 00:59) [9]

Вызов MessageBox не критичен, я его привел для наглядности) Спасибо всем ответившим!


 
bems ©   (2012-08-25 13:32) [10]


> Чтой-то вдруг ?

потому что user32.dll еще может быть не инициализирована


> в DllMain следует остерегаться манипуляций созданием тредов

треды создавать можно, но нельзя ожидать любого события в коде выполнения треда (потому что фактическое выполнение начнется после выхода из DllMain)


 
Leonid Troyanovsky ©   (2012-08-25 13:57) [11]


> Егорка   (24.08.12 16:34) [1]

http://msdn.microsoft.com/en-us/windows/hardware/gg487379.aspx

--
Regards, LVT.


 
Сергей М. ©   (2012-08-27 09:33) [12]


> user32.dll еще может быть не инициализирована


Это еще надо умудриться загрузить свою либу раньше user32


 
bems ©   (2012-09-03 02:36) [13]

> Это еще надо умудриться загрузить свою либу раньше user32
в этой ситуации нет ничего невероятного. в msdn обещают только то, что будет доступна kernel32. Это подразумевает доступность ntdll
dllmain остальных модулей может быть еще не вызвана на момент вызова dllmain модуля который их использует


 
Дмитрий С ©   (2012-09-03 18:04) [14]

А разве загрузчик не выстроит порядок загрузки DLL на основе зависимостей?


 
Rouse_ ©   (2012-09-03 20:41) [15]


> Дмитрий С ©   (03.09.12 18:04) [14]
> А разве загрузчик не выстроит порядок загрузки DLL на основе
> зависимостей?

Если проект написан на дельфи, то шансов ошибки практически не существует.
Статические линкуемые библиотеки будут подгружены до передачи управления на OP. Правда я уже не помню по какому принципу идет подгрузка но в принципе, если имеешь желание навредить самому себе, то остаются еще TLS каллбэки, во время исполнения которых некоторые "особо продвинутые пакеры" умудряются искать API из еще не подгруженных модулей, не озабачиваясь о их подгрузке и полагаясь что тот-же shell32.dll или еще что-то из com* уже присутствует.


 
bems ©   (2012-09-03 23:04) [16]

> А разве загрузчик не выстроит порядок загрузки DLL на основе зависимостей?

Обычно выстраивает правильно, но гарантий никто не даёт. К тому же user-функции внутренне любят делать динамическую загрузку, которая всё ломает

длл на дельфи не удавалось использовать для загрузки из KnownDLLs, если дллка спользовала SysUtils. не помню точно, но кажется дело было в каком-то user-вызове в секции инициализации юнита


 
bems ©   (2012-09-04 00:42) [17]


> длл на дельфи не удавалось использовать для загрузки из KnownDLLs

AppInit конечно же



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

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

Наверх




Память: 0.48 MB
Время: 0.059 c
15-1346838937
GanibalLector
2012-09-05 13:55
2013.03.22
Tagged PDF


4-1263784073
SPeller
2010-01-18 06:07
2013.03.22
Синхронные вызовы Read/WriteFile при FILE_FLAG_OVERLAPPED


15-1346322658
Артём
2012-08-30 14:30
2013.03.22
Как программно нажать на кнопку на сайте?


15-1353500246
ЕщеОдинКакжеНадоели
2012-11-21 16:17
2013.03.22
Документация к программе.


15-1337676209
ClawClaw
2012-05-22 12:43
2013.03.22
Чемпионат Европы 2012





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский