ReadProcessMemory problem on x64

c++ / delphi package - dll injection and api hooking
Post Reply
ExPx
Posts: 34
Joined: Fri Oct 21, 2016 3:20 pm

ReadProcessMemory problem on x64

Post by ExPx »

Hi all.

I have succesfully injected chrome.exe(x64) to filter DNS queries. I have a problem with 64bit processes. My test project contains signed driver, windows service for injection(x64), injection dll(x64) and desktop app (x64). Injected dll sends WM_COPYDATA with data contains processid, pointer and data size to desktop app. Then desktop app receives this message open process with PROCESS_VM_READ flag and try to read data at pointer. After using ReadProcessMemory I get ERROR_PARTIAL_COPY error (by using GetLastError). I read somewhere this error generally result of trying to read x64 process memory from x86 process. But I am using x64 process. Some of my code.

This is IPC messaging structure

Code: Select all

Type TIPCMessage = record
       pid       : Integer;
       IP        : ShortString;
       Port      : Integer;
       Sock      : Integer;
       Size      : Integer; 
       Address   : Cardinal;
       MsgType   : Integer;
     End;

injection dll

Code: Select all

msg : TIPCMessage;
aCopyData   : TCopyDataStruct;


with aCopyData do
begin
	dwData := 0;
	cbData := SizeOf(msg);
	lpData := @msg;
end;
  
SendMessageTimeoutW(hTargetWnd, WM_COPYDATA,WPARAM(666), LPARAM(@aCopyData),0, 10000,@smresult) 
Desktop app

Code: Select all

var  
  msg        : TIPCMessage;
  BytesRead  : NativeUInt;
  DataBytesByteArray  : PByteArray;


ReadProcessMemory(Proc, Pointer(msg.Address), DataBytesByteArray, msg.Size, BytesRead)

iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Re: ReadProcessMemory problem on x64

Post by iconic »

Type TIPCMessage = record
pid : Integer;
IP : ShortString;
Port : Integer;
Sock : Integer;
Size : Integer;
Address : Cardinal;
MsgType : Integer;
End;
PID doesn't need a signed type since the value is never negative, use DWORD

You might make IP a DWORD (assuming IPv4) which you can convert to string form (PAnsiChar) with something like ws2_32.dll!inet_ntoa() in the receiving application

Port is represented as a WORD/USHORT unsigned type, not a 4 byte signed Integer (Again, no need to use a signed type such as mentioned with PID)

Size doesn't need to be signed, make DWORD

Address needs to be UINT64 (8 bytes wide) and not a Cardinal/DWORD (4 bytes wide) since you said Chrome.exe is 64-bit. This is the real problem I see here since larger addresses will be truncated or high virtual addresses with large read sizes

You might also use the "packed" modifier for the record (reduces storage size, optional since this isn't a big structure), both sender and receiver need to have the same keyword present

You're better off reading the data inside your injected DLL in-the-moment instead of sending the virtual address to another separate process to do so. If you don't want to do that you can alloc your own mem in the injected process, copy the data to this new buffer and then pass the allocation pointer to your receiving app. This way you know it's allocated by you and will not magically disappear before reading it or have the data change before your receiving app can read it. Afterwards, you can VirtualFreeEx() on the pointer address.

madCodeHook's SendIpcMessage() can easily be used for this, you're making things more difficult than they need to be ;) Also, calling user32 functions such as SendMessage variants inside critical system services can bring the system down (BSOD). I'm not saying you're doing this directly since it sounds like you only want to affect CHROME however this is good to know for the future. I'd recommend using madCodeHook's IPC facilities and losing SendMessageXxX

P.S: Can't help but to ask, why the 666 in your code as an identifier? I hope this browser injection is for legit purposes as we all know what that number implies in the security world


--Iconic
ExPx
Posts: 34
Joined: Fri Oct 21, 2016 3:20 pm

Re: ReadProcessMemory problem on x64

Post by ExPx »

Thank you. I will try uint64 type for address variable. I hope this will work.
I tried many times madshi's ipc mechanism but every time i get crashes both server and client side. I dont hook just chrome. İt is system wide hook and control access to web sites. I can send you products used with pm. Dont worry it is completely legal.

666 is magic :) İt is simple security number for handler function of desktop app. Desktop app does more stuff more than hooking message handling.
ExPx
Posts: 34
Joined: Fri Oct 21, 2016 3:20 pm

Re: ReadProcessMemory problem on x64

Post by ExPx »

Thank you again iconic. Converting address to UINT64 solved the problem.
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Re: ReadProcessMemory problem on x64

Post by iconic »

You're welcome, thank you for sharing your results with us :D

--Iconic
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: ReadProcessMemory problem on x64

Post by madshi »

Thanks to iconic for good support... :D
ExPx
Posts: 34
Joined: Fri Oct 21, 2016 3:20 pm

Re: ReadProcessMemory problem on x64

Post by ExPx »

One more question. Is there way to read 64bit process memory from x86 process by using ReadProcessMemory ?
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: ReadProcessMemory problem on x64

Post by madshi »

Your question isn't completely clear, but I suppose you want to do a google search for ReadProcessMemory64.
ExPx
Posts: 34
Joined: Fri Oct 21, 2016 3:20 pm

Re: ReadProcessMemory problem on x64

Post by ExPx »

In first question my desktop app is x64. It was a test app and no issue with ReadProcessMemory. But my real application is x86. So ReadProcessMemory from x86 app is not working. Converting this app to x64 will cost me too much time. Can I use ReadProcessMemory64 from x86 app ?
ExPx
Posts: 34
Joined: Fri Oct 21, 2016 3:20 pm

Re: ReadProcessMemory problem on x64

Post by ExPx »

Thank you madshi for ReadProcessMemory64 trick. I found that library and successfully implemented it.
Post Reply