AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Startparameter fremder Anwendung auslesen

Startparameter fremder Anwendung auslesen

Ein Thema von mw19 · begonnen am 1. Mär 2010 · letzter Beitrag vom 2. Mär 2010
Antwort Antwort
mw19
(Gast)

n/a Beiträge
 
#1

Startparameter fremder Anwendung auslesen

  Alt 1. Mär 2010, 14:21
Hallo Gemeinde,

ich habe gerade ein kleines Problem beim Auslesen der Startparameter einer "fremden" Anwendung.

Unter Windows XP funktioniert alles wunderbar, ab Vista aber geht nichts mehr.
Erstmal ein Schnipsel Code:
Delphi-Quellcode:
  Snap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  try
    ProcessE.dwSize := SizeOf(ProcessE);
    if Process32First(Snap, ProcessE) then begin
      repeat
        if ExtractFilePath(ParamStr(0)) + ProcessE.szExeFile = Application.ExeName then begin
          Parameter := GetStartParameter(ProcessE.th32ProcessID);
In der Variablen "Parameter" steht unter XP der bzw. die Parameter, welche mit dem Programmstart übergeben wurden. Gebe ich mir diese Variable mit ShowMessage zum Beispiel aus, ist der Wert unter Vista leer. Ich gehe also quasi alle Prozesse durch uns suche die Prozesse, die denselben Namen habe wie meine EXE. Von diesen möchte ich dann die Parameter auslesen.

Frage ist jetzt, wieso das unter Vista nicht funkioniert bzw. was ich ändern muss.

Vielen Dank fürs Lesen!

Gruß,
Michael
  Mit Zitat antworten Zitat
Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#2

Re: Startparameter fremder Anwendung auslesen

  Alt 1. Mär 2010, 14:27
Dazu solltest Du aber den Source von GetStartParameter posten .
Fridolin Walther
"While Mr. Kim, by virtue of youth and naiveté, has fallen prey to the inexplicable need for human contact, let me step in and assure you that my research will go on uninterrupted, and that social relationships will continue to baffle and repulse me."
  Mit Zitat antworten Zitat
mw19
(Gast)

n/a Beiträge
 
#3

Re: Startparameter fremder Anwendung auslesen

  Alt 1. Mär 2010, 14:31
Hallo,

ja, da hast du allerdings Recht
Vielleicht sollte man nicht immer alles gleichzeitig machen...

Delphi-Quellcode:
function GetStartParameter(ProcessID: DWORD): String;
var
  MBI : TMemoryBasicInformation;
  Buffer,PosCmdLine : Pointer;
  SystemInfo : TSystemInfo;
  Size : DWORD;
  CmdLine : WideString;
  LengthCmdLine : Word;
  ProcessHandle : THandle;
begin
  Result := '';
  FillChar(SystemInfo, SizeOf(TSystemInfo), 0);
  GetSystemInfo(SystemInfo);
  GetMem(Buffer, SystemInfo.dwPageSize);
  Size := SizeOf(TMemoryBasicInformation);
  FillChar(MBI, Size, 0);
  ProcessHandle := OpenProcess(PROCESS_VM_READ or PROCESS_QUERY_INFORMATION, False, ProcessId);
  if VirtualQueryEx(ProcessHandle, Pointer($20000), MBI, Size) = Size then if ReadProcessMemory(ProcessHandle, MBI.BaseAddress, Buffer, SystemInfo.dwPageSize, DWORD(nil^)) then
  begin
    LengthCmdLine := PWord(Longint(Buffer) + $42)^;
    if LengthCmdLine < 520 then
    begin
      SetLength(CmdLine,LengthCmdLine);
      PosCmdLine := Pointer(PLongint(Longint(Buffer) + $44)^);
      if ReadProcessMemory(ProcessHandle, PosCmdLine, PWideChar(CmdLine), LengthCmdLine, DWORD(nil^)) then Result := Copy(CmdLine, 1, Pos(#0,CmdLine) - 1);
    end;
  end;
  CloseHandle(Processhandle);
  FreeMem(Buffer);
end;
So, dass ist die Funktion.

Danke!

Gruß,
Michael
  Mit Zitat antworten Zitat
Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#4

Re: Startparameter fremder Anwendung auslesen

  Alt 1. Mär 2010, 15:01
Was Du in der Funktion machst ist an fixen Offsets die Parameter zu lesen. Die Offsets mögen für Windows XP konstant sein, können sich in späteren Windows Versionen aber ändern.

Der korrekte Weg wäre die Adresse des PEB innerhalb des fremden Prozesses zu ermitteln, den PEB dann auszulesen um den Pointer auf die ProcessParameters Datenstruktur zu erhalten, selbige dann wiederum zu lesen um dann letztlich an die Command Line zu kommen. Die Methode funktioniert dann auch für alle Windows Versionen, solange sich die Datenstrukturen nicht grundlegend ändern. Da Microsoft aber meist neue Parameter "hinten dranhängt", solltest Du damit keine Probleme haben.

Eine Implementation des Ganzen gibts hier sogar im Board:
http://www.delphipraxis.net/internal...=873389#873389

PS: Gewöhn Dir an statt "Magic Values" Konstanten zu benutzen. Niemand weiß sonst was $200000 dort soll oder $44.
Fridolin Walther
"While Mr. Kim, by virtue of youth and naiveté, has fallen prey to the inexplicable need for human contact, let me step in and assure you that my research will go on uninterrupted, and that social relationships will continue to baffle and repulse me."
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.868 Beiträge
 
Delphi 12 Athens
 
#5

Re: Startparameter fremder Anwendung auslesen

  Alt 1. Mär 2010, 15:17
'ne andere Möglichkeit wäre noch:
- eine DLL oder Code in den gewünschten Prozess injizieren
- und dort GetCommandLine aufrufen
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
helgew

Registriert seit: 30. Jul 2008
125 Beiträge
 
#6

Re: Startparameter fremder Anwendung auslesen

  Alt 1. Mär 2010, 15:33
Also ich mache das etwa so (keine injection, dafür aber debugging-Rechte) ...

Delphi-Quellcode:
function GetProcessCommandLine(pID: Cardinal):string;
var
  hProcess, hHeap: THandle;
  dwsize, dwSizeNeeded, dwBytesRead: DWORD;
  dwStatus: LONG;
  pbi : smPPROCESS_BASIC_INFORMATION;
  spi : smPROCESSINFO;
  peb : smPEB;
  bpp: smRTL_USER_PROCESS_PARAMETERS;
  pWideStrBuf: PWideChar;
begin
  if not EnableTokenPrivilege(SE_DEBUG_NAME) then
  begin
     // writeln('Debug privileges not available for current user.');
  end;

  result := '';
  hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, // PROCESS_ALL_ACCESS,//
              false, PID);
  if hProcess = 0 then
  begin
    // writeln('Could not open process #',pID,' with desired privileges. Error ',GetLastError);
    exit;
  end;
  // else writeln('access granted.');

  if IsNTDLLLibraryLoaded then
  begin
    hHeap := GetProcessHeap;
    if hHeap <> 0 then
    begin
      dwSize := sizeof(smPROCESS_BASIC_INFORMATION);
      pbi := HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwSize);
      if assigned(pbi) then
      begin
        dwStatus := NtQueryInformationProcess(hProcess, ProcessBasicInformation, Pointer(pbi), dwSize, @dwSizeNeeded);
        if dwStatus >= 0 then
        begin
          spi.dwPID := DWORD (pbi^.UniqueProcessId);
          spi.dwParentPID := DWORD (pbi^.InheritedFromUniqueProcessId);
          spi.dwBasePriority := LONG (pbi^.BasePriority);
          spi.dwExitStatus := NTSTATUS (pbi^.ExitStatus);
          spi.dwPEBBaseAddress := DWORD (pbi^.PebBaseAddress);
          spi.dwAffinityMask := DWORD (pbi^.AffinityMask);

          if 0 <> spi.dwPEBBaseAddress then
          begin
            if ReadProcessMemory ( hProcess, Pointer(spi.dwPEBBaseAddress), @peb, sizeof(peb), dwBytesRead) then
            begin
              spi.dwSessionID := DWORD (peb.SessionId);
              spi.cBeingDebugged := BYTE (peb.BeingDebugged);
              try
                if assigned(peb.ProcessParameters) then
                begin
                  ReadProcessMemory( hProcess,Pointer(peb.ProcessParameters),@bpp,sizeof(bpp),dwBytesRead);
                  if bpp.CommandLine.Length > 0 then
                  begin
                    pWideStrBuf := HeapAlloc(hHeap,HEAP_ZERO_MEMORY,bpp.CommandLine.Length*sizeof(WideChar));
                    ReadProcessMemory( hProcess,
                            bpp.CommandLine.Buffer,
                            pWideStrBuf,
                            bpp.CommandLine.Length*sizeof(WideChar),
                            dwBytesRead);
                    result := WideCharToString(pWideStrBuf);
                    HeapFree(hHeap,0,pWideStrBuf);
                  end;
                end;
              except
              else
                result := ' - ';
              end;
            end; // else writeln('ReadMemory Failed.');
          end; // else writeln('PEB Base Address is NULL.');
        end; // else writeln('NtQueryInformationProcess Failed.');
      end; // else writeln('HeapAlloc Failed.');
      if hHeap <> 0 then windows.HeapFree(hHeap,0,pbi); // 0 : Do not specify this value when accessing the process heap. The system may create additional threads within the application's process, such as a CTRL+C handler, that simultaneously access the process heap. Otherwise, use HEAP_NO_SERIALIZE = 1
    end;
  end;

  CloseHandle(hProcess);
end;
Referenz: http://www.delphipraxis.net/internal...t.php?t=166858
  Mit Zitat antworten Zitat
mw19
(Gast)

n/a Beiträge
 
#7

Re: Startparameter fremder Anwendung auslesen

  Alt 1. Mär 2010, 17:37
Hallo,

ringli hatte in einem verlinkten Thread eine Demo verlinkt. Mit dieser konnte ich das Problem jetzt erst einmal lösen.

@Fridolin Walther: Deine Antwort liest sich sehr gut, umsetzen konnte ich sie leider nicht. In deinem Source sind z.B. die Units JwaWinBase und JwaNative erwähnt. Wo bekomme ich die her?

Vielen Dank an alle für die Tipps!!

Gruß,
Michael
  Mit Zitat antworten Zitat
Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#8

Re: Startparameter fremder Anwendung auslesen

  Alt 1. Mär 2010, 17:44
Die bekommst Du hier:
http://blog.delphi-jedi.net/jedi-api-headers/
Fridolin Walther
"While Mr. Kim, by virtue of youth and naiveté, has fallen prey to the inexplicable need for human contact, let me step in and assure you that my research will go on uninterrupted, and that social relationships will continue to baffle and repulse me."
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#9

Re: Startparameter fremder Anwendung auslesen

  Alt 1. Mär 2010, 22:38
Du brauchst keine Debuggingrechte, wenn du nur deine eigenen Prozesse öffnen willst. Lass das also weg.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
mw19
(Gast)

n/a Beiträge
 
#10

Re: Startparameter fremder Anwendung auslesen

  Alt 2. Mär 2010, 07:40
Hallo,

@Fridolin Walthe: Danke für den Hinweis! Bei Gelegenheit werde ich mir das sicherlich noch mal im Detail ansehen.

@Dezipaitor: Ja, es handelt sich hierbei um die eigene Anwendung. Funktionieren tut es auch, von daher ist dieser Punkt für mich erledigt.

Danke noch einmal an Alle!

Gruß,
Michael
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 15:26 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