Autor Beitrag
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Mo 11.08.03 12:17 
Hi,
ich lese mit folgendem Code die Bezeichnung des ersten Icons auf dem Desktop aus:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
uses CommCtrl;

procedure TForm1.Button1Click(Sender: TObject);

 function GetDskLVH: THandle;
 var s: string;
 begin
   Result := FindWindow('ProgMan', nil);
   Result := GetWindow(Result, GW_CHILD);
   Result := GetWindow(Result, GW_CHILD);
   SetLength(S, 40);
   GetClassName(Result, PChar(S), 39);
   if PChar(s) <> 'SysListView32' then begin
     MessageBox(0, 'Fehler bei Ermittlung des Desktophandles!', 'Fehler', 0);
     Result := 0;
   end;
 end;

var dwSize,dwNumberOfBytes,PID,hProcess:Cardinal;
    PLocalShared,PSysShared:PlvItem;
begin
  dwSize := SizeOf(LV_ITEM) + SizeOf(CHAR) * MAX_PATH;
  pLocalShared := VirtualAlloc(nil, dwSize, MEM_RESERVE + MEM_COMMIT,
    PAGE_READWRITE);
  GetWindowThreadProcessID(GetDskLVH, @PID);
  hProcess := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or
    PROCESS_VM_WRITE, FALSE, PID);
  pSysShared := VirtualAllocEx(hProcess, nil, dwSize, MEM_RESERVE or MEM_COMMIT,
    PAGE_READWRITE);
  pLocalShared.mask := LVIF_TEXT;
  pLocalShared.iItem := 0;
  pLocalShared.iSubItem := 0;
  pLocalShared.pszText := LPTSTR(DWord(pSysShared) + SizeOf(LV_ITEM));
  pLocalShared.cchTextMax := 100;
  WriteProcessMemory(hProcess, pSysShared, pLocalShared, 1024,
    dwNumberOfBytes);
  SendMessage(GetDskLVH, LVM_GETITEM, 0, LPARAM(pSysShared));
  ReadProcessMemory(hProcess, pSysShared, pLocalShared, 1024,
    dwNumberOfBytes);

  Caption:=PChar(DWord(pLocalShared) + SizeOf(LV_ITEM));

  VirtualFree(pLocalShared, 0, MEM_RELEASE);
  VirtualFreeEx(hProcess, pSysShared, 0, MEM_RELEASE);
  CloseHandle(hProcess);
end;
// Copyright SmR 2002


Das funktioniert auch ganz gut, nur ist mir der Code zu kompliziert.
Geht es nicht auch einfacher?

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Mo 11.08.03 12:43 
Zitat:
Geht es nicht auch einfacher?

Das findest du kompliziert? Dann hast du noch nicht gesehen, was es alles für Dinge gibt, die wirklich kompilziert sind.

Kleine Verbesserung: Den eigenen Speicher brauchst du nicht über VirtualAlloc reservieren, das kann auch eine lokale Zeigervariable mit GetMem/FreeMem erledigen.

_________________
Ist Zeit wirklich Geld?
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Mo 11.08.03 12:45 
Leider nicht, da Steuerelemnt-Botschaften nicht Prozessübergreifend funktonieren. Bei zB WM_GETTEXT mappt Windows im Hintergrund ziemlich herum. Hier musst du das eben selbst machen indem du per VirtualAllocEx Speicher im fremden Prozess reservierst in dem dann die Daten abgelegt werden, damit du sie dann per ReadProcessMemory auslesen kannst.

Eine andere Möglichkeit (aber nicht unbedingt einfachere) wäre das ganze über eine Inject-Dll zu lösen...

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Mo 11.08.03 12:46 
AndyB hat folgendes geschrieben:
Zitat:
Geht es nicht auch einfacher?

Das findest du kompliziert? Dann hast du noch nicht gesehen, was es alles für Dinge gibt, die wirklich kompilziert sind.

Jeder hat einmal klein angefangen... ;)

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
maxk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Mo 11.08.03 20:14 
Motzi hat folgendes geschrieben:
Jeder hat einmal klein angefangen...
:shock: Danke für die Verteidigung - aber ich bin kein Anfänger :twisted: Ich würde mich selbst schon eher als Fortgeschrittener bezeichnen. Die Frage richtete sich nur darum, ob es wirklich nötig ist, so im Speicher rumzusauen...

Windows ist noch ein Anfänger und evtl. nicht in der Lage korrekt mit dem Code zu arbeiten :mrgreen:

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Di 12.08.03 13:29 
Ja, es ist nötig.. das warum hab ich oben bereits beschrieben! :roll:

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
RFZ
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 137

WinME, WinXP, Win2k*, Win98*, Win95*, Win3.11*, DOS* (*VMware)
D4 Prof
BeitragVerfasst: Di 12.08.03 14:11 
schlagt mich, wenn ich schmarrn erzähle, aber kannst du nich einfach schaun welche Dateien in "c:\windows\desktop" (oder hald bei NT/XP im Userverzeichnis) liegen?
Vielleicht hab ich auch net ganz verstanden was du willst ;)

cu RFZ
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Di 12.08.03 16:27 
Das wäre doch viel zu einfach. 8)

_________________
Ist Zeit wirklich Geld?
maxk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Di 12.08.03 21:30 
:oops: Erwischt, das Programm wird später auch die Position der Icons auslesen. (Es soll ein alternativer WindowsManager werden).
:? Ich weiß, es gibt schon hundert davon, aber es ist immer schon, etwas eigenes zu haben...

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 15.08.03 00:44 
Einfacher geht es nicht, wenn man es richtig macht, wird es nur komplizierter (für dich). BTW liest er auch gleich die Position aus.

Den Source haben Nico (90%) und ich (10%) :roll: gestern überarbeitet und hauptsächlich alle möglichen Fehlerquellen abgefangen, Datentypen korrigiert und lesbarer gemacht.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
uses CommCtrl;

////////////////////////////////////////////////////////////////////////////////
// Durch die Verwendung von VirtualAllocEx() funktioniert dieser Code nur auf NT

procedure TForm1.Button1Click(Sender: TObject);
  // Diese Funktion ist zwar einfach, aber nicht sicher genug (WinXP)
  function GetDesktopListView(): HWND;
  var
    ClassName: string;
  begin
    Result := FindWindow('ProgMan', nil);
    Result := GetWindow(Result, GW_CHILD);
    Result := GetWindow(Result, GW_CHILD);
    SetLength(ClassName, 40);
    SetLength(ClassName, GetClassName(Result, PChar(ClassName), 39));
    if (ClassName <> 'SysListView32') then
    begin
      MessageBox(Self.Handle, 'Fehler bei Ermittlung des Desktophandles!',
        'Fehler', MB_ICONERROR or MB_OK);
      Result := 0;
    end;
  end;
var
  ListView: HWND;
  ProcessId: DWORD;
  Process: THandle;
  Size: Cardinal;      // SIZE_T
  MemLocal: Pointer;
  MemRemote: Pointer;
  NumBytes: Cardinal;  // SIZE_T
  IconIndex: Integer;
  IconLabel: string;
  IconPos: TPoint;
begin
  // Fensterhandle des Desktop-ListView ermitteln und Prozess oeffnen
  ProcessId := 0;
  ListView := GetDesktopListView();
  GetWindowThreadProcessId(ListView, @ProcessId);
  Process := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or
    PROCESS_VM_WRITE, False, ProcessId);
  if (Process <> 0) then
  try
    // Lokalen und entfernten (im Zielprozess) Puffer anlegen
    Size := SizeOf(TLVItem) + SizeOf(Char) * MAX_PATH + 1;
    MemLocal := VirtualAlloc(nil, Size, MEM_RESERVE or MEM_COMMIT,
      PAGE_READWRITE);
    MemRemote := VirtualAllocEx(Process, nil, Size, MEM_RESERVE or MEM_COMMIT,
      PAGE_READWRITE);
    if Assigned(MemLocal) and Assigned(MemRemote) then
    try
      // Anzahl der Symbole ermitteln und in einer Schleife durchlaufen
      for IconIndex := 0 to SendMessage(ListView, LVM_GETITEMCOUNT, 0, 0) - 1 do
      begin
        // Symboltext auslesen
        // (es gibt zwei identische Strukturen, jeweils eine in diesem und eine
        //  im Zielprozess. Wobei die Daten zwischen den Puffern hin und her
        //  kopiert werden muessen. Dieser Aufwand ist noetig, da LVM_GETITEM
        //  eine Struktur liest und schreibt, die sich im Adressraum des
        //  Prozesses befindet, dem das entsprechende Fenster gehoert...)
        ZeroMemory(MemLocal, SizeOf(TLVItem));
        with PLVItem(MemLocal)^ do
        begin
          mask := LVIF_TEXT;
          iItem := IconIndex;
          // Der Puffer fuer den Text liegt direkt hinter der TLVItem-Struktur
          pszText := LPTSTR(Cardinal(MemRemote) + Cardinal(SizeOf(TLVItem)));
          cchTextMax := MAX_PATH;
        end;
        NumBytes := 0;
        if WriteProcessMemory(Process, MemRemote, MemLocal, Size, NumBytes) and
          Boolean(SendMessage(ListView, LVM_GETITEM, 0, LPARAM(MemRemote))) and
          ReadProcessMemory(Process, MemRemote, MemLocal, Size, NumBytes) then
        begin
          IconLabel := string(
            PChar(Cardinal(MemLocal) + Cardinal(SizeOf(TLVItem))));
          // Position auslesen
          // (-1, -1 ist nur ein Indiz fuer einen Fehlschlag, da diese Position
          //  natuerlich moeglich ist...)
          IconPos.X := -1;
          IconPos.Y := -1;
          if Boolean(SendMessage(ListView, LVM_GETITEMPOSITION, IconIndex,
            LPARAM(MemRemote))) and ReadProcessMemory(Process, MemRemote,
            MemLocal, Size, NumBytes) then
          begin
            IconPos := PPoint(MemLocal)^;
          end;
          // Anzeige ;)
          Memo1.Lines.Add(IconLabel +
            ' [' + IntToStr(IconPos.X) + ', ' + IntToStr(IconPos.Y) + ']');
        end;
      end;
    except
      // Exceptions ignorieren
    end;
    // Aufraeumen
    if Assigned(MemRemote) then
      VirtualFreeEx(Process, MemRemote, 0, MEM_RELEASE);
    if Assigned(MemLocal) then
      VirtualFree(MemLocal, 0, MEM_RELEASE);
  finally
    CloseHandle(Process);
  end;
end;


Bitte unbedingt die Kommentare beachten!!!
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Fr 15.08.03 00:49 
Wobei ich es immer noch nicht verstehe, warum der eigene Speicher über
Zitat:
MemLocal := VirtualAlloc(nil, Size, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);

reserviert wird. Ein einfaches: GetMem(MemLocal, Size); hätte es auch getan.

_________________
Ist Zeit wirklich Geld?
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 15.08.03 00:54 
Ist lesbarer denke ich. Da deutlich wird, das local das gleiche passiert wie remote. Eventuell hat es auch noch was mit ReadProcessMemory zu tun.
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Fr 15.08.03 00:57 
Luckie hat folgendes geschrieben:
Ist lesbarer denke ich.

Das finde ich ganz und gar nicht.

Zitat:
Eventuell hat es auch noch was mit ReadProcessMemory zu tun.

Damit hat es überhaupt nichts zu tun. Wäre das der Fall, so würden einige meiner Funktionen nicht funktionieren. Tun sie aber, auf Win95-ME/WinNT-XP Systemen.

_________________
Ist Zeit wirklich Geld?
maxk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Fr 15.08.03 19:34 
Luckie hat folgendes geschrieben:
Einfacher geht es nicht, wenn man es richtig macht, wird es nur komplizierter (für dich). BTW liest er auch gleich die Position aus.
Danke! Ich hatte eigentlich vor, den Code von SmR zu nutzen, aber der gefällt mir besser :)

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 16.08.03 02:07 
Bitte, aber wenn du unbedingt einen Code mit solchen Schwachstellen verwenden willst, tu es, aber wunder dich nicht, wenn er dir mal um die Ohren fliegt.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 16.08.03 15:37 
Ups, sorry. Da habe ich was falsch verstanden, du willst Nico's Code nehmen oder?
maxk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Sa 16.08.03 19:57 
Luckie hat folgendes geschrieben:
Ups, sorry. Da habe ich was falsch verstanden, du willst Nico's Code nehmen oder?
Jepp :D

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 16.08.03 20:20 
Das beruhigt ungemein. :?
r_o_M_a_n
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Sa 28.02.04 21:36 
Gibt es auch eine Möglichkeit, die Handles der Icons auszulesen, um sie mit ShowWindow(Handle,SW_HIDE); auszublenden? Sind Icons überhaupt Child-Windows des Desktop-Listviews?
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 28.02.04 21:44 
Nein. Der Desktop ist nur ein SyListview in der Icon-Ansicht.