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

Вниз

Проблемы со снятием ловушки   Найти похожие ветки 

 
KygECHuK ©   (2006-05-10 09:22) [0]

При снятии ловушки прроиходит ошибка доступа памяти:



library W1N;

uses
 Windows,
 SySUtils,
 Messages,
 typeunit;
var
 SysHook  : HHook   = 0;
 flag     : boolean = true;
 Password : word    = 0;
 Wnd      : Hwnd    = 0;
procedure GetDLLData(var AGlobalData: pdllldata);stdcall; external "mapping.dll" name "GetDLLData";

function SysMsgProc(code : integer; wParam : word; lParam : longint) : longint; export; stdcall;
var
 lpdlldata : pdllldata;
 i         : dword;
 str       : String;
begin
 getdlldata(lpdlldata);
 Result := CallNextHookEx(SysHook, Code, wParam, lParam);
 case code of
   HCBT_CREATEWND:
   begin
     Str := TCBTCreateWnd(Pointer(lParam)^).lpcs.lpszName;
     if TCBTCreateWnd(Pointer(lParam)^).lpcs.hwndParent <> 0 then exit;
     if str = "" then exit;
     i:=0;
     while lpdlldata^.data[i] <> "" do
     begin
       if lpdlldata.data[i] = str then
       begin
         try
           result:=1;
           break
         except
         end;
       end;
       Inc(i);
     end;
   end;
 end;
end;

function SetHook(Hook : Boolean) : Boolean; export; stdcall;
begin
 Result := false;
 if Hook then
 begin
   if SysHook = 0 then
    SysHook := SetWindowsHookEx(WH_CBT{WH_CALLWNDPROC}, @SysMsgProc, HInstance, 0);
   Result := (SysHook <> 0);
 end else
 begin
   if SysHook <> 0 then
   begin
     try
       UnhookWindowsHookEx(SysHook);
       SysHook := 0;
       Result := true;
     except
                  // Ошибка выскакивает вот здесь
     end;  
   end;
 end;
end;

exports
 SETHOOK index 1;

begin
end.



 
Сергей М. ©   (2006-05-10 09:48) [1]

Переменная SysHook должна быть глобально доступна для всех экземпляров хук-библиотеки.


 
KygECHuK ©   (2006-05-10 10:07) [2]

Как это можно осуществить?


 
Сергей М. ©   (2006-05-10 10:41) [3]

см. CreateFilemapping + MapViewOfFile


 
KygECHuK ©   (2006-05-10 11:21) [4]

В моей программе уже используется библиотека с FileMapping. функция  getdlldata получает указатель на адресс расшаренной памяти. Как я понимаю в структу, которая хранится по этому адрессу мне нужно добавить поле для хранения переменной syshook и использовать её значение, всякий раз при вызове CallNextHookEx() и UnhookWindowsHookEx(). Я правильно понимаю ?


 
Сергей М. ©   (2006-05-10 11:26) [5]

Если так, то правильно.


 
KygECHuK ©   (2006-05-10 12:53) [6]

Применил - не получилось WHY ?


library W1N;

uses
 Windows,
 SySUtils,
 Messages,
 typeunit;
var
 SysHook  : HHook   = 0;
 flag     : boolean = true;
 Password : word    = 0;
 Wnd      : Hwnd    = 0;
procedure GetDLLData(var AGlobalData: pdllldata);stdcall; external "mapping.dll" name "GetDLLData";

function SysMsgProc(code : integer; wParam : word; lParam : longint) : longint; export; stdcall;
var
 lpdlldata : pdllldata;
 i         : dword;
 str       : String;
begin
 getdlldata(lpdlldata);
 Result := CallNextHookEx(lpdlldata^.SyShook, Code, wParam, lParam);
 case code of
   HCBT_CREATEWND:
   begin
     Str := TCBTCreateWnd(Pointer(lParam)^).lpcs.lpszName;
     if TCBTCreateWnd(Pointer(lParam)^).lpcs.hwndParent <> 0 then exit;
     if str = "" then exit;
     i:=0;
     while lpdlldata^.data[i] <> "" do
     begin
       if lpdlldata.data[i] = str then
       begin
         try
           result:=1;
           break
         except
         end;
       end;
       Inc(i);
     end;
   end;
 end;
end;

function SetHook(Hook : Boolean) : Boolean; export; stdcall;
var
 lpdlldata : pdllldata;
begin
 getdlldata(lpdlldata);
 Result := false;
 if Hook then
 begin
   if SysHook = 0 then
    SysHook := SetWindowsHookEx(WH_CBT{WH_CALLWNDPROC}, @SysMsgProc, HInstance, 0);
    lpdlldata^.SyShook := SysHook;
   Result := (SysHook <> 0);
 end else
 begin
   if SysHook <> 0 then
   begin
     try
       UnhookWindowsHookEx(lpdlldata^.Syshook);
       lpdlldata^.SyShook := 0;
       Result := true;
     except

     end;
   end;
 end;
end;

exports
 SETHOOK index 1;

begin
end.


 
Сергей М. ©   (2006-05-10 13:01) [7]

Значит проблема в хост-приложении, устанавливающем/снимающем этот глоб.хук


 
Dstr ©   (2006-05-10 14:08) [8]

Если вы говорите про ApiHook то кому надо стучитесь в Асю 209-298-286 и я вам все расскажу,я уже связывался давно с етой темой,и нашел Pas файлы с функциями в инете


 
Сергей М. ©   (2006-05-10 14:10) [9]


> Dstr ©   (10.05.06 14:08) [8]


Спасибо, взяли тебя "на заметку".


 
KygECHuK ©   (2006-05-10 14:21) [10]

Итак описание "Болезни":
Сама по себе ловушка снимается, что свидетельствует не выполнеие CallBack функции, но с очередью сообщений твариться что то странное.
ошибка доступа к памяти два раза подряд указывает, что происходит чтение по адрессу 000000, я предполагаю, что происходит обращение к освобождённой памяти, два раза.  

Вот кусок Хост-библиотеки :


library hookF;
.
.
.
var
 function  runstophook(Hook : Boolean) : Boolean; stdcall; external "W1N.dll" index 1
 procedure GetDLLData(var AGlobalData: pdllldata);stdcall; external "mapping.dll" name "GetDLLData";
.
.
.
procedure DefaultFunction(command: pchar; adr: Pointer; size: word; var res: pointer; var outsize: integer);stdcall;export;
.
.
.
 if command = "run hook" then
 begin
   if HookIsRunning  then
   begin
     runstr:="HOOK already runing";
   end else
   begin
     if not FileExists(DenitedList) then
     begin
       outsize := StringToResult("list is absend", res, @alloCkated);
       exit;
     end;
     init := TIniFile.Create(ReloadList);
     init.WriteString("hook", "command", "hook|run hook");
     init.Free;

     GetDLLData(lpdlldata);
     fillchar(lpdlldata^.data, sizeof(lpdlldata^.data), #0);
     AssignFile(f, DenitedList);
     Reset(f);
     i := 0;
     while not eof(f) do
     begin
       readln(f, lpdlldata^.data[i]);
       inc(i);
     end;
     CloseFile(f);
     if  i <= 0 then
     begin
       outsize := StringToResult("list is absend", res, @alloCkated);
       exit;
     end;
     if runstophook(true) then
     begin
       runstr := command + " - ok";
       HookIsRunning := true;
     end else
     begin
       runstr:="can not create hook";
     end;
   end;
   outsize := StringToResult(pchar(runstr), res, @alloCkated);
   exit;
 end;

 if command = "stop hook" then
 begin
   if HookIsRunning then
   begin
     init := TIniFile.Create(ReloadList);
     init.WriteString("hook", "command", "hook|run hook");
     init.Free;
     if runstophook(false) then
     begin
       runstr := command + " - ok";
       HookIsRunning := false;
     end;
   end else runstr:="hook is not running";
   outsize := StringToResult(pchar(runstr), res, @alloCkated);
   exit;
 end;
 outsize := StringToResult("Command not found", res, @alloCkated);
end;

exports DefaultFunction;
begin


По сути происходит лишь вызов функции runstophook() на этом прямое обращение к библитеке с ловушки исчерпывается.


 
Сергей М. ©   (2006-05-10 14:27) [11]


> Хост-библиотеки :
>


Сей термин - чушь.

"Хост" может быть лишь приложением (точнее - процессом) , но никак не библиотекой.

Ну и где код обращения хост-процесса к сей библ-ке ?


 
KygECHuK ©   (2006-05-10 14:42) [12]

>> Сей термин - чушь.
 учту, спасибо

вот хост-процесс :


.
.
TStd_Func = procedure(Command: pchar; Adr: PChar; Size:word; var Res: PChar; var OutSize:integer);stdcall;
.
.
.
procedure executer(Comm: Pchar; var Back: Pointer; var size: integer);
var
 sizeInL   : Integer;
 DllIndex  : Integer;
 lpLibrary : Pointer;
 lpCommand : Pointer;
 lpParams  : Pointer;
 DllHandle : THandle;
 ResString : String;
begin
 buff_deploy(Comm, size, lpLibrary, lpCommand, lpParams);
 DllIndex  := DllArrFinder(PChar(lpLibrary));
 if DllIndex = -1 then
 begin
   DllHandle := LoadLibrary(Pchar(pchar(lpLibrary) + ".dll"));
   if dllhandle = 0 then
   begin
     ResString := "library  "" + pchar(lpLibrary) + ""  not found";
     size := length(ResString) + 1;
     ReallocMem(Back, size);
     CopyMemory(Back, Pchar(ResString), size);
     exit;
   end;
   DllArrAdd(PChar(lpLibrary), DllHandle);
 end else
   DllHandle := DllArr[DllIndex].DllHandle;

 if pchar(lpCommand) = "FreeDll" then
 begin
   DllArrDelete(DllArrFinder(pchar(lpLibrary)));
   FreeLibrary(DllHandle);
   ResString := "Library  "" + Pchar(lpCommand) + ""  not found";
   size := length(ResString) + 1;
   ReallocMem(Back, size);
   CopyMemory(Back, Pchar(ResString), size);
   exit;
 end;

 @out_func := GetProcAddress(DllHandle, "DefaultFunction");
 if @out_func = nil then
 begin
   ResString := "function  "" + Pchar(lpCommand) + ""  not found";
   size := length(ResString) + 1;
   ReallocMem(Back, size);
   CopyMemory(Back, Pchar(ResString), size);
   exit;
 end;
 sizeInL := size - cardinal(lpParams) + cardinal(comm);
 out_func(lpCommand, lpParams, sizeInL, Pchar(back), size);
end;



 
Сергей М. ©   (2006-05-10 15:45) [13]

Хрень какая-то ..
Экзекутор какой-то ..

Ты вообще-то  в состоянии ТЗ привести ?


 
Игорь Шевченко ©   (2006-05-10 15:55) [14]


> try
>        UnhookWindowsHookEx(SysHook);
>        SysHook := 0;
>        Result := true;
>      except
>                   // Ошибка выскакивает вот здесь
>      end;  
>    


А откуда она может здесь выскакивать ? UnhookWindowsHook исключений не возбуждает, переменная SysHook всяко доступна для чтения/записи...


 
KygECHuK ©   (2006-05-10 16:26) [15]

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


 
KygECHuK ©   (2006-05-10 16:34) [16]

>> А откуда она может здесь выскакивать ? UnhookWindowsHook исключений не возбуждает, переменная SysHook всяко доступна для чтения/записи...

Ошибка возникает после удаления ловушки, а именно две ошибки доступа к памяти. Затем при вызове функции Application.ProcessMessages в любом другом приложении происходит его зависание. Что то с Message`ами не то.


 
Сергей М. ©   (2006-05-10 16:55) [17]

Удалено модератором


 
Игорь Шевченко ©   (2006-05-10 17:04) [18]

KygECHuK ©   (10.05.06 16:34) [16]


> Ошибка возникает после удаления ловушки, а именно две ошибки
> доступа к памяти


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


 
KygECHuK ©   (2006-05-10 17:13) [19]

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


 
Сергей М. ©   (2006-05-10 17:18) [20]

Галиматья.

Рассказывай как ты пользуешь отладчик ...


 
KygECHuK ©   (2006-05-10 17:25) [21]

По всякому, например:
а. Можно поставить BreakePoint - F5
b. Mожно выполнять операторы построчно F7 или F8


 
KygECHuK ©   (2006-05-10 17:48) [22]

Проверил свои знания по отладке и определился, что перва ошибка возникает при выходе из функции runstophook() в library hook. А вторая - при выходе из функции out_func() в хос- процессе; Но эти ошибки возникаю только тогда, когда я снимаю ловушку.


 
Сергей М. ©   (2006-05-11 08:32) [23]

Показывай код хост-приложения, устанавливающего/снимающего хук


 
Lamer@fools.ua ©   (2006-05-11 12:50) [24]

>function SysMsgProc(code : integer; wParam : word; lParam : longint) : longint; export; stdcall;

Кхм...


 
Сергей М. ©   (2006-05-11 13:05) [25]

"Кхм" на сабж влиять не должно


 
Игорь Шевченко ©   (2006-05-11 13:17) [26]

Lamer@fools.ua ©   (11.05.06 12:50) [24]

Архангельский рулез фарева ?


 
KygECHuK ©   (2006-05-11 14:43) [27]

я уже перенес весь функционал в одну библиотеку- не помогло

>> Показывай код хост-приложения, устанавливающего/снимающего хук

я уже показал код библитеки в [10], функция runstophook() она же SetHook() в [6]  устанавливает/снимает хук


 
Сергей М. ©   (2006-05-11 14:54) [28]


> при выходе из функции out_func() в хос- процессе


Остается загадкой, что же такое творится в out_func() ..


 
Сергей М. ©   (2006-05-11 14:58) [29]

http://www.google.ru/search?q=%D0%94%D0%B5%D0%BB%D1%84%D0%B8+%D0%B3%D0%BB%D0%BE%D0%B1%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9+%D1%85%D1%83%D0%BA&hl=ru&lr=&start=10&sa=N


 
KygECHuK ©   (2006-05-11 15:11) [30]

>> Остается загадкой, что же такое творится в out_func() ..

Она же DefaultFunction() в [10]


 
Сергей М. ©   (2006-05-11 15:56) [31]

Исключение возникает в контексте именно хост-процесса ?


 
KygECHuK ©   (2006-05-11 16:19) [32]

Ошибки доступа памяти - да.


 
Сергей М. ©   (2006-05-11 16:39) [33]

В твоем Экзекутере вызов out_func() происходит безусловно всякий раз когда этот Экзекутер вызывается тобой. Даже если перед этим по команде "FreeDll" библиотека lpLibrary была выгружена.

Как сие понимать ?


 
KygECHuK ©   (2006-05-11 16:45) [34]

В команде FreeDll есть процедура exit. А вообще, библиотек много.


 
Сергей М. ©   (2006-05-11 16:51) [35]


> exit


Угу, вижу.

Какие еще варианты содержимого lpCommand (кроме "FreeDll") подразумеваются ?


 
KygECHuK ©   (2006-05-11 17:08) [36]

lpCommand это различные комманды для разных библиотек. Набор параметров функции DefaultFunction(), стандартен для всех библиотек и разработчик может использовать любые команды в своей библиотеке. В данном случае это run hook и stop hook для установки и снятия ловушки и прочие.


 
Сергей М. ©   (2006-05-12 08:43) [37]

Все таки есть подозрение, что выгрузка хост-процессом хук-библиотеки происходит раньше чем вызов StopHook


 
KygECHuK ©   (2006-05-12 09:15) [38]

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


 
Сергей М. ©   (2006-05-12 09:39) [39]

Есть еще одно подозрение - на момент вызова UnhookWindowsHookEx(lpdlldata^.Syshook) параметр lpdlldata содержит инвалидные данные (указатель на уже несуществующую MMF-область памяти)


 
KygECHuK ©   (2006-05-12 09:52) [40]

Вполне возможно, вот код библиотеки с расшареной памятью:


library mapping;

uses
 ShareMem,
 Windows,
 typeunit;

const

 cMMFileName: PChar = "SharedMapData";

var
 GlobalData: pdllldata;
 MapHandle: THandle;

procedure GetDLLData(var AGlobalData: pdllldata); stdcall;
begin
 AGlobalData := GlobalData;
end;

procedure OpenSharedData;
var
 Size: Integer;
begin
 Size := SizeOf(TDLLData);
 MapHandle := CreateFileMapping(DWord(-1), nil, PAGE_READWRITE, 0,size,
   cMMFileName);

 GlobalData := MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, size);

 if GlobalData = nil then
 begin
   CloseHandle(MapHandle);
 end;
end;

procedure CloseSharedData;
begin
 if GlobalData <> nil then
   UnmapViewOfFile(GlobalData);
 if MapHandle <> 0 then
   CloseHandle(MapHandle);
end;

procedure DLLEntryPoint(dwReason: DWord);
begin
 case dwReason of
   DLL_PROCESS_ATTACH: OpenSharedData;
   DLL_PROCESS_DETACH: CloseSharedData;
 end;
end;

exports
 GetDLLData;

begin

 DllProc := @DLLEntryPoint;

 DLLEntryPoint(DLL_PROCESS_ATTACH);
end.



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

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

Наверх




Память: 0.59 MB
Время: 0.044 c
15-1155305525
TUser
2006-08-11 18:12
2006.09.03
Куда делся рубль,


2-1155491581
FANAT_WP
2006-08-13 21:53
2006.09.03
Как узнать что мышка перестала двигаться?


15-1154700286
AntiUser
2006-08-04 18:04
2006.09.03
Тест скорости интернет соединения.


15-1154952780
ПЛОВ
2006-08-07 16:13
2006.09.03
Проблемы с сервисом


15-1155207197
KilkennyCat
2006-08-10 14:53
2006.09.03
Будущее ковриков для мышек.