| Autor |
Beitrag |
maxk
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: Mo 11.08.03 12:17
Hi,
ich lese mit folgendem Code die Bezeichnung des ersten Icons auf dem Desktop aus: 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; |
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
      
Beiträge: 1173
Erhaltene Danke: 14
RAD Studio XE2
|
Verfasst: 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
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: 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
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: 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 
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: Mo 11.08.03 20:14
| Motzi hat folgendes geschrieben: | | Jeder hat einmal klein angefangen... |  Danke für die Verteidigung - aber ich bin kein Anfänger  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 
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Di 12.08.03 13:29
Ja, es ist nötig.. das warum hab ich oben bereits beschrieben! 
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
RFZ
      
Beiträge: 137
WinME, WinXP, Win2k*, Win98*, Win95*, Win3.11*, DOS* (*VMware)
D4 Prof
|
Verfasst: 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
      
Beiträge: 1173
Erhaltene Danke: 14
RAD Studio XE2
|
Verfasst: Di 12.08.03 16:27
Das wäre doch viel zu einfach. 
_________________ Ist Zeit wirklich Geld?
|
|
maxk 
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: Di 12.08.03 21:30
 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
|
Verfasst: 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%)  gestern überarbeitet und hauptsächlich alle möglichen Fehlerquellen abgefangen, Datentypen korrigiert und lesbarer gemacht.
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;
procedure TForm1.Button1Click(Sender: TObject); 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; MemLocal: Pointer; MemRemote: Pointer; NumBytes: Cardinal; IconIndex: Integer; IconLabel: string; IconPos: TPoint; begin 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 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 for IconIndex := 0 to SendMessage(ListView, LVM_GETITEMCOUNT, 0, 0) - 1 do begin ZeroMemory(MemLocal, SizeOf(TLVItem)); with PLVItem(MemLocal)^ do begin mask := LVIF_TEXT; iItem := IconIndex; 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)))); 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; Memo1.Lines.Add(IconLabel + ' [' + IntToStr(IconPos.X) + ', ' + IntToStr(IconPos.Y) + ']'); end; end; except end; 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
      
Beiträge: 1173
Erhaltene Danke: 14
RAD Studio XE2
|
Verfasst: 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
|
Verfasst: 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
      
Beiträge: 1173
Erhaltene Danke: 14
RAD Studio XE2
|
Verfasst: 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 
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: 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
|
Verfasst: 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
|
Verfasst: Sa 16.08.03 15:37
Ups, sorry. Da habe ich was falsch verstanden, du willst Nico's Code nehmen oder?
|
|
maxk 
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: 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 
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Sa 16.08.03 20:20
Das beruhigt ungemein. 
|
|
r_o_M_a_n
Hält's aus hier
Beiträge: 2
|
Verfasst: 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
|
Verfasst: Sa 28.02.04 21:44
Nein. Der Desktop ist nur ein SyListview in der Icon-Ansicht.
|
|
|