簡體   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