Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL ab (https://www.delphipraxis.net/125298-tastatur-maus-hook-internet-explorer-stuerzt-wegen-dll-ab.html)

blackdrake 3. Dez 2008 20:48


Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL ab
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo.

Ich habe mit Unterstützung des Forums und Tutorials einen Maus/Tastaturhook geschrieben, der Tastaturereignisse erkennt und die Maus für eine gewisse Zeit sperrt.

Ich habe jetzt ein großes Problem gefunden: Bei meinem Testsystem - Vista - stürzt Internet Explorer aufgrund der Hook-DLL ab.

Die Fehlermeldung scheint irgendetwas mit Buffer-Overrun zu tun zu haben (was bei Delphi aber unwahrscheinlich ist) und ich weiß echt nicht, woran es liegt. Weiß jemand weiter?

Zitat:

Produkt
Internet Explorer

Problem
Funktioniert nicht mehr

Datum
01.12.2008 17:52

Status
Bericht gesendet

Problemsignatur
Problemereignisame: APPCRASH
Anwendungsname: iexplore.exe
Anwendungsversion: 7.0.6001.18000
Anwendungszeitstempel: 47918f11
Fehlermodulname: atl_hooks.dll
Fehlermodulversion: 0.0.0.0
Fehlermodulzeitstempel: 2a425e19
Ausnahmecode: c0000005
Ausnahmeoffset: 00003c5e
Betriebsystemversion: 6.0.6001.2.1.0.768.3
Gebietsschema-ID: 1031
Zusatzinformation 1: 6718
Zusatzinformation 2: 3fab1118733fd991e6b3f07ef0d90511
Zusatzinformation 3: 7591
Zusatzinformation 4: 18cb549cf9e0d1d27b18034a323f5b99
Die DLL:

Delphi-Quellcode:
library atl_hooks;

uses
  Windows,
  Messages;

var
  Mouse_HookHandle:   Cardinal = 0;
  Keyboard_HookHandle: Cardinal = 0;

  WM_ANYKEYPRESSED:  Cardinal = 0;
  WM_LMB_KEY_CONFIRM: Cardinal = 0;
  WM_RMB_KEY_CONFIRM: Cardinal = 0;

  TargetHandle, hMapping: Cardinal;
  pView: pointer;

const
  MappingGUID   = '{C8B1CCD2-4B00-45F1-9B96-9B82E086D473}';
  MsgTimeOut    = 10;
  RES_LMB_LOCKED = 10;
  RES_RMB_LOCKED = 11;

type
  ULONG_PTR = ^DWORD;

  PKBDLLHOOKSTRUCT = ^TKBDLLHOOKSTRUCT;
  TKBDLLHOOKSTRUCT = packed record
    vkCode     : DWORD;
    scanCode   : DWORD;
    flags      : DWORD;
    time       : DWORD;
    dwExtraInfo : ULONG_PTR;
  end;

const
  WH_KEYBOARD_LL = 13; // WINUSER.H

function KeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
  //res: Cardinal;
  KHSp: PKBDLLHOOKSTRUCT;
  KHSd: TKBDLLHOOKSTRUCT;
begin
  Result := CallNextHookEx(Keyboard_HookHandle, nCode, wParam, lParam);
  case nCode < 0 of
    TRUE: exit;
    FALSE:
      begin
        // Strg/Shift+Maustaste ist legitim für Mehrfachselektion
        if (wParam = WM_KEYDOWN) then
        begin
          KHSp := PKBDLLHOOKSTRUCT(lParam);
          KHSd := KHSp^;
          if not
              (
                ( KHSd.vkCode = 160 ) and ( KHSd.scanCode = 42 ) or // Shift Left
                ( KHSd.vkCode = 162 ) and ( KHSd.scanCode = 29 ) or // Ctrl Left
                ( KHSd.vkCode = 161 ) and ( KHSd.scanCode = 54 ) or // Shift Right
                ( KHSd.vkCode = 163 ) and ( KHSd.scanCode = 29 )    // Ctrl Right
              )
          then
            //SendMessageTimeOut(TargetHandle, WM_ANYKEYPRESSED, wParam, lParam,
            //                   SMTO_ABORTIFHUNG or SMTO_BLOCK, MsgTimeOut, res);
            SendMessage(TargetHandle, WM_ANYKEYPRESSED, wParam, lParam);
        end;
      end;
  end;
end;

function MouseHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
  res: Cardinal;
begin
  Result := CallNextHookEx(Mouse_HookHandle, nCode, wParam, lParam);
  case nCode < 0 of
    TRUE: exit;
    FALSE:
      begin
        // Handelt es sich um einen linken Mausklick?
        if (wParam = WM_LBUTTONUP)    or (wParam = WM_NCLBUTTONUP) or
           (wParam = WM_LBUTTONDOWN)  or (wParam = WM_NCLBUTTONDOWN) or
           (wParam = WM_LBUTTONDBLCLK) or (wParam = WM_NCLBUTTONDBLCLK) then
        begin
          SendMessageTimeOut(TargetHandle, WM_LMB_KEY_CONFIRM, wParam, lParam,
                             SMTO_ABORTIFHUNG or SMTO_BLOCK, MsgTimeOut, res);

          // Host-Application verweigert den Tastenklick
          if res = RES_LMB_LOCKED then
          begin
            Result := 1; // Maustaste verwerfen
          end;
        end;

        // oder um einen rechten Mausklick?
        if (wParam = WM_RBUTTONUP)    or (wParam = WM_NCRBUTTONUP) or
           (wParam = WM_RBUTTONDOWN)  or (wParam = WM_NCRBUTTONDOWN) or
           (wParam = WM_RBUTTONDBLCLK) or (wParam = WM_NCRBUTTONDBLCLK) then
        begin
          SendMessageTimeOut(TargetHandle, WM_RMB_KEY_CONFIRM, wParam, lParam,
                             SMTO_ABORTIFHUNG or SMTO_BLOCK, MsgTimeOut, res);

          // Host-Application verweigert den Tastenklick
          if res = RES_RMB_LOCKED then
          begin
            Result := 1; // Maustaste verwerfen
          end;
        end;
      end;
  end;
end;

function InstallHooks(Hwnd: Cardinal): Boolean; stdcall;
var
  mouseh, keybh: boolean;
begin
  keybh := false;
  mouseh := false;

  case Mouse_HookHandle of
    0: begin
        Mouse_HookHandle := SetWindowsHookEx(WH_MOUSE, @MouseHookProc, HInstance, 0);
        mouseh := true;
      end;
  end;
  case Keyboard_HookHandle of
    0: begin
        Keyboard_HookHandle := SetWindowsHookEx(WH_KEYBOARD_LL, @KeyboardHookProc, HInstance, 0);
        keybh := true;
      end;
  end;

  Result := keybh and mouseh;
end;

function UninstallHooks: Boolean; stdcall;
var
  mouseh, keybh: boolean;
begin
  mouseh := UnhookWindowsHookEx(Mouse_HookHandle);
  keybh := UnhookWindowsHookEx(Keyboard_HookHandle);
  Mouse_HookHandle := 0;
  Keyboard_HookHandle := 0;
  Result := keybh and mouseh;
end;

exports
  InstallHooks,
  UninstallHooks;

procedure Initalisation(Reason: DWORD);
begin
  case Reason of
    DLL_PROCESS_ATTACH:
      begin
        hMapping := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, MappingGUID);
        pView := MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);

        TargetHandle := PCardinal(pView)^;
      end;
    DLL_PROCESS_DETACH:
      begin
        // Wird das auch tatsächlich aufgerufen??
        UnmapViewOfFile(pView);
        CloseHandle(hMapping);
      end;
  end;
end;

begin
  WM_ANYKEYPRESSED  := RegisterWindowMessage('WM_ANYKEYPRESSED');
  WM_LMB_KEY_CONFIRM := RegisterWindowMessage('WM_LMB_KEY_CONFIRM');
  WM_RMB_KEY_CONFIRM := RegisterWindowMessage('WM_RMB_KEY_CONFIRM');

  Initalisation(DLL_PROCESS_ATTACH); // Ist das so OK?
end.
Anbei auch das reproduzierbare Projekt.

Gruß
blackdrake

Relicted 3. Dez 2008 21:48

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Ist bei mir unter Vista x64 auch reproduzierbar der Fehler.
Liegt vielleicht daran, dass der Iexplorer in ner speziellen abgeschotteten Umgebung läuft unter Vista? Nur ne Vermutung.

Gruß
reli

blackdrake 3. Dez 2008 21:50

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Hallo. Ja, irgendwas macht IE anders, aber trotzdem darf es keinen Fehler geben. Andere Hook-DLLs funktionieren aber irgendwie. Und meine DLL macht ja nichts großartig besonderes. Deswegen vermute ich, dass ich irgendwo etwas mit dem Speicher, z.B. der Mem-Map-File unsauber gemacht habe.

Relicted 3. Dez 2008 22:17

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
kommentier mal einzelne Parts aus... Versuch mal mit nur Maushook und mit nur Keyboardhook den IE zu starten. So kannst es evtl. eingrenzen.

Gruß
reli

Apollonius 4. Dez 2008 16:00

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Prüfe mal, ob du einen gültigen Zeiger für pView erhältst. Wenn du nicht genügend Rechte hast, sollte bereits hMapping ungültig sein und MapViewOfFile gibt nil zurück.

Deine Prozedur wird übrigens nicht aufgerufen, wenn die DLL beendet wird. Dazu musst du die globale Variable DllProc setzen.

Sir Rufo 4. Dez 2008 17:02

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
bzgl.
Zitat:

Zitat von blackdrake
Delphi-Quellcode:
begin
  ...
  Initalisation(DLL_PROCESS_ATTACH); // Ist das so OK?
end.

schau mal hier Controling DLL loading

und ob eine bestimmter Teil in einer DLL auch ausgeführt wird, das bekommt man am einfachsten raus, wenn man in dem Teil eine Ausgabe in einer Datei produziert (Log-Datei). Wenn da, dann war die DLL auch da :)

cu

Oliver

blackdrake 4. Dez 2008 20:27

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Hallo.

Attach und Detach werden nun ausgeführt, nachdem ich DLLProc gesetzt habe.

Seitdem ich auf pView <> nil prüfe, stürzt Internet-Explorer nicht mehr ab.

Das Problem ist aber, dass pView = nil wird. Das ist jetzt natürlich ziemlich problematisch und auch das Schreiben in die Logdatei schlägt beim Aufruf von InternetExplorer mit dem RunTime Error 5 (File inaccessable) ab. Was kann ich tun?

Zusätzliche Frage: Wie ist es möglich, den DLL-Teilprozess zu terminieren, wenn pView doch mal nil werden sollte?

Der DLL-Code sieht nun so aus:

Delphi-Quellcode:
procedure Log(N: string); // debug
var
  f: TextFile;
begin
  AssignFile(f, 'c:\meinlog.txt');
  Append(f);
  WriteLn(f, N);
  CloseFile(f);
end;

procedure DllMain(Reason: DWORD);
begin
  case Reason of
    DLL_PROCESS_ATTACH:
      begin
        hMapping := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, MappingGUID);
        pView := MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);

Log('Attach');
        if pView <> nil then
          TargetHandle := PCardinal(pView)^; // ToDo: Wenn nil, sollte DLL terminiert werden
if pView = nil then
log('Fehler 1');
      end;
    DLL_PROCESS_DETACH:
      begin
Log('Detach');
        if pView <> nil then
          UnmapViewOfFile(pView);
if pView = nil then
log('Fehler 2');
        CloseHandle(hMapping);
      end;
  end;
end;

begin
  WM_ANYKEYPRESSED  := RegisterWindowMessage('WM_ANYKEYPRESSED');
  WM_LMB_KEY_CONFIRM := RegisterWindowMessage('WM_LMB_KEY_CONFIRM');
  WM_RMB_KEY_CONFIRM := RegisterWindowMessage('WM_RMB_KEY_CONFIRM');

  DllProc := @DllMain;
  DllProc(DLL_PROCESS_ATTACH);
end.
Nachtrag! Ignoriert man diesen Fehler, wird trotz des pView=nil das Tastaturereignis (WH_KEYBOARD_LL SendMessage) an die Host-Applikation (TargetHandle) weitergegeben. Das Maus-Ereignis (WH_MOUSE SendMessageTimeOut) wird aber nicht weitergegeben, die Maustaste kann also nicht durch die Host-Applikation gesperrt werden! Seltsamerweiße funktioniert das ähnliche Programm MTANWT einwandfrei mit Internet Explorer. Was ist das Geheimnis?

Gruß
blackdrake

Apollonius 4. Dez 2008 20:54

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Um die DLL in der Initialisierung abzuwürgen, reicht es, ExitCode auf einen Wert ungleich Null zu setzen.
Was du tun kannst, um das Problem zu beheben? Setze beim Erstellen des File Mappings die Rechte, sodass alle Benutzer Lesezugriff haben. Es ist übrigens auch nicht nötig, in der DLL Schreibzugriff zu verlangen.
Eine andere Frage: Warum hältst du Handle und View des Mappings so lange offen? Du kannst diese Ressourcen direkt nach dem Lesen von TargetHandle wieder freigeben. Dann brauchst du auch keine DllProc.

blackdrake 4. Dez 2008 21:07

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Hallo.

Danke für den Hinweis. Ich habe jetzt auf die DLL-Proc verzichtet und habe nun folgenden Code:

Delphi-Quellcode:
begin
  WM_ANYKEYPRESSED  := RegisterWindowMessage('WM_ANYKEYPRESSED');
  WM_LMB_KEY_CONFIRM := RegisterWindowMessage('WM_LMB_KEY_CONFIRM');
  WM_RMB_KEY_CONFIRM := RegisterWindowMessage('WM_RMB_KEY_CONFIRM');

  hMapping := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, MappingGUID);
  pView := MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);

  if pView <> nil then
  begin
    TargetHandle := PCardinal(pView)^;

    UnmapViewOfFile(pView);
    CloseHandle(hMapping);
  end
  else
  begin
    ExitCode := 1;
  end;
end.
Das mit dem Schreibzugriff verstehe ich nicht ganz.

Die Host-APP legt die MemMap an mittels FILE_MAP_WRITE und schreibt das eigene WindowHandle hinein:

Delphi-Quellcode:
hMapping := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, 4, MappingGUID);
pView := MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0);

PCardinal(pView)^ := Handle;
Die DLL öffnet die MemMap mit FILE_MAP_READ und liest das Handle.

Dann habe ich doch in der DLL keinen Fehler gemacht, oder?

Und bezüglich des Exit-Code ungleich Null: Wird die DLL dann automatisch entladen, wenn in der Initialisierung der ExitCode gesetzt wurde? Die Host-Applikation müsste dann doch trotzdem die DLL-Export-Funktion InstallHooks() aufrufen, was ja bedeutet, dass die DLL trotzdem arbeitet, obwohl ein Fehler festgestellt wurde.

PS: Internet Explorer läuft nun in eine Endlosschleife.

Gruß
blackdrake

Apollonius 4. Dez 2008 21:18

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Wenn du eine DLL mit LoadLibrary lädst und die DllProc dieser DLL false zurückgibt (in Delphi wird das in System.pas über ExitCode geregelt), gibt LoadLibrary nil zurück. Wie sich das bei Hook-Dlls verhält (bedenke, dass jede Applikation ihre eigene DLL-Instanz hat!), weiß ich nicht, ich vermute aber mal, dass Windows dort pragmatisch vorgeht und die DLL nur in diesen Prozess nicht lädt.

Bezüglich der Rechte: Ausschlaggebend sind die angegebenen Rechte bei OpenFileMapping. Du solltest dir in deinem Hauptprogramm Security Attributes erstellen, die allen Benutzern Lese-Zugriff erlaubt, und diesen dann als Parameter für CreateFileMapping angeben. Eine solche Struktur lässt sich sehr elegant mit der JWSCL erzeugen; direkt über die API ist es etwas schwieriger.

blackdrake 4. Dez 2008 21:34

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Hallo.

Zitat:

Zitat von Apollonius
Wenn du eine DLL mit LoadLibrary lädst und die DllProc dieser DLL false zurückgibt (in Delphi wird das in System.pas über ExitCode geregelt), gibt LoadLibrary nil zurück. Wie sich das bei Hook-Dlls verhält (bedenke, dass jede Applikation ihre eigene DLL-Instanz hat!), weiß ich nicht, ich vermute aber mal, dass Windows dort pragmatisch vorgeht und die DLL nur in diesen Prozess nicht lädt.

Mh, ein bisschen Problematisch.

Ich habe folgendermaßen getestet:

Delphi-Quellcode:
if FileExists('C:\ary.txt') then ExitCode := 2;
InstallHook() wird durch die Host-Applikation zu Beginn 1 Mal aufgerufen. Anschließend wird der Hook gesetzt.

Das Problem: Wird dieser ExitCode nach dem Installieren der Hooks auf 2 gesetzt (durch die Anwesenheit der Datei ary.txt als eine Art "Signal"), dann interessiert Windows die LoadLibrary=False nicht. Der Hook wird trotzdem ausgeführt. Die Tastaturereignisse gehen weiterhin an die Host-Applikation.

Möglicherweise müsste ich innerhalb der Hook-Funktion in der DLL auf ExitCode != 0 prüfen. Wäre das sinnvoll?

Zitat:

Zitat von Apollonius
Bezüglich der Rechte: Ausschlaggebend sind die angegebenen Rechte bei OpenFileMapping. Du solltest dir in deinem Hauptprogramm Security Attributes erstellen, die allen Benutzern Lese-Zugriff erlaubt, und diesen dann als Parameter für CreateFileMapping angeben. Eine solche Struktur lässt sich sehr elegant mit der JWSCL erzeugen; direkt über die API ist es etwas schwieriger.

Das hört sich ja schon wieder so kompliziert an :pale: Außerdem kann ich bei meinem Turbo Delphi keine 3rd Party VCLs direkt installieren. Gibt es keine andere Möglichkeit?

@Sir Rufo: Wie machst du das mit MTANWT? Verwendest du JWSCL oder einen anderen API-Trick?

Gruß
blackdrake

Sir Rufo 4. Dez 2008 23:04

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Ich habe auf den ganzem Krams verzichtet und prüfe in der Haupt-EXE per Timer ab, ob die DLL noch sperrt :mrgreen: das ist simpel und robust.

blackdrake 4. Dez 2008 23:06

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Genau das mache ich doch auch. Die DLL frägt die Host-App per Message, ob der Mausklick OK ist oder nicht. Wurde mir ja auch empfohlen, weil eine Prüfung innerhalb der DLL nicht ressourcenschonend ist.

Sir Rufo 4. Dez 2008 23:07

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Falsch, bei mir sperrt die DLL und die Haupt-EXE fragt nur ab, ob die DLL noch sperrt, du machst das andersherum.

Zu den Ressourcen in der DLL: Da werde ich doch wohl noch zwei Cardinal-Werte vergleichen dürfen?

Die Aussage habe ich auch nie verstanden aber auch nie dementiert :mrgreen:

blackdrake 5. Dez 2008 14:07

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Das Problem bei der DLL-Internen Prüfung war ja, dass dann Timer innerhalb der DLL bei jedem Prozess anders wären. Ich finde das mit der Host-App im Endeffekt auch viel besser.


Weiß niemand, wie ich dieses Benutzerrechte-Hubbiflubbi beheben kann? Und ist es denn dann auch möglich, dass es dann mit Internet Explorer funktioniert? Ich verstehe einfach nicht, wieso der IE verbietet, dass ein Hook auf ein MemMap-File zuzugreift.

Apollonius 5. Dez 2008 14:17

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Die JWSCL ist keine Komponentensammlung, sondern eine Bibliothek. Diese müsstest du nur in das Hauptprogramm einbinden.
Zur Frage, warum der IE den Zugriff nicht erlaubt: In Vista gibt es sogenannte Integrity Labels. Prozesse mit einem niedrigen Integrity Label dürfen nicht auf Objekte mit einem höheren Label zugreifen. Der IE hat gewöhnlich ein IL von "niedrig", um zu verhindern, dass dein ganzer Rechner kompromittiert wird, wenn der IE einem Hack zum Opfer fällt. Dies halte ich für einen sinnvollen Schutzmechanismus, den du nebenbei bemerkt sicherlich abschalten kannst.
Bei CreateFileMapping hast du für die Security Attributes nil angegeben. Das führt dazu, dass ein Standard-Security-Descriptor gesetzt wird. Dieser hat nun das IL "normal". Daher kann Code aus dem IE nicht auf das MMF-Objekt zugreifen. Um das zu verhindern, musst du manuell einen Security Descriptor mit einem IL von "niedrig" erstellen. Eben dieses Erstellen vereinfacht die JWSCL erheblich, indem sie Security Descriptors als Objektinstanzen kapselt. Einen Blog zur JWSCL inklusive Downloadlink findest du hier.

Sir Rufo 5. Dez 2008 14:56

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Zitat:

Zitat von blackdrake
Das Problem bei der DLL-Internen Prüfung war ja, dass dann Timer innerhalb der DLL bei jedem Prozess anders wären. Ich finde das mit der Host-App im Endeffekt auch viel besser.

Wenn man Timer benutzt, dann mag das wohl stimmen, aber wer braucht dafür schon einen Timer :mrgreen:

blackdrake 5. Dez 2008 16:10

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Hallo

Apollonius, vielen Dank für die Ausführliche Beschreibung.

Ich habe nun versucht, JWSCL und JWAPI (was auch benötigt wird) einzubinden. Nachdem ich alle Pfade hingebogen habe, erhalte ich

[Pascal Fehler] JwsclToken.pas(4311): E2010 Inkompatible Typen: 'JwaWinNT.PSid' und 'JwsclSid.PSid'

Ich hoffe, dass meine EXE später noch auf eine CD passt, denn es scheint mir, als ob er versucht, alle 680 PAS Dateien einzubinden :lol:

Apollonius 5. Dez 2008 16:16

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Bist du dieser Anleitung gefolgt? Der Fehler sieht so aus, als versuchest du, Einzelunits und JwaWindows gleichzeitig zu nutzen.

blackdrake 5. Dez 2008 16:31

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Ich komm mir langsam wie ein DAU vor...

Mein Suchpfad ist gesetzt auf:

jedi_api22a_jwscl092a\jwapi2.2a\Win32API;
jedi_api22a_jwscl092a\jwapi2.2a\Common;
jedi_api22a_jwscl092a\jwscl0.9.2a\source

Und im Projekt habe ich wie in dem einen Example-Code folgende Units eingebunden:

Delphi-Quellcode:
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ComCtrls, XPMan, Registry, ComObj, ShlObj,
  ActiveX, Menus, ImgList,

  JwaVista,
  jwaWindows,
  JwsclSecureObjects,
  JwsclDescriptor,
  JwsclMapping,
  JwsclAcl,
  JwsclTypes;
Und die Fehlermeldung kommt wieder.

Dabei habe ich die JWAPI vor der JWSCL deklariert.

Und im Blog steht ja nur "when you set JWAPI up, then just ..." - wie denn aufsetzen? Gibt es denn kein gescheites Schritt-für-Schritt Tutorial?

Apollonius 5. Dez 2008 16:40

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Ich gebe zu, dass das Setup nicht ganz trivial ist. Ich hatte damit auch schon Probleme. Du musst die zweite Variante wählen, die hier erwähnt wird. Dazu suchst du dir zuerst das Package, dass du verwenden willst (bei mir immer Dynamic Debug) und kompilierst es. In deinen Suchpfad kommt dann der Bin-Ordner des Packages. Nicht in den Suchpfad gehören Win32API und Common! Wenn du so die JWA-Header installiert hast, sollte es bei der JWSCL keine Probleme mehr geben.

blackdrake 5. Dez 2008 17:10

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Hallo.

Danke für den Hinweis. Jetzt hat es funktioniert. Der Suchpfad ist:

jedi_api22a_jwscl092a\jwapi2.2a\Packages\bds10\bin \release\static;
jedi_api22a_jwscl092a\jwscl0.9.2a\source

Nur wie arbeite ich jetzt mit einem Security-Descriptor und einem File-Mapping?

Delphi-Quellcode:
  SD: TJwSecurityDescriptor;
  AC: TJwSAccessControlList;
begin
  SD := TJwSecurityDescriptor.Create;
  //AC.
  SD.SACL := AC;

  hMapping := CreateFileMapping(INVALID_HANDLE_VALUE, SD, PAGE_READWRITE, 0, 4,
                                MappingGUID);
  pView := MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0);
Aus dem Example-Projekt konnte ich nicht wirklich etwas rauslesen. Auch habe ich nicht gesehen, wie jetzt ein Dateirecht auf Alle-Lesen gesetzt wurde.

Auserdem verstehe ich nicht den Zusammenhang zwischen dem Security-Descriptor und dem Integrity-Level, das ich auf "niedrig" setzen möchte.

Gruß
blackdrake

Apollonius 5. Dez 2008 23:22

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Security Descriptors sind nicht mein Spezialgebiet (speziell die Vista-spezifischen Integrity Labels), aber ich versuche trotzdem, deine Fragen nach besten Wissen zu beantworten.
Zitat:

Auserdem verstehe ich nicht den Zusammenhang zwischen dem Security-Descriptor und dem Integrity-Level, das ich auf "niedrig" setzen möchte.
In einem Security Descriptor sind ALLE sicherheitsrelevanten Einstellungen verzeichnet, also u.A. der Besitzer, die Discretionary Access Control List und eben auch das Integrity Label.

Vereinfacht könnte dein Code auf einem vor-Vista-System so aussehen:
Delphi-Quellcode:
var Attrs: PSecurityAttributes;
    Desc: TJwSecurityDescriptor;
begin
  Desc := TJwSecurityDescriptor.Create;
  try
{Verleiht allen Benutzern alle Rechte - also auch Schreibrechte! Wenn du sie auf Lesezugriff beschränken willst, musst du die DACL bis auf einen Eintrag lehren, der allen Benutzern Lesezugriff verleiht.}
    Desc.DACL := nil;

    Attrs := Desc.Create_SA; //API-Struktur erstellen
    try
      hMapping := CreateFileMapping(..., Attrs, ...);
    finally
      TJwSecurityDescriptor.Free_SA(Attrs);
    end;
  finally
    Desc.Free;
  end;
end;
Um zusätzlich das Integrity Label zu setzen, musst du die SACL ändern. Das geht über die Methode TJwSAccessControlList.SetMandatoryLabel.

blackdrake 6. Dez 2008 00:09

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Hallo.

Vielen Dank für deine Antwort. Leider blicke ich immer noch nicht durch. Die Dokumentation von Delphi hilft mir leider auch nicht weiter.

Ich habe bei deinem Code noch ein @ hinzufügen müssen. Ich bekomme jetzt aber noch einen Accessed-Fehler beim erstellen der MMF.

Muss das DACL überhaupt gesetzt werden, oder ist es nicht der Standard-Fall, dass alle Benutzer (=Prozesseigentümer?) Lesezugriff auf die MMF haben?

Und bezüglich des SACL: Ich hoffe, ich habe das Integrity-Label nun korrekt gesetzt. In den Examples wird nur das Auslesen erläutert. Und außerdem bin ich ein bisschen Verwirrt durch die Bezeichnung Mandatory-Label und Integrity-Label (sind das Symonyme?)...

Delphi-Quellcode:
  Attrs: PSecurityAttributes;
  Desc: TJwSecurityDescriptor;
  ACE: TJwSystemMandatoryAccessControlEntry;
begin
  Desc := TJwSecurityDescriptor.Create;
  try
    {Verleiht allen Benutzern alle Rechte - also auch Schreibrechte!
    Wenn du sie auf Lesezugriff beschränken willst, musst du die DACL bis
    auf einen Eintrag lehren, der allen Benutzern Lesezugriff verleiht.}
    Desc.DACL := nil; // braucht man das?

    ACE := TJwSystemMandatoryAccessControlEntry.Create(MandatoryLevelLow); // oder MandatoryLevelUntrusted?
    try
      Desc.SACL.SetMandatoryLabel(ACE, cfPointAtInstance);
    finally
      ACE.Free;
    end;

    Attrs := Desc.Create_SA; //API-Struktur erstellen

    try
      hMapping := CreateFileMapping(INVALID_HANDLE_VALUE, @Attrs, PAGE_READWRITE,
                                    0, 4, MappingGUID);
    finally
      TJwSecurityDescriptor.Free_SA(Attrs);
    end;
  finally
    Desc.Free;
  end;
Gruß
blackdrake

Apollonius 6. Dez 2008 11:23

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Ich bin mir ziemlich sicher, dass das @ falsch ist. Ich erinnere mich aber auch daran, dass ich dort einen Cast durchführen musste, weil es zwei verschiedene SecurityAttributes-Definitionen gab. Ich werde das noch einmal nachprüfen.

Die DACL musst du nur setzen, wenn du den Standard-Konstruktor von TJwSecurityDescriptor verwendest, da dieser die DACL so füllt, dass niemand Zugriff erhält. Wenn du hingegen CreateDefaultByToken verwendest und die Default-Parameter verwendest, kannst du vermutlich darauf verzichten.

Beim Aufruf von SetMandatoryLabel sind die Besitzverhältnisse nicht richtig. Durch cfPointAtInstance drückst du aus, dass die Instanz ACE direkt speichern soll. Durch das nachfolgende Free ziehst du ihr ihr den Eintrag unter den Füßen weg. Am besten lässt du einfach das Free weg und setzt OwnsObjects auf True (ich weiß nicht, ob das der Standard ist).

Soweit ich das weiß, sind Mandatory Label und Integrity Label tatsächlich Synonyme.

Dezipaitor 6. Dez 2008 15:19

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Zitat:

Zitat von blackdrake
Und im Blog steht ja nur "when you set JWAPI up, then just ..." - wie denn aufsetzen?

Wo steht das? Dann könnte ich es deutlicher machen.

blackdrake 7. Dez 2008 00:34

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Zitat:

Zitat von Apollonius
Ich bin mir ziemlich sicher, dass das @ falsch ist. Ich erinnere mich aber auch daran, dass ich dort einen Cast durchführen musste, weil es zwei verschiedene SecurityAttributes-Definitionen gab. Ich werde das noch einmal nachprüfen.

Irgendwie ist das alles ein bisschen unkonsistent. Es hieß, dass S... inkompatibel ist mit PS..., weswegen ich einfach den Pointer von S... genommen habe, also einfach ein @ daran gehängt. Eigentlich sollte ja der Name vor dem "P" eindeutig sein, oder? Ich habe ja lediglich einen Pointer gegeben, wo ein Pointer verlangt wurde. Das verwirrt mich irgendwie.

Zitat:

Zitat von Apollonius
Die DACL musst du nur setzen, wenn du den Standard-Konstruktor von TJwSecurityDescriptor verwendest, da dieser die DACL so füllt, dass niemand Zugriff erhält. Wenn du hingegen CreateDefaultByToken verwendest und die Default-Parameter verwendest, kannst du vermutlich darauf verzichten.

Hört sich ein bisschen kompliziert an. Ich habe mit dem "nil" ein Problem: Ich denke, dass "nil" soviel wie "leere ACL-Liste" bedeutet. Und da Windows bei Dateirechten die Regel Deny-Before-Allow verwendet, müsste eine leere Liste einen Zweifelsfall darstellen (in diesem Fall einen nicht definierten Fall 0-0), bei dem Windows sich für Deny entscheiden muss (deswegen vielleicht der Fehler "mapping file could not be accessed"?)

Zitat:

Zitat von Apollonius
Beim Aufruf von SetMandatoryLabel sind die Besitzverhältnisse nicht richtig. Durch cfPointAtInstance drückst du aus, dass die Instanz ACE direkt speichern soll. Durch das nachfolgende Free ziehst du ihr ihr den Eintrag unter den Füßen weg. Am besten lässt du einfach das Free weg und setzt OwnsObjects auf True (ich weiß nicht, ob das der Standard ist).

OK, probiere ich mal aus. Die Fehlermeldung kommt aber auch ohne Verwendung von ACE.

Zitat:

Zitat von Apollonius
Soweit ich das weiß, sind Mandatory Label und Integrity Label tatsächlich Synonyme.

Denke ich auch. Aber irgendwie scheint etwas mit deiner vorherigen Beschreibung von niedrigen Integrity-Labels falsch zu sein. Eventuell ist das Mandatory Label der Kehrwert der I-Labels. Bei den M-Labels gibt es nämlich die Stufen Untrusted..Low.....High, was ja eigentlich bedeutet, wenn ich möchte, dass meine Anwendung mit IE kommuniziert brauche ich ja eigentlich kein niedriges Label, sondern ein hohes. (Eventuell entspricht ein niedriges M-Label einenem hohem I-Level)

Dezipaitor 7. Dez 2008 10:26

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Zitat:

Zitat von blackdrake
Irgendwie ist das alles ein bisschen unkonsistent. Es hieß, dass S... inkompatibel ist mit PS..., weswegen ich einfach den Pointer von S... genommen habe, also einfach ein @ daran gehängt. Eigentlich sollte ja der Name vor dem "P" eindeutig sein, oder? Ich habe ja lediglich einen Pointer gegeben, wo ein Pointer verlangt wurde. Das verwirrt mich irgendwie.

Ich gebe ja zu, dass es verwirrend ist. Diese Definition:
Delphi-Quellcode:
  Pxxx = ^XXX;
  LPxxx = ^XXX;
wurde konsequent überall verwendet, und ist erst jetzt durch die unterschiedliche Verwendung in der JWA und JWSCL zum Problem geworden. Eigentlich sollte es dasselbe sein und deshalb habe ich es auch geändert (SVN: 0.9.2a + trunk).

Zitat:

Zitat von blackdrake
Hört sich ein bisschen kompliziert an. Ich habe mit dem "nil" ein Problem: Ich denke, dass "nil" soviel wie "leere ACL-Liste" bedeutet. Und da Windows bei Dateirechten die Regel Deny-Before-Allow verwendet, müsste eine leere Liste einen Zweifelsfall darstellen (in diesem Fall einen nicht definierten Fall 0-0), bei dem Windows sich für Deny entscheiden muss (deswegen vielleicht der Fehler "mapping file could not be accessed"?)

Denke dir einfach:
nil = garkeine DACL-Klasse und damit Vollzugriff für jeden
leere DACL-Klasse und damit Verweigerung für jeden



Zitat:

Zitat von Apollonius
Soweit ich das weiß, sind Mandatory Label und Integrity Label tatsächlich Synonyme.

Das ganze Prinzip nennt man "Integrity Level".
Prozesse haben ein "Integrity Level" definiert in ihrem Token (Gruppe). Integrity Levels (=Verbindlichkeitsstufen) sind vordefinierte Benutzergruppen,
die jedoch nicht über den Benutzermanager zuweisbar sind. Hier sind die SIDs:
Delphi-Quellcode:
const JwLowIL = 'S-1-16-4096';
      JwMediumIL = 'S-1-16-8192';
      JwHighIL = 'S-1-16-12288';
      JwSystemIL = 'S-1-16-16384';
      JwProtectedProcessIL = 'S-1-16-20480';
In DACLs kommen Mandatory Labels (Verbindliche Beschriftungen) = ACE zum Einsatz, die eine Verbindlichkeitsstufen aufnehmen.

Man verwendet also eine "Verbindliche Beschriftung" TJwSystemMandatoryAccessControlEntry und definiert im Konstruktor, welche Stufe es haben soll (und noch ein Flag).
Delphi-Quellcode:
 MANDATORY_LEVEL = (
    MandatoryLevelUntrusted, {= 0}
    MandatoryLevelLow,
    MandatoryLevelMedium,
    MandatoryLevelHigh,
    MandatoryLevelSystem,
    MandatoryLevelSecureProcess, //MS vorbehalten
    MandatoryLevelCount);
Das sind die Stufen für die verbindliche Beschriftung. Daher werden sie von MS auch verbindliche Stufen genannt (nur um noch mehr Verwirrung zu stiften). Man hätte auch die Verbindlichkeitsstufen (=Gruppen) direkt als ACE einfügen und es mit dem ACE Typ "Integrity" versehen können (So macht es die JWSCL).

Die Flags (MandatoryPolicy) definieren, ob andere Objekte mit einem kleineren I.Level, das eigene Objekt schreiben, lesen und/oder ausführen können. Man setzt es, um dies zu verbieten.
Delphi-Quellcode:
type
  TJwMandatoryPolicy = (mpNoWriteUp, mpNoReadUp, mpNoExecuteUp);
  TJwMandatoryPolicyFlagSet = set of TJwMandatoryPolicy;
TJwSystemMandatoryAccessControlEntry setzt eine leere Policy Menge!

blackdrake 7. Dez 2008 20:57

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Danke für deine Antwort. Aber wie muss ich jetzt konkret vorgehen, damit ich mit IE zusammenarbeiten kann? Du schreibst ja oben auch etwas, dass Microsoft sich sogar 1 ML vorbehält. Ich blicke in der Materie einfach nicht richtig durch.

Dezipaitor 8. Dez 2008 09:48

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a
 
Erstmal solltest du die Libs aktualisieren mit den neusten Sourcen aus Subversion (SVN) und danach das Setup nochmals wiederholen.
Dann kannst du erstmal mit DACL := nil und ohne @ bei SecAttr ausprobieren, ob jeder Zugriff hat.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:49 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