📄 jclhookexcept.pas
字号:
if Result then
with Notifiers.LockList do
try
for I := 0 to Count - 1 do
begin
O := TNotifierItem(Items[I]);
if @O.FNotifyProc = @NotifyProc then
begin
O.Free;
Items[I] := nil;
end;
end;
Pack;
finally
Notifiers.UnlockList;
end;
end;
function JclRemoveExceptNotifier(const NotifyMethod: TJclExceptNotifyMethod): Boolean;
var
O: TNotifierItem;
I: Integer;
begin
Result := Assigned(NotifyMethod);
if Result then
with Notifiers.LockList do
try
for I := 0 to Count - 1 do
begin
O := TNotifierItem(Items[I]);
if (TMethod(O.FNotifyMethod).Code = TMethod(NotifyMethod).Code) and
(TMethod(O.FNotifyMethod).Data = TMethod(NotifyMethod).Data) then
begin
O.Free;
Items[I] := nil;
end;
end;
Pack;
finally
Notifiers.UnlockList;
end;
end;
procedure JclReplaceExceptObj(NewExceptObj: Exception);
begin
Assert(Recursive);
NewResultExc := NewExceptObj;
end;
function JclHookExceptions: Boolean;
var
RaiseExceptionAddressCache: Pointer;
begin
if not ExceptionsHooked then
begin
Recursive := False;
RaiseExceptionAddressCache := RaiseExceptionAddress;
with TJclPeMapImgHooks do
Result := ReplaceImport(SystemBase, kernel32, RaiseExceptionAddressCache, @HookedRaiseException);
if Result then
begin
@Kernel32_RaiseException := RaiseExceptionAddressCache;
SysUtils_ExceptObjProc := System.ExceptObjProc;
System.ExceptObjProc := @HookedExceptObjProc;
end;
ExceptionsHooked := Result;
end
else
Result := True;
end;
function JclUnhookExceptions: Boolean;
begin
if ExceptionsHooked then
begin
with TJclPeMapImgHooks do
ReplaceImport(SystemBase, kernel32, @HookedRaiseException, @Kernel32_RaiseException);
System.ExceptObjProc := @SysUtils_ExceptObjProc;
@SysUtils_ExceptObjProc := nil;
@Kernel32_RaiseException := nil;
Result := True;
ExceptionsHooked := False;
end
else
Result := True;
end;
function JclExceptionsHooked: Boolean;
begin
Result := ExceptionsHooked;
end;
function JclHookExceptionsInModule(Module: HMODULE): Boolean;
begin
Result := ExceptionsHooked and
TJclPeMapImgHooks.ReplaceImport(Pointer(Module), kernel32, RaiseExceptionAddress, @HookedRaiseException);
end;
function JclUnkookExceptionsInModule(Module: HMODULE): Boolean;
begin
Result := ExceptionsHooked and
TJclPeMapImgHooks.ReplaceImport(Pointer(Module), kernel32, @HookedRaiseException, @Kernel32_RaiseException);
end;
// Exceptions hooking in libraries
procedure JclHookExceptDebugHookProc(Module: HMODULE; Hook: Boolean); stdcall;
begin
if Hook then
HookExceptModuleList.HookModule(Module)
else
HookExceptModuleList.UnhookModule(Module);
end;
function CallExportedHookExceptProc(Module: HMODULE; Hook: Boolean): Boolean;
var
HookExceptProcPtr: PPointer;
HookExceptProc: TJclHookExceptDebugHook;
begin
HookExceptProcPtr := TJclHookExceptModuleList.JclHookExceptDebugHookAddr;
Result := Assigned(HookExceptProcPtr);
if Result then
begin
@HookExceptProc := HookExceptProcPtr^;
if Assigned(HookExceptProc) then
HookExceptProc(Module, True);
end;
end;
function JclInitializeLibrariesHookExcept: Boolean;
begin
{$IFDEF HOOK_DLL_EXCEPTIONS}
if IsLibrary then
Result := CallExportedHookExceptProc(SystemTObjectInstance, True)
else
begin
if not Assigned(HookExceptModuleList) then
HookExceptModuleList := TJclHookExceptModuleList.Create;
Result := True;
end;
{$ELSE HOOK_DLL_EXCEPTIONS}
Result := True;
{$ENDIF HOOK_DLL_EXCEPTIONS}
end;
function JclHookedExceptModulesList(var ModulesList: TJclModuleArray): Boolean;
begin
{$IFDEF HOOK_DLL_EXCEPTIONS}
Result := Assigned(HookExceptModuleList);
if Result then
HookExceptModuleList.List(ModulesList);
{$ELSE HOOK_DLL_EXCEPTIONS}
Result := False;
{$ENDIF HOOK_DLL_EXCEPTIONS}
end;
procedure FinalizeLibrariesHookExcept;
begin
FreeAndNil(HookExceptModuleList);
if IsLibrary then
CallExportedHookExceptProc(SystemTObjectInstance, False);
end;
//=== { TJclHookExceptModuleList } ===========================================
constructor TJclHookExceptModuleList.Create;
begin
inherited Create;
FModules := TThreadList.Create;
HookStaticModules;
JclHookExceptDebugHook := @JclHookExceptDebugHookProc;
end;
destructor TJclHookExceptModuleList.Destroy;
begin
JclHookExceptDebugHook := nil;
FreeAndNil(FModules);
inherited Destroy;
end;
procedure TJclHookExceptModuleList.HookModule(Module: HMODULE);
begin
with FModules.LockList do
try
if IndexOf(Pointer(Module)) = -1 then
begin
Add(Pointer(Module));
JclHookExceptionsInModule(Module);
end;
finally
FModules.UnlockList;
end;
end;
procedure TJclHookExceptModuleList.HookStaticModules;
var
ModulesList: TStringList;
I: Integer;
Module: HMODULE;
begin
ModulesList := nil;
with FModules.LockList do
try
ModulesList := TStringList.Create;
if LoadedModulesList(ModulesList, GetCurrentProcessId, True) then
for I := 0 to ModulesList.Count - 1 do
begin
Module := HMODULE(ModulesList.Objects[I]);
if GetProcAddress(Module, JclHookExceptDebugHookName) <> nil then
HookModule(Module);
end;
finally
FModules.UnlockList;
ModulesList.Free;
end;
end;
class function TJclHookExceptModuleList.JclHookExceptDebugHookAddr: Pointer;
var
HostModule: HMODULE;
begin
HostModule := GetModuleHandle(nil);
Result := GetProcAddress(HostModule, JclHookExceptDebugHookName);
end;
procedure TJclHookExceptModuleList.List(var ModulesList: TJclModuleArray);
var
I: Integer;
begin
with FModules.LockList do
try
SetLength(ModulesList, Count);
for I := 0 to Count - 1 do
ModulesList[I] := HMODULE(Items[I]);
finally
FModules.UnlockList;
end;
end;
procedure TJclHookExceptModuleList.UnhookModule(Module: HMODULE);
begin
with FModules.LockList do
try
Remove(Pointer(Module));
finally
FModules.UnlockList;
end;
end;
initialization
Notifiers := TThreadList.Create;
finalization
{$IFDEF HOOK_DLL_EXCEPTIONS}
FinalizeLibrariesHookExcept;
{$ENDIF HOOK_DLL_EXCEPTIONS}
FreeNotifiers;
// History:
// $Log: JclHookExcept.pas,v $
// Revision 1.10 2005/02/25 07:20:15 marquardt
// add section lines
//
// Revision 1.9 2005/02/24 16:34:52 marquardt
// remove divider lines, add section lines (unfinished)
//
// Revision 1.8 2004/10/17 21:00:15 mthoma
// cleaning
//
// Revision 1.7 2004/08/02 15:30:17 marquardt
// hunting down (rom) comments
//
// Revision 1.6 2004/07/31 06:21:03 marquardt
// fixing TStringLists, adding BeginUpdate/EndUpdate, finalization improved
//
// Revision 1.5 2004/06/16 07:30:30 marquardt
// added tilde to all IFNDEF ENDIFs, inherited qualified
//
// Revision 1.4 2004/05/05 07:33:49 rrossmair
// header updated according to new policy: initial developers & contributors listed
//
// Revision 1.3 2004/04/06 04:55:17
// adapt compiler conditions, add log entry
//
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -