Как использовать WriteProcessMemory в 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;
Он показывает "Типы фактических и формальных параметров var должны быть идентичны" в строке, где используется "WriteProcessMemory".
2 ответа
В вашем коде есть несколько митак.
вы передаете
HWND
вVirtualAllocEx()
, но это ожидаетTHandle
вместо открытого процесса. А ты звонишьVirtualAllocEx()
прежде чем вы открыли дескриптор процесса. И вы не запрашиваете запись в выделенную память.при звонке
OpenProcess()
вы не проситеPROCESS_VM_WRITE
разрешение, котороеWriteProcessMemory()
требует.ваше использование
WriteProcessMemory()
не соответствует его объявлению. Вот почему вы получаете ошибку компилятора.вы передаете
HWND
Идентификатор процесса какLPARAM
из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;
Типы фактических и формальных параметров 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
неизбежно потерпит неудачу, потому что вы передаете дескриптор окна, а не дескриптор процесса. - Семантически нет смысла проверять положительный идентификатор потока. Тест не равен нулю для успеха или иным образом.
- Вы не проверяете
OpenProcess
возвращаемое значение Это может легко потерпеть неудачу. - Вы не открываете процесс с
PROCESS_VM_WRITE
право доступа, которое необходимо дляWriteProcessMemory
, - Вы пропустите ручку, если вызов
WriteProcessMemory
выходит из строя. - Тип возврата
WriteProcessMemory
являетсяBOOL
, hDTP
странное имя для идентификатора процесса. Это имя говорит о том, что вы думаете, что это дескриптор элемента управления выбора даты. Это не. Это идентификатор процесса.- Вы передаете этот идентификатор процесса в
SendMessage
звоните, а не адрес системного времени, которое вы только что написали.