Форум: "WinAPI";
Текущий архив: 2008.01.27;
Скачать: [xml.tar.bz2];
ВнизСервис. 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 вся ветка
Форум: "WinAPI";
Текущий архив: 2008.01.27;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.007 c