How to use WriteProcessMemory in Delphi
我无法编译此代码。我可以帮忙吗?谢谢。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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参数的类型必须相同"。
Types of actual and formal var parameters must be identical
这是编译器错误E2003。如果遇到不了解的编译器错误,则要做的第一件事就是阅读文档。它说:
For a variable parameter, the actual argument must be of the exact type of the formal parameter.
导致此错误的函数调用为
1 2 | function WriteProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer; nSize: SIZE_T; var lpNumberOfBytesWritten: SIZE_T): BOOL; stdcall; |
这里只有一个
其他一些评论:
-
对
VirtualAllocEx 的调用注定会失败,因为您传递了窗口句柄而不是进程句柄。 - 从语义上讲,测试正线程ID是没有意义的。测试成功与否不等于零。
-
您无需检查
OpenProcess 返回值。那很容易失败。 -
您不能使用
WriteProcessMemory 必需的PROCESS_VM_WRITE 访问权限来打开进程。 -
如果对
WriteProcessMemory 的调用失败,则泄漏句柄。 -
WriteProcessMemory 的返回类型为BOOL 。 -
hDTP 是进程ID的奇怪名称。该名称表明您认为它是日期时间选择器控件的句柄。它不是。这是进程ID。 -
您在
SendMessage 调用中传递该进程ID,而不是您刚刚编写的系统时间的地址。
您的代码中有几个错误。
-
您正在将
HWND 传递给VirtualAllocEx() ,但是它希望将THandle 传递给打开的进程。并且您在打开进程句柄之前正在调用VirtualAllocEx() 。而且您不要求对分配的内存进行写访问。 -
在调用
OpenProcess() 时,您并不是在请求WriteProcessMemory() 所需的PROCESS_VM_WRITE 许可。 -
您使用的
WriteProcessMemory() 与它的声明不匹配。这就是为什么出现编译器错误的原因。 -
您正在将
HWND 的进程ID作为DTM_SETSYSTEMTIME 的LPARAM 传递,但是它期望分配的TSystemTime 指针代替。
尝试更多类似的方法:
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 | 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; |