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

Вниз

загрузка dll из ресурса   Найти похожие ветки 

 
Scott Storch   (2011-01-13 17:47) [0]

Приложение юзает функции библиотеки 7z.dll. Проблема, заказчик не хочет таскать вместе с исполняемым файлом файл библиотеки. Думаю запихнуть ее в ресурс. Как из ресурса ее потом загрузить через LoadLibrary?


 
Ega23 ©   (2011-01-13 17:53) [1]


>  Проблема, заказчик не хочет таскать вместе с исполняемым
> файлом файл библиотеки.


Запиши всё в один rar.exe :)


 
Scott Storch   (2011-01-13 17:57) [2]

А по существу


 
Leonid Troyanovsky ©   (2011-01-13 18:00) [3]


> Scott Storch   (13.01.11 17:57) [2]

> А по существу

Красть грешно.

--
Regards, LVT.


 
DiamondShark ©   (2011-01-13 18:13) [4]


> Как из ресурса ее потом загрузить через LoadLibrary?

Записать в файл и загрузить.

А вообще, заказчик странного хочет.


 
Rouse_ ©   (2011-01-13 19:22) [5]

////////////////////////////////////////////////////////////////////////////////
//
//  ****************************************************************************
//  * Unit Name : DLLLoader
//  * Purpose   : Модуль подгрузки и инициализации DLL из памяти
//  *           : без выгрузки на диск.
//  *           : На основе статьи "Загрузчик PE-файлов" Максима Гумерова
//  *           : http://rsdn.ru/article/baseserv/peloader.xml
//  * Author    : Александр (Rouse_) Багель
//  * Copyright : Центр Гранд 2001 - 2007 г.
//  * Version   : 1.00
//  ****************************************************************************
//

unit DLLLoader;

interface

uses
 Windows;

 function xLoadLibrary(Image: Pointer): HMODULE;
 function xGetProcAddress(Module: HMODULE; ProcName: PChar): Pointer;
 function xFreeLibrary(Module: HMODULE): Boolean;

implementation

uses
 Classes, SysUtils, Types, Math;

type
 TSections = array [0..0] of TImageSectionHeader;
 TDllEntryProc = function(Hinst: Integer;
   Reason: Integer; Resvd: Pointer): LongBool; stdcall;

 TLibInfo = record
   ImageBase: Pointer;//Базовый адрес образа
   DllProc: TDllEntryProc;
   //Список, содержащий имена импользуемых DLL модулей и их значения HModule
   LibsUsed: array of record
     Name: String;
     Instance: HModule;
   end;
   PExports: PImageExportDirectory;
   BlockSize: Cardinal;
 end;
 PLibInfo = ^TLibInfo;

 TWordArray = array [0..0] of Word;
 PWordArray = ^TWordArray;
 TDWORDArray = array [0..0] of DWORD;
 PDWORDArray = ^TDWORDArray;

 TImageBaseRelocation = packed record
   VirtualAddress: Cardinal;
   SizeOfBlock: Cardinal;
 end;
 PImageBaseRelocation = ^TImageBaseRelocation;

 TImageImportDescriptor = packed record //(C++:  IMAGE_IMPORT_DESCRIPTOR)
   OriginalFirstThunk: DWORD;//Ранее это поле называлось Characteristics; в целях сохранения
   //совместимости кода это название поддерживается и сейчас, но не
   //отражает содержание поля. Далее мы на нем остановимся подробнее
   TimeDateStamp: DWORD;//0, если импортирование осуществляется без привязки (binding - см. далее)
   //При импортировании с привязкой содержит отметку времени файла, из которого
   // импортируем, но:
   //Если -1, то здесь использовался новый стиль привязки
   ForwarderChain: DWORD;// См. описание импорта с привязкой (далее)
   Name: DWORD;//Виртуальный адрес ASCII-строки с именем файла, из которого импортируем
   FirstThunk: DWORD;//Виртуальный адрес подтаблицы импортируемых символов
 end;
 PImageImportDescriptor = ^TImageImportDescriptor;

var
 LoadedLibs: TList = nil;

function xFreeLibrary(Module: HMODULE): Boolean;
var
 I, J: Integer;
 LibInfo: PLibInfo;

 procedure CallProcessDetach;
 begin
   try
     if @LibInfo.DllProc <> nil then
       LibInfo.DllProc(Module, DLL_PROCESS_DETACH, nil);
   except
   end;
 end;

begin
 Result := False;
 if (Module = 0) or not Assigned(LoadedLibs) then Exit;
 for I := 0 to LoadedLibs.Count - 1 do
 begin
   LibInfo := LoadedLibs[I];
   if LibInfo.ImageBase = Pointer(Module) then
   begin
     LoadedLibs.Delete(I);
     CallProcessDetach;
     for J := 0 to High(LibInfo.LibsUsed) do
       FreeLibrary(LibInfo.LibsUsed[J].Instance);
     Dispose(LibInfo);
     Result := True;
     Break;
   end;
 end;
 VirtualFree(Pointer(Module), 0, MEM_RELEASE);
end;

function GetLibrary(LibInfo: PLibInfo; const DLLName: String): HModule;
var
 I: Integer;
begin
 for I := 0 to High(LibInfo.LibsUsed) do
   if AnsiSameText(LibInfo.LibsUsed[I].Name, DLLName) then
   begin
     Result := LibInfo.LibsUsed[I].Instance;
     Exit;
   end;
 Result := LoadLibrary(PChar(DllName));
 SetLength(LibInfo.LibsUsed, Length(LibInfo.LibsUsed) + 1);
 with LibInfo.LibsUsed[High(LibInfo.LibsUsed)] do
 begin
   Name := DllName;
   Instance := Result;
 end;
end;

function xGetProcAddress(Module: HMODULE; ProcName: PChar): Pointer;
var
 I, J, A: Integer;
 LibInfo: PLibInfo;
 PC: PChar;
 S: String;
begin
 Result := nil;
 if (Module = 0) or not Assigned(LoadedLibs) then Exit;
 for I := 0 to LoadedLibs.Count - 1 do
   if TLibInfo(LoadedLibs[I]^).ImageBase = Pointer(Module) then
   begin
     LibInfo := LoadedLibs[I];
     //Проход по всем символам, экспортированным по имени
     for J := 0 to LibInfo.PExports.NumberOfNames - 1 do
       if StrComp(ProcName, PChar(PDWORDArray(
         Cardinal(LibInfo.PExports.AddressOfNames) +
         Cardinal(LibInfo.ImageBase))^[J] +
         Cardinal(LibInfo.ImageBase))) = 0 then
       begin
         Result := Pointer(PDWORDArray(
           Cardinal(LibInfo.PExports.AddressOfFunctions) +
           Cardinal(LibInfo.ImageBase))^[
           PWordArray(Cardinal(LibInfo.PExports.AddressOfNameOrdinals) +
           Cardinal(LibInfo.ImageBase))^[J]] + Cardinal(LibInfo.ImageBase));
           
         if (PChar(Result) >= PChar(LibInfo.PExports)) and
           (PChar(Result) < PChar(LibInfo.PExports) + LibInfo.BlockSize) then
         begin
           S := PChar(Result);
           Result := nil;
           A := Pos(".", S);
           if A = 0 then Exit;
           if S[A + 1] = "#" then
             PC := Pointer(StrToIntDef(Copy(S, A + 2, MaxInt), -1))
           else
             PC := @S[A + 1];
           Result := GetProcAddress(
             GetLibrary(LibInfo, Copy(S, 1, A - 1)), PC);
           Exit;
         end;
       end;
     Break;
   end;
end;


 
Rouse_ ©   (2011-01-13 19:23) [6]

function XLoadLibrary(Image: Pointer): HMODULE;
var
 ImageBase, SectionBase: Pointer;
 ImageBaseDelta: Integer;
 PEHeader: PImageNtHeaders;
 PSections: ^TSections;
 S: Integer;
 VirtualSectionSize, RawSectionSize, Dummy: Cardinal;
 PNewLibInfo: PLibInfo;

 procedure ProcessRelocs(PRelocs: PImageBaseRelocation);
 var
   PReloc: PImageBaseRelocation;
   P: PWord;
   I: Cardinal;
 begin
   PReloc := PRelocs;
   while Cardinal(PReloc) - Cardinal(PRelocs) <
     PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size do
   begin
     P := Pointer(Cardinal(PReloc) + SizeOf(PReloc^));
     for I := 0 to(PReloc.SizeOfBlock -
       SizeOf(TImageBaseRelocation)) div 2 - 1 do
     begin
       if P^and $F000 <> 0 {//Если тип ссылки - не IMAGE_REL_BASED_ABSOLUTE(=0)} then
         Inc(PDWORD(Cardinal(ImageBase) +
           PReloc.VirtualAddress + (P^ and $0FFF))^, ImageBaseDelta);//Исправляем ссылку
       Inc(P);
     end;
     PReloc := Pointer(P);
   end;
 end;

 procedure ProcessImports(PImport: PImageImportDescriptor);
 var
   PRVA_Import: LPDWORD;
   LibHandle: HModule;
 begin
   while PImport.Name <> 0 do
   begin
     LibHandle :=
       GetLibrary(PNewLibInfo, PChar(Cardinal(PImport.Name) +
         Cardinal(ImageBase)));
     if PImport.TimeDateStamp = 0{//Привязка есть?} then
       PRVA_Import := LPDWORD(pImport.FirstThunk + Cardinal(ImageBase))
     else
       PRVA_Import := LPDWORD(pImport.OriginalFirstThunk + Cardinal(ImageBase));
     while PRVA_Import^ <> 0 do
     begin
       if (PRVA_Import^and $80000000) <> 0 then //Это импортирование по номеру
         PPointer(PRVA_Import)^ :=
           GetProcAddress(LibHandle, PChar(PRVA_Import^ and $FFFF))
       else
         PPointer(PRVA_Import)^ :=
           GetProcAddress(LibHandle, PChar(PRVA_Import^ + DWORD(ImageBase) + 2));
       Inc(PRVA_Import);
     end;
     Inc(PImport);
   end;
 end;
 
 function GetSectionProtection(SC: Cardinal): Cardinal;
   //SC - значение ImageSectionHeader.Characteristics,
   //на выходе - значение флагов доступа для VirtualProtect
 const
   Mapping: array[0..7] of ULONG =
     (
       PAGE_NOACCESS,
       PAGE_EXECUTE,
       PAGE_READONLY,
       PAGE_EXECUTE_READ,
       PAGE_READWRITE,
       PAGE_EXECUTE_READWRITE,
       PAGE_READWRITE,
       PAGE_EXECUTE_READWRITE);
 begin
   Result := Mapping[SC shr 29] or
     DWORD(IfThen((SC and IMAGE_SCN_MEM_NOT_CACHED) <> 0, PAGE_NOCACHE));
 end;
 
begin
 Result := 0;
 try
   PEHeader :=
     Pointer(Int64(Cardinal(Image)) + PImageDosHeader(Image)._lfanew);
   ImageBase :=
     VirtualAlloc(nil, PEHeader.OptionalHeader.SizeOfImage,
       MEM_RESERVE, PAGE_NOACCESS);
   if ImageBase = nil then OutOfMemoryError;
   ImageBaseDelta := DWORD(ImageBase) - PEHeader.OptionalHeader.ImageBase;
   SectionBase :=
     VirtualAlloc(ImageBase, PEHeader.OptionalHeader.SizeOfHeaders,
       MEM_COMMIT, PAGE_READWRITE);
   if SectionBase = nil then OutOfMemoryError;
   Move(Image^, SectionBase^, PEHeader.OptionalHeader.SizeOfHeaders);
   VirtualProtect(SectionBase, PEHeader.OptionalHeader.SizeOfHeaders,
     PAGE_READONLY, Dummy);
   PSections := Pointer(PChar(@(PEHeader.OptionalHeader)) +
     PEHeader.FileHeader.SizeOfOptionalHeader);
   for S := 0 to PEHeader.FileHeader.NumberOfSections - 1 do
   begin
     VirtualSectionSize := PSections[S].Misc.VirtualSize;
     RawSectionSize := PSections[S].SizeOfRawData;
     if VirtualSectionSize < RawSectionSize then
       VirtualSectionSize := PSections[S].SizeOfRawData;
     SectionBase := VirtualAlloc(PSections[S].VirtualAddress +
       PChar(ImageBase), VirtualSectionSize, MEM_COMMIT, PAGE_READWRITE);
     if SectionBase = nil then OutOfMemoryError;
     Move((PChar(Image) + PSections[S].PointerToRawData)^,
       SectionBase^, RawSectionSize);
   end;
   if LoadedLibs = nil then
     LoadedLibs := TList.Create;
   New(PNewLibInfo);
   FillChar(PNewLibInfo^, SizeOf(TLibInfo),0);
   PNewLibInfo^.DllProc :=
     TDllEntryProc(PEHeader.OptionalHeader.AddressOfEntryPoint +
       Cardinal(ImageBase));
   PNewLibInfo^.ImageBase := ImageBase;
   LoadedLibs.Add(PNewLibInfo);
   with PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC] do
     if VirtualAddress <> 0 then
       ProcessRelocs(Pointer(VirtualAddress + Cardinal(ImageBase)));
   with PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] do
     if VirtualAddress <> 0 then
       ProcessImports(Pointer(VirtualAddress + Cardinal(ImageBase)));
   with PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] do
     if VirtualAddress <> 0 then
     begin
       PNewLibInfo^.PExports := Pointer(VirtualAddress+Cardinal(ImageBase));
       PNewLibInfo^.BlockSize := Size;
     end;
   for S := 0 to PEHeader.FileHeader.NumberOfSections - 1 do
     with PSections[S] do
       VirtualProtect(VirtualAddress + PChar(ImageBase),
         Misc.VirtualSize,GetSectionProtection(Characteristics), Dummy);
   if (@PNewLibInfo^.DllProc <> nil) and not
     PNewLibInfo^.DllProc(Cardinal(ImageBase), DLL_PROCESS_ATTACH, nil) then
   begin
     PNewLibInfo^.DllProc := nil;
     XFreeLibrary(Result);
     Result := 0;
   end
   else
     Result := Cardinal(ImageBase);
 except
   VirtualFree(ImageBase, 0, MEM_RELEASE);
 end;
end;

initialization

finalization
 if Assigned(LoadedLibs) then
 begin
   while LoadedLibs.Count > 0 do
     XFreeLibrary(HMODULE(TLibInfo(LoadedLibs.First^).ImageBase));
   FreeAndNil(LoadedLibs);
 end;
end.


 
Leonid Troyanovsky ©   (2011-01-13 21:46) [7]


> Rouse_ ©   (13.01.11 19:22) [5]

Хорошо, что уже три года, как ты с этим делом завязал.

--
Regards, LVT.


 
Rouse_ ©   (2011-01-13 22:24) [8]

С каким? :)


 
Rouse_ ©   (2011-01-13 22:28) [9]

А, ты про 2007 в хидере - так это просто год последней правки исходника :)


 
Leonid Troyanovsky ©   (2011-01-13 22:51) [10]


> Rouse_ ©   (13.01.11 22:28) [9]

> А, ты про 2007 в хидере - так это просто год последней правки
> исходника :)

Что исходнее прижилось это есть только гуд :)
Просто, самоя идея изжилась, и Макс, IMHO, оное принял.

--
Regards, LVT.


 
Германн ©   (2011-01-14 01:50) [11]


> Просто, самоя идея изжилась, и Макс, IMHO, оное принял.

О. Значит и LVT (может быть неявно) участвует в той самой (самой ДМ) фирме.


 
Дмитрий С ©   (2011-01-14 07:26) [12]

Можно вопрос в тему?)
Можно в своем процессе в отдельном потоке запустить другой exe?:)
Например, загрузить модуль и createthread на его точку входа?


 
Leonid Troyanovsky ©   (2011-01-14 08:28) [13]


> Дмитрий С ©   (14.01.11 07:26) [12]

> Например, загрузить модуль и createthread на его точку входа?

Это вряд ли.

См., например,
http://groups.google.com/group/microsoft.public.win32.programmer.kernel/msg/fb58c55a2edd8e88
по-дельфийски
http://groups.google.com/group/fido7.ru.delphi/msg/dbf6083b8b7fbee4

--
Regards, LVT.


 
RWolf ©   (2011-01-14 09:53) [14]


> Приложение юзает функции библиотеки 7z.dll. Проблема, заказчик
> не хочет таскать вместе с исполняемым файлом файл библиотеки.

не надо таскать исполняемый файл, для этого есть дистрибутив.


 
reqyz   (2011-02-22 11:26) [15]

я понимаю, что уже месяц прошёл, и врятли мне ответят, но всё же, блин, какой нафиг поинтер в загрузке библиотеке, и почему он имэйдж, как это юзать вообще?  я вот так попытался, и естественно комп сматерился

rs := TResourceStream.Create(hInstance, "REQ", "STRING");
   hndDLLHandle:=XLoadLibrary(rs);


 
имя   (2011-02-22 11:46) [16]

Удалено модератором



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

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

Наверх





Память: 0.52 MB
Время: 0.004 c
2-1298927662
Sashka
2011-03-01 00:14
2011.06.05
Работа с AsyncCall


2-1299047111
filimonic
2011-03-02 09:25
2011.06.05
Re


2-1298609942
maxefficiently
2011-02-25 07:59
2011.06.05
RAR Component


2-1298780760
filimonic
2011-02-27 07:26
2011.06.05
Как заблокировать кнопку Пуск в Windows 7


15-1296771492
xayam
2011-02-04 01:18
2011.06.05
Какая у Вас группа крови?





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