跨模块边界读取进程内存
ReadProcessMemory across module boundaries
我正在使用 ReadProcessMemory
读取进程的内存。似乎当我读取模块的末尾时,其余字节未成功读取。我还收到以下内核错误:
299: Only part of a ReadProcessMemory or WriteProcessMemory request was completed.
如果我列出带有 EnumProcessModules
的所有模块,其中 none 包含我试图读取的地址,但 Cheat Engine
可以很好地显示所有内存内容。 Cheat Engine
说模块的大小是 0xE000
这正是我在它停止之前可以读取的字节数并且只将 0x00
字节放入缓冲区这是不正确的并且不代表实际内存内容。
下面的代码是否不适合跨模块边界读取(即使它们是连续的)?
static Memory getOutputMemory(Pointer openedProcess, long baseAddress, int length)
{
val outputMemory = new Memory(length);
val intByReference = new IntByReference();
if (!MY_KERNEL_32.ReadProcessMemory(openedProcess, baseAddress,
outputMemory, (int) outputMemory.size(), intByReference))
{
checkForKernelError();
}
return outputMemory;
}
事实证明,单独读取内存页是如何做到的,例如喜欢下面的代码:
public byte[] readBytes(long address, int length)
{
val byteBuffer = allocate(length);
var totalRemainingLength = length;
var currentAddress = address;
while (totalRemainingLength > 0)
{
val memoryBasicInformation = new MEMORY_BASIC_INFORMATION();
val process = new HANDLE(processHandle);
val pointer = new Pointer(currentAddress);
val memoryPageQueryResult = KERNEL_32.VirtualQueryEx(process, pointer, memoryBasicInformation,
new BaseTSD.SIZE_T(memoryBasicInformation.size()));
if (memoryPageQueryResult.equals(new SIZE_T(0)))
{
throw new IllegalStateException("Memory not contiguous");
}
val memoryPageBaseAddress = nativeValue(memoryBasicInformation.baseAddress);
val memoryPageSize = memoryBasicInformation.regionSize.longValue();
val memoryPageEndAddress = memoryPageBaseAddress + memoryPageSize;
val remainingMemoryPageBytes = memoryPageEndAddress - address;
val currentLength = (int) min(totalRemainingLength, remainingMemoryPageBytes);
val outputMemory = getOutputMemory(processHandle, currentAddress, currentLength);
val byteArray = outputMemory.getByteArray(0, currentLength);
byteBuffer.put(byteArray);
currentAddress += currentLength;
totalRemainingLength -= currentLength;
}
return byteBuffer.array();
}
static Memory getOutputMemory(Pointer openedProcess, long baseAddress, int length)
{
val outputMemory = new Memory(length);
val intByReference = new IntByReference();
if (!MY_KERNEL_32.ReadProcessMemory(openedProcess, baseAddress,
outputMemory, (int) outputMemory.size(), intByReference))
{
checkForKernelError();
}
return outputMemory;
}
我正在使用 ReadProcessMemory
读取进程的内存。似乎当我读取模块的末尾时,其余字节未成功读取。我还收到以下内核错误:
299: Only part of a ReadProcessMemory or WriteProcessMemory request was completed.
如果我列出带有 EnumProcessModules
的所有模块,其中 none 包含我试图读取的地址,但 Cheat Engine
可以很好地显示所有内存内容。 Cheat Engine
说模块的大小是 0xE000
这正是我在它停止之前可以读取的字节数并且只将 0x00
字节放入缓冲区这是不正确的并且不代表实际内存内容。
下面的代码是否不适合跨模块边界读取(即使它们是连续的)?
static Memory getOutputMemory(Pointer openedProcess, long baseAddress, int length)
{
val outputMemory = new Memory(length);
val intByReference = new IntByReference();
if (!MY_KERNEL_32.ReadProcessMemory(openedProcess, baseAddress,
outputMemory, (int) outputMemory.size(), intByReference))
{
checkForKernelError();
}
return outputMemory;
}
事实证明,单独读取内存页是如何做到的,例如喜欢下面的代码:
public byte[] readBytes(long address, int length)
{
val byteBuffer = allocate(length);
var totalRemainingLength = length;
var currentAddress = address;
while (totalRemainingLength > 0)
{
val memoryBasicInformation = new MEMORY_BASIC_INFORMATION();
val process = new HANDLE(processHandle);
val pointer = new Pointer(currentAddress);
val memoryPageQueryResult = KERNEL_32.VirtualQueryEx(process, pointer, memoryBasicInformation,
new BaseTSD.SIZE_T(memoryBasicInformation.size()));
if (memoryPageQueryResult.equals(new SIZE_T(0)))
{
throw new IllegalStateException("Memory not contiguous");
}
val memoryPageBaseAddress = nativeValue(memoryBasicInformation.baseAddress);
val memoryPageSize = memoryBasicInformation.regionSize.longValue();
val memoryPageEndAddress = memoryPageBaseAddress + memoryPageSize;
val remainingMemoryPageBytes = memoryPageEndAddress - address;
val currentLength = (int) min(totalRemainingLength, remainingMemoryPageBytes);
val outputMemory = getOutputMemory(processHandle, currentAddress, currentLength);
val byteArray = outputMemory.getByteArray(0, currentLength);
byteBuffer.put(byteArray);
currentAddress += currentLength;
totalRemainingLength -= currentLength;
}
return byteBuffer.array();
}
static Memory getOutputMemory(Pointer openedProcess, long baseAddress, int length)
{
val outputMemory = new Memory(length);
val intByReference = new IntByReference();
if (!MY_KERNEL_32.ReadProcessMemory(openedProcess, baseAddress,
outputMemory, (int) outputMemory.size(), intByReference))
{
checkForKernelError();
}
return outputMemory;
}