| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > сам импортирую API функцию MessageBox / VS 6.0 |
| Автор: SaikstiN 15.10.2009, 14:52 |
| С с++ знаком не очень давно, зато с гуглом уже на ты (это, так сказать, небольшое замечание) Вообще, я гуглил практически везде где можно, но ничего путного в том числе и примеров не нашел... Проблема в следующем.. Есть у меня обычный проект Win32 в VS 6.0 (если не ошибаюсь, About говорит о 94-98) Хотел я там создать окошко через API (люблю я это : ) полупрозрачное.. Естественно, линковщик заругался на отсутствие описания функции SetLayeredWindowAttributes и несколько констант к ним... + в коде мне нужно было отслеживать WM_LEAVE с помощью TrackMouseEvent, чего в VS 6.0 тоже нет...почему нет, мне ответил гугл... (он еще, разумеется, посоветовал юзать VS 2008 ну или какая там последняя, но переход на новый IDE не состоялся : ) Ок, я решил написать их описание у себя и столкнулся с проблемой незнания как это всё написать поиск дал немного инфы, ничего путного я не нашел... вконце концов гугл посоветовал мне юзать LoadLibrary и GetProcAddress ок, вышло супер... но я подумал, а если вообще не подключать windows.h (смущает огромное количество инструкций внутри; макросов, обьявлений, подключений других библиотек и т.д.) и все функции загружать автоматически (т.е. динамическая линковка) (зачем я так подумал даже не спрашивайте) ок...отключил..куча ошибок...прописал дефайны на типы и несколько структур...ошибок поменьшало.... теперь стал остро вопрос...откуда брать (адреса ф-ций) LoadLibrary и GetProcAddress? ответ -> гугл....пошарив с полдня, Хром от большого количества вкладок вырубился, что впрочем ничуть не огорчило - инфы там особо не было... нашел я только два момента - __declspec(dllimport) и DEF-файл второй способ работает только с длл (?) и в IMPORTS внешних функций содержать вроде как не может.... первый вроде оно самое, но как его использовать не увидел (всмысле как использовать для внешних функций, вроде вызова MessageBeep от user32.dll, или той же LoadLibrary от кернела) я копал микрософтские header'ы, но, то, что я там находил, и пытался вставить к себе в проект, не работало... если кто-то знает (или же может это очень заезженная тема, киньте ссыль), напишите хотя бы возможно ли это, и если да, малююсенький пример если так никто и не понял о чем это я, могу привести код и описание ошибок (хотя, на мой взгяд, всё наглядно) Спасибо |
| Автор: jonie 15.10.2009, 16:42 | ||
|
| Автор: SaikstiN 15.10.2009, 16:59 |
| и что же...максимум что я могу делать, это подключать windows.h для LoadLibrary и GetProcAddress и потом уже загружать через них остальные функции? весело.... а это только загрузку kernel'а так сделали хреново динамически, или и остальных библиотек тоже? ...антивирусники и в таком случае (через LoadLibrary и GetProcAddress) будут сигналить? |
| Автор: DrHex 15.10.2009, 17:58 | ||
Это одни из самых базовых функций. Не хочешь юзать системные??? Пиши сам. Не хочеш подключать windows.h Сделай свою ручками таблицу импорта..... А вообще зачем такое на С++ пишу на асме............ |
| Автор: SaikstiN 15.10.2009, 18:49 | ||||||||||
Именно это я (наверно) и искал! Не понимал, откуда __declspec(dllimport) будет брать библиотеку, но теперь ясно...
именно так я и делал, но..почти всегда, даже когда я все макросы #define позаменял ручками, ничего не хотело работать...причем брал header'ы с самых разных компиляторов, и искал в них, но всё отказывалось работать...наверное проблема была в чем-то маленьком и незаметном как всегда сейчас попробовал опять собрать, уже с вашим кодом, вывело такую ошибку
я так понял, адрес ищет внутри екзешника? вот код:
и ещё вопросик
- это когда перед запуском антивирус его проверяет? (ну пусть по эвристическому анализу, или как там) у меня, например, Касперский перед запуском новых или измененных екзешников окошечко выводит, для проверки , и частенько довольно долго проверяет... это, конечно же, не может нравиться пользователю... значит, все таки лучше вписывать объявления функций, как выше.. тогда объявления пишутся в таблицу импорта, так ведь? |
| Автор: GremlinProg 15.10.2009, 19:34 | ||
| нужно отключить декорирование плюсов: поставить extern "C" упростил немного типизацию, для наглядности:
+ по-моему, при отключении CRT прагма comment lib уже не будет распознанаваться, в этом случае, можно просто из свойств проекта подключить библиотеки, но это уже смотри сам, VS 6 под рукой нету, не подскажу Добавлено через 28 секунд да |
| Автор: jonie 15.10.2009, 19:51 | ||||||
B где у вас динамическая линковка? Я её не вижу. Вижу статическую, в бинарнике будет ссылка на user32.dll, и на функцию из него. Тут же человек хочет получить адрес функции GetProceAddress без использования GetProcAddress, чтобы в дальнейшем через неё получить адрес LoadLibrary и выполнить её... Добавлено через 43 секунды GremlinProg, ну не динамическое это, вам не кажется?) Добавлено через 1 минуту и 54 секунды или под
|
| Автор: GremlinProg 15.10.2009, 20:16 | ||||||
динамическую я и не писал ) как и SaikstiN
да, уже понял, я просто связал в цепочку "LoadLibrary и GetProcAddress" и "подобные программы будут с 99% вероятностью блокироваться", а на первую часть цитаты не обратил внимания, мои извинения jonie непонятно только, зачем искать в секции импорта адреса из Kernel32, которая уже заведомо участвует в работе приложения ) объявить обе функции статически и все строим замки на пустом месте?
видимо, SaikstiN все таки хочет просто подключить API без windows.h, а статически или динамически - не имеет значения |
| Автор: GoldFinch 15.10.2009, 20:17 | ||
Редко кто получал базу kernel32 по статическим адресам, т.к. в каждой ОС (и сервиспаке) она разная Никто получение базы kernel32 блокировать не будет, т.к. это нормальный код для упаковщиков. Нормальные антивирусы это проигнорируют, а недоантивирусы (типа авиры) этого не заметят, т.к. сигнатуру на такой код делать глупо, будут ложные срабатывания на кучу программ, а эмулятора у недоантивирусов нет. Код получения базы kernel32, и затем адресов ее функций гуглится с 1го запроса, однако нормальный импорт конечно проще. |
| Автор: GremlinProg 15.10.2009, 20:47 | ||
по статическим адресам? может все таки по фиксированным адресам? в секции импорта статически задаются только расположения адресов, а не сами адреса, база библиотеки тут не имеет значения, т.к. загрузчик уже сам корректирует эти адреса в соответствии с базами по статическим расположениям, т.е. на выходе образа в адресное пространство, все адреса функций уже корректны, в этом и фишка статической адресации |
| Автор: SaikstiN 15.10.2009, 20:58 |
| GremlinProg, спасибо, работает. Даже не знал о таком extern "C", теперь понял я подключил user32.lib через Link -> General Object/Library Modules Всем спасибо за ответы ;) |
| Автор: jonie 15.10.2009, 21:30 |
| GoldFinch, не надо нам тут. Получение базы кернела это признак не упаковщика, а защиты вроде asprotect или армадиллы... и это плохой подход и плохой код. У меня включена DEP - попробуйте позапускайте такие "игрушки" в win vista под гостем .. |
| Автор: GoldFinch 15.10.2009, 21:47 |
| GremlinProg, по "статически прописанным в коде", типа 0x7C800000 для xpsp2 секция импорта тут ни при чем вообще, база (HMODULE) kernel32 нужна чтобы вызвать аналог GetProcAddress(Kernel32Base,"funcname") jonie, упаковщики ничем не отличаются от протекторов в плане получения импорта DEP тут вообще ни при чем, это запрет исполнения кода в страницах памяти где исполнение кода запрещено. С импортами это никак не связано. Учите матчасть. |
| Автор: jonie 16.10.2009, 08:27 |
| GoldFinch, учите матчасть. В любом нормальном упаковщике GetProcAddress присуствует в импорте - покажите где нет? |
| Автор: SaikstiN 16.10.2009, 10:55 | ||||
| Снова здравствуйте Не хочу прерывать наметившуюся здесь дискуссию, но у меня возник вопрос в процессе дальнейшего написания этой программки, и ответа я найти не смог... Точнее сказать, такой проблемы наверное ни у кого не возникало... В-общем, в продолжении, у меня в программе имеются импортированные функции SetLayeredWindowAttributes и TrackMouseEvent +несколько define'ов и typedef'ов Наверное я где-то что-то напутал с обьявлением, хотя по msdn правильно, но при вызове TrackMouseEvent в WM_MOUSEMOVE (для получения WM_LEAVE) программа закрывается вылетает Продебаггить этот участок я не смог, но с помощью незаменимых MessageBox'ов, стало ясно что проблема возникает именно когда я вызываю TrackMouseEvent Тогда я засунул вызов TrackMouseEvent до начала цикла обработки сообщений окна (TranslateMessage), и, о чудо, работает и даже возвращает первый WM_LEAVE... самое смешное что я совершенно не догадываюсь от чего это оно так себя ведёт.. вот обьявление
а вот код которым вызываю
я почти уверен что ошибок там нет... подскажите пожалуйста, я уже почти сошел с ума от безысходности.. |
| Автор: 586 16.10.2009, 11:01 |
Почему здесь _cdecl, там должен быть __stdcall. |
| Автор: SaikstiN 16.10.2009, 11:16 |
| Ура!!!!, огромное спасибо, 586 |
| Автор: GoldFinch 16.10.2009, 17:30 | ||
да пусть так, я хз как там в упаковщиках, но только при чем тут DEP, при чем тут антивирусы, и почему это плохой код? |