Форум: "Система";
Текущий архив: 2003.01.27;
Скачать: [xml.tar.bz2];
ВнизЗагрузка DLL Найти похожие ветки
← →
BarikNT (2002-11-13 01:12) [0]Програмеры!
кто подскажет как загрузить динамически DLL не с диска
а например из ресурсов проги
я делаю пока так
---------------------------------------------
Procedure LoadDataResource;
мar
SF : TFileStream;
dHandle: THandle;
pData : pointer;
Size : Integer;
HG : HGLOBAL;
Begin
pData := Nil;
dHandle := FindResource( hInstance, "RCDATA_1" , RT_RCDATA );
If dHandle <> 0 Then
Begin
Size:=SizeofResource(hInstance,dHandle);
HG := LoadResource( hInstance, dHandle );
If HG <> 0 Then
begin
pData := LockResource(HG);
!!! SF :=TFileStream.Create(ExtractFilePath(Application.ExeName)+"DLL\namedll.dll",fmCreate);
SF.Write(pData^,Size);
SF.Free;
end;
end;
end;
--------------------------------
!!! - приходится писать Dll на винт чтоб потом
H := LoadLibrary(PChar(ExtractFilePath(Application.ExeName)+"DLL\namedll.DLL"));
if H >= 32 then
begin
GetIDR := GetProcAddress(H, "NameFunction_Or_Proc");
Result:=PChar(GetIDR);
FreeLibrary(H);
.......................
а хотелось бы из загрузить из памяти
может такого вообще не возможно
Подскажите
← →
Игорь Шевченко (2002-11-13 12:58) [1]Невозможно
← →
msts (2002-11-13 14:09) [2]http://www.uinc.ru/files/dr.golova/TFakeDll.zip
← →
msts (2002-11-13 14:23) [3]или вот куча всякой ... http://directory.google.com/Top/Computers/Software/Shareware/Windows/Programming/
← →
msts (2002-11-13 15:02) [4]кто помнит можно ли LIB файл в Delphi прилинковать ?
← →
apay (2002-11-14 00:21) [5]2 BarikNT
в принципе возможно, но придется писать свой загрузчик таких DLL
2 msts
с LIB файлом у меня были траблы, приходилось tlib-ом на obj разбивать, а потом линковать. и еще, если у тебя он в формате COFF переведи в OMF, у меня дельфя COFF не понимала.
← →
paul_shmakov (2002-11-14 14:10) [6]есть несколько способов, но все они достаточно кривые. все они похожи. первый - это то, что реализовано в back orifice 2000, tfake.dll - реализация функций стандартного загрузчика, т.е. загрузка секций образа pe-файла в память по правильным вертуальным адресам, установка аттрибутов защиты этих секций, обработка импорта модуля (загрузка необходимых dll, настройка адресов импортируемых функций), настройка релокейшинов и т.д.
я пока не видел ни одной реализации, которая бы выполняла все функции стандартного загрузчика. например, ни одна из них не регистрирует модуль в списке загруженных модулей. т.е. GetProcAddress, например, работать не будет, также как и остальные функции, ожидающие на входе HMODULE. а это большой недостаток. для bo2k это не очень большая проблема, т.к. он использует только свои dll, при написании которых придерживались некоторых ограничений.
в случае, когда вы желаете подключить в своему exe-шнику чужую dll, то нет никаких гарантий, что она будет корректно функционировать в таких условиях.
еще один способ - это загрузка dll с диска вызовом стандартной LoadLibrary, потом выделение временного буфера в памяти и копирование в него всего загруженного модуля, после этого dll выгружается с помощью FreeLibrary. теперь dll можно с диска удалить. по тому адресу в виртуальном адресном пространстве, где находилась dll, выделяется память, в нее копируется содержимое временного буфера, после чего временный буфер освобождается. в результате у нас dll как бы загружена, и с ней можно работать, но на самом деле файл dll уже удален. продублирую псевдокодом то, что только что сказал:
function LoadAndDeleteLibrary(DllName: PChar): HMODULE;
var
ImageSize: DWord;
TempBuf: Pointer;
begin
// загружаем dll стандартными методами
Result := LoadLibrary(DllName);
if Result <> 0 then
try
// все остальные потоки нужно заморозить, а то не избежать беды
StopAllOtherThreads;
// получаем полный размер модуля из PE-заголовка
ImageSize := GetModuleImageSizeFromPEHeader(Result);
// выделяем временный буфер
GetMem(TempBuf, ImageSize);
try
// копируем в него весь модуль целиком
CopyMemory(TempBuf, Result, ImageSize);
// теперь dll можно выгрузить, а ее файл удалить
FreeLibrary(Result);
DeleteFile(DllName);
// на прежнем месте (где только что была dll загружена) выделяем память
Result := VirtualAlloc(Result, ImageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// копируем в нее образ dll
CopyMemory(Result, TempBuf, ImageSize);
// для каждой секции нужно бы восстановить необходимые атрибуты защиты
// хотя это и необязательный шаг
SetImageSectionAccessProtection(Result);
finally
// временный буфер больше не нужен
FreeMem(TempBuf);
end;
finally
// все остальные потоки теперь можно запустить
ResumeAllOtherThreads;
end;
end;
т.е. dll выгружена, а в виртуальном адресном пространстве ее образ остался. недостатки тут все те же - нельзя использовать функции вроде GetProcAddress. нужно использовать самостоятельно реализованные аналоги. этот второй вариант лучше тем, что загрузку и настройку модуля осуществляет стандартный загрузчик - ему виднее, как правильно все сделать.
недостаток - файл с dll все таки создается на диске, хотя и сразу уничтожается.
я пробовал в качестве файла скормить LoadLibrary named pipe, но к несчастью она не оценила моего рвения. а то было бы очень приятно - можно было бы просто использовать LoadLibrary, GetProcAddress, GetModuleFileName и т.д. без всяких проблем, а удалять именованный пайп при выгрузке процесса.
Страницы: 1 вся ветка
Форум: "Система";
Текущий архив: 2003.01.27;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.008 c