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


Автор: Kostyaxp 28.10.2012, 16:38
Привествую всех заглянувших в ветку, и прошу помощи по возможности в решении следующего вопроса.

Задача такова: В системе другим (не моим) процессом загружена dll. Имя этой dll известно, имя процесса ее загрузившего тоже. 

Необходимо из ресурса этой dll загрузить hex данные в свое приложение. Имя ресурса (RCDATA) в dll тоже известно.

Есть код (пример):
Код

  Rs := TResourceStream.Create(HInstance, 'TXT', RT_RCDATA);
  Memo1.Lines.LoadFromStream(Rs);
  FreeAndNil(Rs);


Вопрос в том, как получить HInstance этой dll (загруженной чужим процессом) не загружая ее в свое приложение, чтобы передать ее HInstance, как параметр для TResourceStream.Create?

Автор: Illusion Dolphin 28.10.2012, 20:44
Не понимаю полностью проблему. Если известно имя длл, то грузим её как данные (LoadLibraryEx, LOAD_LIBRARY_AS_DATAFILE) и читаем что хотим - чем это не устраивает? 

Автор: Чучмек 28.10.2012, 20:56
HInstance это адрес по которому загружена  длл.

Автор: MetalFan 28.10.2012, 21:52
Цитата(Illusion Dolphin @  28.10.2012,  20:44 Найти цитируемый пост)
то грузим её

Но автор хочет
Цитата(Kostyaxp @  28.10.2012,  16:38 Найти цитируемый пост)
не загружая ее в свое приложение


Почему поставлено такое ограничение, что нельзя библиотеку "загрузить" в свое АП и сделать с ней то, что надо?


Автор: Illusion Dolphin 29.10.2012, 00:03
Цитата

Но автор хочет

99% что этого автор не хочет, а пытается сделать. Задача имхо совсем в другом, но он забыл об этом рассказать. 

Но в лоб как это сделать - делается dll inject, код которого делает GetModuleHandle(Имя этой dll) и операции с ресурсами, по завершению через межпроцессорное взаимодействие передаёт днные в программу автора. 

Чтобы получить список dll у процесса можно сделать вот так (© stackoverflow):

Цитата

type
  TEnumModulesCallback = function (Module: HMODULE; Data: Pointer = nil): Boolean;

function EnumModulesPS(PID: Cardinal; Callback: TEnumModulesCallback; Data: Pointer = nil): Boolean;
var
  ProcessHandle: THandle;
  SizeNeeded: Cardinal;
  P, ModuleHandle: PHModule;
  I: Integer;
begin
  Result := False;

  ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID);
  if ProcessHandle = 0 then
    RaiseLastOSError;
  try
    SizeNeeded := 0;
    EnumProcessModules(ProcessHandle, nil, 0, SizeNeeded);
    if SizeNeeded = 0 then
      Exit;

    P := AllocMem(SizeNeeded);
    try
      if EnumProcessModules(ProcessHandle, P, SizeNeeded, SizeNeeded) then
      begin
        ModuleHandle := P;
        for I := 0 to SizeNeeded div SizeOf(DWORD) - 1 do
        begin
          if Callback(ModuleHandle^, Data) then
            Exit;
          Inc(ModuleHandle);
        end;

        Result := True;
      end;
    finally
      FreeMem(P);
    end;
  finally
    CloseHandle(ProcessHandle);
  end;
end;


Получите список dll и их ModuleHandle - то же, что и HInstance для win32. Дальше GetModuleFileNameEx и если совпало - получите искомое HInstance.
Теперь самое интересное - это не поможет получить ресурсы, т.к. полученный HInstance  это виртуальный адрес в адресном пространстве того exe, а не нашего. FindResource не будет работать. Считать данные можно кое-как через ReadProcessMemory и операции с форматом PE файла, но это уже как-то сложно.  

Автор: bems 30.10.2012, 18:17
Цитата(Чучмек @  28.10.2012,  20:56 Найти цитируемый пост)
HInstance это адрес по которому загружена  длл. 

младшие биты могут отличаться (используются как флаги)

Автор: Kostyaxp 1.11.2012, 18:45
Всем спасибо за ответы.

В итоге сам точно также и пришел к выводу о том, что dll-ку придется грузить, иначе слишком сложно все получается.

Ограничение изначально было из-за того, что путь до dll не известен (хотелось в другом процессе отловить), а само содержимое ее ресурсов может при этом меняться.

Код такой получился:
Код

var
//dllname путь к нашей dll-ке
dllname : widestring;
//handle dll-ки
dllhandle : thandle;
begin
dllhandle := LoadLibraryEx(pwidechar(dllname),0,LOAD_LIBRARY_AS_DATAFILE);


Хотел поставить "плюсеги", но постов не хватает. smile 

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