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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> сам импортирую API функцию MessageBox / VS 6.0, не получается импортировать API функции 
V
    Опции темы
SaikstiN
  Дата 15.10.2009, 14:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



 smile Доброго времени суток всем

С с++ знаком не очень давно, зато с гуглом уже на ты (это, так сказать, небольшое замечание)

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

Проблема в следующем.. Есть у меня обычный проект Win32 в VS 6.0 (если не ошибаюсь, About говорит о 94-98)

Хотел я там создать окошко через API (люблю я это : ) полупрозрачное.. 
Естественно, линковщик заругался на отсутствие описания функции SetLayeredWindowAttributes и несколько констант к ним...
 + в коде мне нужно было отслеживать WM_LEAVE с помощью TrackMouseEvent, чего в VS 6.0 тоже нет...почему нет, мне ответил гугл... (он еще, разумеется, посоветовал юзать VS 2008 ну или какая там последняя, но переход на новый IDE не состоялся : )

Ок, я решил написать их описание у себя и столкнулся с проблемой незнания как это всё написать  smile 
поиск дал немного инфы, ничего путного я не нашел...
вконце концов гугл посоветовал мне юзать LoadLibrary и GetProcAddress
ок, вышло супер...

но я подумал, а если вообще не подключать windows.h (смущает огромное количество инструкций внутри; макросов, обьявлений, подключений других библиотек и т.д.) и все функции загружать автоматически (т.е. динамическая линковка) (зачем я так подумал даже не спрашивайте)

ок...отключил..куча ошибок...прописал дефайны на типы и несколько структур...ошибок поменьшало....

теперь стал остро вопрос...откуда брать (адреса ф-ций) LoadLibrary и GetProcAddress?
ответ -> гугл....пошарив с полдня, Хром от большого количества вкладок вырубился, что впрочем ничуть не огорчило - инфы там особо не было...

нашел я только два момента - __declspec(dllimport) и DEF-файл

второй способ работает только с длл (?) и в IMPORTS внешних функций содержать вроде как не может....
первый вроде оно самое, но как его использовать не увидел (всмысле как использовать для внешних функций, вроде вызова MessageBeep от user32.dll, или той же LoadLibrary от кернела)

я копал микрософтские header'ы, но, то, что я там находил, и пытался вставить к себе в проект, не работало...

если кто-то знает (или же может это очень заезженная тема, киньте ссыль), напишите хотя бы возможно ли это, и если да, малююсенький пример  smile  (только кодом в с++, затей с асмом не надо : )

если так никто и не понял о чем это я, могу привести код и описание ошибок (хотя, на мой взгяд, всё наглядно)

Спасибо  smile 
PM MAIL   Вверх
jonie
Дата 15.10.2009, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата
теперь стал остро вопрос...откуда брать (адреса ф-ций) LoadLibrary и GetProcAddress?
я не стал бы этого делать. дело в том что начиная с висты майкрософт стала динамически выбирать (из 256 вариантов вроде) базу kernel-а при загрузке приложения+еще что-то для защиты сделала. Кроме того подобные программы будут с 99% вероятностью блокироваться антивирусным и прочим анти- ПО. 


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
SaikstiN
  Дата 15.10.2009, 16:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



и что же...максимум что я могу делать, это подключать windows.h для LoadLibrary и GetProcAddress и потом уже загружать через них остальные функции?

весело.... smile 

а это только загрузку kernel'а так сделали хреново динамически, или и остальных библиотек тоже?

...антивирусники и в таком случае (через LoadLibrary и GetProcAddress) будут сигналить?

Это сообщение отредактировал(а) SaikstiN - 15.10.2009, 17:01
PM MAIL   Вверх
DrHex
Дата 15.10.2009, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата

LoadLibrary и GetProcAddress

Это одни из самых базовых функций. 

Не хочешь юзать системные???
Пиши сам.

Не хочеш подключать windows.h 
Сделай свою ручками таблицу импорта.....

А вообще зачем такое на С++ пишу на асме............



--------------------
google.com и это все.
PM MAIL   Вверх
GremlinProg
Дата 15.10.2009, 18:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(jonie @  15.10.2009,  18:42 Найти цитируемый пост)
Кроме того подобные программы будут с 99% вероятностью блокироваться антивирусным и прочим анти- ПО.

с чего бы это?
динамическая загрузка - шанс распознать и учесть особенности платформы, на которой выполняется приложение,
например: отсутствие какой-либо библиотеки, или различие имен библиотек или функций

иногда без динамической загрузки вообще не обойтись,
например: при использовании драйверов, не поставляющихся с операционкой,
особенно, когда программа заточена не только для работы с этим устройством

смешно бы было: `работа программы "рога и копыта" невозможна без устройства "копыта", так что бреются все, кого интересуют только "рога"`
просто антивирусному ПО сложнее анализировать такие динамические вложения,
но это совсем не значит, что только поэтому они их блокируют
Цитата(SaikstiN @  15.10.2009,  16:52 Найти цитируемый пост)
первый вроде оно самое, но как его использовать не увидел (всмысле как использовать для внешних функций, вроде вызова MessageBeep от user32.dll, или той же LoadLibrary от кернела)

для примера мог хотя бы заглянуть в тот же winuser.h
все ведь описано:
Код

WINUSERAPI
int
WINAPI
MessageBoxW(
    __in_opt HWND hWnd,
    __in_opt LPCWSTR lpText,
    __in_opt LPCWSTR lpCaption,
    __in UINT uType);


Код

#define WINAPI      __stdcall

Код

#define WINUSERAPI DECLSPEC_IMPORT

Код

#define DECLSPEC_IMPORT __declspec(dllimport)

для статической загрузки, по типу того, что представлено выше, требования примерно те же, что и для динамической,
т.е. тут участвует та же пара : библиотека и имя функции

__declspec(dllimport) обеспечивает привязку к имени функции,
а библиотеку можно подключить разными способами, вот один из них:
Код

#pragma comment(lib,"User32")



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


Новичок



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

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



Цитата

а библиотеку можно подключить разными способами, вот один из них:


Именно это я (наверно) и искал! smile 
Не понимал, откуда __declspec(dllimport) будет брать библиотеку, но теперь ясно...


Цитата

для примера мог хотя бы заглянуть в тот же winuser.h
все ведь описано:


именно так я и делал, но..почти всегда, даже когда я все макросы #define позаменял ручками, ничего не хотело работать...причем брал header'ы с самых разных компиляторов, и искал в них, но всё отказывалось работать...наверное проблема была в чем-то маленьком и незаметном как всегда smile

сейчас попробовал опять собрать, уже с вашим кодом, вывело такую ошибку

Код

error LNK2001: unresolved external symbol "__declspec(dllimport) int __stdcall MessageBoxA(void *,char const *,char const *,unsigned int)" (__imp_?MessageBoxA@@YGHPAXPBD1I@Z)
Release/smiletop.exe : fatal error LNK1120: 1 unresolved externals


я так понял, адрес ищет внутри екзешника?

вот код:

Код

#define WINVER        0x0500

typedef void *HANDLE;
typedef HANDLE HWND;

typedef const char          *LPCSTR;
typedef unsigned int        UINT;

#pragma comment(lib,"User32")

#define WINAPI      __stdcall
#define WINUSERAPI DECLSPEC_IMPORT
#define DECLSPEC_IMPORT __declspec(dllimport)

WINUSERAPI
int
WINAPI
MessageBoxA(
     HWND hWnd,
     LPCSTR lpText,
     LPCSTR lpCaption,
     UINT uType);


#pragma comment(linker,"/MERGE:.rdata=.text")
#pragma comment(linker,"/FILEALIGN:512 /SECTION:.text,EWRX /IGNORE:4078")
#pragma comment(linker,"/ENTRY:main")
#pragma comment(linker,"/NODEFAULTLIB")


void WINAPI main(){
    MessageBoxA(0,"hello","world",0);
}





и ещё вопросик smile 

Цитата

просто антивирусному ПО сложнее анализировать такие динамические вложения,
но это совсем не значит, что только поэтому они их блокируют


- это когда перед запуском антивирус его проверяет? (ну пусть по эвристическому анализу, или как там)

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

значит, все таки лучше вписывать объявления функций, как выше..  smile 
тогда объявления пишутся в таблицу импорта, так ведь?
PM MAIL   Вверх
GremlinProg
Дата 15.10.2009, 19:34 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



нужно отключить декорирование плюсов: поставить extern "C"

упростил немного типизацию, для наглядности:
Код

typedef void*            HINSTANCE;
typedef void*            HWND;
typedef char*            LPSTR;
typedef const char*        LPCSTR;
typedef unsigned int    UINT;
#define WINAPI            __stdcall
#define APIENTRY        WINAPI

#pragma comment(lib,"user32")

extern "C" __declspec(dllimport) int WINAPI MessageBoxA( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType );

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
    MessageBoxA(0,0,0,0);
    return 0;
}

+ по-моему, при отключении CRT прагма comment lib уже не будет распознанаваться,
в этом случае, можно просто из свойств проекта подключить библиотеки,
но это уже смотри сам, VS 6 под рукой нету, не подскажу

Добавлено через 28 секунд
Цитата(SaikstiN @  15.10.2009,  20:49 Найти цитируемый пост)
тогда объявления пишутся в таблицу импорта, так ведь?

да


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


Эксперт
****


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

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



Цитата(GremlinProg @ 15.10.2009,  18:18)
Цитата(jonie @  15.10.2009,  18:42 Найти цитируемый пост)
Кроме того подобные программы будут с 99% вероятностью блокироваться антивирусным и прочим анти- ПО.

с чего бы это?
динамическая загрузка - шанс распознать и учесть особенности платформы, на которой выполняется приложение,
например: отсутствие какой-либо библиотеки, или различие имен библиотек или функций
....поскипано
а библиотеку можно подключить разными способами, вот один из них:
[/code]

B где у вас динамическая линковка? Я её не вижу. Вижу статическую, в бинарнике будет ссылка на user32.dll, и на функцию из него.

Тут же человек хочет получить адрес функции GetProceAddress без использования GetProcAddress, чтобы в дальнейшем через неё получить адрес LoadLibrary и выполнить её...

Добавлено через 43 секунды
GremlinProg, ну не динамическое это, вам не кажется?)

Добавлено через 1 минуту и 54 секунды
или под 
Цитата

теперь стал остро вопрос...откуда брать (адреса ф-ций) LoadLibrary и GetProcAddress?
человек имел ввиду как их вызвать (получить в таблице импорта), а не как получить адреса в runtime?


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
GremlinProg
Дата 15.10.2009, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(jonie @  15.10.2009,  21:51 Найти цитируемый пост)
B где у вас динамическая линковка? Я её не вижу. Вижу статическую, в бинарнике будет ссылка на user32.dll, и на функцию из него.

динамическую я и не писал )
как и SaikstiN
Цитата(jonie @  15.10.2009,  21:51 Найти цитируемый пост)
Тут же человек хочет получить адрес функции GetProceAddress без использования GetProcAddress, чтобы в дальнейшем через неё получить адрес LoadLibrary и выполнить её...

да, уже понял,
я просто связал в цепочку "LoadLibrary и GetProcAddress" и "подобные программы будут с 99% вероятностью блокироваться",
а на первую часть цитаты не обратил внимания, мои извинения jonie

непонятно только, зачем искать в секции импорта адреса из Kernel32, которая уже заведомо участвует в работе приложения )
объявить обе функции статически и все

строим замки на пустом месте?

Цитата(jonie @  15.10.2009,  21:51 Найти цитируемый пост)
человек имел ввиду как их вызвать (получить в таблице импорта), а не как получить адреса в runtime?

Цитата(SaikstiN @  15.10.2009,  16:52 Найти цитируемый пост)
 а если вообще не подключать windows.h

видимо, SaikstiN все таки хочет просто подключить API без windows.h,
а статически или динамически - не имеет значения



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



****


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

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



Цитата(jonie @  15.10.2009,  17:42 Найти цитируемый пост)
дело в том что начиная с висты майкрософт стала динамически выбирать (из 256 вариантов вроде) базу kernel-а при загрузке приложения+еще что-то для защиты сделала. Кроме того подобные программы будут с 99% вероятностью блокироваться антивирусным и прочим анти- ПО. 

Редко кто получал базу kernel32 по статическим адресам, т.к. в каждой ОС (и сервиспаке) она разная

Никто получение базы kernel32  блокировать не будет, т.к. это нормальный код для упаковщиков. 
Нормальные антивирусы это проигнорируют, а недоантивирусы (типа авиры) этого не заметят, т.к. сигнатуру на такой код делать глупо, будут ложные срабатывания на кучу программ, а эмулятора у недоантивирусов нет.

Код получения базы kernel32, и затем адресов ее функций гуглится с 1го запроса,
однако нормальный импорт конечно проще.

Это сообщение отредактировал(а) GoldFinch - 15.10.2009, 20:17
PM MAIL ICQ   Вверх
GremlinProg
Дата 15.10.2009, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(GoldFinch @  15.10.2009,  22:17 Найти цитируемый пост)
Редко кто получал базу kernel32 по статическим адресам, т.к. в каждой ОС (и сервиспаке) она разная

по статическим адресам?
может все таки по фиксированным адресам?

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


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


Новичок



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

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



GremlinProg, спасибо, работает.
Даже не знал о таком extern "C", теперь понял smile 

я подключил user32.lib через Link -> General Object/Library Modules

Всем спасибо за ответы ;)

Это сообщение отредактировал(а) SaikstiN - 15.10.2009, 21:04
PM MAIL   Вверх
jonie
Дата 15.10.2009, 21:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



GoldFinch, не надо нам тут. Получение базы кернела это признак не упаковщика, а защиты вроде asprotect или армадиллы... и это плохой подход и плохой код. У меня включена DEP - попробуйте позапускайте такие "игрушки"  в win vista под гостем ..


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
GoldFinch
Дата 15.10.2009, 21:47 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



GremlinProg, по "статически прописанным в коде", типа 0x7C800000 для xpsp2
секция импорта тут ни при чем вообще, база (HMODULE) kernel32 нужна чтобы вызвать аналог GetProcAddress(Kernel32Base,"funcname")

jonie, упаковщики ничем не отличаются от протекторов в плане получения импорта
DEP тут вообще ни при чем, это запрет исполнения кода в страницах памяти где исполнение кода запрещено. С импортами это никак не связано. 

Учите матчасть.
PM MAIL ICQ   Вверх
jonie
Дата 16.10.2009, 08:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



GoldFinch, учите матчасть. В любом нормальном упаковщике GetProcAddress присуствует в импорте - покажите где нет?


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "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.1174 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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