mahdisafsafi / ddetours Goto Github PK
View Code? Open in Web Editor NEWDelphi Detours Library
License: Mozilla Public License 2.0
Delphi Detours Library
License: Mozilla Public License 2.0
Hello!
Can you do a demo how to hook this function? I would like to hook thread
creation/termination in only my app. Is good idea for your demo. :)
Original issue reported on code.google.com by [email protected]
on 9 Jan 2015 at 11:01
` TwsRecv: function(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
function NewRecv(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
begin
Result := TwsRecv(s, Buf, len, flags);
end;
@TwsRecv := InterceptCreate(@recv, @NewRecv);`
Hi! What could be the problem?
Hello!
Maybe you can make a demo how to do this? To intercept requests, headers :)
http://web.archive.org/web/20130313164317/http://www.blackfishsoftware.com/blog/
don/passthroughapp_bho_toolbar_intercepting_requests_responses
Original issue reported on code.google.com by [email protected]
on 5 May 2014 at 3:18
MY CODE:
------
uses DDetours;
var
TrampolineGetTickCount: function: DWORD; stdcall = nil;
IsHooked: Boolean = False;
function InterceptGetTickCount: DWORD; stdcall;
begin
Result := TrampolineGetTickCount;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if not IsHooked then
begin
@TrampolineGetTickCount := InterceptCreate(GetProcAddress(LoadLibrary('kernel32.dll'), 'GetTickCount'), @InterceptGetTickCount);
IsHooked := True;
Button1.Enabled := False;
Button2.Enabled := True;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if (@TrampolineGetTickCount <> nil) and IsHooked then
begin
IsHooked := False;
InterceptRemove(@TrampolineGetTickCount);
TrampolineGetTickCount := nil;
Button1.Enabled := True;
Button2.Enabled := False;
end;
end;
------
I get Access violation error when i click Button1
Original issue reported on code.google.com by [email protected]
on 17 Aug 2014 at 4:33
Please provide any additional information below.
DDL v2 is not compatible with DXE. The issues are:
* It has a namespaced unit : "WinApi.Windows"
* It has an incorrect compiler define that wraps the unit "WinApi.TLHelp32".
Only DXE2 or better has this unit, the rest only has "TLHelp32"
* SIZE_T is not declared (DE7 has it defined as ULONG_PTR)
Original issue reported on code.google.com by [email protected]
on 3 Mar 2015 at 11:26
Fails on 32 & 64..
program Project3;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
Winapi.Windows,
Winapi.Wininet,
DDetours;
var
FHttpAddRequestHeadersW: function(hRequest: HINTERNET; lpszHeaders: LPWSTR; dwHeadersLength: DWORD; dwModifiers: DWORD): BOOL; stdcall;
function HttpAddRequestHeadersW(hRequest: HINTERNET; lpszHeaders: LPWSTR;
dwHeadersLength: DWORD; dwModifiers: DWORD): BOOL; stdcall;
begin
Result := FHttpAddRequestHeadersW(hRequest, lpszHeaders, dwHeadersLength, dwModifiers);
end;
begin
@FHttpAddRequestHeadersW := InterceptCreate('wininet.dll', 'HttpAddRequestHeadersW', @FHttpAddRequestHeadersW, tRUE); // ERROR!!
end.
{
First chance exception at $75514598. Exception class Exception with message 'Invalid InterceptProc Pointer.'. Process Project3.exe (4296)
}
Original issue reported on code.google.com by [email protected]
on 20 Jan 2015 at 11:33
Hi,
can you please add a sample to the wiki how to hook a constructor? I tried, but I'm not sure how the signature of the hook function has to look like. I came up with a working solution, but I don't know what the Foo-Parameter really should be:
function (ClassType: TClass; Foo: NativeInt; AValue: Integer): TObject;
Here is a working sample:
unit HookConstructor;
interface
implementation
uses
ddetours,
type
THookTest = class
FValue: Integer;
constructor Create(AValue: Integer); virtual;
end;
var
Trampoline: function (ClassType: TClass; Foo: NativeInt; AValue: Integer): THookTest;
function Hooked(ClassType: TClass; Foo: Integer; AValue: Integer): THookTest;
begin
Result := Trampoline(ClassType, Foo, AValue);
end;
{ THookTest }
constructor THookTest.Create(AValue: Integer);
begin
inherited Create;
FValue := AValue;
end;
initialization
Trampoline := InterceptCreate(@THookTest.Create, @Hooked);
THookTest.Create(42);
end.
Hello,
how can i hook a virtual function like TObject.AfterConstruction?
In my Little example i get an ErrorFuncSize in the call of InterceptCreate.
unit memprofile;
interface
implementation
uses
Generics.Defaults,
Generics.Collections,
DDetours;
type
TSimpleProc = procedure(Self: TObject);
var
SaveAfterConstruction: TSimpleProc = nil;
SaveBeforeDestruction: TSimpleProc = nil;
mDict: TDictionary<string, Integer>;
procedure AfterConstruction(Self: TObject);
var
cnt: Integer;
s: String;
begin
s := Self.ClassName;
if not mDict.TryGetValue(s, cnt) then
begin
cnt := 0;
end;
inc(cnt);
mDict.AddOrSetValue(s, cnt);
SaveAfterConstruction(Self);
end;
procedure BeforeDestruction(Self: TObject);
var
cnt: Integer;
s: String;
begin
s := Self.ClassName;
if not mDict.TryGetValue(s, cnt) then
begin
cnt := 0;
end;
dec(cnt);
mDict.AddOrSetValue(s, cnt);
SaveBeforeDestruction(Self);
end;
initialization
mDict := TDictionary<string, Integer>.Create;
SaveAfterConstruction := InterceptCreate(@TObject.AfterConstruction, @AfterConstruction);
SaveBeforeDestruction := InterceptCreate(@TObject.BeforeDestruction, @BeforeDestruction);
end.
The Readme.md mentions Lazarus/FPC support. Using the corresponding menu items from the Lazarus IDE, I converted the project and units of the DetoursDemo\win32api\Demo1 and tried to compile. But finally the compiler fails in CPUID.PAS: MOV EDI.TCPUIDStruct.rEAX,EAX (Error: Invalid reference syntax). How do I have to modify the code in order to compile it with Lazarus/FPC?
delphi 2009 doesn't have RTTI lib and class constructor
Crashes with
"First chance exception at $00007FFA621914B0. Exception class $C0000005 with
message 'c0000005 ACCESS_VIOLATION'. Process Project3.exe (9752)"
At 2# hook.
program HookThread;
{$APPTYPE CONSOLE}
{.$DEFINE WINDOWS_XP}
uses
System.SysUtils,
WinApi.Windows,
System.Classes,
CPUID,
DDetours,
InstDecode;
type
LPTHREAD_START_ROUTINE = function(lpThreadParameter: LPVOID): DWORD; stdcall;
TLdrShutdownThread = procedure; stdcall;
TCreateThread = function(lpThreadAttributes: Pointer; dwStackSize: SIZE_T; lpStartAddress: TFNThreadStartRoutine; lpParameter: Pointer; dwCreationFlags: DWORD; var lpThreadId: DWORD): THandle; stdcall;
var
LdrShutdownThread: TLdrShutdownThread;
CreateThreadHook: TCreateThread;
procedure LdrShutdownThreadCallback;
begin
Writeln('Shutdown Thread !');
LdrShutdownThread;
end;
function CreateThreadCallback(lpThreadAttributes: Pointer; dwStackSize: SIZE_T;
lpStartAddress: TFNThreadStartRoutine; lpParameter: Pointer; dwCreationFlags:
DWORD; var lpThreadId: DWORD): THandle; stdcall;
begin
Writeln('Thread Started !');
Result := CreateThreadHook(lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId);
end;
begin
@LdrShutdownThread := InterceptCreate('ntdll.dll', 'LdrShutdownThread', @LdrShutdownThreadCallback);
@CreateThreadHook := InterceptCreate('kernel32.dll', 'CreateThread', @CreateThreadCallback); // CRASH
TThread.CreateAnonymousThread(
procedure
begin
Sleep(1000);
end).Start;
ReadLn;
end.
Original issue reported on code.google.com by [email protected]
on 9 Jan 2015 at 10:52
Hi!
How can this be written with DDetours. Now is made with BeaEngine.
I want to intercept Assign, Construct, Destruct of records and objects.
http://www.raysoftware.cn/wp-content/uploads/2014/09/Source.zip
http://www.raysoftware.cn/?p=518
Hello,
I'm trying DDetours in one of my large applications and it fails. I nailed down the code to a very very simple test program (See attached file).
The issue is what looks like a memory corruption seen when a descriptor is removed (DDetours.pas file, TIntercept.RemoveDescriptor, lines "FreeMem(PDscr);"). This memory corruption is detected by madExcept, turning on his option "instantly crash on buffer overrun" (Or underrun by the way).
RemoveDescriptor is called by InterceptRemove which is called in my test program from the main form destructor. If I don't call InterceptRemove, then madExcept detect a memory leak for obvious reasons.
To check the issue with my sample program, you need to install madExcept which is free for non commercial use. Download setup at http://madshi.net/madCollection.exe. I have tested using Delphi 10.2 Tokyo but madExcept support a bunch of Delphi versions as well.
Regards
Francois Piette
Embarcadero MVP
What is the function that you are trying to hook ?
- FInternetSetCookieExW := InterceptCreate('wininet.dll',
'InternetSetCookieExW', @InternetSetCookieExW, True);
- FInternetGetCookieExW := InterceptCreate('wininet.dll',
'InternetGetCookieExW', @InternetGetCookieExW, True);
- FInternetSetCookie := InterceptCreate('wininet.dll', 'InternetSetCookieW',
@InternetSetCookie, True);
- FInternetGetCookie := InterceptCreate('wininet.dll', 'InternetSetCookieW',
@InternetSetCookie, True);
What is the expected output? What do you see instead?
- Function is not fired
What version of the product are you using? On what operating system? Which
architecture x86 or x64 ?
- x64
If the function hooked is not an windows API function , please include this
function .
Please provide any additional information below.
- Nothing happens on WebBrowser1.Navigate('http://www.google.com');
Original issue reported on code.google.com by [email protected]
on 18 Jan 2015 at 1:33
What is the function that you are trying to hook ?
Using Vcl.Styles.Hooks: user32.dll > GetSysColor
What is the expected output? What do you see instead?
When hook is being created: EIntOverflow.
What version of the product are you using? On what operating system? Which
architecture x86 or x64 ?
Delphi XE3, Win8, x86.
Please provide any additional information below.
The version of DDetours included in VCL Style Utils was used.
Original issue reported on code.google.com by [email protected]
on 10 Jun 2014 at 3:56
What is the function that you are trying to hook ?
Interface IInternetProtocol
What is the expected output? What do you see instead?
First chance exception at $006C0063. Exception class $C0000005 with message
'access violation at 0x006c0063: write of address 0x009f2948'. Process
Project3.exe (6552)
What version of the product are you using? On what operating system? Which
architecture x86 or x64 ?
Both
If the function hooked is not an windows API function , please include this
function .
Please provide any additional information below.
unit ComHook;
interface
uses
Winapi.Windows,
Winapi.WinInet,
ComObj,
ComServ,
ActiveX,
UrlMon,
MSHTML,
SHDocVw,
DDetours;
const
CLSID_HttpProtocol: TGUID = '{79EAC9E2-BAF9-11CE-8C82-00AA004BA90B}';
type
TInternetProtocol = record
class function Read(Self: Pointer; pv: Pointer; cb: ULONG; out cbRead: ULONG): HResult; stdcall; static;
class function Seek(Self: Pointer; dlibMove: LARGE_INTEGER; dwOrigin: DWORD; out libNewPosition: ULARGE_INTEGER): HResult; stdcall; static;
class function LockRequest(Self: Pointer; dwOptions: DWORD): HResult; stdcall; static;
class function UnlockRequest(Self: Pointer): HResult; stdcall; static;
end;
procedure Hook;
procedure UnHook;
var
FInternetProtocol: IInternetProtocol;
FRead: function(Self: Pointer; pv: Pointer; cb: ULONG; out cbRead: ULONG): HResult; stdcall;
FSeek: function(Self: Pointer; dlibMove: LARGE_INTEGER; dwOrigin: DWORD; out libNewPosition: ULARGE_INTEGER): HResult; stdcall;
FLockRequest: function(Self: Pointer; dwOptions: DWORD): HResult; stdcall;
FUnlockRequest: function(Self: Pointer): HResult; stdcall;
implementation
{ TInternetProtocol }
class function TInternetProtocol.Read(Self: Pointer; pv: Pointer; cb: ULONG;
out cbRead: ULONG): HResult; stdcall;
begin
Result := FRead(Self, pv, cb, cbRead);
end;
class function TInternetProtocol.Seek(Self: Pointer; dlibMove: LARGE_INTEGER;
dwOrigin: DWORD; out libNewPosition: ULARGE_INTEGER): HResult; stdcall;
begin
Result := FSeek(Self, dlibMove, dwOrigin, libNewPosition);
end;
class function TInternetProtocol.LockRequest(Self: Pointer; dwOptions: DWORD):
HResult; stdcall;
begin
Result := FLockRequest(Self, dwOptions);
end;
class function TInternetProtocol.UnlockRequest(Self: Pointer): HResult; stdcall;
begin
Result := FUnlockRequest(Self);
end;
procedure Hook;
begin
{ IInternetProtocol } { starts with 7 }
@FRead := InterceptCreate(FInternetProtocol, 'Read', @TInternetProtocol.Read);
@FSeek := InterceptCreate(FInternetProtocol, 'Seek', @TInternetProtocol.Seek);
@FLockRequest := InterceptCreate(FInternetProtocol, 'LockRequest', @TInternetProtocol.LockRequest);
@FUnlockRequest := InterceptCreate(FInternetProtocol, 'UnlockRequest', @TInternetProtocol.UnlockRequest);
end;
procedure UnHook;
begin
//
end;
initialization
CoCreateInstance(CLSID_HttpProtocol, nil, CLSCTX_INPROC_SERVER, IID_IInternetProtocol, FInternetProtocol);
Hook;
end.
Original issue reported on code.google.com by [email protected]
on 23 Jan 2015 at 12:24
I look through the wiki and couldn't find a way to update hook in fast way. Can
you make such a method?
Original issue reported on code.google.com by [email protected]
on 23 Jan 2015 at 7:15
This is a possibly-quite-complex feature request, but would be very useful.
The problem is this: multiple bits of code, written by several unrelated
people, want to hook the same method. (For example, CnPack hooks a method in
the IDE, and other IDE plugins also want to hook the same method in the IDE.)
Uninstalling a hook overwrites the other hooks, so this relies on everyone very
carefully installing a hook once, and uninstalling once only when the program
exits (eg their DLL is unloaded) and hoping that other affected hooks aren't
needed after that point. If anyone uninstalls (removes) a hook during normal
program execution, it removes all hooks installed by other people too.
So - is it possible to create a list of hooks, and have DDetour's create and
remove methods add to a list, each one of which is called by DDetours? That
way many hooks can co-exist.
I would suggest:
- for each item (hook) in the list, being able to add a "before calling the trampoline" event, which can cancel calling the original
- then call the original if it was not canceled
- then for each item (hook) in the list, add a "after calling the trampoline" event, which is given the trampoline's result if it was a function
I know this would be complicated to implement, and not used very often. But it
is a cool idea, and in the cases where it is used, it would be very useful.
Original issue reported on code.google.com by [email protected]
on 16 Aug 2014 at 11:34
Is there any example to hook a generic class 's (for example: TList) method?
hi mahdi
can u make a remote hook ?? generate asm op to hook a remote function in other process
hook go to shellcode for example and return to org address
Hello!
Can you make a simple demo how to patch RTL functions? Such as Move or
functions related to string operations etc.
Original issue reported on code.google.com by [email protected]
on 8 May 2014 at 3:36
I want to hook WMActivate.
This code assumes which the PShort type is defined in versions greater than
Delphi 2009.
{{{
{$IF CompilerVersion <20}
type
PUInt64 = ^UInt64;
PShort = ^SHORT;
{$IFEND}
}}}
but is not, as workaround the type must be defined always, or just use the
PSmallInt , because the SHORT type is an alias for SmallInt.
Original issue reported on code.google.com by [email protected]
on 21 Apr 2014 at 3:51
Is possible to use method of object as intercepted procedure?
Something like this:
var
TrampolineSetTextBuf: procedure(const Self; Buffer: PChar) = nil;
TMyClass = class
mprocedure SetTextBufHooked(const Self; Buffer: PChar);
end;
procedure TMyClass.SetTextBufHooked(const Self; Buffer: PChar);
var
S: String;
begin
S := 'Hooked _' + String(Buffer);
TrampolineSetTextBuf(Self, PChar(S)); // Call the original function .
end;
@TrampolineSetTextBuf := InterceptCreate(@TControl.SetTextBuf, @TMyClass.SetTextBufHooked);
When I try this then I get AV.
Unfortunately the promised compatibility with Delphi 7 is not given.
I guess, there are no plans to assure them, right?
Cheers,
Klaus
Hello!
Can you show how to hook WinINet in Delphi? I would like to monitor TWebbrowser
control requests.
Original issue reported on code.google.com by [email protected]
on 15 Jan 2015 at 3:37
What is the function that you are trying to use?
- InterceptRemove, to remove a hook
What is the expected output? What do you see instead?
- Expected: InterceptRemove returns True
- Observed: InterceptRemove returns False
Please provide any additional information below.
The bug is in the call to VirtualFree. It is called passing the size of the
trampoline (eg, 42 bytes.) However, according to MSDN's VirtualFree
documentation:
"dwSize ... If the dwFreeType parameter is MEM_RELEASE, this parameter must be
0 (zero)."
I can verify that if I change the DDetours code to pass a size of 0, instead of
the TrampolineSize variable, VirtualFree succeeds.
Please note this issue was found by vitalyg2 of CnPack, not by me - see
https://github.com/cnpack/cnwizards/pull/3 (a pull request from me to integrate
DDetours into CnPack - halfway down you can see discussion about this method
failing.) However I have tested and can verify the problem and found the
solution.
Original issue reported on code.google.com by [email protected]
on 16 Aug 2014 at 11:03
8 byte instruction 66 0f af 1d 77 00 00 00 (imul bx,WORD PTR ds:0x77) is decoded as 3 bytes length.
Same instruction without operand prefix 66 decoded corectly.
0f af 1d 77 00 00 00 (imul ebx,DWORD PTR ds:0x77) is decoded as 7 bytes length.
Hi this hook fails when injected in Explorer.exe on Windows 8.1 x64. Maybe because of trampoline size?
To test compile and inject in to Explorer.exe using ProcessHacker x64.
library Hook64;
uses
System.SysUtils,
System.Classes,
Winapi.Windows,
DDetours;
type
HINST = NativeUInt;
HMENU = type UINT_PTR;
var
_CreateWindowExW: function(
dwExStyle: DWORD;
lpClassName: LPCWSTR;
lpWindowName: LPCWSTR;
dwStyle: DWORD;
x: Integer;
y: Integer;
nWidth: Integer;
nHeight: Integer;
hWndParent: HWND;
hMenu: HMENU;
hInstance: HINST;
lpParam: LPVOID
): HWND; WINAPI = nil;
function __CreateWindowExW(
dwExStyle: DWORD;
lpClassName: LPCWSTR;
lpWindowName: LPCWSTR;
dwStyle: DWORD;
x: Integer;
y: Integer;
nWidth: Integer;
nHeight: Integer;
hWndParent: HWND;
hMenu: HMENU;
hInstance: HINST;
lpParam: LPVOID
): HWND; WINAPI;
begin
if (lpClassName = 'Worker Window') then
WriteLn('Intercepted!');
Result := _CreateWindowExW(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
end;
begin
AllocConsole;
@_CreateWindowExW := InterceptCreate(@CreateWindowExW, @__CreateWindowExW);
end.
Hello!
I see this example in the demo..
procedure TMain.BtnEnableHookClick(Sender: TObject);
begin
if not Assigned(Trampoline_FileOpenDialog_Show) then
@Trampoline_FileOpenDialog_Show := InterceptCreate(FileOpenDialog, 3, @FileOpenDialog_Show_Hook); // Index???
Trampoline_FileOpenDialog_SetTitle := InterceptCreate(FileOpenDialog, 17, @FileOpenDialog_SetTitle_Hook); // Index???
end;
But how do you get an index of the procedure/function of interface? Is there a
way to calculate this?
Thanks.
Original issue reported on code.google.com by [email protected]
on 15 Jan 2015 at 4:44
hi , can you send , help how to hook createprocess ?
I just hooked the TControl.Click, that's ok!
Click has not arguments but I want to get the name of the clicked button.
How do I get this from hooking the procedure ?
Something like:
var
TrampolineSetTextBuf: procedure(const Self) = nil;
procedure ClickWithOverride(const Self);
var
Control: TControl;
begin
Control := TControl(Self);
X.Add('The name of the button is: ' + Control.Name);
TrampolineSetTextBuf(Self);
end;
Small issue inside DDetours.pas calls to OpenThread() are being compared to INVALID_HANDLE_VALUE in both ResumeSuspendedThreads() and SuspendAllThreads() when it should be checked against 0 to properly test against failure.
According to MSDN docs for OpenThread
"If the function fails, the return value is NULL."
Using Embarcadero Delphi 10 I compiled the demo project DetoursDemo\win32api\Demo1. The local hook on the MessageBox API function works as expected. Can I use your library to make this interception global or to inject it into a foreign process? How?
Hi
Can you provide a simple sample how to hook keys from keyboard like arrow keys or any key?
Thank you
What is the function that you are trying to hook ?
type
TUnhookSynchronizeWakeupProc = procedure;
var
TrampoUnhookSynchronizeWakeup : TUnhookSynchronizeWakeupProc = nil;
procedure MyUnhookSynchronizeWakeup;
begin
TrampoUnhookSynchronizeWakeup; <--- this line raise AV
end;
initialization
@TrampoUnhookSynchronizeWakeup :=
InterceptCreate(@Forms.TApplication.UnhookSynchronizeWakeup,
@MyUnhookSynchronizeWakeup);
What is the expected output? What do you see instead?
I get AV.
What version of the product are you using? On what operating system? Which
architecture x86 or x64 ?
Delphi XE7, Windows 7 x64
Original issue reported on code.google.com by [email protected]
on 6 Nov 2014 at 4:45
What is the function that you are trying to hook ?
CloseHandle
What is the expected output? What do you see instead?
At function ResumeSuspendedThreads CloseHandle trumpoline function is not yet
returned, so exception is caused
What version of the product are you using? On what operating system? Which
architecture x86 or x64 ?
Both
If the function hooked is not an windows API function , please include this
function .
Here is the fix by adding the following overloaded function:
procedure InterceptCreate(const TargetProc, InterceptProc: Pointer; var
MyPointer : Pointer; Options: Byte = v1compatibility);
var
Intercept: TIntercept;
begin
Intercept := TIntercept.Create(Options);
try
MyPointer := Intercept.InstallHook(TargetProc, InterceptProc, Options);
finally
Intercept.Free;
end;
end;
Please provide any additional information below.
Original issue reported on code.google.com by [email protected]
on 26 Feb 2015 at 1:03
I want to intercept an interface, without intercepting the method behind the interface.
for example the _AddRef method.
if i intercept the IInterface, calls to IInterface.AddReff and Self.AddRef will end up in my hooked method.
var
LRef: IInterface;
LFoo: TFoo;
begin
LRef := TFoo as IInterface;
InterCeptCreate(LRef._AddRef, 1, MyMethod);
LRef._AddRef; <--endsup in my hook
LFoo._AddRef; <--endsup in my hook?
end;
is it possible to actually hook the IMT?
It is normal that can't GetLastError procedure Hooked ? (win32 api)
I'm using latest Lazarus version
// --------------------------- GetLastError
var TpGetLastError: function:DWORD; stdcall = nil;
function InGetLastError: DWORD; stdcall;
Begin
showmessage('Hooked');
Result := TpGetLastError;
end;
// GetLastError
if not Assigned(TpGetLastError) then
@TpGetLastError := InterceptCreate('Kernel32.dll', 'GetLastError', @InGetLastError , true); // ERROR!!
// @TpGetLastError := InterceptCreate(@GetLastError, @InGetLastError); // ERROR TOO!!
i got a SIGILL error in the file: DDetours.pas
function TIntercept.AddHook
NxHook := AllocMem(TrampoSize); <------ SIGILL error
Thanks for the support
Will it work on Linux?
Original issue reported on code.google.com by [email protected]
on 23 Apr 2014 at 1:30
Can you make an example how to hook local DirectX or OpenGL to get a screenshot
of control hosted in VCL application that is hidden or rendered offscreen.
Thanks!
Original issue reported on code.google.com by [email protected]
on 24 May 2014 at 9:24
Hi, first thanks to your delphi-detours-library project, it help me a lot.
I use it on the global hook , it work good and stable, but when i hook the API:
CloseHandle or NtClose , it will cause the program to crash(the target process crash).
I do not know what causes it. and can you fix this problem?
Thank you very much!
There was no error when hook 'MessageBoxA'.
But, There was problem while hook ZwQuerySystemInformation API (ntdll.dll).
I made dll and i inject dll into other target process.
Hooking was working successfully.
But , AV Error occured when target process terminating.
I mean i close taget process window.
But, there was no problem when i try to hooking MessageBoxA in the user32.dll.
Usings VCL.Styles.Hooks in a delphi application uses delphi-detours-library.
The application fails then basic MS application verifier tests.
Problematic seems to be the uninstall of hooks. This is the error:
=======================================
VERIFIER STOP 0000060C: pid 0x1550: Incorrect Size parameter for VirtualFree
(MEM_RELEASE) operation.
0000002A : Incorrect size used by the application.
00000000 : Expected correct size (0).
00000000 : Not used.
00000000 : Not used.
=======================================
Debugger stops in DDetours in InterceptRemove:
OrgProcAccess := SetMemPermission(P, Sb, PAGE_EXECUTE_READWRITE);
CopyInstruction(Q^, P^, Sb);
SetMemPermission(P, Sb, OrgProcAccess);
Result := VirtualFree(PSave, TrampolineSize, MEM_RELEASE); // +++ problematic call here +++
Steps to reproduce:
Create empty Win32 Delphi application. Add VCL.Styles.Hooks tio uses clause,
this integrates DDetours.
Add program in Application verifier and choose basic tests. start application
in Delphi debugger and watch debug breakpoint while closing the application
(break in InterceptRemove)
Best regards
Dirk
Original issue reported on code.google.com by [email protected]
on 8 Dec 2014 at 9:17
Attachments:
Hello MahdiSafsafi,
I'm tried to use DDetours to creating DLL Hook, but I received a lot of access violation when stop the hook or when try to kill the process. In additional, causes craches in taskmanager and Windows Explorer as well. Could you please have any ideia about its happened? What's wrong?
My code builds without problems: Zero Hints, Zero Warnings and Zero Errors. I'm using Delphi 10.2 (Tokyo release).
Library Hook;
{$IMAGEBASE $13140000}
{$ifdef win64}
{$LIBSUFFIX '64'}
{$else}
{$LIBSUFFIX '32'}
{$endif}
uses
SysUtils,Vcl.Dialogs,
Windows, Winapi.Messages,
DDetours; //Using MahdiSafsafi Delphi Detours Library version 2 - https://github.com/MahdiSafsafi/delphi-detours-library
const
HOOK_MEM_FILENAME = 'Hook.mem';
MAPFILESIZE = 1000;
{$R *.res}
type
old_TerminateProcess = function (hProcess: THandle;uExitCode: UINT): BOOL; Stdcall;
old_OpenProcess = function (dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle; stdcall;
var
MemFile : THandle;
Haken : HHOOK = 0;
THooking : Boolean = False;
SetPriv : Boolean = False;
StartPid : PDWORD;
fhProcess: THandle;
NextHook1: old_TerminateProcess = nil;
NextHook2: old_OpenProcess = nil;
function NewOpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle; stdcall;
begin
if startPid^ = dwProcessId then
begin
Result := NextHook2 (dwDesiredAccess, bInheritHandle, dwProcessId);
fhProcess:=Result;
exit;
end;
Result := NextHook2(dwDesiredAccess, bInheritHandle, dwProcessId);
end;
function NewTerminateProcess(hProcess: THandle;uExitCode: UINT): BOOL; Stdcall;
begin
if fhProcess = hProcess then
begin
ShowMessage('I am not allowed to close!');
Result:=True;
exit;
end;
Result:=NextHook1(hProcess,uExitCode);
end;
procedure MemShared();
begin
MemFile:=OpenFileMapping(FILE_MAP_ALL_ACCESS,False, HOOK_MEM_FILENAME);
if (MemFile = 0) then begin
MemFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, MAPFILESIZE, HOOK_MEM_FILENAME);
end;
if (MemFile <> 0) then
begin
StartPid := MapViewOfFile(MemFile,FILE_MAP_ALL_ACCESS,0,0,0);
Fillchar(StartPid, 0, MAPFILESIZE);
end;
end;
procedure UnMemShared();
begin
if (StartPid <> NIL) then
begin
UnMapViewOfFile(StartPid);
StartPid := NIL;
end;
if (MemFile > 0) then
begin
CloseHandle(MemFile);
MemFile := 0;
end;
end;
Function EnableDebugPriv(szPrivilege: LPCTSTR): BOOL;
Var
hToken : THANDLE;
sedebugnameValue: Int64;
tkp : TOKEN_PRIVILEGES;
ReturnLength : LongWord;
begin
Result:=SetPriv;
If not OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) Then
exit;
If not LookupPrivilegeValue(nil,szPrivilege,sedebugnameValue) Then
begin
CloseHandle(hToken);
exit;
end;
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Luid := sedebugnameValue;
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
If not AdjustTokenPrivileges(hToken,False,tkp,Sizeof(tkp),nil,ReturnLength) Then
begin
Closehandle(hToken);
exit;
end
else SetPriv:=True;
Result := SetPriv;
end;
procedure InitHook;
begin
if not Assigned(NextHook1) then
begin
BeginHooks();
@NextHook2 := InterceptCreate('kernel32.dll','OpenProcess',@NewOpenProcess);
@NextHook1 := InterceptCreate('kernel32.dll','TerminateProcess',@NewTerminateProcess);
EndHooks();
end;
if (Assigned(NextHook1) and Assigned(NextHook2)) then
begin
THooking:=True;
end;
end;
procedure UninitHook;
begin
if THooking then
begin
BeginHooks();
InterceptRemove(@NextHook1);
InterceptRemove(@NextHook2);
EndHooks();
FreeAndNil(NextHook1);
FreeAndNil(NextHook2);
THooking:=False;
end;
UnMemShared;
end;
function HookProc(nCode: Integer; wParam: Cardinal; lParam: Integer):Integer; Stdcall;
begin
Result := CallNextHookEx(Haken, nCode, wParam, lParam);
end;
procedure StartHook(pid: DWORD); Stdcall;
begin
StartPid^ := pid;
// Haken := SetWindowsHookEx(WH_CALLWNDPROC, @HookProc, hInstance, 0);
end;
procedure EndHook; Stdcall;
begin
if Haken <> 0 then
begin
UnhookWindowsHookEx(Haken);
end;
end;
procedure DllEntry(dwResaon: DWORD);
begin
case dwResaon of
DLL_PROCESS_ATTACH: InitHook;
DLL_PROCESS_DETACH: UninitHook;
DLL_THREAD_ATTACH:;
DLL_THREAD_DETACH:;
end;
end;
exports
StartHook, EndHook;
begin
MemShared;
EnableDebugPriv('SeDebugPrivilege');
DllProc:= @DllEntry;
DllEntry(DLL_PROCESS_ATTACH);
end.
> App to test DLL Hook
unit HTeste;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm2 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button3Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
procedure StartHook(pid: DWORD); stdcall; external 'Hook32.dll';
procedure EndHook; stdcall; external 'Hook32.dll';
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
StartHook(GetCurrentProcessId);
end;
procedure TForm2.Button2Click(Sender: TObject);
begin
EndHook;
end;
procedure TForm2.Button3Click(Sender: TObject);
begin
close;
end;
end.
Please test on Win32:
GetJmpType($7466B350, $FFE49D6A, $FFE49D38)
Is "OffsetSize=8" correct for x86?
FYI:
I altered the code of the demo project DetoursDemo\win32api\Demo1 to intercept a different function (DrawTextW). This is what I did:
var
TrampolineDrawTextW: function(hDCx: HDC; lpchText: LPCTSTR; nCount: Integer; lpRect: TRect; uFormat: UINT): Integer; stdcall = nil;
function InterceptDrawTextW(hDCx: HDC; lpchText: LPCTSTR; nCount: Integer; lpRect: TRect; uFormat: UINT): Integer; stdcall;
begin
Result := TrampolineDrawTextW(hDCx, lpchText, nCount, lpRect, uFormat);
end;
procedure TMain.BtnHookClick(Sender: TObject);
begin
if not Assigned(TrampolineDrawTextW) then
begin
@TrampolineDrawTextW := InterceptCreate(@DrawTextW, @InterceptDrawTextW);
end;
end;
procedure TMain.BtnTestMsgBoxClick(Sender: TObject);
var lpRect: TRect;
begin
lpRect := Rect((Screen.width-1) shr 1,0,Screen.width-1,Screen.height-1);
DrawTextW(GetDC(0),'Test Text', 9, lpRect, $00000900);
end;
(Works unhooked)
procedure TMain.BtnUnHookClick(Sender: TObject);
begin
if Assigned(TrampolineDrawTextW) then
begin
InterceptRemove(@TrampolineDrawTextW);
TrampolineDrawTextW := nil;
end;
This works unhooked with the desired output. After hooking, the DrawTextW function is also being called from the trampoline function, so the detour works. But then, the program aborts with a memory exception error. Is it a library error, or what's wrong?
DelphiDetours is a great library! I've been using it very happily.
One thing I thought of is that you could use it in an object-oriented way: to
install a hook/detour object, and remove the hook by freeing the object.
(Currently it's used only procedurally.) So, for example:
TMyProc = function(A : Integer): Boolean; // Use this to type-safely declare
the prototype of the method you're detouring
...
FDetour : TDetour<TMyProc>; // Using generics, now it's a detour only for this
type of method
...
FDetour := TDetour<TMyProc>.Create(@Original, @Replacement); // Installs the
detour
FDetour.Free; // Uninstalls the detour
Meanwhile, while it's installed, you can call the trampolined function like so:
FDetour.Trampoline(5); // Calls the trampoline / original
It's just a neat OO style of using the detour, and I think suits Delphi quite
well.
In fact I wrote a small wrapper unit that does exactly the above, and so if you
like it you are very welcome to add it to DDetours! I've attached it here.
Original issue reported on code.google.com by [email protected]
on 21 May 2014 at 11:02
Attachments:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.