Skip to content

Commit

Permalink
finish the NtReadVirtualMemory hook
Browse files Browse the repository at this point in the history
  • Loading branch information
cheat-engine committed Jan 18, 2017
1 parent cc298c7 commit 2709e88
Showing 1 changed file with 87 additions and 43 deletions.
130 changes: 87 additions & 43 deletions Cheat Engine/dbk32/DBK32functions.pas
Original file line number Diff line number Diff line change
Expand Up @@ -1385,7 +1385,7 @@ function RPM(hProcess:THANDLE;lpBaseAddress:pointer;lpBuffer:pointer;nSize:DWORD
result:=ReadProcessMemory64(hProcess, uint64(ptrUint(lpBaseAddress)), lpBuffer, nSize, NumberOfBytesRead);
end;

function ReadProcessMemory64(hProcess:THANDLE;lpBaseAddress:UINT64;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesRead:PtrUInt):BOOL; stdcall;
function ReadProcessMemory64_Internal(processid:dword;lpBaseAddress:UINT64;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesRead:PtrUInt):BOOL; stdcall;
type TInputstruct=packed record
processid: uint64;
startaddress: uint64;
Expand All @@ -1410,58 +1410,70 @@ function ReadProcessMemory64(hProcess:THANDLE;lpBaseAddress:UINT64;lpBuffer:poin
numberofbytesread:=0;
//find the hprocess in the handlelist, if it isn't use the normal method (I could of course use NtQueryProcessInformation but it's undocumented and I'm too lazy to dig it up

handlemapmrew.Beginread;
validhandle:=handlemap.GetData(hProcess,l);
handlemapmrew.Endread;


if validhandle then
if hdevice<>INVALID_HANDLE_VALUE then
begin
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=IOCTL_CE_READMEMORY;
mempointer:=lpBaseAddress;
bufpointer:=ptrUint(lpbuffer);
cc:=IOCTL_CE_READMEMORY;
mempointer:=lpBaseAddress;
bufpointer:=ptrUint(lpbuffer);

ok:=true;
while ok do
ok:=true;
while ok do
begin
input.processid:=processid;
if (mempointer and $fff) > 0 then //uneven
begin
input.processid:=l.processid;
if (mempointer and $fff) > 0 then //uneven
begin
toread:=4096-(mempointer and $fff);
if toread>(nSize-numberofbytesread) then toread:=nSize-numberofbytesread;
end
toread:=4096-(mempointer and $fff);
if toread>(nSize-numberofbytesread) then toread:=nSize-numberofbytesread;
end
else
begin
if nSize-numberofbytesread>=4096 then
toread:=4096
else
begin
if nSize-numberofbytesread>=4096 then
toread:=4096
else
toread:=nSize-numberofbytesread;
end;
toread:=nSize-numberofbytesread;
end;

input.bytestoread:=toread;
input.startaddress:=mempointer;
input.bytestoread:=toread;
input.startaddress:=mempointer;

if not deviceiocontrol(hdevice,cc,@input,sizeof(input),pointer(bufpointer),toread,br,nil) then
exit;
if not deviceiocontrol(hdevice,cc,@input,sizeof(input),pointer(bufpointer),toread,br,nil) then
exit;

inc(mempointer,toread);
inc(bufpointer,toread);
inc(numberofbytesread,toread);
inc(mempointer,toread);
inc(bufpointer,toread);
inc(numberofbytesread,toread);

if numberofbytesread=nSize then
begin
result:=true;
exit;
end;
if numberofbytesread=nSize then
begin
result:=true;
exit;
end;
end;
end;
end;

exit;
end else if not l.validhandle then exit; //else use the normal method...
function ReadProcessMemory64(hProcess:THANDLE;lpBaseAddress:UINT64;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesRead:PtrUInt):BOOL; stdcall;
var
l: THandleListEntry;
validhandle: boolean;
begin
result:=false;
numberofbytesread:=0;
//find the hprocess in the handlelist, if it isn't use the normal method (I could of course use NtQueryProcessInformation but it's undocumented and I'm too lazy to dig it up

handlemapmrew.Beginread;
validhandle:=handlemap.GetData(hProcess,l);
handlemapmrew.Endread;

if validhandle then
begin
if (hdevice<>INVALID_HANDLE_VALUE) then
exit(ReadProcessMemory64_Internal(l.processid,lpBaseAddress, lpBuffer, nSize,NumberOfBytesRead));

if not l.validhandle then exit; //else use the normal method...
end;
//not found so ....

//not found, or driver not loaded and a valid handle
result:=windows.ReadProcessMemory(hProcess,pointer(ptrUint(lpBaseAddress)),lpBuffer,nSize,NumberOfBytesRead);
end;

Expand Down Expand Up @@ -1551,8 +1563,41 @@ function WriteProcessMemory64(hProcess:THANDLE;BaseAddress:qword;lpBuffer:pointe
end;

function DBK_NtReadVirtualMemory(ProcessHandle : HANDLE; BaseAddress : PVOID; Buffer : PVOID; BufferLength : ULONG; ReturnLength : PULONG): NTSTATUS; stdcall;
var
l: THandleListEntry;
validhandle: boolean;
br: ptruint;
begin
result:=oldNtReadVirtualMemory(processhandle, BaseAddress, Buffer, BufferLEngth, ReturnLength);
//outputdebugstring('----DBK_NtReadVirtualMemory----'); (don't do this, inf loop)
handlemapMREW.Beginread;
validhandle:=handlemap.GetData(ProcessHandle, l);
handlemapMREW.Endread;

if validhandle then
begin
if hdevice<>INVALID_HANDLE_VALUE then
begin
//read/write using kernelmode rpm
if ReturnLength<>nil then
br:=returnlength^;

try
if ReadProcessMemory64_Internal(l.processid, qword(baseaddress), buffer,bufferlength, br) then
begin
result:=0;
ReturnLength^:=br;
end
else
result:=STATUS_ACCESS_DENIED;
except
result:=STATUS_ACCESS_VIOLATION;
end;

if result=0 then exit;
end;
end;

result:=oldNtReadVirtualMemory(processhandle, BaseAddress, Buffer, BufferLength, ReturnLength);
end;

function DBK_NtQueryInformationProcess(ProcessHandle: HANDLE; ProcessInformationClass: PROCESSINFOCLASS; ProcessInformation: PVOID; ProcessInformationLength: ULONG; ReturnLength: PULONG): NTSTATUS; stdcall;
Expand Down Expand Up @@ -1588,7 +1633,6 @@ toutput=record
//if (ProcessHandle=-1) or (ProcessInformationClass<>ProcessBasicInformation) then
// exit(oldNtQueryInformationProcess(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, ReturnLength));

outputdebugstring('----DBK_NtQueryInformationProcess----');
handlemapMREW.Beginread;
validhandle:=handlemap.GetData(ProcessHandle, l);
handlemapMREW.Endread;
Expand Down

0 comments on commit 2709e88

Please sign in to comment.