如何在Delphi中使用WriteProcessMemory

shi*_*ken 0 delphi delphi-xe2

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

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;
Run Code Online (Sandbox Code Playgroud)

它显示"实际和正式var参数的类型必须相同"在使用"WriteProcessMemory"的行.

Dav*_*nan 6

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

这是编译器错误E2003.如果遇到您不理解的编译器错误,首先要做的是阅读文档.它说:

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

导致此错误的函数调用是WriteProcessMemory.让我们来看看它的声明:

function WriteProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; 
  lpBuffer: Pointer; nSize: SIZE_T; var lpNumberOfBytesWritten: SIZE_T): BOOL; stdcall;
Run Code Online (Sandbox Code Playgroud)

这里只有一个var参数,即最终参数.您传递的变量必须是类型SIZE_T,但是您传递了一个类型的变量DWORD.那就是不匹配.

其他一些评论:

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