如何在Windows中获取任务管理器的listview内容?

时间:2015-03-17 21:49:57

标签: delphi listview taskmanager readprocessmemory

我尝试在任务管理器Windows中获取所有项目,但所有我得到的 - 空行。我使用RAD Studio XE7

procedure wtff(hwn: Thandle);
var
  ListView: HWND;
  ProcessId: DWORD;
  Process: Thandle;
  Size: Cardinal;
  MemLocal: Pointer;
  MemRemote: Pointer;
  NumBytes: NativeUInt;
  IconIndex: Integer;
  IconLabel: string;
begin
  ProcessId := 0;
  ListView := FindWindowEx(hwn, 0, 'SysListView32', nil);
  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

        // If Assigned memory

        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

              // Getting the text

              IconLabel :=
                string(PChar(Cardinal(MemLocal) + Cardinal(SizeOf(TLVItem))));
              if CaseSensitive then
              begin
                IconLabel := LowerCase(IconLabel);
                aText := LowerCase(aText);
              end;

              Form1.Memo1.Lines.Add(IconLabel);
              /// ADD IN MEMO

            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;

所以,在备忘录中我只看到很多空行。

1 个答案:

答案 0 :(得分:0)

我尝试编写类似的代码。 无论出于何种原因,在某些应用程序中,此方法有效,但在某些应用程序中它并不起作用(特别是当外部进程需要提升权限时)。

可能外部进程窗口不接受消息,作为保护措施。 SendMessage可能会给出错误号5(拒绝访问) 我看到一个可能的解决方法可能是dll injection进入进程并从该进程内部发出ChangeWindowMessageFilterEx以使窗口接受消息。

但这可能太麻烦并引发防病毒警报..