1

我正在尝试使用 LVM_GETITEMPOSITION 设置/获取桌面图标位置。设置位置按预期工作,但获得它们不是。

当我发送消息时(DeskHandle,LVM_GETITEMPOSITION,1,ppt);资源管理器崩溃,这显然是因为 ppt 只是我进程中的有效地址,所以我需要将一个 dll 注入资源管理器的内存地址空间..这就是我再次被卡住的地方

问题是返回位置始终为 0,0

dll:

library Project2_dll;

uses
  SysUtils,Classes,windows,messages,dialogs,commctrl;

{$R *.res}

procedure hookit; stdcall;
var ppt:tpoint;
    Desktop,DeskHandle : hwnd;
    DeskThread : cardinal;
begin
  Desktop := FindWindow('ProgMan', nil);
  Desktop := FindWindowEx(Desktop, 0, 'SHELLDLL_DefView', nil);
  DeskThread := GetWindowThreadProcessID(Desktop, nil);
  DeskHandle := FindWindowEx(Desktop, 0, 'SysListView32', nil);

  sendmessage(DeskHandle, LVM_GETITEMPOSITION, 1, Longint(@ppt) );
  showmessage(inttostr(ppt.X)+'  '+inttostr(ppt.Y));
end;

exports hookit;

begin

end.

可执行程序 :

var
  lib : hwnd;
  prc: procedure; stdcall;

procedure TForm2.Button1Click(Sender: TObject);
var hListView : HWND;
    DeskThread : cardinal;
begin
  hListView := FindWindow('ProgMan', nil);
  hListView := FindWindowEx(hListView, 0, 'SHELLDLL_DefView', nil);
  DeskThread := GetWindowThreadProcessID(hListView, nil);

  lib:= LoadLibrary('Project2_dll.dll');
  prc := GetProcAddress(lib, 'hookit');

  HH := SetWindowsHookEx(WH_MOUSE,GetProcAddress(lib, 'getit'),lib,DeskThread);

  prc;
end;

我已经在这里看到了一些类似的问题,没有任何帮助。

ps:在 Delphi XE、windows 7 x64 中运行它,并假设 SysListView32 始终是 progman 的孩子(不是 WorkerW)

任何帮助表示赞赏^_^

4

1 回答 1

4

您不能将 32 位 DLL 注入 64 位进程。为了将 DLL 注入 64 位资源管理器,您需要获取 XE2 或 XE3 并构建 64 位 DLL。如果您无法访问 64 位 Delphi,或者使用 C++ 编写这部分代码。

碰巧的是,您的代码无论如何都不会注入。它只是从您的流程中调用 SendMessage。注入通常涉及对 CreateRemoteThread 的调用。

事实上,你不需要注入。您可以使用VirtualAllocEx在资源管理器进程中分配内存。然后,您可以将该地址传递到您的SendMessage. 由于该内存位于另一个进程中,因此您必须使用ReadProcessMemoryWriteProcessMemory访问它。不过,您仍然需要从 64 位进程执行此操作。

我原以为 shell 为您提供了在不破坏资源管理器进程内存的情况下获取这些信息的工具。

于 2012-09-11T16:32:42.507 回答