Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.01.27;
Скачать: CL | DM;

Вниз

Сервис. DLL. Не работают функции экспортируемые из DLL. Хуки...   Найти похожие ветки 

 
MInd_f ©   (2007-06-21 21:19) [0]

Написал DLL. В ней нужные мне функции (пока только хук на клавиатуру - возможно корявый, но в обычной(не сервисе) программе работает коряво, но планирую еще несколько функций) Вроде все сделал правильно, сервис работает. И вроде функции из DLL все же вызываются, но хук не работает. Не понимаю.
Проверял с обычной програмой - работает отлично.

Сообствено вопросы:
1. Может есть какие-нить особенности в реалезации на сервисе?
2. Обязательно ли в DLL так называемы EntryPoint? И без него работает.
3. Ниже код DLL и сервиса.. если есть какие-нить очевидные ошибки или просто замечания укажыте пожалуста


===============DLL=============
library SpyDll;

uses
 SysUtils,Messages,Windows;

var
 HookHandle: hHook;
 MainProg: HWND;

function KeyboardProc(code: integer; wParam: word; lParam: longint): longint; stdcall;
var
 AppWnd: HWND;
 //Buf: array [0..254] of Char;
 //kbState: TKeyboardState;
begin
 if code < 0 then
 begin
   CallNextHookEx(HookHandle, Code, wParam, lParam);
   Result:=0;
   Exit;
 end;
 if (((lParam and KF_UP)=0) and (wParam>=65) and (wParam<=90)) OR
     (((lParam and KF_UP)=0) and (wParam=VK_SPACE)) then
  begin
    AppWnd:=GetForegroundWindow();
    GetKeyboardState(kbState);
    //ToUnicode(wParam,lParam,kbState,@Buf,255, 0);
    MessageBox(0, PChar("In "+ IntToStr(AppWnd) +"  wParam = " + intToStr(wParam) + ", lparam = " +  intToStr(wParam)+ "   =   " + Buf), "Message from SpyDll.dll", MB_OK+MB_SERVICE_NOTIFICATION);
  end;
 Result:=CallNextHookEx(HookHandle, Code, wParam, lParam);
end;

procedure Set_Hook(MainProg:HWND); export; stdcall;
begin
 SpyDll.MainProg:=MainProg;
 //MessageBox(0, "Hook instaled.", "Message from SpyDll.dll", MB_OK+MB_SERVICE_NOTIFICATION);
 HookHandle:=SetWindowsHookEx(WH_KEYBOARD, @KeyboardProc, HInstance, 0);
end;

procedure Del_Hook; export; stdcall;
begin
 //MessageBox(0, "Hook deleted.", "Message from SpyDll.dll", MB_OK);
 UnhookWindowsHookEx(HookHandle);
end;

//procedure DLLEntryPoint(dwReason: DWord); stdcall;
//begin
//  if dwReason=DLL_PROCESS_DETACH then Del_Hook;
//end;

exports Set_Hook,Del_Hook;

{$R *.res}

begin
//DLLProc:=@DLLEntryPoint;
end.

=====================service=====================
unit mainUnit;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs;

type
 TSpyServ = class(TService)
 procedure ServiceExecute(Sender: TService);
 procedure ServiceStop(Sender: TService; var Stopped: Boolean);
 procedure ServiceStart(Sender: TService; var Started: Boolean);
 private
   { Private declarations }
 public
   function GetServiceController: TServiceController; override;
   { Public declarations }
 end;

var
 SpyServ: TSpyServ;
 logOnOffPath:String;

 procedure Set_Hook(MainProg:HWND); stdcall; external "SpyDll.dll";
 procedure Del_Hook; stdcall; external "SpyDll.dll";
 
implementation

{$R *.DFM}

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
 SpyServ.Controller(CtrlCode);
end;

function TSpyServ.GetServiceController: TServiceController;
begin
 Result := ServiceController;
end;

procedure TSpyServ.ServiceExecute(Sender: TService);
begin
 Set_Hook(ServiceThread.Handle);
 while not terminated do
   begin
   //MessageBox(0, "Service Execited", "Message from UserSpy.exe", MB_OK+MB_SERVICE_NOTIFICATION);
   ServiceThread.ProcessRequests(False);
   end;
 Del_Hook;
end;

procedure TSpyServ.ServiceStart(Sender: TService; var Started: Boolean);
 Started:=True;
end;

procedure TSpyServ.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
 Stopped:=True;
end;

end.

и еще вопрос как с помощью функции ToUnicode, перехватив сообщение перевести его в символ?

ЗЫ. Разобрался бы сам, но время поджимает. Нужна помощь.


 
MInd_f ©   (2007-06-21 21:21) [1]


> но в обычной(не сервисе) программе работает коряво

тьфу.. редактировать темы нельзя?. эхх.. в обычной проге работает норм.


 
MInd_f ©   (2007-06-21 21:21) [2]


> но в обычной(не сервисе) программе работает коряво

тьфу.. редактировать темы нельзя?. эхх.. в обычной проге работает норм.


 
Eraser ©   (2007-06-21 21:38) [3]

> [0] MInd_f ©   (21.06.07 21:19)

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


 
MInd_f ©   (2007-06-21 21:50) [4]

> Eraser ©   (21.06.07 21:38) [3]
на счет хука согласен, что не коректно, но работает ведь. зачем тогда париться с MMF? **для меня в данный момент не столько важна коректность или "правильность" - сколько работоспособность. Еще бы разобраться как виртуальный код в unicode перевести.
да и к тому же разрешить программно запись в MMF непривелегированным пользователям.. это возможно?


 
Leonid Troyanovsky ©   (2007-06-21 22:08) [5]


> Eraser ©   (21.06.07 21:38) [3]


И в-третьих, надо выяснить, откуда, собс-но, берется
клавиатурный ввод на десктопе сервиса.

--
Regards, LVT.


 
Eraser ©   (2007-06-21 22:22) [6]

> [4] MInd_f ©   (21.06.07 21:50)


> на счет хука согласен, что не коректно, но работает ведь.

очень странно, что работает.. не должен по идее )

> да и к тому же разрешить программно запись в MMF непривелегированным
> пользователям.. это возможно?

возможно даже, что с "записью" я погорячился, может хватить только чтения.

> да и к тому же разрешить программно запись в MMF непривелегированным
> пользователям.. это возможно?

примерно так
procedure OpenInputSharedData;
var
 size: integer;
 pSD: PSECURITY_DESCRIPTOR;
 sa: SECURITY_ATTRIBUTES;
begin
 try
   pSD := PSECURITY_DESCRIPTOR(LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH));
   if not InitializeSecurityDescriptor (pSD,
      SECURITY_DESCRIPTOR_REVISION) then
   begin
     LocalFree(HLOCAL(pSD));
     Exit;
   end;
   // Добавить NULL ACL к дескриптору безопасности.
   if not SetSecurityDescriptorDacl(pSD, true, nil, false) then begin
     LocalFree(HLOCAL(pSD));
     Exit;
   end;
   sa.nLength := sizeof(sa);
   sa.lpSecurityDescriptor := pSD;
   sa.bInheritHandle := true;

   size := sizeof(TGlobalInputDLLData);
   MapHandleInput := CreateFileMapping(DWord(-1),
     @sa,
     PAGE_READWRITE,
     0,
     size,
     DllInputMapFileName);
   if MapHandleInput = 0 then
     Exit;

   InputGlobalData := MapViewOfFile(MapHandleInput,
     FILE_MAP_ALL_ACCESS,
     0,
     0,
     size);
   if InputGlobalData = nil then
     Exit;
   bIsInputGlobalDataExists := true;
 except
 end;
end;

procedure CloseInputSharedData;
begin
 if bIsInputGlobalDataExists then
 begin
   UnmapViewOfFile(InputGlobalData);
   CloseHandle(MapHandleInput);
   bIsInputGlobalDataExists := false;
 end;
end;

procedure DLLEntryPoint(dwReason: DWord);
begin
 case dwReason of
   DLL_PROCESS_ATTACH:
     begin
       OpenInputSharedData;
       DefaultOvrIndex;
       OpenSharedData;
     end;
   DLL_PROCESS_DETACH:
     begin
       CloseInputSharedData;
       UnCapt;
       ClosePictureData;
       CloseSharedData;
     end;
 end;
end;

кусок из рабочего проекта, требует доработки.. лишнее/недостающее подправите ))


 
Eraser ©   (2007-06-21 22:23) [7]

> [5] Leonid Troyanovsky ©   (21.06.07 22:08)


> И в-третьих, надо выяснить, откуда, собс-но, берется
> клавиатурный ввод на десктопе сервиса.

а это еще зачем? )


 
Leonid Troyanovsky ©   (2007-06-21 22:26) [8]


> Eraser ©   (21.06.07 22:23) [7]

> > И в-третьих, надо выяснить, откуда, собс-но, берется
> > клавиатурный ввод на десктопе сервиса.
>
> а это еще зачем? )

Чтобы перехватить в зародыше :)

--
Regards, LVT.


 
MInd_f ©   (2007-06-21 22:27) [9]

> Leonid Troyanovsky ©   (21.06.07 22:08) [5]
т.е. хотите сказать, что такой хук в сервисе работать не будет? хмм...
если правильно понял, на десктопе обычного приложения клавиатурный ввод отлавливаться будет, а в службе нет..

тогда какой выход посоветуете? если с MMF, то как сообственно разрешить туда запись для сервиса?


 
MInd_f ©   (2007-06-21 22:28) [10]

> Eraser ©   (21.06.07 22:22) [6]
спасибо. буду разбираться. )


 
Eraser ©   (2007-06-21 22:30) [11]

> [8] Leonid Troyanovsky ©   (21.06.07 22:26)

так оно итак вроде будет на всех десктопах текущей терм. сессии.. только по-умолчанию доступа к MMF у обычных приложений не будет, если права просто наследовать.. или я что-то недопонял? )


 
Leonid Troyanovsky ©   (2007-06-21 22:34) [12]


> MInd_f ©   (21.06.07 22:27) [9]

> т.е. хотите сказать, что такой хук в сервисе работать не
> будет? хмм...

Это не я, а msdn: SetWindowsHookEx Function

These events are associated either with a specific thread or with all threads in the same desktop as the calling thread

--
Regards, LVT.


 
Eraser ©   (2007-06-21 22:39) [13]

> [12] Leonid Troyanovsky ©   (21.06.07 22:34)

да да да.. и точно, надо в каждом десктопе ставить.. и подзабыл уже )

> [10] MInd_f ©   (21.06.07 22:28)

тогда нужно в цикле или по таймеру проверять OpenInputDesktop, к примеру.. и если десктоп поменялся - ставить в нем хук ))


 
Leonid Troyanovsky ©   (2007-06-21 22:39) [14]


> Eraser ©   (21.06.07 22:30) [11]

> не будет, если права просто наследовать.. или я что-то недопонял?
>  )

Не знаю, что ты, а я недопонял, причем тут терм. сессии :)

--
Regards, LVT.


 
Eraser ©   (2007-06-21 22:54) [15]

> [14] Leonid Troyanovsky ©   (21.06.07 22:39)

ну в другой терм. сессии вообще хук установить нельзя из текущего приложения или сервиса..


 
Инс   (2007-06-21 23:12) [16]

Так, к сведению автора... Параметр wParam имеет тип DWord, а времена, когда он был Word давно канули в лету...


 
MInd_f ©   (2007-06-21 23:12) [17]

видимо придется обойтись без хука.. а сделать то же с помощью GetAsyncKeyState..

хотелось бы подведения итога: как сделать хук в сервисе? *хотя бы для справки, по пунктам*

и еще пример с функцией ToUnicode, если возможно.
int ToUnicode(UINT wVirtKey,
   UINT wScanCode,
   const PBYTE lpKeyState,
   LPWSTR pwszBuff,
   int cchBuff,
   UINT wFlags
);

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


 
MInd_f ©   (2007-06-21 23:13) [18]

> Инс   (21.06.07 23:12) [16]
спасибо. *буду знать.


 
Cj ©   (2007-06-22 04:37) [19]


> видимо придется обойтись без хука.. а сделать то же с помощью
> GetAsyncKeyState..


советую не этой а просто GetKeyState пользоваться, тк некоторые проги и игры у меня засекали ее испорльзование и отказывались работать, типа "Тренер запущен" или другое.

Кстати реализацию ее использования можешь посмотреть в моем компоненте, или лучше используй его самого:
http://code.progler.ru/get/439


 
MInd_f ©   (2007-06-24 13:20) [20]

тот же хук. та же DLL. **и не важно что корявый.. )

вопрос:
почему функция KeyboardProc вызываеться два раза, хотя нажатие было одно?..
как выснить что было и WM_KEYDOWN и WM_KEYUP, и тогда только обработать, а иначе вызвать следующий хук?



Страницы: 1 вся ветка

Текущий архив: 2008.01.27;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.016 c
11-1183016834
LazyBob
2007-06-28 11:47
2008.01.27
работа с несколькими формами


15-1198096562
Tirael
2007-12-19 23:36
2008.01.27
почем сбрасывается пароль


2-1198917596
Dana
2007-12-29 11:39
2008.01.27
Ограничение на ввод в строки DBGrid


15-1198089746
serega
2007-12-19 21:42
2008.01.27
Установка


2-1198659999
dumka
2007-12-26 12:06
2008.01.27
Запросы