Форум: "Начинающим";
Текущий архив: 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.073 c