2017-11-13 3 views
0

Ich kann diesen Code nicht kompilieren. Könnte ich Hilfe haben? Vielen Dank.So verwenden Sie 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; 

Es zeigt in Zeile „Typen der tatsächlichen und formalen Parameter var identisch sein muss“, wo verwendet „Write“.

Antwort

2

Ihr Code enthält mehrere Verbesserungen.

  • Sie vorbei ein HWND zu VirtualAllocEx(), aber es erwartet einen THandle in einen offenen Prozess statt. Und Sie rufen VirtualAllocEx() bevor Sie das Prozesshandle geöffnet haben. Und Sie fordern keinen Schreibzugriff auf den zugewiesenen Speicher an.

  • Wenn Sie OpenProcess() anrufen, fragen Sie nicht nach PROCESS_VM_WRITE Erlaubnis, die WriteProcessMemory() erfordert.

  • Ihre Verwendung von WriteProcessMemory() stimmt nicht mit ihrer Deklaration überein. Aus diesem Grund erhalten Sie einen Compilerfehler.

  • Sie vorbei am HWND ‚s Prozess-ID als LPARAM von DTM_SETSYSTEMTIME, aber es erwartet, dass die zugewiesenen TSystemTime Zeiger statt.

etwas mehr wie die Sie interessieren:

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; 
6

Typen der tatsächlichen und formalen var Parameter müssen

Dies ist Compiler-Fehler E2003 identisch sein. Wenn Sie auf einen Compilerfehler stoßen, den Sie nicht verstehen, lesen Sie zuerst documentation. Es heißt:

Für einen variablen Parameter muss das tatsächliche Argument der genaue Typ des formalen Parameters sein.

Der Funktionsaufruf, der zu diesem Fehler führt, ist WriteProcessMemory. Lassen Sie uns an seiner Erklärung aus:

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

Es gibt nur einen var Parameter ist hier, der letzte Parameter. Die übergebene Variable muss vom Typ SIZE_T sein, aber Sie haben eine Variable vom Typ DWORD übergeben. Das ist das Missverhältnis.

Einige andere Kommentare:

  • Der Aufruf an VirtualAllocEx ist zum Scheitern verurteilt, weil Sie einen Fenstergriff eher als ein Prozess Handle übergeben.
  • Semantisch macht es keinen Sinn, auf positive Thread ID zu testen. Test nicht gleich Null für Erfolg oder sonstwie.
  • Sie überprüfen den Rückgabewert OpenProcess nicht. Das könnte leicht scheitern.
  • Sie öffnen den Prozess nicht mit dem Zugriffsrecht PROCESS_VM_WRITE, das für WriteProcessMemory erforderlich ist.
  • Sie verlieren den Griff, wenn der Anruf an WriteProcessMemory fehlschlägt.
  • Der Rückgabetyp WriteProcessMemory ist BOOL.
  • hDTP ist ein seltsamer Name für eine Prozess-ID. Dieser Name weist darauf hin, dass Sie denken, dass es sich um das Handle des Datumszeitauswahlsteuerelements handelt. Es ist nicht. Es ist die Prozess-ID.
  • Sie übergeben diese Prozess-ID im SendMessage-Aufruf anstelle der Adresse der Systemzeit, die Sie gerade geschrieben haben.
+0

Können Sie dieses Verfahren als Kommentar ändern? Hast du einen Test gemacht? Für BOOL können Sie TRUE/FALSE oder 1/0 erhalten. Über SIZE_T, DWORD oder Integer sind gleich. – shinken

+0

Sie haben nach einem Compilerfehler gefragt, den ich ausführlich behandelt habe. Was würde ich testen? Ich verstehe das nicht? –

Verwandte Themen