AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Hook in Klasse einbinden...

Ein Thema von glkgereon · begonnen am 28. Aug 2005 · letzter Beitrag vom 29. Aug 2005
Antwort Antwort
Seite 2 von 2     12   
NicoDE
(Gast)

n/a Beiträge
 
#11

Re: Hook in Klasse einbinden...

  Alt 29. Aug 2005, 03:41
Zitat von glkgereon:
stimmt das alles?
Nö, nicht kopieren, sondern mitdenken
Die Funktionsprototypen aus meinem Beispiel haben nichts mit deinem Code zu tun...

Hier mal ein Beispiel für Deine Klasse:
Delphi-Quellcode:
unit KbdStats;

interface

uses
  Windows;

//////////////////////////////////////////////////////////////////////////////
// stuff

type
  PKbdLlHookStruct = ^TKbdLlHookStruct;
  TKbdLlHookStruct = record
    vkCode : DWORD;
    scanCode : DWORD;
    flags : DWORD;
    time : DWORD;
    dwExtraInfo: Cardinal; // ULONG_PTR
  end;
  TFNLowLevelKeyboardProc = function(nCode: Integer; wParam: WPARAM;
    lParam: PKbdLlHookStruct): LRESULT stdcall;
  TFNLowLevelKeyboardMethod = function(nCode: Integer; wParam: WPARAM;
    lParam: PKbdLlHookStruct): LRESULT stdcall of object;

//////////////////////////////////////////////////////////////////////////////
// TKeyboardStatistics

type
  TKeyboardStatistics = class
  private
    FHook: HHOOK;
    FActive: Boolean;
    FCounter: Integer;
    FLowLevelKeyboardProc: TFNLowLevelKeyboardProc;
    FLowLevelKeyboardMethod: TFNLowLevelKeyboardMethod;
    function LowLevelKeyboardMethod(nCode: Integer; wParam: WPARAM;
      lParam: PKbdLlHookStruct): LRESULT; stdcall;
    procedure SetActive(Active: Boolean);
  public
    constructor Create(Active: Boolean = True);
    destructor Destroy; override;
  published
    property Active: Boolean read FActive write SetActive;
    property Counter: Integer read FCounter write FCounter;
  end;

implementation

//////////////////////////////////////////////////////////////////////////////
// stuff

function MakeStdcallCallback(const Method: TMethod): Pointer;
type
  PCallbackCode = ^TCallbackCode;
  TCallbackCode = packed record
    Ops1: array [0..2] of Longword;
    Val1: Pointer;
    Ops2: array [0..1] of Longword;
    Val2: Pointer;
  end;
begin
  Result := VirtualAlloc(nil, SizeOf(TCallbackCode), MEM_COMMIT,
    PAGE_EXECUTE_READWRITE);
  if Assigned(Result) then
    try
      with PCallbackCode(Result)^ do
      begin
        Ops1[0] := $448B5050;
        Ops1[1] := $44890824;
        Ops1[2] := $058B0424;
        Val1 := Addr(Method.Data);
        Ops2[0] := $08244489;
        Ops2[1] := $25FF9058;
        Val2 := Addr(Method.Code);
      end;
    except
      VirtualFree(Result, 0, MEM_RELEASE);
      Result := nil;
    end;
end;

procedure FreeCallback(Callback: Pointer);
begin
  if Assigned(Callback) then
    VirtualFree(Callback, 0, MEM_RELEASE);
end;

//////////////////////////////////////////////////////////////////////////////
// TKeyboardStatistics

constructor TKeyboardStatistics.Create(Active: Boolean);
begin
  inherited Create;
  FHook := 0;
  FActive := False;
  FCounter := 0;
  FLowLevelKeyboardMethod := LowLevelKeyboardMethod;
  FLowLevelKeyboardProc := TFNLowLevelKeyboardProc(
    MakeStdcallCallback(TMethod(FLowLevelKeyboardMethod)));
  if not Assigned(FLowLevelKeyboardProc) then
    Fail;
  SetActive(Active);
end;

destructor TKeyboardStatistics.Destroy;
begin
  SetActive(False);
  FCounter := 0;
  if Assigned(FLowLevelKeyboardProc) then
  begin
    FreeCallback(Addr(FLowLevelKeyboardProc));
    FLowLevelKeyboardProc := nil;
  end;
  inherited;
end;

procedure TKeyboardStatistics.SetActive(Active: Boolean);
const
  WH_KEYBOARD_LL = 13;
begin
  if FActive = Active then
    Exit;
  if FHook <> 0 then
    if UnhookWindowsHookEx(FHook) then
      FHook := 0;
  if Active then
    FHook := SetWindowsHookEx(WH_KEYBOARD_LL,
      TFNHookProc(FLowLevelKeyboardProc), HInstance, 0);
  FActive := FHook <> 0;
end;

function TKeyboardStatistics.LowLevelKeyboardMethod(nCode: Integer;
  wParam: WPARAM; lParam: PKbdLlHookStruct): LRESULT;
const
  LLKHF_EXTENDED = KF_EXTENDED shr 8;
  LLKHF_INJECTED = $00000010;
  LLKHF_ALTDOWN = KF_ALTDOWN shr 8;
  LLKHF_UP = KF_UP shr 8;
begin
  if HC_ACTION = nCode then
    if Assigned(lParam) then
      if LLKHF_UP = (lParam.flags and LLKHF_UP) then
        Inc(FCounter);
  Result := CallNextHookEx(FHook, nCode, wParam, Windows.LPARAM(lParam));
end;

end.
Gruß Nico
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#12

Re: Hook in Klasse einbinden...

  Alt 29. Aug 2005, 09:31
Wunderschöne Beispiele, man kann es ja nicht nur für Hooks verwenden. Aber wo genau ist der Sinn dahinter? Ernsthafte Frage. Bei einer Callbackfunktion habe ich doch genau wie bei einer Klasse eine "Instanz" (eben der Code der aufgerufen wird), aber wo genau ist der Vorteil? Okay, Self-Pointer, aber außer bei einem lokalen Hook, wo "Hook-Server" und "Client" in einer Binärdatei untergebracht werden, bringt doch die Kapselung eines Hooks nichts. Ihr seht, die Frage geht eher in die Richtung einer Sinnfrage.

Ich weiß auch, daß man prinzipiell Fastcall-Funktionen auch in Delphi aufrufen kann, man braucht ja "nur" einen Wrapper. Aber dann geht doch der Sinn irgendwie verloren, oder?
  Mit Zitat antworten Zitat
NicoDE
(Gast)

n/a Beiträge
 
#13

Re: Hook in Klasse einbinden...

  Alt 29. Aug 2005, 09:48
Mal abgesehen von den Hooks... es gibt genug Fälle, bei denen eine 'flache' API objektorientiert verpackt werden soll.
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#14

Re: Hook in Klasse einbinden...

  Alt 29. Aug 2005, 09:53
Zitat von NicoDE:
Mal abgesehen von den Hooks... es gibt genug Fälle, bei denen eine 'flache' API objektorientiert verpackt werden soll.
Nur meistens läßt sich das ja ohne viel Aufhebens machen, weil man ja nicht oft den Pointer auf eine Callback übergeben muß. Außer beim Auflisten von Dingen und bei Hooks wüßte ich spontan nix. Und ansonsten würde man die API wie gewöhnlich aufrufen.

Aber ich nehme das mal so hin ...
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#15

Re: Hook in Klasse einbinden...

  Alt 29. Aug 2005, 12:32
falls jemand der nicht so mit assembler bewandert ist sowas auch mal machen will dem sei gesagt das es ganz einfach ist. Einfach die Procedure die später zur Laufzeit erstellt werden soll in Delphi schreiben und aufrufen. Dann einfach mal das CPU-Fenster anschauen und da steht der assembler-code.

Im Anhang befindet sich mal ein Screenshot von dem ASM-Code so einer funktion.

Diesen asm-code braucht man dann nur abtippen und in den speicher schreiben und dann aufrufen
Delphi-Quellcode:
function TForm1.CreateMemHookProc(AHookMethod: THookMethod): Pointer;
  procedure LWriteToMem(var ADest: Pointer; AToWrite, ASize: Integer);
  begin
    move(AToWrite, ADest^, ASize);
    inc(Integer(ADest), ASize);
  end;
var LMem: Pointer;
begin
  LMem := VirtualAlloc(nil, 512, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  result := LMem;
  //begin
  LWriteToMem(LMem, $55, 1);
  LWriteToMem(LMem, $EC8B, 2);
  LWriteToMem(LMem, $53, 1);
  //Hookmethode zuweisen
  LWriteToMem(LMem, $B8, 1); LWriteToMem(LMem, Integer(@AHookMethod), 4);

  LWriteToMem(LMem, $10558B, 3);
  LWriteToMem(LMem, $52, 1);
  LWriteToMem(LMem, $D88B, 2);
  LWriteToMem(LMem, $0C4D8B, 3);
  LWriteToMem(LMem, $08558B, 3);
  LWriteToMem(LMem, $B8, 1); LWriteToMem(LMem, Integer(Self), 4); //Self übergeben
  LWriteToMem(LMem, $D3FF, 2);

  //End
  LWriteToMem(LMem, $5B, 1);
  LWriteToMem(LMem, $5D, 1);
  LWriteToMem(LMem, $C2, 1); LWriteToMem(LMem, $000C, 2);
  LWriteToMem(LMem, $00408D, 3);
end;
Wobei ich zugeben muss das die paar zeilen weniger von NicoDE das ganze schöner machen.
und durch den Aufruf der obigen funktion ist die funktion dann in den speicher geschrieben.
Miniaturansicht angehängter Grafiken
cpu-asm-memproc_385.jpg  
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
NicoDE
(Gast)

n/a Beiträge
 
#16

Re: Hook in Klasse einbinden...

  Alt 29. Aug 2005, 13:03
Zitat von SirThornberry:
falls jemand der nicht so mit assembler bewandert ist sowas auch mal machen will dem sei gesagt das es ganz einfach ist.
Würde ich nicht gerade behaupten. Es ist nicht gerade trivial den Inhalt aller Register zu erhalten um den Aufruf so wenig wie möglich zu beeinflussen...
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#17

Re: Hook in Klasse einbinden...

  Alt 29. Aug 2005, 13:04
Zitat von SirThornberry:
Wobei ich zugeben muss das die paar zeilen weniger von NicoDE das ganze schöner machen.
... und generischer, oder?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:19 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz