Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как из ДЛЛ получить свой описатель? 
:(
    Опции темы
HappyLife
Дата 29.8.2007, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 642
Регистрация: 17.5.2006

Репутация: нет
Всего: 8



Как не используя переменную из функции DllEntryPoint получить HINSTANCE текущего модуля.
GetModuleHandle требует имя, а мне бы стандартный прием, типа GetThisHandle.....
При помощи GetModuleHandle(0) можно получить описатель EXE вызвавшей модуль.
PM MAIL   Вверх
Earnest
Дата 29.8.2007, 16:25 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



По-моему - никак (если имени модуля не знаешь). А чем тебя DllEntryPoint не устраивает? Заведи глобальную переменную и запомни, потом спрашивай.

Добавлено через 1 минуту и 25 секунд
Т.е. DllMain


--------------------
...
PM   Вверх
HappyLife
Дата 29.8.2007, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 642
Регистрация: 17.5.2006

Репутация: нет
Всего: 8



Earnest, Кхм. Потому что хочется сделать независимый класс, который ничего не экстернит.
Ну раз никак значит никак.)
PM MAIL   Вверх
Earnest
Дата 30.8.2007, 08:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Ну и не экстернь. Сделай приватную статическую переменную и инициализируй ее в DllMain (соответствующей статической функцией). Так примерно MFC делает.


--------------------
...
PM   Вверх
Tectoder
Дата 1.9.2007, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 202
Регистрация: 13.3.2007

Репутация: 7
Всего: 8



В принципе никак.
Откуда твоя функция будет это знать? Над адресом возврата чтоли издеваться?
PM   Вверх
Pale_Master
Дата 1.9.2007, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 22.2.2007

Репутация: нет
Всего: нет



На самом деле это довольно просто сделать. Мой пример нуждается в библиотеке dbghelp.dll.

Код

#include "DbgHelp.h"

#pragma comment(lib,"Dbghelp.lib")

BOOL CALLBACK EnumerateLoadedModulesProc64(PTSTR pszModuleName, DWORD64 qwModuleBase, ULONG dwModuleSize, PVOID pUserContext)
{
    const DWORD64 qwCurAddress = (DWORD64)&EnumerateLoadedModulesProc64;

    if (qwCurAddress >= qwModuleBase && qwCurAddress <= qwModuleBase+(DWORD64)dwModuleSize)
    {
        strcpy_s((char*)pUserContext,MAX_PATH,pszModuleName);
        return FALSE;
    }

    return TRUE;
}

HMODULE GetCurrentInstance()
{
    char szModuleName[MAX_PATH];

    ::EnumerateLoadedModules64(::GetCurrentProcess(),&EnumerateLoadedModulesProc64,szModuleName);

    return ::GetModuleHandle(szModuleName);
}




PM MAIL   Вверх
Tectoder
Дата 1.9.2007, 17:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 202
Регистрация: 13.3.2007

Репутация: 7
Всего: 8



Ну если такой способ, с учетом всех возможных багов, то почему бы не использовать просто VirtualQuery ^_^
PM   Вверх
Pale_Master
Дата 1.9.2007, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 22.2.2007

Репутация: нет
Всего: нет



Tectoder, есть много способов получить базовый адрес текущего модуля, коим и является HMODULE (HINSTANCE), тем не менее вы утверждали, что это невозможно сделать. smile
PM MAIL   Вверх
GremlinProg
Дата 2.9.2007, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Примерно, таким же образом я получал текущий модуль, только использовал разбор секции импорта, в поисках экспортируемого "ключевого символа". Но раз условие таково:
Цитата(HappyLife @  29.8.2007,  18:30 Найти цитируемый пост)
Потому что хочется сделать независимый класс, который ничего не экстернит

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

На сколько я помню, VirtualQuery вернет для того же qwCurAddress базовый адрес исполняемого модуля, а не модуля dll, хотя могу ошибаться, у кого на ходу какая-нибудь библиотека, проверьте плз. мои сомнения


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
W4FhLF
Дата 3.9.2007, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 12
Всего: 121



Куда-то всех понесло не туда smile

Код

#include "windows.h"

BOOL __stdcall DllMain (HANDLE hInst,DWORD dwReason, LPVOID IpReserved) 
{
    DWORD hModule;
    switch (dwReason) {
        case DLL_PROCESS_ATTACH: // Инициализация процесса.

            hModule = (DWORD)&DllMain & 0xFFFF0000; // берём любой адрес в пределах нашей DLL
            while (*(PWORD)hModule != 'ZM') // листаем страницы в поисках сигнатуры MZ. Любой модуль в памяти начинается с этой сигнатуры.
                hModule -= 0x1000;

            // в hModule базовый адрес
            break; 
        case DLL_PROCESS_DETACH: // Очистка структур процесса.
            break;
    }
    return TRUE;



Это сообщение отредактировал(а) W4FhLF - 3.9.2007, 10:55


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
HappyLife
Дата 3.9.2007, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 642
Регистрация: 17.5.2006

Репутация: нет
Всего: 8



W4FhLF, Очень красиво. smile 
PM MAIL   Вверх
GremlinProg
Дата 3.9.2007, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Забавно, только упаси вас бог, таким способом искать текущий модуль ))
Сигнатура MZ не уникальна, нет ни какой гарантии, что MZ не втретится, ни в коде, ни в статических данных. К примеру, 0x48r - код команды DEC. Если DEC будет выполняться для регистра BP или EBP, в зависимости от разрядности команды, то код будет 0x4D, т.е. 'M', аналогично и для 'Z'.



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
586
Дата 4.9.2007, 05:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 39
Всего: 146



Цитата(GremlinProg @  3.9.2007,  20:32 Найти цитируемый пост)
Сигнатура MZ не уникальна, нет ни какой гарантии, что MZ не втретится, ни в коде, ни в статических данных.

есть еще сигнатура PE и OptionalHeader.Magic и такое совпадение маловероятно. Расположение PE-файла в ресурсах по такому выравниванию в ресурсах тоже маловероятно. К тому же в PE заголовке где-то есть флаг, что модуль загружен в память.
PM   Вверх
W4FhLF
Дата 4.9.2007, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 12
Всего: 121



Про сигнатуру PE 586 отметил верно, в своих программах я учитывал это. 

Цитата(GremlinProg @  3.9.2007,  19:32 Найти цитируемый пост)
Сигнатура MZ не уникальна, нет ни какой гарантии, что MZ не втретится, ни в коде, ни в статических данных.


А ты видел много программ в которых нативные секций данных и ресурсов располагаются в памяти по адресам младшим относительно адреса секции кода?

Добавлено @ 14:56
И ещё, лучше перестраховаться и сделать hModule = (DWORD)&DllMain & 0xFFFFF000;

Это сообщение отредактировал(а) W4FhLF - 4.9.2007, 17:46


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
GremlinProg
Дата 4.9.2007, 21:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(W4FhLF @  4.9.2007,  16:50 Найти цитируемый пост)
А ты видел много программ в которых нативные секций данных и ресурсов располагаются в памяти по адресам младшим относительно адреса секции кода?

Зря бушуешь, я не говорю, что твой метод не сработает, в конкретных программах - конечно, не спорю, быстро и аккуратно так можно найти базовый адрес модуля, НО. Виртуальный адрес любой секции физически можно переназначить без особых проблем и загрузчик это проглотит, практически все среды позволяют менять, по крайней мере базовые адреса, я уже не говорю о умных следопытах, которые практикуют прямое назначение адресов секций, в таком случае секция кода может располагаться где-угодно, ресурсы, в которых так же может лежать как модуль, так и драйвер, так же можно переносить в любое место. Выравнивание условно и выставляется в основном только ms компиляторами. Если говорить об общем случае, то возьми просто, наугад пару-тройку левых программ и попробуй найти фаром эти сигнатуры.

Вобщем, если нет гарантии, что последовательность уникальна, то не стоит использовать "лобовые" поисковые алгоритмы в своих программах, в основном это временные или частные решения.

Я тут просто еще раз посмотрел на третий пост
Цитата

Потому что хочется сделать независимый класс

Ключевое слово независимый, т.е. независимый от среды внедрения, т.е. работающий везде...

надеюсь, я понятно все изложил


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
W4FhLF
Дата 5.9.2007, 08:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 12
Всего: 121



Цитата(GremlinProg @  4.9.2007,  21:40 Найти цитируемый пост)
Виртуальный адрес любой секции физически можно переназначить без особых проблем и загрузчик это проглотит, практически все среды позволяют менять, по крайней мере базовые адреса, я уже не говорю о умных следопытах, которые практикуют прямое назначение адресов секций, в таком случае секция кода может располагаться где-угодно, ресурсы, в которых так же может лежать как модуль, так и драйвер, так же можно переносить в любое место. Выравнивание условно и выставляется в основном только ms компиляторами.


Извини конечно, но я не понимаю к чему эти многабукофф? Ты же получаешь описатель СВОЕГО модуля, тебе заранее должны быть известны расположение секций. Я не видел ниодного компилятора располагающего секцию кода за секциями данных или ресурсов. 
Хорошо, пусть ты решил извратиться и сделал секцию кода последней, пусть у тебя в ресурсах лежит ещё какой-то PE файл и пусть его адрес совпадает с началом страницы в памяти, тогда возьми InMemoryOrderModuleList в PEB'e и пройдись по нему в цикле или пропусти это срабатывание и всё. 

Цитата(GremlinProg @  4.9.2007,  21:40 Найти цитируемый пост)
 Если говорить об общем случае, то возьми просто, наугад пару-тройку левых программ и попробуй найти фаром эти сигнатуры.


И что я должен увидеть?

Цитата(GremlinProg @  4.9.2007,  21:40 Найти цитируемый пост)
Вобщем, если нет гарантии, что последовательность уникальна, то не стоит использовать "лобовые" поисковые алгоритмы в своих программах, в основном это временные или частные решения.


Называть частным решение, которое основано на фундаментальных аспектах архитектуры ОС я бы не решился. 

Это сообщение отредактировал(а) W4FhLF - 5.9.2007, 08:42


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
GremlinProg
Дата 5.9.2007, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(W4FhLF @  5.9.2007,  10:01 Найти цитируемый пост)
же получаешь описатель СВОЕГО модуля, тебе заранее должны быть известны расположение секций

Согласен, только если бы вопрос стоял именно так, то я, честно, использовал бы hInstance из DllMain, и не морочил бы ни кому голову. Суть ведь именно в том, что доступ к модулю не должен быть привязан к конкретной архитектуре приложения, на то он и класс, т.е. понятие СВОЙ модуль он в принципе-то и знать не должен. Сможешь найти в примере Pale_Master какую-нибудь такую привязку или неопределенность?
Цитата(W4FhLF @  5.9.2007,  10:01 Найти цитируемый пост)
Называть частным решение, которое основано на фундаментальных аспектах архитектуры ОС я бы не решился. 

Громко, но я бы наверное именно это и не решился бы написать, по крайней мере не стал бы призывать всех пресвятых, как то старо, и не убедительно.


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
W4FhLF
Дата 5.9.2007, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 12
Всего: 121



Цитата(GremlinProg @  5.9.2007,  11:12 Найти цитируемый пост)
Согласен, только если бы вопрос стоял именно так


Цитата(HappyLife @  29.8.2007,  16:18 Найти цитируемый пост)
Как не используя переменную из функции DllEntryPoint получить HINSTANCE текущего модуля.


Цитата(HappyLife @  29.8.2007)

Как из ДЛЛ получить свой описатель?


Цитата(GremlinProg @  5.9.2007,  11:12 Найти цитируемый пост)
на то он и класс, т.е. понятие СВОЙ модуль он в принципе-то и знать не должен.


Ещё разок перечитай, задача состоит в том, чтобы получить СВОЙ описатель. Классу пофиг в пределах какого модуля выполняться, известно лишь одно - код класса выполняется в пределах модуля описатель которого надо получить. В этом состоит задача, не знаю чего ты споришь.

Цитата(GremlinProg @  5.9.2007,  11:12 Найти цитируемый пост)
Громко, но я бы наверное именно это и не решился бы написать, по крайней мере не стал бы призывать всех пресвятых, как то старо, и не убедительно.


Чего?

Это сообщение отредактировал(а) W4FhLF - 5.9.2007, 14:49


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
Tectoder
Дата 5.9.2007, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 202
Регистрация: 13.3.2007

Репутация: 7
Всего: 8



Цитата(Pale_Master @  1.9.2007,  17:58 Найти цитируемый пост)
Tectoder, есть много способов получить базовый адрес текущего модуля, коим и является HMODULE (HINSTANCE), тем не менее вы утверждали, что это невозможно сделать.  
Если исполнительная среда устроена так что код библиотеки генерируется в рантайме(примеры таких сред приводить надо?), адрес какойнибудь функции может оказаться очень сильно отличен от базы dll, вы не находите? Имелось ввиду это. А не то что нельзя определить базу региона обладающего кучей характерных признаков.
Хотя если речь идет о C++ в частности, а не о Win32 вообще, то сказанное тобой конечно вполне разумно.

Это сообщение отредактировал(а) Tectoder - 5.9.2007, 20:09
PM   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1230 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.