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 Prozesse oder Anwendungen ermitteln, die eine Datei benutzen (https://www.delphipraxis.net/79705-prozesse-oder-anwendungen-ermitteln-die-eine-datei-benutzen.html)

PainInYourBrain 26. Okt 2006 18:44


Prozesse oder Anwendungen ermitteln, die eine Datei benutzen
 
schönen guten Abend,

Manchmal wenn ich versuche Dateien zu ändern oder zu löschen (... versenden, mit anderen Programmen öffnen usw usw usw...)
bekomme ich von Windows eine Meldung irgendwie "Datei kann nicht gelöscht werden, sie wird noch von einer anderen Anwendung verwendet, schließen sie diese Anwendung und versuchen sie es später nochmal ..."
(oder igendwie so sinngemäß, den Wortlaut habe ich jezt nichtmehr 100% im Kopf)

Da mich solche Probleme desöfteren mal nerven, wollte ich mal fragen ob es irgendwie möglich ist Prozesse oder Anwendungen zu ermitteln, die eine bestimmte Datei benutzen (also grade geöffnet haben).

Ich bräuchte da nur nen paar Ideen WO bzw WIE ich das auslesen kann ... (Windows muss ja auch irgendwie merken, dass die Datei verwendet wird ... ich hoffe es lässt sich da auch iregndwie rausfinden von "WEM" (hauptsächlich interessiert mich wie gesagt der Prozess oder die Anwendung (wenn das damit gleich mit möglich ist, wär' der Benutzer auch noch recht interessant) )

[vielen Dank für's lesen]
Ich bin für alle Vorschläge dankbar!

EDIT: falls hier ein Profi sein sollte, der könnte mit vllt. auchnoch ne Idee sagen, ob das möglich wär' Windows einfach zu sagen "nein die Datei wird nicht verwendet, vergess das einfach!" (dabei bin ich mir nicht ganz sicher ob das vllt. Fehler produzieren kann, denn dagegen ist diese "Markierung" ja eigendlich ...)

[naja das ist ja aber auch mehr nebensache, da man wenn man die verantwortlichen Prozesse oder Anwendungen kennt, das ja sowiso meistens beheben kann ...]

/EDIT

Luckie 26. Okt 2006 19:02

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Die Lösung ist wohl ein dateisystem-Filter-Treiber. Auf Sysinternals findest du ein Programm dass das kann. filemon oder so ähnlich.

mirage228 26. Okt 2006 19:03

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Hi,

Da gbibts das Programm Bei Google suchenWhoLockMe.
Dann hast Du einen neuen Kontextmenü-Eintrag im Explorer, mit du prüfen kannst, welche Programm die angegebene Datei komplett sperren.

mfG
mirage228

PainInYourBrain 26. Okt 2006 19:18

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
vielen Dank!

Mit Filemon hatte ich auchnoch irgendwo im Hinterkopf, aber das produzierte mir immer so viele Informationen, die das dann unübersichtlich gestaltet haben ...

Dieses "WhoLockMe" macht genau das, was ich mir da vorgestellt hatte :)

Zwar nicht selbst programmiert, aber ich denke das wird mir für's erste genügen.

[Eigendliche Frage beantwortet]

Flocke 26. Okt 2006 19:52

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Zitat:

Zitat von mirage228
Da gbibts das Programm Bei Google suchenWhoLockMe.

Hab' ich früher auch genommen. Danach habe ich das Programm Unlocker gefunden, das IMHO noch besser ist.

Mackhack 26. Okt 2006 21:14

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Interessant.

Weis jemand wie diese Unlock-Funktion funktioniert?

daPimP 27. Okt 2006 00:03

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
@Mackhack:

Genau die selbe Frage habe ich mir auch seit einigen Tagen gestellt.

Wie finde ich den Prozess raus.
Vielleicht kommen wir ja noch auf ne Lösung.
Zwei Köpfe sind mehr als einer 2 > 1 w.z.b.w...

Werde mal ein bisschen dem wirklich guten Tool Unlocker auf die Finger schauen, was es so macht.

:coder:

Luckie 27. Okt 2006 00:07

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Nimm dir einen Disassembler und Debugger und guck nach, was er für API-Funktionen aufruft.

daPimP 27. Okt 2006 00:37

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
@Luckie:

Schläfst du nie?

Mach ich schon.
Sitz gerad an PEiD und schmöcker ein bisschen in Unlocker.
Mal schauen wieviele Funktionen dann noch übrig bleiben... :gruebel:

Mackhack 27. Okt 2006 01:01

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Zitat:

Zitat von daPimP
@Luckie:

Schläfst du nie?

Mach ich schon.
Sitz gerad an PEiD und schmöcker ein bisschen in Unlocker.
Mal schauen wieviele Funktionen dann noch übrig bleiben... :gruebel:

Halt uns auf dem Laufenden!

daPimP 30. Okt 2006 14:40

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Habe mir mal die Funktionen von Unlocker
und auch von WhoLockme angeschaut, da beide Programme ähnlich arbeiten. (Links dazu oben)

Habe mal die Funktionen aufgelistet, die beide gemeinsam haben und mir entweder so nichts sagen
oder die speziell mit dem Problem: Welcher Prozess blockt die Datei?, zu tun haben.

Das sind die Parallelen, die BEIDE Programme haben und wohl am Auslesen beteiligt sind.
Delphi-Quellcode:
GetFileAttributes
GetModuleHandle
GetProcAddress
kenn ich nicht - hab ich aber auch noch nicht nachgeschlagen:

Delphi-Quellcode:
DisableThreadLibraryCalls
InterlockedIncrement
InterlockedDecrement
So, hab noch zu tun - aber vielleicht hat ja noch jemand nen Hinweis auf die weitere Bearbeitung des Problems. :wall:

Mackhack 26. Mär 2007 07:16

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Hallo,

weis eigentlich jemand genaueres wie dieses Programm funktioniert?

Zacherl 26. Mär 2007 09:17

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
GetProcAddress und GetModuleHandle kannst du rauslassen, da sie nur dazu dienen andere Funktionen zu importieren. Somit müsstest du im Debugger genau nachsehen, welche Funktionen das sind. Es können theoretisch alle APIs sein. GetFileAttributes ist denke ich auch keine der Schlüsselfunktionen.

himitsu 26. Mär 2007 09:45

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Die Interlocked-Funktionen fallen auch raus (das sind im Grunde nur die threadsicheren versionen von Inc und Dec)
und DisableThreadLibraryCalls hat nichts Dateien zu tun.

Bleibt dir also wirklich nur mitzuverfolgen welche Funktionen/Prozeduren von GetProcAddress importiert werden.

EgoFelix 29. Mär 2007 20:12

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Hab da was gefunden, was euch vielleicht etwas weiterbringen kann.
Vielleicht setz ich mich auch mal dran ;)

http://www.codeguru.com/Cpp/W-P/file...cle.php/c1287/

Jetzt müsstet ihr noch die Funktion raussuchen, welche die Handles eines Programmes anzeigen kann. Dann könntet ihr diese auch Schliessen.

Kleine Anmerkung:
Wenn ihr es macht, dass ihr die Handles bekommt, dann könnt ihr auch direkt über das Handle die Datei auslesen!

MfG

Felix ;)

Christian Seehase 29. Mär 2007 20:49

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Moin Felix,

erst einmal herzlich willkommen hier in der Delphi-PRAXiS.

Nur mal interessehalber:
Hast Du den Codeabschnitt auf den Dein Link verweist mal unter Vista ausprobiert?
Da dort die Startadressen der DLLs nicht mehr immer an der gleichen Stelle liegen sollen, dürfte es dort eigentlich nicht mehr funktionieren, da sich dadurch ja die Startadresse der Kernel32.dll, und somit auch die der enthaltenen Funktionen verschieben, womit dann die Adresse von CloseHandle im eigenen Prozess eine andere ist als die im Remote-Prozess.

Olli 30. Mär 2007 00:31

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Ich bin sicher sowohl andere Treiber als auch andere Prozesse werden es wirklich schätzen, wenn ihnen der Boden (lies: Handle) unter den Füssen weggezogen wird. Weiter so :roll:

Interessanter sind übrigens die Funktionen welche sie nicht gemeinsam haben :zwinker:

daPimP 11. Apr 2007 00:28

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Zitat:

Interessanter sind übrigens die Funktionen welche sie nicht gemeinsam haben
@OLLI: Verstehe deine Anspielung nicht ganz...

Im übrigen ist der Link doch wirklich hilfreich.
Da ich selbst wenig mit C zu tun habe, bin ich nicht in der Lage ihn 1:1 zu übersetzen.

Ich brauche eigentlich nur eine Liste ALLER Dateien (nicht nur die Module...)
vom Prozess XY, die momentan verwendet werden.




Wie gehts weiter?
Ich hab alle PIDs und TIDs und alle Rechte und mir reicht wenn es auf XP läuft.

daPimP 17. Mai 2007 02:21

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Da mir das Thema nicht aus dem Kopf geht, werde ich in geraumer Zeit einige Fortschritte hier posten,
hoffe das wir der Lsg dann Näher kommen.

Ich halte nochmal fest:

ZIEL: eine X-beliebige Datei (nicht nur dll, exe) soll überprüft werden, von welchem Prozess
sie gerade benutzt wird.



AUFGABE: Ermitteln des HANDLE der Datei (und ich rede hier nicht von den Fensterhandles)

Verwirklicht wurde das schon im Programm Unlocker und im C++ SourceCode codeguru.com

Desweiteren ist das bloße Anzeigen des speziellen Handles definiv ONHE Treiberdatei möglich.
(im Gegensatz zu Unlocker)

Es reicht wenn es unter XP läuft.

FORTSCHRITT:
meine Delphi Übersetzung:

Hier soll ein Prozess per PID überprüft werden, und ALLE seine Handleverknüpfungen angezeigt werden.
Ich bekomme auch eine Zahl, die im Bereich der Handles liegt zurück, kann sie aber nicht zuordnen.

Delphi-Quellcode:
(*
Note: 1. SE_DEBUG privilege must be enabled.                  OK
      2. The function works with every kind of HANDLE
      3. It will bother the remote process :)
      4. The handles will be invalid after you closed         OK
         them remotely
*)

function CloseRemoteHandle(processID: DWORD; lpparameter: pointer ):DWORD;
var
  ht :THANDLE;
  rc : DWORD;
  hProcess: THandle;
  hKernel32: cardinal;
begin
 TRY
 lpparameter:= nil;
   ht:=0;
   rc:=0;
   // open the process
   HPROcESS:= OpenProcess(PROCESS_CREATE_THREAD
                                or PROCESS_VM_OPERATION
                                or PROCESS_VM_WRITE
                                or PROCESS_VM_READ, FALSE, processID);
   if hProcess = 0 then
     showmessage('hprocess ist null'); //tritt nicht ein

   // load kernel32.dll
   hKernel32 := LoadLibrary('kernel32.dll');

   // CreateRemoteThread()
   ht := CreateRemoteThread(
   hProcess,
   0,
   0,
   GetProcAddress(hKernel32, 'CloseHandle'),
   lpparameter,       //////was mach ich hiermit?????
   0,
   rc );

    if ht =0 then begin
     rc := GetLastError();
     showmessage('ht ist null');              //tritt nicht ein
   end;

   case WaitForSingleObject(ht, 2000) of
     WAIT_OBJECT_0: begin end;              //OK
   else
     rc := GetLastError();                    //tritt nicht ein
     showmessage('Fehler WaitForSingle:');
   end;
 FINALLY
  result:= rc;    
  showmessage('rc :'+ inttostr(rc)+' ht :'+ inttostr(ht)) //zum Anzeigen der Werte

  CloseHandle(ht);

  //Free up the kernel32.dll
  if hKernel32 <> 0 then
    FreeLibrary(hKernel32);

  CloseHandle(hProcess);
 END;
end;


procedure Tform1.Button1Click(Sender: TObject);    
var PID: cardinal;
begin
 PID:= ....;
 CloseRemoteHandle(PID, 0); //die null is auch nicht astrein...
end;
der Original C++ Code

Delphi-Quellcode:
/*
Note: 1. SE_DEBUG privilege must be enabled.
      2. The function works with every kind of HANDLE
      3. It will bother the remote process :)
      4. The handles will be invalid after you closed
         them remotely
*/

//Close a handle in a remote process
DWORD CloseRemoteHandle( DWORD processID, HANDLE handle )
{
 HANDLE ht = 0;
 DWORD rc = 0;

 _tprintf( _T("Closing handle in process #%d ... "),
          processID );

 // open the process
 HANDLE hProcess = OpenProcess( PROCESS_CREATE_THREAD
                                | PROCESS_VM_OPERATION
                                | PROCESS_VM_WRITE
                                | PROCESS_VM_READ,
                                FALSE, processID );

 if ( hProcess == NULL )
 {
  rc = GetLastError();
  _tprintf( _T("OpenProcess() failed\n") );
  return rc;
 }

 // load kernel32.dll
 HMODULE hKernel32 = LoadLibrary( _T("kernel32.dll") );

 // CreateRemoteThread()
 ht = CreateRemoteThread(
  hProcess,
  0,
  0,
  (DWORD(__stdcall *)(void*))GetProcAddress(hKernel32,"CloseHandle"),
  handle,
  0,
  &rc );

 if ( ht == NULL )
 {
  //Something is wrong with the privileges,
  //or the process doesn't like us
  rc = GetLastError();
  _tprintf( _T("CreateRemoteThread() failed\n") );
  goto cleanup;
 }

 switch ( WaitForSingleObject( ht, 2000 ) )
 {
  case WAIT_OBJECT_0:
   //Well done
   rc = 0;
   _tprintf( _T("Ok\n"), rc );
  break;

  default:
   //Oooops, shouldn't be here
   rc = GetLastError();
   _tprintf( _T("WaitForSingleObject() failed\n") );
   goto cleanup;
  break;
 }

 cleanup:
 //Closes the remote thread handle
 CloseHandle( ht );

 //Free up the kernel32.dll
 if ( hKernel32 != NULL)
  FreeLibrary( hKernel32 );

 //Close the process handle
 CloseHandle( hProcess );

 return rc;
}
FRAGE: Ist die Übersetzung soweit in Ordnung? Irgendwelche konstruktiven Anregungen?

Apollonius 17. Mai 2007 08:48

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Warum hast du den zweiten Parameter von einem Handle zu einem Pointer gemacht?

Olli 17. Mai 2007 11:05

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Interessant, daß du genau den Code übersetzt hast, dessen Funktionalität ich kritisiert hatte. Ich versuche es nochmal metaphorisch.

Du (Thread) kaufst dir bei IKEA (System) einen Sessel (Öffnen einer Datei) und bekommst ihn (Handle) ins Haus (Prozeß) geliefert. Da ich als Dieb zufällig Superheldenfähigkeiten habe, ziehe ich dir den gelieferten Sessel in dem Moment unterm Popöchen weg (Schließen des Handles), als du dich hinsetzen möchtest (irgendeine Operation an der Datei). Unglücklicherweise ist dahinter eine Tischkante, auf die du mit dem Hinterkopf fällst und du bist tot (Thread crasht, da es der einzige war, nimmt er den Prozeß mit).

BTW: In den meisten Fällen wird es, bspw. beim Aufruf von Win32-Dateifunktionen, zu keinem Absturz kommen, weil das Handle einfach nicht mehr gültig ist. Leider kann es aber so sein, daß die Logik des Programms es normalerweise nicht erlauben würde, daß eine Operation an einer bereits erfolgreich geöffneten Datei fehlschlägt. Was dann?

Viel Spaß noch :zwinker:

daPimP 17. Mai 2007 17:25

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
@Olli: Ich hatte noch überlegt in meinen vorhergehenden Eintrag reinzuschreiben, KEIN Sarkassmus oder Poesie - aber ich dachte das Wort KONSTRUKTIV würde reichen!

Da ich schon einige Beiträge von dir gelesen habe, hätte ich mir eigentlich etwas "Hilfe" erwartet, anstatt den Lehrerfinger. :zwinker:

NOCHMAL: Meine Absicht ist es, alle Handles aufzulisten. Das über das killen von Handles die Systemstabilität beieinträchtigt werden KÖNNTE, ist kein Geheimnis.

@Apollonius: Da C++ nicht meine Muttersprache ist, kann sich beim Übersetzen schon mal ein Fehler eingeschlichen haben. Schau ich nochmal drauf.

Anhand der Klicks auf diesen Beitrag, scheint im Allgemeinen ein hohes Interesse daran zu bestehen.

Olli 17. Mai 2007 20:37

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Zitat:

Zitat von daPimP
Da ich schon einige Beiträge von dir gelesen habe, hätte ich mir eigentlich etwas "Hilfe" erwartet, anstatt den Lehrerfinger. :zwinker:

Hättest du auch bekommen, aber nicht für eine Funktion CloseRemoteHandle() :zwinker:

Zitat:

Zitat von daPimP
NOCHMAL: Meine Absicht ist es, alle Handles aufzulisten.

http://jedi-apilib.sourceforge.net/ntapi_current.zip und dann http://www.openrce.org/forums/posts/46 oder "Windows NT/2000 Native API Reference" ("Listing Open Handles of a Process").

Zitat:

Zitat von daPimP
Das über das killen von Handles die Systemstabilität beieinträchtigt werden KÖNNTE, ist kein Geheimnis.

Na dann ist ja alles in bester Ordnung, solange man es weiß.

daPimP 21. Mai 2007 08:47

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
@Olli: Genau das hab ich gesucht. :P

Es fehlt nur noch die endgültige Umsetzung.
1) Wenn der erste Teil bis //-------------- richtig ist
2) Wie kann ich alle Werte korrekt anzeigen, irgendwie steh ich auf dem Schlauch :wall:

Delphi-Quellcode:
implementation

uses JwaNative;
...

function SHOWHANDLE(const lv: TListView): BOOL;
const
  BUF_SIZE = $15000;
var
  HANDLEListBuffer: PChar;
  HANDLEInfo: jwanative.PSYSTEM_HANDLE_INFORMATION;

  BufSize: Cardinal;
  Status: Integer;
   i: integer;
  li: TListItem;
begin
  Result := false;
  lv.Items.BeginUpdate;
  lv.Items.Clear;

//  capture Liste
  BufSize := BUF_SIZE;
  repeat
    GetMem(HANDLEListBuffer, BufSize);
    if HANDLEListBuffer = nil then
    begin
      lv.Items.EndUpdate;
      Exit;
    end;

    Status := jwanative.NtQuerySystemInformation(SystemHandleInformation ,
                                       HANDLEListBuffer,
                                       BufSize,
                                       nil);

    if Status <> NO_ERROR then
    begin
      // Buffer zu klein, vergrößern
      FreeMem(HANDLEListBuffer);
      Inc(BufSize, BUF_SIZE);
    end
    else if Status < 0 then  // irgendein Fehler...
    begin
      lv.Items.EndUpdate;
      Exit;
    end;
  until Status >= 0;

  // AB HIER STECK ICH FEST ---------------------------------------
 for i:= 1 to 6 do begin //zur probe nur mal die ersten 6 Werte...
   HANDLEInfo := PSYSTEM_HANDLE_INFORMATION(HANDLEListBuffer);
   HANDLEInfo := PSYSTEM_HANDLE_INFORMATION(Cardinal(HANDLEInfo));
 
          li := lv.Items.Add;
   li.Caption:= HANDLEInfo^.ProcessId;
   li.SubItems.Add(IntToStr(HANDLEInfo^.Handle));
 end;

  Result := true;
  FreeMem(HANDLEListBuffer);
  lv.Items.EndUpdate;
end;

Olli 21. Mai 2007 09:37

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Einige Anmerkungen.
  • NO_ERROR ist kein geeigneter Vergleichswert. Benutze die Funktion (in C ein Makro) NT_SUCCESS() aus JwaWinType!
  • Vergleiche mit dem Wert den du finden willst (IMO ist das STATUS_BUFFER_TOO_SMALL aus JwaNtStatus) und andernfalls NT_SUCCESS() - bei dir mußt du das der Reihe nach machen. Also wenn STATUS_BUFFER_TOO_SMALL dann Puffer freigeben und mit neuer Größe allozieren - sonst, wenn NT_SUCCESS nicht True zurückgibt, Fehler ausgeben und raus aus der Routine.
  • SYSTEM_HANDLE_INFORMATION hat eine feste Größe, daher benutzt du hier einfach nur sizeof() um die Größe des Typs zum aktuellen Pointerwert zu addieren und so den Pointer zum nächsten Record zu bekommen (Stichwort: Pointerarithmetik!).
  • Am Ende wirst du irgendwo bei SYSTEM_OBJECT_INFORMATION landen. Dort benutzt du statt sizeof() den Wert von NextEntryOffset aus dem aktuellen Record und addierst ihn zum Offset des aktuellen Records um das Offset zum nächsten Record zu bekommen. Das Prinzip ist also gleich. Das kommt daher, daß SYSTEM_OBJECT_INFORMATION eine variable Länge hat (hier ein String).

Beachte auch, daß die Abfrage der Informationen eines Handles (und ultimativ des entsprechenden Objektes) bei Pipes und Mailslots blockieren kann. Nico kann dir ein Lied davon singen.

daPimP 21. Mai 2007 19:42

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Danke für die Tips. Zur Umsetzung:

Zitat:

Vergleiche mit dem Wert den du finden willst (IMO ist das STATUS_BUFFER_TOO_SMALL aus JwaNtStatus) und andernfalls NT_SUCCESS() - bei dir mußt du das der Reihe nach machen. Also wenn STATUS_BUFFER_TOO_SMALL dann Puffer freigeben und mit neuer Größe allozieren - sonst, wenn NT_SUCCESS nicht True zurückgibt, Fehler ausgeben und raus aus der Routine.
Delphi-Quellcode:
  status:= jwanative.NTQuerySystemInformation(jwanative.SystemHandleInformation,
                                              @HANDLEInfo,
                                              sizeof(jwanative.PSYSTEM_HANDLE_INFORMATION),
                                              0);

 if status = jwantstatus.STATUS_BUFFER_TOO_SMALL then
  begin
    form1.Memo1.Lines.Add('STATUS_BUFFER_TOO_SMALL: '+IntToStr(status)); //info
  end else
    if JwaWinType.NT_SUCCESS(Status)= false then begin
      form1.Memo1.Lines.Add('NT_SUCCESS: fehler');          //hier schmeißt er mich raus
      Exit;                                           //worin liegt der fehler?
    end else
      form1.Memo1.Lines.Add('NT_SUCCESS: ok');
Zitat:

SYSTEM_HANDLE_INFORMATION hat eine feste Größe, daher benutzt du hier einfach nur sizeof()
Wenn richtig verstanden, dann so wie oben.

Anschließend..

Zitat:

Pointerwert zu addieren und so den Pointer zum nächsten Record zu bekommen (Stichwort: Pointerarithmetik!).
Am Ende wirst du irgendwo bei SYSTEM_OBJECT_INFORMATION landen.
so was "in der Art"

Delphi-Quellcode:
 
var
  HANDLEListBuffer: PChar;
               obj: PSystem_Object_Information;
            offset: cardinal;
...
 obj := PSYSTEM_OBJECT_INFORMATION(handleListBuffer);
  repeat
    obj := PSYSTEM_OBJECT_INFORMATION(Cardinal(obj) + Offset);
    Offset := obj^.NextEntryOffset;
...
  until Offset = 0;
...
  FreeMem(HANDLEListBuffer);

Olli 21. Mai 2007 20:43

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Zitat:

Zitat von daPimP
//worin liegt der fehler?

Meine Kristallkugel ist im Urlaub, wenn du so lieb wärst mir derweil den Statuscode zu nennen, kann ich vielleicht mehr sagen.

NicoDE 21. Mai 2007 22:03

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Kleiner Hinweis am Rande: Unter Windows XP Professional x64 Edition gibt es Probleme mit dem Aufruf von NtQuerySystemInformation(SystemHandleInformation) durch eine 32-Bit Anwendung. Die Funktion meldet einen Erfolg, aber nur der erste Eintrag im Array ist gültig (der Rest wird vom WOW64-Wrapper nicht kopiert). Zudem kann es vorkommen (insbesondere unter einem mit /3GB gestartetem Windows), dass der Kernel nicht genug Speicher hat, um die komplette Liste zu liefern.

ps: der Ausgabepuffer sollte übrigens an einer ausgerichteten Adresse liegen.

Zitat:

Zitat von Olli
Beachte auch, daß die Abfrage der Informationen eines Handles (und ultimativ des entsprechenden Objektes) bei Pipes und Mailslots blockieren kann. Nico kann dir ein Lied davon singen.

Nicht nur das... es gibt auch Probleme mit Software, die sich darauf verlässt, dass ihr ReadFile (auf eine Pipe) immer Daten liefert (was nicht der Fall ist, wenn man den Namen des Objekts abfragt *g*). In solchen Fällen neigen diese Programme zu äußerst unschönem Fehlverhalten (Abstürze sind wenigestens Fehler die man 'sehen' kann).

daPimP 29. Mai 2007 20:44

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Habe den kompletten Source noch mal über den Haufen geworfen.
Mein neuer Code funktioniert.

Kann die Handles eines Prozesses auslesen und auch den ObjectType bestimmen.

Delphi-Quellcode:
  _SYSTEM_HANDLE_INFORMATION = record // Information Class 16
    ProcessId: ULONG;                                  
    ObjectTypeNumber: UCHAR;
    Flags: UCHAR; // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT
    Handle: USHORT;                                        
    Object_: PVOID;
    GrantedAccess: ACCESS_MASK;                            
  end;
Aber wie kann ich nun Object_: PVOID auslesen(PVOID ist ein Pointer), bzw. wie funktioniert dies. Was liefert mir der Wert zurück?

NicoDE 30. Mai 2007 10:14

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Zitat:

Zitat von daPimP
Aber wie kann ich nun Object_: PVOID auslesen(PVOID ist ein Pointer), bzw. wie funktioniert dies. Was liefert mir der Wert zurück?

Der Pointer ist nur für den KernelMode interessant (du müsstest also einen KM-Treiber schreiben um den Inhalt des Pointers auszuwerten).
Wie bereits erwähnt, bekommst du unter WOW64 keinen 64-Bit-Zeiger (den du aber benötigen würdest).

Für UserMode-Prozesse sind nur die anderen Felder interessant (insbes. ProcessId/Handle).

daPimP 30. Mai 2007 12:58

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Zitat:

Für UserMode-Prozesse sind nur die anderen Felder interessant (insbes. ProcessId/Handle).
Wie gesagt, diese Dinge sind klar. Mir fehlt jetzt noch der Schritt,
aus dem Handle 1234 des Prozesses ABC den Namen des Handles herauszubekommen.

In einer Liste so in etwa:
Code:
Type      Handle Name

File      1234    C:\Windows\system32
File      321     \Device\KsecDD
Key       3232    HKLM\Software\...
Semaphore 1123    \BaseNamedObjects\shell.{...}
Event     123 
....
Idee? :gruebel:

CCRDude 30. Mai 2007 13:24

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
NtQueryObject mit ObjectNameInformation :)

daPimP 30. Mai 2007 19:25

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Für alle die Mitlesen, hier noch ein paar Links.

Delphi Praxis

und

dateifreigabe

Zusammenfassung:
Info des Autors von Unlocker:
Zitat:

You need to first find all locks opened by a system using undocumented functions such as ZwQueryObject and NtQueryObject.

Then to get informations you need you write a device driver since some informations are only accessible at the device driver level. There is no device driver specific function, it is just that you need to run in a driver to have maximum access to the system.
von Nico zum Thema Treiber:
Zitat:

Der Treiber ist deswegen notwendig, weil die Abfrage des Namens eines Dateiobjektes (Dateien, Verzeichnisse, Pipes, MailSlots, ...) bei synchronisierten Objekten solange benötigt bis die aktuelle Operation abgeschlossen ist (und das kann ewig dauern). Da zum Beispiel der Service Control Manager (SCM) Pipes verwendet um mit Service-DLLs zu kommunizieren, gibt es eine Menge solcher Objekte. Zudem gibt es aus dem Benutzermodus keinen sicheren Weg um Dateien von Pipes und/oder MailSlots zu untercheiden. Der Treiber löst das erste Problem üblicherweise dadurch, dass er den IRP zur Abfrage des Objekts selbst erzeugt. Das zweite Problem kann ebenso im Treiber (mit Hilfe des IFS-Kits) gelöst werden (MailSlots oder Pipes sind an Flags erkennbar).

Kurz, für eine saubere Lösung kommt man nicht um einen Treiber herum.
und

Ironie des Schicksals, nachdem ich immer wieder ein kleines Stück der Lösung näher gerutscht war
und es nun auch geschafft hatte (Danke CCRDude), gibts das schon relativ kompakt im Netz.
Nicht so toll wie meine Lösung :zwinker: , aber dafür OHNE Treiber.

für die Copy&Paste 'ler der Delphi Source.
experts exchange

toms 31. Mai 2007 06:19

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von daPimP
für die Copy&Paste 'ler der Delphi Source.
experts exchange

Und für alle, die kein experts-exchange login haben: Habe den Code als Attachment angehängt.

NicoDE 31. Mai 2007 09:21

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Randbemerkung: "SysErrorMessage(GetLastError())" ist nicht korrekt, richtig wäre "SysErrorMessage(RtlNtStatusToDosError(Status) )" gewesen.

Zitat:

Zitat von daPimP
aber dafür OHNE Treiber.

Viel Spaß beim Testen auf Live-Systemen...

daPimP 31. Mai 2007 15:04

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
@Nicode: Ja da hast du verdammt recht. Aber als Basis ist das durchaus nutzvoller Quellcode.
Bei meinen Proben war die Chance, das das Programm nicht hängt 1:10. :cheers: Mahlzeit.

Luckie 11. Jul 2007 14:18

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
@toms: Wie benutzt man den Code? Also wie würde ein Beispielaufruf aussehen?

QuickAndDirty 16. Jan 2008 14:58

Re: Prozesse oder Anwendungen ermitteln, die eine Datei benu
 
Zitat:

Zitat von NicoDE
Randbemerkung: "SysErrorMessage(GetLastError())" ist nicht korrekt, richtig wäre "SysErrorMessage(RtlNtStatusToDosError(Status) )" gewesen.

Zitat:

Zitat von daPimP
aber dafür OHNE Treiber.

Viel Spaß beim Testen auf Live-Systemen...

Meinst es würde helfen, wenn OpLocks abgeschaltet sind?


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:50 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz