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

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


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

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


 




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


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

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