Closed hrt closed 5 years ago
Nice, for your information the Vmm functions of PCILeech will be removed in the next major release since they are already supported by the Memory Process File System project (which integrates fully with PCILeech). If doing new work I recommend looking into Memory Process File System vmm.dll linked to pcileech.dll instead.
You are right that the annotation is messed up, pb is an input buffer in this case. Thanks for reporting this. I'll fix this in the Memory Process File System project. (I'll fix this in the next major PCILeech release by removing the API). I'll check the VmmWrite to see if I get the same problem though. Or please let me know if you experience the same problem with the Memory Process File System vmm.dll implementation.
thanks!
Appears like the annotation is fine in vmmdll
BOOL VMMDLL_MemWrite(_In_ DWORD dwPID, _In_ ULONG64 qwVA, _In_ PBYTE pb, _In_ DWORD cb);
However, I am experiencing the same issue with vmmdll. Maybe worth noting that VMMDLL_MemReadEx works fine
I'm unable to replicate this with FPGA hardware. A couple of questions:
What hardware are you using? FPGA hardware? PCIeScreamer or Xilinx dev board?
are you checking the return value of the pcbReadOpt parameter from VMMDLL_MemReadEx. The read function will return TRUE even though only a partial read or no read was possible - you have to check the number of read bytes i the pcbReadOpt output parameter to be sure your read was completely successful.
what address are you reading/writing to, any special offsets, does the read cross page bounds, not DWORD aligned 32/64-bit address? just giving a sample address that's not working should be enough for me right now.
target OS, I assume Win10 64-bit?
at last I plan to release a new version of vmm.dll tomorrow with a bunch of bug-fixes included, it would be aswesome if you could try that one out as well after the relase. mbe the problem isn't existing in the new version.
Unfortunately I won't be able to play around today since I have two exams today. But I can give you info I already know.
First of all lets clarify that reading memory works fine it's only write memory that fails (100% of the time). I have used the pcbreadoutput param (in the read function) to print the hex ascii and it prints a lot of lines out which are correct to what's in memory
I just pushed some very minor bugfixes to the Memory Process File System (vmm.dll). It would be awesome if you could re-check if your issue still exists.
I just checked with the new dll and lib and still cannot write. An example address I am using is 0x7ffca4ddce0c . On the target process the value at the address doesn't change and VMMDLL_MemWrite returns false. cbWrite is 0 and cb is 8 within VmmWrite .
Related virtual memory region on target process:
Also, I don't run the code under _INITIALIZE_FROM_FPGA since it fails
CALL: VMMDLL_InitializeFPGA
FAIL: VMMDLL_InitializeFPGA
So I did some printing and I think I'm missing something. Perhaps I'm not able to write because I don't run VMMDLL_InitializeFPGA (since it fails due to MemProcFS: Failed to connect to memory acquisition device)?
ctxVmm->fReadOnly is true in VmmWriteScatterVirtual I commented that line out to ignore this flag.
ctxMain->dev.pfnWriteMEM is NULL in DeviceWriteMEM
update: I'll stick to my old ways for now (no dll and cr3 specific)
BOOL _WVM(_Inout_ PPCILEECH_CONTEXT ctx, QWORD virtualAddress, PBYTE buffer, SIZE_T size)
{
QWORD physicalAddress = VirtualToPhysical(ctx, virtualAddress);
if (!physicalAddress)
return FALSE;
SIZE_T pageSize = 0x1000;
PBYTE pageBuffer = LocalAlloc(0, pageSize);
QWORD physicalAddressBase = physicalAddress & 0xfffffffff000;
QWORD physicalAddressOffset = physicalAddress & 0xfff;
// we need to first read the page
if (!DeviceReadDMA(ctx, physicalAddressBase, pageBuffer, pageSize, PCILEECH_MEM_FLAG_RETRYONFAIL))
return FALSE;
// overwite the pageBuffer with what we want to write
SIZE_T sizeToWrite = MIN(size, pageSize - physicalAddressOffset);
memcpy(&(pageBuffer[physicalAddressOffset]), buffer, sizeToWrite);
// write modified page back to target
if (!DeviceWriteDMA(ctx, physicalAddressBase, pageBuffer, pageSize, PCILEECH_MEM_FLAG_RETRYONFAIL))
return FALSE;
LocalFree(pageBuffer);
if (sizeToWrite < size)
{
if (!_WVM(ctx, virtualAddress + sizeToWrite, &(buffer[sizeToWrite]), size - sizeToWrite))
return FALSE;
}
return TRUE;
}
When you say you aren't running the VMMDLL_InitializeFPGA are you by any chance initializing a file instead? The ReadOnly flag is only set if the device type is set to file (which doesn't allow writing).
When you say VMMDLL_InitializeFPGA
fail, have you made sure both pcileech.dll
and FTD3XX.dll
is put in the same directory as vmm.dll
?
You can enable the verbose output to see why the FPGA init fails in the initialization stage by calling (instead of the InitializeFPGA function):
VMMDLL_InitializeReserved(6, (LPSTR[]) {"", "-device", "fpga", "-vdll", "-v", "-vv"});
Yes I do initialize with a file. Are the cr3's found some other way instead of through a dump file? Also I was not aware of FTD3XX.dll will have a look
Update, it all works good. I'm surprised it finds all the cr3s so quickly. Very convenient
Are there any limits on VMMDLL_MemWrite? e.g. max size, aligned address currently having trouble writing a size of 1024 bytes edit: this might be because I am writing across memory regions - will check edit2: can't find an issue with crossing memory regions
Thanks for the update and for clearing up the misunderstanding about the file not being read/write. I'll update the documentation in the next release.
Also, if running against a live FPGA the vmm.dll does refreshes of the process list which may lead to small hickups in access times. There are options that will let you fine tune or disable this behavior.
The MemWrite should be able to write across memory pages and 1024 bytes shouldn't be problematic. But the write parts aren't as well tested as the read parts so I cannot guarantee that it's completely bug free - even though I haven't had a problem in my tests. I'll look into it.
Thanks, I don't think it's an issue with size - I've tried reducing it. The write to that specific address never works. But when I actively look at the memory on cheat engine on the target pc the write works. I suspect it's because the virtual address (region) I want to write to doesn't have an active physical address since it isn't used at all by the process
but the writes to other addresses work fine
I've decided to move away from my own work and begin using the dll.
Is the signature of this function correct? BOOL PCILeech_VmmWrite(In DWORD dwPID, In ULONG64 qwVA, Out PBYTE pb, In DWORD cb);
My first impression is that pb should be the input buffer from which the function should be writing from rather than being some sort of output? And cb is the size to write (from the buffer, pb)?
With all of that being said, I can't get it to write a 64bit value
targetLock address is fine since I've printed it and checked on the target PC. dwPID is fine too