cheat-engine/Cheat Engine/exceptionhandler.pas
2019-12-19 17:49:30 +01:00

112 lines
4.3 KiB
ObjectPascal
Executable file

unit exceptionhandler;
{$mode delphi}
interface
uses
jwawindows, //I use jwawindows only for the purpose of the structure declaration of PVECTORED_EXCEPTION_HANDLER, I declare and assign AddVectoredExceptionHandler myself
windows, Classes, SysUtils;
var
exceptrsp,exceptrbp, tryBegin, tryExcept: ptrUint; //globally accessible, set each time when a thread is about to raise an exception that needs to be handled
implementation
type TAddVectoredExceptionHandler=function(FirstHandler: ULONG; VectoredHandler: PVECTORED_EXCEPTION_HANDLER): PVOID; stdcall;
type TRemoveVectoredExceptionHandler=function(VectoredHandlerHandle: PVOID): ULONG; stdcall;
type TStackWalk64=function(MachineType: DWORD; hProcess: HANDLE; hThread: HANDLE; var StackFrame: STACKFRAME64; ContextRecord: PVOID; ReadMemoryRoutine: PREAD_PROCESS_MEMORY_ROUTINE64; FunctionTableAccessRoutine: PFUNCTION_TABLE_ACCESS_ROUTINE64; GetModuleBaseRoutine: PGET_MODULE_BASE_ROUTINE64; TranslateAddress: PTRANSLATE_ADDRESS_ROUTINE64): BOOL; stdcall;
type TSymFunctionTableAccess64=function(hProcess: HANDLE; AddrBase: Int64): PVOID; stdcall;
type TSymGetModuleBase64=function(hProcess: HANDLE; qwAddr: Int64): Int64; stdcall;
type TSymInitialize=function(hProcess: HANDLE; UserSearchPath: PSTR; fInvadeProcess: BOOL): BOOL; stdcall;
var k,d: THandle;
veh: PVOID;
AddVectoredExceptionHandler: TAddVectoredExceptionHandler;
RemoveVectoredExceptionHandler: TRemoveVectoredExceptionHandler;
StackWalk64: TStackWalk64;
SymFunctionTableAccess64: TSymFunctionTableAccess64;
SymGetModuleBase64:TSymGetModuleBase64;
SymInitialize:TSymInitialize;
function MyVectoredHandler(ExceptionInfo: PEXCEPTION_POINTERS): DWORD; stdcall;
var sf: STACKFRAME64;
tempcontext: CONTEXT;
begin
//check if the exception falls within the region of the try block
(*
// else
begin
//secondary check
//do a stacktrace
tempcontext:=ExceptionInfo.ContextRecord^; //copy over the details
ZeroMemory(@sf,sizeof(sf));
sf.AddrPC.Offset:=tempcontext.{$ifdef cpu64}Rip{$else}eip{$endif};
sf.AddrPC.Mode:=AddrModeFlat;
sf.AddrFrame.Offset:=tempcontext.{$ifdef cpu64}rbp{$else}ebp{$endif};
sf.AddrFrame.Mode:=AddrModeFlat;
sf.AddrStack.Offset:=tempcontext.{$ifdef cpu64}rsp{$else}esp{$endif};
sf.AddrStack.Mode:=AddrModeFlat;
while StackWalk64(IMAGE_FILE_MACHINE_AMD64, GetCurrentProcess, GetCurrentThread, sf, @tempcontext, nil, SymFunctionTableAccess64, SymGetModuleBase64, nil) do
begin
if (sf.AddrPC.Offset>=tryBegin) and (sf.AddrPC.Offset<tryExcept) then
begin
//if so, adjust eip to go to the except block
ExceptionInfo.ContextRecord^.Rip:=tryExcept;
ExceptionInfo.ContextRecord^.rbp:=exceptrbp;
ExceptionInfo.ContextRecord^.rsp:=exceptrsp;
result:=EXCEPTION_CONTINUE_EXECUTION;
exit;
end;
sf.AddrPC.Offset:=tempcontext.Rip;
sf.AddrPC.Mode:=AddrModeFlat;
sf.AddrFrame.Offset:=tempcontext.rbp;
sf.AddrFrame.Mode:=AddrModeFlat;
sf.AddrStack.Offset:=tempcontext.rsp;
sf.AddrStack.Mode:=AddrModeFlat;
end;
result:=EXCEPTION_CONTINUE_SEARCH; //else let the other exception handlers deal with it
end; *)
end;
initialization
(*
k:=LoadLibrary('kernel32.dll');
AddVectoredExceptionHandler:=GetProcAddress(k,'AddVectoredExceptionHandler');
RemoveVectoredExceptionHandler:=GetProcAddress(k,'RemoveVectoredExceptionHandler');
d:=LoadLibrary('Dbghelp.dll');
StackWalk64:=GetProcAddress(d,'StackWalk64');
SymFunctionTableAccess64:=GetProcAddress(d,'SymFunctionTableAccess64');
SymGetModuleBase64:=GetProcAddress(d,'SymGetModuleBase64');
SymInitialize:=GetProcAddress(d,'SymInitialize');
if assigned(SymInitialize) then
if SymInitialize(GetCurrentProcess, nil, true) then
begin
beep;
end;
if assigned(AddVectoredExceptionHandler) then
veh:=AddVectoredExceptionHandler(1, @MyVectoredHandler); //1 = Be the first handler to get the exception. (Note: Even an outputdebugstring raises an exception)
*)
finalization
(* if veh<>nil then
RemoveVectoredExceptionHandler(veh);
FreeLibrary(k); //never forget to unload kernel32.dll, it might not be needed anymore.... yeah....
*)
end.