繁体   English   中英

如何在Delphi中使用WriteProcessMemory

[英]How to use WriteProcessMemory in Delphi

我无法编译此代码。 我可以帮忙吗? 谢谢。

procedure ChangeOutsideDateTime(h: HWND; dt: TDateTime);
var
  st: TSystemTime;
  pst: Pointer;
  hDTP: Cardinal;
  hProc: THandle;
  dwWrote: DWORD;
begin
  DateTimeToSystemTime(dt, st);
  pst:= VirtualAllocEx(h, nil, SizeOf(st), MEM_COMMIT, 0);
  if pst <> nil then begin
    if GetWindowThreadProcessId(h, hDTP) > 0 then begin
      hProc:= OpenProcess(PROCESS_VM_OPERATION, false, hDTP);
      if WriteProcessMemory(hProc, pst, @st, SizeOf(st), dwWrote) > 0 then begin
        SendMessage(h, DTM_SETSYSTEMTIME, GDT_VALID, hDTP);
        CloseHandle(hProc);
      end;
    end;
    VirtualFreeEx(h, pst, 0, MEM_RELEASE);
  end;
end;

它在使用“ WriteProcessMemory”的行中显示“实际和正式var参数的类型必须相同”。

实际和形式化var参数的类型必须相同

这是编译器错误E2003。 如果遇到不了解的编译器错误,那么要做的第一件事就是阅读文档 它说:

对于可变参数,实际参数必须是形式参数的确切类型。

导致此错误的函数调用为WriteProcessMemory 让我们看一下它的声明:

function WriteProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; 
  lpBuffer: Pointer; nSize: SIZE_T; var lpNumberOfBytesWritten: SIZE_T): BOOL; stdcall;

这里只有一个var参数,即最后一个参数。 传递的变量必须为SIZE_T类型,但是传递的变量为DWORD类型。 那是不匹配的。

其他一些评论:

  • VirtualAllocEx的调用注定会失败,因为您传递的是窗口句柄而不是进程句柄。
  • 从语义上讲,测试正线程ID是没有意义的。 测试成功与否不等于零。
  • 您无需检查OpenProcess返回值。 那很容易失败。
  • 您不会使用PROCESS_VM_WRITE访问权限打开该进程,而该权限对于WriteProcessMemory是必需的。
  • 如果对WriteProcessMemory的调用失败,则会泄漏该句柄。
  • WriteProcessMemory的返回类型为BOOL
  • hDTP是进程ID的奇怪名称。 该名称表明您认为它是日期时间选择器控件的句柄。 不是。 这是进程ID。
  • 您在SendMessage调用中传递该进程ID,而不是您刚刚编写的系统时间的地址。

您的代码中有几个错误。

  • 您将HWND传递给VirtualAllocEx() ,但是它希望将THandle给已打开的进程。 并且您在打开进程句柄之前正在调用VirtualAllocEx() 并且您不要求对分配的内存进行写访问。

  • 调用OpenProcess() ,您并不需要的是WriteProcessMemory()所需的PROCESS_VM_WRITE权限。

  • 您对WriteProcessMemory()使用与其声明不匹配。 这就是为什么您遇到编译器错误的原因。

  • 您将HWND的进程ID作为DTM_SETSYSTEMTIMELPARAM DTM_SETSYSTEMTIME ,但是它期望分配的TSystemTime指针代替。

尝试更多类似这样的方法:

procedure ChangeOutsideDateTime(h: HWND; dt: TDateTime);
var
  st: TSystemTime;
  PID: DWORD;
  hProc: THandle;
  pst: Pointer;
  NumWrote: SIZE_T;
begin
  GetWindowThreadProcessId(h, PID);
  hProc := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_WRITE, false, PID);
  if hProc <> 0 then
  try
    pst := VirtualAllocEx(hProc, nil, SizeOf(st), MEM_COMMIT, PAGE_READWRITE);
    if pst <> nil then
    try
      DateTimeToSystemTime(dt, st);
      if WriteProcessMemory(hProc, pst, @st, SizeOf(st), NumWrote) then begin
        SendMessage(h, DTM_SETSYSTEMTIME, GDT_VALID, LPARAM(pst));
      end;
    finally
      VirtualFreeEx(hProc, pst, 0, MEM_RELEASE);
    end;
  finally
    CloseHandle(hProc);
  end;
end;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM