Всем доброго времени суток! dll пишу на ассме. exe на delphi. Exe загружает dll, потом грузит функцию на отлов клавиши(хук). С этим проблем нет, приложение написанное на delphi прекрасно с этим справляется Когда происходит событие(нажатие или отжатие клавиши) хук передает управление процедуре которая должна находиться в exe. Пытался неоднократно разобраться сам - но не вышло Вот как пытался (правда я тут пытался передать управления exe из самой процедуры обработки): Код (Text): KeyProc proc nCode:DWORD, wParam:DWORD, lParam:DWORD mov eax,wParam .if eax==65 invoke GetModuleHandle, addr NameEXE ; ТУТА ИМЯ exe ФАЙЛА mov hEXE, eax ; тУТА ЕГО HANDLE invoke GetProcAddress, hEXE, addr NameProc ; Тута имя вызываемой процедуры: KeyHook mov AddrKeyHook,eax call [AddrKeyHook] ; ТУТА ПЫТАЮСЬ ВЫЗВАТЬ ПРОЦЕДУРУ ИЗ EXE .endif invoke CallNextHookEx, hHook, nCode,wParam,lParam ret KeyProc endp А вот процедура которыю вызываю из exe : procedure KeyHook; begin MessageBox(0,'УДАЧААА','Good', MB_OK) end; PS: А вообще есть подозрения, что GetModuleHandle работает не так как мне надо, а именно: проганял dll через отладчик и когда данная функция должна была возратить хэндел файла exe, то регистр eax оказывался равным нулю. А если я пытался данной функцией узнать хэндел самой dll , то функция возращало отличное значение от нуля в eax. Кто чем поможет??? Благодарю за внимание!!!!!
Попробуй через toolhelp Код (Text): var lpme: MODULEENTRY32; h: longword begin h:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetModuleHandle(0)); Module32First(h, @lpme); CloseHandle(h); end; Если вызвать этот код из dll, то хендл exe должен быть в lpme.hModule.
Извиняюсь за нескромный вопрос: а что, у вас exe-шник с экспортом? Потому что GetProcAddress иначе вернет ошибку, даже если базу экзешника правильно получить, и хендл правильно получить... Кстати, ВООБЩЕ не уверен, что GetProcAddress применима к экзешникам, пусть даже с экспортом...
murder Спасибо, попробую... FatMoon А как же тогда быть??? Может есть другой способ вызова процедуры из exe ??
FatMoon Загрузчик не проверяет флажёк LDRP_IMAGE_DLL при вызове LdrGetProcedureAddress(), больше разницы между длл и экзе нет. Вот ядро например - экзешник с экспортом. XxLEVxX Код (Text): call [AddrKeyHook] Тут ошибка наверно, лодер возвратит непосредственно ссылку на процедуру, а у вас переход по ссылке. Модуль с диспетчером хука может быть в экзе. Искать модуль не совсем красивое решение, лучше получить базу в экзешнике и передать в длл, как сказали в #3. Код (Text): когда данная функция должна была возратить хэндел файла exe, то регистр eax оказывался равным нулю. Используйте ntdll!RtlGetLastNtStatus() для получения подробной информации об ошибке.
Странно.... А почему же тогда все нормально работает когда я вызываю процедуру из dll??? Вот код: Код (Text): invoke GetProcAddress, hLib, addr NameInstallHook mov AddrInstallHook,eax Call [AddrInstallHook]
Ну проблема, если я правильно понял, в том, что в программе на Дельфи ты не можешь определить адрес нужной тебе процедуры. Поэтому ты хочешь объявить процедуру как экспортируемую, потом из программы на Дельфи (exe) вызвать длл, а из длл вызывать процедуру из экзешника через поиск в экспортируемых функциях нужного имени. Мне кажется, это очень замудреный способ... Ради интереса, попробуй в самом экзе получить адрес своей процедуры через GetProcAddress. Хендл самого себя ты получишь нормально, и ЕСЛИ сработает - в принципе, должно сработать и так, как ты хочешь. Или каким-то образом передашь этот адрес в длл )) Или как-то двумя потоками организовать? Скажем, один поток из экзешника спит до семафора, а при возникновении события в длл семафор сбрасывается.
Код (Text): FatMoon Спасиб, с семафорам нужно будет попробывать... Нашел статью, что хук можно устанавливать и без dll http://forum.vingrad.ru/act-ST/f-193/t-27143.html Как думаете, проканает? как функцию в exe сделать экспортируемой???(masm) Я могу ошибаться, но наверно также как и в dll?
XxLEVxX Какого рода хук ты устанавливаешь? Если хук на один конкретный поток то непонятно зачем, тебе понадобилась длл - делал бы всё в экзе. Красивей, эстетичней и геммора меньше. Если ты ставишь глобальный хук на всю систему, что ж... тогда понятно почему у тебя GetModuleHandle "работает не так как мне надо". Код твоей длл может находится в адресном пространстве одного процесса(того который имел фокус ввода, когда ты нажал клавишу), а код функции которую вызываешь - в адресном пространстве совершенно другого процесса.
XxLEVxX Если в файле есть хотя бы одна экспортируемая функция, то из этого файла можно вызвать любую функцию: определяешь дельту и делаешь вызов.
FatMoon Вполне применима и работает, по меньшей мере, на XP и Win7x64. Более древние оси не смотрел, но там почти наверняка тоже самое.
Там самая главная заморочка - получить Hinstance именно EXE, а не хрен знамо чего, чтобы можно было скормить GetProcAddress.
n0name У меня всё было хитрее: иногда нужно было брать хэндл DLL, загрузившей мою библиотеку (которую грузил совершенно другой EXE без всяких экспортов), а иногда - хэндл EXE, опять же загрузившего мою библиотеку. Функция экспортировалась и там, и там, но вот способы получения этого хэндла были сильно разные. Проще всего оказалось явным образом отдавать своей библиотеке хэндл модуля с экспортируемыми функциями.
Друзья, как бы я не пытался - ни чего с этой задумкой не получилось........... Есть еще одна идея, как решить мою проблему, но для этого нужно создавать файл(txt) куда бы производилась запись. Есть одно не приятное НО... Данный файл создавал в системной директории system32. Если ОС WinXP то запись производится без проблем, а вот если WinVista / Win7 (у меня ща семерка) То запись не производится, т.к. в доступе отказано... Три варианта выхода: 1. Программным путем открыть доступ файлу(чтобы производилась запись) 2. Найти где-нибудь другое местечко под файл, гдебы был доступ на запись 3. Могу ошибаться, а что если создать ключ в реестре и туда производить временный запись? Какбы с теорией получше, а на практике...
на флаг длл ей глубоко фиолетово. если ПЕшник нормальный, есть валидная секция эскпорта, есть эта точка входа в экспорте, то все будет чики-пики. Да конечно, именно так и стоит делать.
Ты ничего толком не сказал о сути задумки (какой хук ставишь - глобальный или нет, WH_KEYBOARD или WH_KEYBOARD_LL) и увлек народ бестолклвыми рассуждениями о получении адреса функции из ехе А суть проблемы в том, что если ты ставишь глобальный WH_KEYBOARD для ловли WM_KEDOWN\UP в чужих приложениях, то соотв-но и хук твой срабатывает в контексте чужих приложений и соотв-но говорить о каком-то адресе функции своего ехе просто бессмысленно - нужно передавать данные своему приложению через посылку сообщений или именованный файл-маппинг. Если же ты ловишь WH_KEYBOARD_LL, то этот хук вызывается всегда в контексте потока, установившего хук, т.е. твоего ехе. В таком случае самое простое - это передать из ехе в длл указатель на callback функцию, которую и будет вызывать dll при срабатывании хука.
Спасибо БОЛЬШОЕ!!!! Открыл глаза!!! Даже не задумался, что такое возможно.... Глобальный хук, WH_KEYBOARD. Пожалуйста, тут поподробней, если не трудно, то с кодом. Спасибо!