I have a coclass which checks the registry to determine if an application is installed, but it does this poorly and doesn't find newer versions of the application. In cases where a competing application has been installed, it will try to open that one. If the competing application has been uninstalled, the program will crash. This coclass is defined in a DLL file I do not have the source code for the library, so I can't just change开发者_StackOverflow中文版 that. I have been looking into using hooking to replace the function with one that works, but it seems complicated when I look at the MSDN documentation on using SetWindowsHookEx. Can someone please provide an example of how to use SetWindowsHookEx or another method of hooking into Windows?
Thank You
EDIT: I would like to note that I accepted the answer I did because it worked for me. I could not use the other answer at the time the question was asked, but it looks like its just as good.
Here is a short example from my own codebase which shows the most basic hooking technique:
unit MethodHooker;
interface
implementation
uses
SysUtils, Windows, Classes;
procedure Patch(Address: Pointer; const NewCode; Size: Integer);
var
NumberOfBytes: DWORD;
begin
WriteProcessMemory(GetCurrentProcess, Address, @NewCode, Size, NumberOfBytes);
end;
type
PInstruction = ^TInstruction;
TInstruction = packed record
Opcode: Byte;
Offset: Integer;
end;
procedure Redirect(OldAddress, NewAddress: Pointer);
var
NewCode: TInstruction;
begin
NewCode.Opcode := $E9;//jump relative
NewCode.Offset := Integer(NewAddress)-Integer(OldAddress)-SizeOf(NewCode);
Patch(OldAddress, NewCode, SizeOf(NewCode));
end;
function GetCursorPos(var lpPoint: TPoint): BOOL; stdcall;
(* The GetCursorPos API in user32 fails if it is passed a memory address >2GB which
breaks LARGEADDRESSAWARE apps. We counter this by calling GetCursorInfo instead
which does not suffer from the same problem. *)
var
CursorInfo: TCursorInfo;
begin
CursorInfo.cbSize := SizeOf(CursorInfo);
Result := GetCursorInfo(CursorInfo);
if Result then begin
lpPoint := CursorInfo.ptScreenPos;
end else begin
lpPoint := Point(0, 0);
end;
end;
initialization
if not ModuleIsPackage then begin
if not CheckWin32Version(6, 1) then begin
//this bug was fixed in Windows 7
Redirect(@Windows.GetCursorPos, @MethodHooker.GetCursorPos);
end;
end.
For a very good detouring/hooking unit (can check for jumps and apply new offset!) I would recommend KOLdetours.pas
I use this in many projects, for example my AsmProfiler.
Btw: with detouring you get a "trampoline" so you can call the original function too!
I am the auhtor of koldetours. The license is a free for all: i.e. use as you like EVEN IN COMMERCIAL PROGRAMS. Basically it is real open source, not crippled by any licensing. Just as the code from which it is derived. It clearly states so in the header.
精彩评论