Page 1 of 1

ReadProcessMemory problem on x64

Posted: Fri Oct 21, 2016 3:53 pm
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)


Re: ReadProcessMemory problem on x64

Posted: Sat Oct 22, 2016 2:59 am
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

Re: ReadProcessMemory problem on x64

Posted: Sat Oct 22, 2016 10:17 am
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.

Re: ReadProcessMemory problem on x64

Posted: Mon Oct 24, 2016 7:10 am
by ExPx
Thank you again iconic. Converting address to UINT64 solved the problem.

Re: ReadProcessMemory problem on x64

Posted: Mon Oct 24, 2016 8:33 am
by iconic
You're welcome, thank you for sharing your results with us :D

--Iconic

Re: ReadProcessMemory problem on x64

Posted: Thu Oct 27, 2016 6:57 am
by madshi
Thanks to iconic for good support... :D

Re: ReadProcessMemory problem on x64

Posted: Thu Oct 27, 2016 7:42 pm
by ExPx
One more question. Is there way to read 64bit process memory from x86 process by using ReadProcessMemory ?

Re: ReadProcessMemory problem on x64

Posted: Thu Oct 27, 2016 7:49 pm
by madshi
Your question isn't completely clear, but I suppose you want to do a google search for ReadProcessMemory64.

Re: ReadProcessMemory problem on x64

Posted: Thu Oct 27, 2016 8:02 pm
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 ?

Re: ReadProcessMemory problem on x64

Posted: Thu Oct 27, 2016 8:15 pm
by ExPx
Thank you madshi for ReadProcessMemory64 trick. I found that library and successfully implemented it.