Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как найти handle модуля / 25 сообщений из 46, страница 1 из 2
31.05.2017, 11:27
    #39462952
Pupkin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
Это продолжение этой темы Как найти имя модуля
Там не точно описана проблема и полемика ушла в бок и в треп.
--------
Среда - C++Builder 6.0 (BCB)

Есть BPL (например MyBpl), инсталлирована в BCB.
В BPL есть базовая форма TForm (например TForm::TMyForm) и унаследованные
от MyForm (например TMyForm::TMyFormChild,TMyFormChild:TMyFormGrandChild и т.д.)

Есть несколько DLL (числом 26 штук (пока), например, MyDll1, MyDll2), которые
в своем функционале создают экземпляры наследников TMyForm вызовом конструктора
создаваемого экземпляра. Число экземпляров наследников не подлежит подсчету, а
порядок - единицы сотен в каждой DLL.

Каждый создаваемый экземпляр должен знать handle DLL из которой создан для
удовлетворения "хотелки" заказчика.

Проблема в том, что передача handle из DLL-ки через параметр конструктора или
в member только что созданного экземпляра неприемлемо и не обсуждаемо .
DLL трогать нельзя.

Конструктор должен "сам внутри себя раскопать" handle через API, экспортируемые
функции ядра, через что угодно. "Раскапывание" может быть в форме (лучше базовой)
или в BPL, где живут цепочка унаследованных форм.
...
Рейтинг: 0 / 0
31.05.2017, 13:07
    #39463040
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
Pupkin, смотрю, ты таки жаждишь "одеть штаны через голову"... :)
Чтож... Тогда в конструкторе MyForm на стеке резервируй блок памяти через alloca, по полученному указателю ищи вверх по стеку точку возврата и через PSAPI определяй какому модулю DLL этот адрес принадлежит. Вместо alloca можно попробовать объявить внутри конструктора на стеке volatile void* = NULL и получить на него указатель через оператор &.
...
Рейтинг: 0 / 0
31.05.2017, 13:24
    #39463051
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
Pupkin, и не забудь директиву выравнивания, если будешь определять внутри конструктора volatile void*
...
Рейтинг: 0 / 0
31.05.2017, 13:38
    #39463067
CEMb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
GetHandle по имени возвращает HANDLE на DLL-ку, если она загружена. Иначе nullptr. При этом не надо делать потом FreeLibrary!
Предыдущую ветку не читал.
...
Рейтинг: 0 / 0
31.05.2017, 14:15
    #39463106
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
CEMb, у него GetHandle вернет handle на BPL, а не на DLL.
...
Рейтинг: 0 / 0
31.05.2017, 14:59
    #39463135
Pupkin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
rdb_devPupkin, смотрю, ты таки жаждишь "одеть штаны через голову"... :)
Чтож... Жаждю !!!

А нельзя ли поподробней. Не про штаны, а про второе...
...
Рейтинг: 0 / 0
31.05.2017, 15:14
    #39463139
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
Pupkinrdb_devPupkin, смотрю, ты таки жаждишь "одеть штаны через голову"... :)
Чтож... Жаждю !!!

А нельзя ли поподробней. Не про штаны, а про второе...

Да фигня это всё, тщетные попытки спеть басом...
...
Рейтинг: 0 / 0
31.05.2017, 15:20
    #39463145
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
PupkinЕсть несколько DLL (числом 26 штук (пока), например, MyDll1, MyDll2), которые
в своем функционале создают экземпляры наследников TMyForm вызовом конструктора
создаваемого экземпляра. Число экземпляров наследников не подлежит подсчету, а
порядок - единицы сотен в каждой DLL.

Каждый создаваемый экземпляр должен знать handle DLL из которой создан для
удовлетворения "хотелки" заказчика.

Проблема в том, что передача handle из DLL-ки через параметр конструктора или
в member только что созданного экземпляра неприемлемо и не обсуждаемо .
DLL трогать нельзя.А в чем проблема то? Так заказчику и говоришь: объем работы очень большой, делать не возьмусь ну за какие деньги. Ну или как вариант: это будет стоить вам $100000.
...
Рейтинг: 0 / 0
31.05.2017, 16:02
    #39463174
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
rdb_devCEMb, у него GetHandle вернет handle на BPL, а не на DLL.
Нет, всё верно он написал. Эта функция вернёт хэндл указанного модуля, если он загружен конечно
...
Рейтинг: 0 / 0
31.05.2017, 16:27
    #39463187
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
kealon(Ruslan)rdb_devCEMb, у него GetHandle вернет handle на BPL, а не на DLL.
Нет, всё верно он написал. Эта функция вернёт хэндл указанного модуля, если он загружен конечно
Как я понял ТСу надо узнать то самое lpModuleName. Т.е. он хочешь узнать хэндл, а по нему определить lpModuleName.
...
Рейтинг: 0 / 0
31.05.2017, 16:28
    #39463189
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
kealon(Ruslan)rdb_devCEMb, у него GetHandle вернет handle на BPL, а не на DLL.
Нет, всё верно он написал. Эта функция вернёт хэндл указанного модуля, если он загружен конечноВозвращаемся к первой серии: а как найти имя?
...
Рейтинг: 0 / 0
31.05.2017, 16:50
    #39463214
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
Barlonekealon(Ruslan)пропущено...

Нет, всё верно он написал. Эта функция вернёт хэндл указанного модуля, если он загружен конечноВозвращаемся к первой серии: а как найти имя?
ну скажем так, у него довольно странная модель плагинов в вакууме
при такой постановке здачи, в общем виде это сделать нельзя, наследуемая форма вообще может не иметь ни одного вызова кода из DLL

тут ванговать бесполезно, нужно знать как создаётся форма, как регистрируется плагин и пр.
...
Рейтинг: 0 / 0
31.05.2017, 16:55
    #39463221
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
хотя нет, туплю уже в середине недели

можно, адресс VMT текущего класса находится в константной секции DLL
дальше искать dll содержащую этот адрес с помощью TlHelp32
...
Рейтинг: 0 / 0
01.06.2017, 05:06
    #39463455
CEMb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
Простите, что вверг вас в рекурсию.
+1 за TlHelp32
...
Рейтинг: 0 / 0
01.06.2017, 08:21
    #39463506
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
kealon(Ruslan)хотя нет, туплю уже в середине недели

можно, адресс VMT текущего класса находится в константной секции DLL
дальше искать dll содержащую этот адрес с помощью TlHelp32
если класс не переопределяет виртуальных методов - оптимизатор часом не воспользуется родительской VMT(если RTTI отключён)?
...
Рейтинг: 0 / 0
01.06.2017, 08:38
    #39463515
Pupkin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
BarlonePupkinЕсть несколько DLL (числом 26 штук (пока), например, MyDll1, MyDll2), которые
в своем функционале создают экземпляры наследников TMyForm вызовом конструктора
создаваемого экземпляра. Число экземпляров наследников не подлежит подсчету, а
порядок - единицы сотен в каждой DLL.

Каждый создаваемый экземпляр должен знать handle DLL из которой создан для
удовлетворения "хотелки" заказчика.

Проблема в том, что передача handle из DLL-ки через параметр конструктора или
в member только что созданного экземпляра неприемлемо и не обсуждаемо .
DLL трогать нельзя.А в чем проблема то? Так заказчику и говоришь: объем работы очень большой, делать не возьмусь ну за какие деньги. Ну или как вариант: это будет стоить вам $100000.Не обсуждаемо !!!
...
Рейтинг: 0 / 0
01.06.2017, 08:42
    #39463518
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
Изопропилkealon(Ruslan)хотя нет, туплю уже в середине недели

можно, адресс VMT текущего класса находится в константной секции DLL
дальше искать dll содержащую этот адрес с помощью TlHelp32
если класс не переопределяет виртуальных методов - оптимизатор часом не воспользуется родительской VMT(если RTTI отключён)?
VMT-блок так же содержит имя класса, ссылку на родительский блок, так что для каждого класса взятого линкёром она обязательно есть. Информаци о полях тут не важна

Код: pascal
1.
class function ClassInfo: Pointer


вовращаемый ей адресс и нужно искать в диапазонах загрузки билиотек
...
Рейтинг: 0 / 0
01.06.2017, 08:48
    #39463521
CEMb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
PupkinНе обсуждаемо !!!Если я всё правильно понял, то: если код DLL-ки создал форму, будучи вызванным в, например, основном потоке, то она (форма) ничем топологически отличаться не будет от формы, созданной самим приложением. Если же это другой поток, например хук с внедрением, то можно по адресу расположения данных понять, какому потоку/DLL-ке принадлежит объект. А, даже есть уже готовая функция: GetWindowThreadProcessId, которая по хендлу окна скажет, в каком потоке оно создано.
...
Рейтинг: 0 / 0
01.06.2017, 08:51
    #39463522
CEMb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
kealon(Ruslan)вовращаемый ей адресс и нужно искать в диапазонах загрузки билиотекя сначала тоже хотел это написать, но потом засомневался: диапазон загрузки библиотеки относится вроде только к исполняемому коду? Данные по созданной форме будут лежать где-то на стеке, и понять по ним/адресу ничего не получится. Но вот я не знаю, где лежать статические данные динамически загружаемых библиотек? Это так, просто интересно... проблему автора это не решает.
...
Рейтинг: 0 / 0
01.06.2017, 09:13
    #39463531
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
Кривой костыль, но как вариант: HMODULE это адрес проецирования содержимого DLL в адресное пространство процесса.
Поэтому берем адрес какого-нибудь виртуального метода, о котором заведомо известно что он прописан внутри DLL и перебором ищем наибольший HMODULE меньше этого адреса.

Может кроме виртуальных методов можно еще что-то использовать, главное чтобы это что-то располагалось в коде искомой DLL и было связано с нужным объектом.
...
Рейтинг: 0 / 0
01.06.2017, 09:20
    #39463540
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
CEMbА, даже есть уже готовая функция: GetWindowThreadProcessId, которая по хендлу окна скажет, в каком потоке оно создано.
а поток то здесь при чём?
срочно выдохни
...
Рейтинг: 0 / 0
01.06.2017, 10:27
    #39463592
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
PupkinА нельзя ли поподробней. Не про штаны, а про второе...Можно!
Некоторые, конечно, могут назвать это грязным хаком, но делается это, примерно, так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
__fastcall TForm1::TForm1(TComponent* Owner)  : TForm(Owner)
{
  volatile size_t ret_address;
  asm
  {
    mov eax, dword ptr [ebp+0x4]; // +0x4 - skip previous EBP value
    mov [ret_address], eax;       // eax = next EIP value after ret
  }
  // Далее на примере, по ссылки ниже, определяешь с какого модуля пришел invoke
}

MSDN::Traversing the Module List

Модератор: rdb_dev, Проверь, правильно ли я исправил код
...
Рейтинг: 0 / 0
01.06.2017, 12:12
    #39463728
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
CEMbkealon(Ruslan)вовращаемый ей адресс и нужно искать в диапазонах загрузки билиотекя сначала тоже хотел это написать, но потом засомневался: диапазон загрузки библиотеки относится вроде только к исполняемому коду? Данные по созданной форме будут лежать где-то на стеке, и понять по ним/адресу ничего не получится. Но вот я не знаю, где лежать статические данные динамически загружаемых библиотек? Это так, просто интересно... проблему автора это не решает.
нет, куда ещё по твоему константы должны идти?


CEMbPupkinНе обсуждаемо !!!Если я всё правильно понял, то: если код DLL-ки создал форму, будучи вызванным в, например, основном потоке, то она (форма) ничем топологически отличаться не будет от формы, созданной самим приложением. Если же это другой поток, например хук с внедрением, то можно по адресу расположения данных понять, какому потоку/DLL-ке принадлежит объект. А, даже есть уже готовая функция: GetWindowThreadProcessId, которая по хендлу окна скажет, в каком потоке оно создано.
смотри, вот тебе готовое решение

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
program D1;
 {$APPTYPE CONSOLE}

uses
  Winapi.Windows, Winapi.Messages, Winapi.ImageHlp, Winapi.TlHelp32,
  Vcl.Forms,

  Unit1 in 'Unit1.pas' {Form2};
procedure WriteLibOfAddr(P: Pointer);
var
  h: THandle;
  me: TModuleEntry32;
  a, b, c : UIntPtr;
begin
  // Get the list of modules in this process
  h := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,GetCurrentProcessId());
  if (h = INVALID_HANDLE_VALUE) then
    Exit;
  try
    FillChar(me, SizeOf(me), 0);
    me.dwSize := sizeof(me);

    c := UIntPtr(P);
    if Module32First(h, me) then
      repeat
        a := UIntPtr(me.modBaseAddr);
        b := UIntPtr(me.modBaseAddr) + UIntPtr(me.modBaseSize);
        if (a <= c) and ( c < b) then
        begin
          Writeln(me.szExePath);
        end;
      until not Module32Next(h, me);
  finally
    CloseHandle(h);
  end;
 end;

{$R *.res}

begin
  WriteLibOfAddr(TForm.ClassInfo);
  WriteLibOfAddr(TForm2.ClassInfo);

  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.



вывод:
Код: plaintext
1.
C:\Program Files (x86)\Embarcadero\RAD Studio\9.0\bin\vcl160.bpl
C:\Users\kealo\Documents\RAD Studio\Projects\Win32\Debug\D1.exe
...
Рейтинг: 0 / 0
01.06.2017, 19:58
    #39464097
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
rdb_devPupkinА нельзя ли поподробней. Не про штаны, а про второе...Можно!
Некоторые, конечно, могут назвать это грязным хаком, но делается это, примерно, так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
__fastcall TForm1::TForm1(TComponent* Owner)  : TForm(Owner)
{
  volatile size_t ret_address;
  asm
  {
    mov eax, dword ptr [ebp+0x4]; // +0x4 - skip previous EBP value
    mov [ret_address], eax;       // eax = next EIP value after ret
  }
  // Далее на примере, по ссылки ниже, определяешь с какого модуля пришел invoke
}

MSDN::Traversing the Module List

Модератор: rdb_dev, Проверь, правильно ли я исправил код
А потом при сборке в релиз отключается stack frames, и всё падает...
...
Рейтинг: 0 / 0
01.06.2017, 20:01
    #39464099
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как найти handle модуля
Dima TКривой костыль, но как вариант: HMODULE это адрес проецирования содержимого DLL в адресное пространство процесса.
Поэтому берем адрес какого-нибудь виртуального метода, о котором заведомо известно что он прописан внутри DLL и перебором ищем наибольший HMODULE меньше этого адреса.

Может кроме виртуальных методов можно еще что-то использовать, главное чтобы это что-то располагалось в коде искомой DLL и было связано с нужным объектом.А вы уверены, что модуль, в котором описан класс, и модуль, в котором вызывается конструктор - один и тот же?
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как найти handle модуля / 25 сообщений из 46, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]