I'm going to use this code to read integers, single and double floating point, and I can't figure this out
NTSTATUS KReadProcessMemory(IN PEPROCESS Process, IN PVOID Address, IN UINT32 Length, IN OUT PVOID Buffer)
{
NTSTATUS ret_status = 0;
KAPC_STATE apc_state;
RtlZeroMemory(&apc_state, sizeof(KAPC_STATE));
PVOID tmpBuf_Kernel = ExAllocatePool(NonPagedPool, Length);
KeStackAttachProcess((PVOID)Process, &apc_state);
BOOLEAN dwRet = MmIsAddressValid(Address);
if (dwRet)
{
KdPrint(("yjx[sys64] RtlCopyMemory(Address=%p, Buffer=%p, Length=%d);\r\n", Address, Buffer, Length));
BOOLEAN isOk = IsOkWritePtr(Address);
if (isOk)
{
__try
{
//可以访问
RtlCopyMemory(tmpBuf_Kernel, Address, Length); // c/c++ memcpy
ret_status = STATUS_SUCCESS;//表示复制成功
}
__except (1)
{
ret_status = STATUS_UNSUCCESSFUL; //不可访问
__debugbreak();
KdPrint(("yjx:sys64:Error line=%d\n", __));
}
}
else
{
ret_status = STATUS_UNSUCCESSFUL; //不可访问
}
}
else
{
KdPrint(("yjx:sys64:Error line=%d\n", __LINE__));
ret_status = STATUS_UNSUCCESSFUL;
}
KeUnstackDetachProcess(&apc_state);
RtlCopyMemory(Buffer, tmpBuf_Kernel, Length);
ExFreePool(tmpBuf_Kernel);
return ret_status;
}
//dwPid为目标进程id
//lpBaseAddress 目标进程地址
//lpBuffer 当前进程地址 1
//内核内存地址 当前进程地址 2
NTSTATUS ReadProcessMemoryForPid(UINT32 dwPid, PVOID pBase, PVOID lpBuffer, UINT32 nSize)
{
NTSTATUS retstatus = STATUS_SUCCESS;
//根据pid获取PEPROCESS OpenProcess
PEPROCESS Seleted_pEPROCESS = NULL;
KdPrint(("yjx:sys64 pid=%d pBase=%p %s 行号=%d\n", dwPid, pBase, __FUNCDNAME__, __LINE__));
retstatus = PsLookupProcessByProcessId((PVOID)(UINT_PTR)(dwPid), &Seleted_pEPROCESS);
if (retstatus == STATUS_SUCCESS)
{
retstatus = KReadProcessMemory(Seleted_pEPROCESS, (PVOID)pBase, nSize, lpBuffer);
ObDereferenceObject(Seleted_pEPROCESS);
//return retstatus;
}
else
{
KdPrint(("yjx sys64 PsLookupProcessByProcessId Fail...%s line=%d\n", __FUNCDNAME__, __LINE__));
//return STATUS_UNSUCCESSFUL;
}
return retstatus;// STATUS_UNSUCCESSFUL;
}
void IRP_IO_通过PID读内存1(PIRP pirp)
{
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(pirp); //获取应用层传来的参数
UINT64* 缓冲区 = (UINT64*)(pirp->AssociatedIrp.SystemBuffer);
KdPrint(("yjx:%s 行号%d\n", __FUNCDNAME__, __LINE__));
if (缓冲区)
{
//
//int*p = (int*)缓冲区;
UINT32 PID = (UINT32)(UINT64)缓冲区[0]; //传入数据
PVOID pBase = (PVOID)((UINT64)缓冲区[1] ); //传入数据
//PVOID lpBuffer = (PVOID)(UINT64)缓冲区[2]; //传入数据
UINT64 nSize = (UINT64)缓冲区[3]; //传入数据
UINT32 ReadSize = ReadProcessMemoryForPid(PID, pBase, 缓冲区, nSize);
ReadSize;
pirp->IoStatus.Status = STATUS_SUCCESS;
pirp->IoStatus.Information = nSize;//返回给DeviceIoControl中的 倒数第二个参数lpBytesReturned
IoCompleteRequest(pirp, IO_NO_INCREMENT);//调用方已完成所有I/O请求处理操作 并且不增加优先级
}
irpStack;
}
这是读64位整数的代码 怎么改成读unicode字符串
UINT64 PID读内存地址x64(INT pid, UINT_PTR 地址)
{
DWORD dwRetSize = 0;//返回字节数
ULONG64 tmp = 0;//存放读取的数据
UINT64 输入缓冲区[4] = { pid,地址,0,8 };
DeviceIoControl(
DeviceHandle,//CreateFile打开驱动设备 返回的句柄
通过PID读整数1,//控制码 CTL_CODE
&输入缓冲区,//输入缓冲区指针
8 * 4,//输入缓冲区大小
&tmp,//返回缓冲区
sizeof(tmp),//返回缓冲区大小
&dwRetSize, //返回字节数
NULL);
return tmp;
}
0 Answer
is a unicode string that can be parsed by itself or output using a character conversion such as A2W or W2A, or simply CString, For example, CString str = CString(CStringA(xxx)) xxx holds the address for the text
import driver_module
driver = driver_module.Driver()
memory_code = driver.get_memory_code()
print(memory_code)
In this example, driver_module is the name of the module that contains the driver code. The class Driver is the class that represents the Driver, and get_memory_code() is a method driver of the class that retrieves strings of memory code. Once the memory_code variable is assigned a value for the memory_code string, the print function prints it to the console.
To read memory with this driver, you need to call the function with ReadProcessMemoryForPid with the following arguments:
dwPid: The process ID of the target process whose memory is to be read.
pBase: The address of the memory location in the target process from which to start reading.
lpBuffer: Pointer to the buffer in the current process to store data read from the target process's memory.
To read Unicode strings, you can use the ReadProcessMemory function. This function reads data from a specified memory address in a process and copies it to a specified buffer. Here is an example of how to read a Unicode string from a specified process using the ReadProcessMemory function:
#include <Windows.h>
// 读取 Unicode 字符串
void ReadUnicodeString(HANDLE hProcess, LPCVOID lpBaseAddress, LPWSTR lpBuffer, SIZE_T nSize)
{
SIZE_T nBytesRead = 0;
BOOL bSuccess = ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, &nBytesRead);
if (!bSuccess || nBytesRead == 0)
{
lpBuffer[0] = L'\0';
}
else
{
// 确保字符串以 null 终止
lpBuffer[nBytesRead / sizeof(WCHAR)] = L'\0';
}
}
// 读取进程中的 Unicode 字符串
void ReadProcessUnicodeString(DWORD dwProcessId, LPCVOID lpBaseAddress, LPWSTR lpBuffer, SIZE_T nSize)
{
// 打开进程句柄
HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, dwProcessId);
if (hProcess == NULL)
{
lpBuffer[0] = L'\0';
return;
}
// 读取字符串
ReadUnicodeString(hProcess, lpBaseAddress, lpBuffer, nSize);
// 关闭进程句柄
CloseHandle(hProcess);
}
To use this function, you need to pass it the ID of the process to be read, the memory address to be read, and the buffer to store the results. If the read was successful, the buffer will contain the read string, otherwise the buffer will contain the empty string. Note that the buffer size passed to the function should be large enough to hold the string to be read. If the buffer is too small, only part of the string can be read.
#include
#include
UINT64 读取Unicode字符串(INT pid, UINT_PTR 地址, std::wstring& 结果) {
DWORD dwRetSize = 0;
UINT64 tmp = 0;
// 输入缓冲区的第一个元素是PID,第二个元素是要读取的地址,
// 第三个元素是要读取的字符串的长度(以字节为单位),第四个元素是0,
// 这样驱动程序就知道要读取的是Unicode字符串。
std::vector<UINT64> 缓冲区 = { pid, 地址, 0, 0 };
// 返回缓冲区是一个用来存放字符串的缓冲区,大小为4096个字符。
std::vector<wchar_t> 返回缓冲区(4096);
// 调用DeviceIoControl函数来读取Unicode字符串。
BOOL bResult = DeviceIoControl(
DeviceHandle,
控制码,
输入缓冲区.data(),
sizeof(UINT64) * 输入缓冲区.size(),
返回缓冲区.data(),
sizeof(wchar_t) * 返回缓冲区.size(),
&dwRetSize,
NULL
);
if (bResult && dwRetSize > 0) {
// 如果读取成功,将结果保存到wstring对象中,并返回字符串的长度。
结果.assign(返回缓冲区.data(), dwRetSize / sizeof(wchar_t));
return 结果.size();
} else {
// 如果读取失败,返回0。
return 0;
}
}
.
这家伙很懒,什么都没留下...