Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > LoadLibrary из ресурса


Автор: kastron 14.8.2012, 14:00
Загрузка DLL из ресурса

Код

uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, StdCtrls, BTMemoryModule;

   type TShp = procedure (hk: HHOOK) stdcall;

 type
   TForm1 = class(TForm)
     Load_Button: TButton;
     do_button: TButton;
     procedure Load_ButtonClick(Sender: TObject);
     procedure do_buttonClick(Sender: TObject);
   private
     { Private declarations }
 public
   m_DllDataSize:int64;
   mp_DllData:Pointer;

 procedure TForm1.Load_ButtonClick(Sender: TObject);
 var
    ms : TMemoryStream;
    rs : TResourceStream;
 begin
    if 0 <> FindResource(hInstance, 'SPDLL', RT_RCDATA) then
    begin
      rs := TResourceStream.Create(hInstance, 'SPDLL', RT_RCDATA);
      ms := TMemoryStream.Create;
      try
        ms.LoadFromStream(rs);
        ms.Position := 0;
        m_DllDataSize := ms.Size;
        mp_DllData := GetMemory(m_DllDataSize);
        ms.Read(mp_DllData^, m_DllDataSize);
      finally
        ms.Free;
        rs.Free;
      end;
    end;
 end;


Так пытаюсь поставить хук из длл, загруженной в память

Код

procedure TForm1.do_buttonClick(Sender: TObject);
 var
    btMM: PBTMemoryModule;
    m_TestCallstd:Pointer;
    p: pointer;
    sh: TShp;
    hk: HHOOK;
    h:THandle;
 begin
    btMM := BTMemoryLoadLibary(mp_DllData, m_DllDataSize);
    h:=THandle(btMM.codeBase);
    try
      if btMM = nil then Abort;
      p := BTMemoryGetProcAddress(btMM, 'HookProc');
      @sh:=BTMemoryGetProcAddress(btMM, 'SetHK');
      if ((p=nil) or (@sh=nil)) then
         begin
              MessageBox(0, PAnsiChar('Библиотека не содержит необходимых процедур!'),
                            0, MB_OK+MB_ICONERROR);
              exit;
         end;
      hk:=SetWindowsHookEx(WH_CALLWNDPROC, p, h, 0);
      if hk=0 then
         begin
              MessageBox(0, PAnsiChar('Невозможно установить ловушку!'),
                            0, MB_OK+MB_ICONERROR);
              FreeLibrary(h);
              exit;
         end;   
      sh(hk);
      MessageBox(0, 'Ловушка установлена! Нажмите OK для снятия.',
                    0, MB_OK);
      UnhookWindowsHookEx(hk);
      FreeLibrary(h);
    except
      Showmessage('Ошибка загрузки DLL: ' + BTMemoryGetLastError);
    end;
    if Assigned(btMM) then BTMemoryFreeLibrary(btMM);
  end;


hk равна нулю, то есть хук не устанавливается... 

P.s если просто грузить DLL не из ресурса, а из файла через LoadLibrary - всё проходит на ура и хук точно таким же образом ставится, а вот с хуком из ресурса не выходит. Помогите пожалуйста разобраться, что я делаю не так?

Автор: 500mhz 14.8.2012, 14:28
Фигней вы страдаете
Сделайте весь функционал в ЕХЕ и сделайте экспорт из него, и хукайте чего угодно.

Автор: bems 14.8.2012, 16:08
экзешник с экспортом не заменяет длл. хорош уже теоретизировать

Автор: 500mhz 14.8.2012, 16:46
bems

В каком случае не заменяет?

Автор: bems 14.8.2012, 18:41
500mhz, при загрузке экзешника в АП другого процесса не делаются фиксапы. Поэтому экспорты из exe можно применять только в ситуации когда из длл нужно использовать функции экзешника который использовался при создании процесса, который загрузил эту длл (надеюсь не слишком запутанно выразился). 

ТС пытается сделать глобальный хук, а значит система должна загрузить экзешник в АП всех процессов где возникают соответствующие события, кроме процесса утановившего хук (там этот экзешник уже есть)



kastron, хендл дллки при создании хука нужен системе чтобы загрузить эту длл в остальные процессы. А раз длл как таковой у тебя нет, то это не заработает

Автор: 500mhz 14.8.2012, 21:59
bems
Не говорите ерунду, делайте ехешник с shared секцией в которой код хука и секцией reloc , и все прекрасно грузится в любой процесс.

Автор: bems 14.8.2012, 22:06
Само по себе наличие релоков в экзешнике не помогает, это проверено. Что касается шаред-секции, то я не проверял, но в дельфи отсутствуют стандартные средства для создания таких секций. Ну а речь про дельфи всё-таки 

Автор: kastron 14.8.2012, 22:08
bems, скажи пожалуйста знаком ли ты с модулем BTMemoryModule? 
Разве таким образом я не получаю хэндл DLL-ки 
Код

  h:=THandle(btMM.codeBase);

или я не прав?

Автор: bems 14.8.2012, 22:22
kastron, не знаком с этим модулем, но вот некоторые общие сведения:
- хендл модуля обычно (строго говоря не всегда) совпадает с базовым адресом загрузки модуля в виртуальную память процесса
- codeBase может означать или этот адрес, или baseofcode из хидера. Это разные вещи
- независимо от значения этого поля, твой образ длл есть в памяти, но отсутствует в списке модулей процесса, который система хранит для каждого процесса. Этот список используется для получения имени по хендлу. Поэтому при установке хука она не сможет определить какой файл нужно маппить в чужие процессы

Автор: kastron 14.8.2012, 23:02
То есть исходя из сказанного прохучить DLL из ресурсов не получится?

Автор: 500mhz 14.8.2012, 23:11
Просто через LoadLibrary не получится

Автор: bems 14.8.2012, 23:32
Цитата(kastron @  14.8.2012,  23:02 Найти цитируемый пост)
То есть исходя из сказанного прохучить DLL из ресурсов не получится? 
нет. А зачем? если нужно хранить длл именно в ресурсах, то можно сохранять на диск перед установкой хука

Автор: northener 15.8.2012, 00:39
Цитата(bems @  14.8.2012,  23:32 Найти цитируемый пост)
А зачем?

Мне тоже непонятно зачем нужен такой хук?

Автор: kastron 15.8.2012, 01:41
Извлечь DLL из ресурса на диск и выполнить LoadLibrary - как вариант можно, это первое что пришло на ум. Интересовало возможно ли установить хук непосредственно из ресурсов.

Автор: northener 15.8.2012, 02:04
Цитата(kastron @  15.8.2012,  01:41 Найти цитируемый пост)
Извлечь DLL из ресурса на диск и выполнить LoadLibrary

Это самое правильное решение с точки зрения ОС.
Зачем нужно именно из пмаяти?

Автор: bems 15.8.2012, 03:17
Цитата(kastron @  15.8.2012,  01:41 Найти цитируемый пост)
Извлечь DLL из ресурса на диск и выполнить LoadLibrary - как вариант можно
а потом следующий шаг - делать это при инсталляции один раз, а не перед каждой установкой хука. И будет как у людей smile

Автор: 500mhz 15.8.2012, 09:13
Ну что вы пристали к ТС ))) 
Может он малварь на дельфи пишет, и сохранять дллку которая палится АВП на диск не кошерно, вот он и идет тернистым путом )))

Автор: kastron 15.8.2012, 12:12
500mhz
Да не пишу я никакой малварь. Просто интересовала возможность реализации данного нестандартного способа.

Автор: bems 15.8.2012, 14:16
Цитата(500mhz @  15.8.2012,  09:13 Найти цитируемый пост)
))) 
Цитата(500mhz @  15.8.2012,  09:13 Найти цитируемый пост)
))) 
ты бы лучше показал глобальный хук их экзешника.
и заодно просветил как при этом вызывается точка входа

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)