Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вызов экспортируемой функции из dll, взятие адреса с последующем вызовом 
V
    Опции темы
magesi
  Дата 10.6.2012, 23:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Привет всем!

Цель моего вопроса: как вызвать экспортируемую функцию из какой-то библиотеки?

Я предварительно пока беру адрес той или иной ф-ции из dll ( к примеру, возьмем openal32.dll ) из программ dlldump/dependecy walker и потом пытаюсь
по адресу вызвать данную ф-цию.

Мой пример:

Код

#include <iostream>
#include <Windows.h>

const DWORD_PTR offset = 0x00003870;

typedef void (uef)();

int main(void)
{
    HMODULE hModule = GetModuleHandle(L"C:\\Windows\\system32\\OpenAL32.dll");

    DWORD_PTR addr = (DWORD_PTR)hModule + offset;

    uef func = (uef)offset;
    func();

    return 0;
}


Я взял для примера ф-цию alEnable(int) из OpenAL32, ее входная точка ( Entry Point ) - 0x00003870

Столкнулся на самом вызове...

Вроде бы, определил тип typedef void (uef)(); и хотел потом вызвать, но компилер выдает:

Код

1>c:\users\root\documents\visual studio 2008\projects\test1\test1\test1.cpp(14) : error C2072: 'func' : initialization of a function
1>c:\users\root\documents\visual studio 2008\projects\test1\test1\test1.cpp(14) : error C2205: 'func' : cannot initialize extern variables with block scope
1>c:\users\root\documents\visual studio 2008\projects\test1\test1\test1.cpp(14) : error C2066: cast to function type is illegal
1>c:\users\root\documents\visual studio 2008\projects\test1\test1\test1.cpp(14) : error C2440: 'initializing' : cannot convert from 'uef (__cdecl *)' to 'uef'
1>There are no conversions to function types, although there are conversions to references or pointers to functions


Я раньше уже делал вызов функции по адресу, но забыл....

И такой еще вопрос: является ли адрес опред. ф-ции в той или иной dll всегда статичным ( одиним и тем же ) или адреса экспортируемых ф-ций в одной и той же либе, на одной и той же ОС, могут быть разными при след. запуске ОС? Подскажите пожалуйста и по данному моменту, спасибо!

PS
Хотя по ошибке: 'uef (__cdecl *)' to 'uef' , вспоминается про stdcall .... Но вспомнить не могу , пока гуглю, но не нашел что-то вразумительного...

Заранее спасибо за помощь!

Это сообщение отредактировал(а) magesi - 11.6.2012, 12:45
PM MAIL   Вверх
magesi
Дата 11.6.2012, 00:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Хотя спасибо!

Уже не надо, сделал так:

Код

#include <iostream>
#include <Windows.h>

typedef void (__stdcall *uef)(int);

int main(void)
{
    HMODULE hModule = LoadLibrary(L"C:\\Windows\\system32\\OpenAL32.dll");
    uef obj = NULL;

    if(hModule != NULL)
    {
        obj = reinterpret_cast<uef>(GetProcAddress(hModule, "alEnable"));
    }

    if(obj != NULL)
    {
        (*obj)(0);
    }

    if(hModule != NULL)
    {
        FreeLibrary(hModule);
    }

    return 0;
}

PM MAIL   Вверх
Randajad
Дата 11.6.2012, 08:20 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



А что это вообще за извращение?
Что мешает сделать:

__declspec(dllimport) void __stdcall alEnable(int); ? И подрубить дллку к линкеру.

Это сообщение отредактировал(а) Randajad - 11.6.2012, 08:21
PM MAIL   Вверх
boostcoder
Дата 11.6.2012, 09:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(Randajad @  11.6.2012,  08:20 Найти цитируемый пост)
что это вообще за извращение?

это называется динамическим связыванием.

PM WWW   Вверх
Randajad
Дата 11.6.2012, 09:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Я понимаю, но, по-моему, нужны веские причины для него. smile
PM MAIL   Вверх
magesi
  Дата 11.6.2012, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(Randajad @ 11.6.2012,  09:19)
Я понимаю, но, по-моему, нужны веские причины для него. smile

И какие же, к примеру, веские могут быть, а какие не могут быть вескими?

Добавлено @ 12:24
Цитата(Randajad @  11.6.2012,  08:20 Найти цитируемый пост)
__declspec(dllimport) void __stdcall alEnable(int); ? И подрубить дллку к линкеру.

а как Вы адрес экспортируемой ф-ции в runtime собрались этим вычислять или как?

Это сообщение отредактировал(а) magesi - 11.6.2012, 12:32
PM MAIL   Вверх
borisbn
Дата 11.6.2012, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(magesi @  11.6.2012,  12:23 Найти цитируемый пост)
И какие же, к примеру, веские могут быть, а какие не могут быть вескими?

Пожалуйста: делается программа с плагинами. Один плагин - одна dll-ка. На этапе разработки программы неизвестно количество и наименование dll-к. Как тут обойтись без динамического связывания - хз.
Вот пример на псевдокоде, объясняющий то, что я хотел сказать на русском )))
Код

for ( dllFileName in pluginDirectory ) {
    HMODULE dll = LoadLibrary( dllFileName );
    PluginInitFunc func = (PluginInitFunc)GetProcAddress( dll, "create" );
    if ( func ) {
        PluginInterface plugin = func();
        m_plugins.push_back( plugin );
    }
}



--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
magesi
Дата 11.6.2012, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(borisbn @ 11.6.2012,  12:56)
Цитата(magesi @  11.6.2012,  12:23 Найти цитируемый пост)
И какие же, к примеру, веские могут быть, а какие не могут быть вескими?

Пожалуйста: делается программа с плагинами. Один плагин - одна dll-ка. На этапе разработки программы неизвестно количество и наименование dll-к. Как тут обойтись без динамического связывания - хз.
Вот пример на псевдокоде, объясняющий то, что я хотел сказать на русском )))
Код

for ( dllFileName in pluginDirectory ) {
    HMODULE dll = LoadLibrary( dllFileName );
    PluginInitFunc func = (PluginInitFunc)GetProcAddress( dll, "create" );
    if ( func ) {
        PluginInterface plugin = func();
        m_plugins.push_back( plugin );
    }
}

foreach уж юзали бы в псевдокоде  smile 

PluginInitFunc - ф-ции могут быть разными и иметь разное кол-во аргументов , как и разн. возвращющий тип, каждый раз переопределять PluginInitFunc?

PM MAIL   Вверх
borisbn
Дата 11.6.2012, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(magesi @  11.6.2012,  13:12 Найти цитируемый пост)
PluginInitFunc - ф-ции могут быть разными и иметь разное кол-во аргументов 

Для каждого типа пишется свой typedef к типу. Ты же не можешь создать массив из разных указателей на функцию.
Вообще-то для плагинов экспортируемые функции д.б. одинаковыми. Если же ты импртируешь разные функции одной dll-ки, то действительно - проще подключить в проект lib-ину импорта, сделать на каждую функцию описание с __declspec(dllimport) вначале, а потом не парясь их вызывать, как-будто они определены в другом cpp-шнике. Проще ведь...

Цитата(magesi @  11.6.2012,  13:12 Найти цитируемый пост)
foreach уж юзали бы в псевдокоде

на то он и псевдокод  smile 

Это сообщение отредактировал(а) borisbn - 11.6.2012, 13:33


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
magesi
  Дата 11.6.2012, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(borisbn @  11.6.2012,  13:33 Найти цитируемый пост)
Для каждого типа пишется свой typedef к типу. Ты же не можешь создать массив из разных указателей на функцию.Вообще-то для плагинов экспортируемые функции д.б. одинаковыми. Если же ты импртируешь разные функции одной dll-ки, то действительно - проще подключить в проект lib-ину импорта, сделать на каждую функцию описание с __declspec(dllimport) вначале, а потом не парясь их вызывать, как-будто они определены в другом cpp-шнике. Проще ведь...

Был-бы свой RTTI для таких целей бы smile 

Это сообщение отредактировал(а) magesi - 11.6.2012, 13:40
PM MAIL   Вверх
magesi
  Дата 11.6.2012, 20:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(borisbn @ 11.6.2012,  12:56)
Цитата(magesi @  11.6.2012,  12:23 Найти цитируемый пост)
И какие же, к примеру, веские могут быть, а какие не могут быть вескими?

Пожалуйста: делается программа с плагинами. Один плагин - одна dll-ка. На этапе разработки программы неизвестно количество и наименование dll-к. Как тут обойтись без динамического связывания - хз.
Вот пример на псевдокоде, объясняющий то, что я хотел сказать на русском )))
Код

for ( dllFileName in pluginDirectory ) {
    HMODULE dll = LoadLibrary( dllFileName );
    PluginInitFunc func = (PluginInitFunc)GetProcAddress( dll, "create" );
    if ( func ) {
        PluginInterface plugin = func();
        m_plugins.push_back( plugin );
    }
}

Хотя, стоп!

Сейчас модно очень при разработке продукта использовать один исполняемый файл и ничего более в директории приложения ( как Skype ). Dll грузятся в Resource, заранее составляется таблица адресов той или иной ф-ции и вызывается.
PM MAIL   Вверх
magesi
  Дата 11.6.2012, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(boostcoder @  11.6.2012,  20:24 Найти цитируемый пост)
Добавлено @ 20:25признаюсь, я впервые слышу пот такую моду. не с теми вожусь, походу  

1). Самый ярый пример уже был приведен - Skype.
2). Метод c LockBytes в исполнеяемом файле актуально моден.


Цитата(boostcoder @  11.6.2012,  20:24 Найти цитируемый пост)
а кто-то считает, что модно сувать в зад(ну не знаю, как еще более культурно об этом сказать).

Вы, что ли, в школе еще учитесь или в универе? Что за лексика? Зад какой-то... С Вами прилично разговаривают и не принебрегают моралью. Если, Вам тема не нравится, то просто игнорируйте, зачем какой-то быдло-стиль общения использовать без конца?

Вы себя не красите, а только указываете на уровень собственной культуры рекурсивно, что она достаточно бедна.

Не нравится - не отвечайте, зачем про какие-то зады писать?

Тем более, метод действительно актуален, и пример одного из самых популярных ПО, я предоставил, это проверяется легко. Embedded стиль насегодня, действительно, стал рентабельным, чем размножение на многие файлы, это и асимптотически даже видно.

Это сообщение отредактировал(а) magesi - 11.6.2012, 21:22
PM MAIL   Вверх
Randajad
Дата 11.6.2012, 21:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Да, про плугины не подумал. Но для того случая, что привел автор, этот код не нужен. smile

P.S. просто не так давно писал внедрение dll'ки из памяти в экзешку и запуск потока в оном приложении. smile
Про цель умолчу.  smile 
PM MAIL   Вверх
magesi
Дата 11.6.2012, 22:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(Randajad @  11.6.2012,  21:45 Найти цитируемый пост)
Но для того случая, что привел автор, этот код не нужен. 

Почему? Чем он не подходит?
PM MAIL   Вверх
500mhz
Дата 11.6.2012, 23:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


шайтан
***


Профиль
Группа: Завсегдатай
Сообщений: 1017
Регистрация: 5.5.2008
Где: Киев / Italy

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



magesi

ТС ну включите мозг, откуда ваш ехешник может знать о
1) и самое главное о кол-ве параметров функции
2) о названии ф-ции в таблице экспорта

хрен с ним оставим в покое пункт 2, там все работает просто, перебором
но пункт 2, вы так просто не определите

для написания плагинов надо изобрести всего на просто свое определение ызова функ
ну к примеру каждая функ имеет 6 параметров, если у функ 4 парам используются то остальные 2 типа равны = 0 
это как грубый пример

а про инжекты дллек в ехе, это мовитон по ряду причин.

Это сообщение отредактировал(а) Daevaorn - 12.6.2012, 13:09


--------------------

PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

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


 




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


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

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