内核驱动程序读取内存未发送整个字符串
Kernel driver read memory is not sending the whole string
我有这个内核驱动程序用于从进程内存中读取字符串:
KeAttachProcess(GlobalProcessPE);
char* source = *(ULONG*)pBuf;
RtlZeroMemory(pBuf, pIoStackLocation->Parameters.DeviceIoControl.OutputBufferLength);
RtlCopyMemory(pBuf, source, 256);
KeDetachProcess();
下面是C++中的通信过程:
DWORD ReadBuffer2[180] = { 0 };
DeviceIoControl(hDevice, IOCTL_READPROCMEM_S, &msg, sizeof(msg), ReadBuffer2, sizeof(ReadBuffer2), &dwBytesRead, NULL);
printf("Message: %s\n", ReadBuffer2);
printf("Bytes read: %d\n", dwBytesRead);
在 运行 和搜索字符串时,它实际上捕获了它的前四个字母,并显示以下内容:
Message: ABCD
Bytes read: 4
我用另一种方法检查了字符串,它应该显示 ABCDEFGHIJKL...
问题来了,为什么它只读取(或可能写入)前四个字节?
我已经通过在每个地址 + 4 处读取每 4 个字符来读取字符串。
通信代码如下:(我在Driver里面加了一些__try {} _except () {}所以不会蓝屏)
std::string str = "";
bool scanning = true;
for (int i = 0; i < 35; i++) {
if (!scanning) break;
msg = 0x095A2A28 + i * 0x4;
DWORD ReadBuffer2[50] = {0};
DeviceIoControl(hDevice, IOCTL_READPROCMEM_S, &msg, sizeof(msg), ReadBuffer2, sizeof(ReadBuffer2), &dwBytesRead, NULL);
char dtostr[4];
sprintf(dtostr, "%s", ReadBuffer2);
for (int l = 0; l < 4; l++) {
str += dtostr[l];
if (dtostr[l] == '[=10=]') {
scanning = false;
break;
}
}
}
std::cout << "~Message: " << str << std::endl;
欢迎来到"kernel land"。这个答案可能有点晚,但总比没有好吧?
您对 send/read 数据所做的操作既不安全又丑陋。
要将整个字符串发送到用户模式,这里是一个例子:
PCHAR data = "This String is from Device Driver !!!";
size_t datalen = strlen(data) + 1;//Length of data including null
RtlCopyBytes(Irp->AssociatedIrp.SystemBuffer, data, irpStack->Parameters.DeviceIoControl.OutputBufferLength);
假设您没有使用 UNICODE,请注意,尽管此示例 100% 有效,但它并不完整,需要改进。
尽情享受吧。
我有这个内核驱动程序用于从进程内存中读取字符串:
KeAttachProcess(GlobalProcessPE);
char* source = *(ULONG*)pBuf;
RtlZeroMemory(pBuf, pIoStackLocation->Parameters.DeviceIoControl.OutputBufferLength);
RtlCopyMemory(pBuf, source, 256);
KeDetachProcess();
下面是C++中的通信过程:
DWORD ReadBuffer2[180] = { 0 };
DeviceIoControl(hDevice, IOCTL_READPROCMEM_S, &msg, sizeof(msg), ReadBuffer2, sizeof(ReadBuffer2), &dwBytesRead, NULL);
printf("Message: %s\n", ReadBuffer2);
printf("Bytes read: %d\n", dwBytesRead);
在 运行 和搜索字符串时,它实际上捕获了它的前四个字母,并显示以下内容:
Message: ABCD
Bytes read: 4
我用另一种方法检查了字符串,它应该显示 ABCDEFGHIJKL...
问题来了,为什么它只读取(或可能写入)前四个字节?
我已经通过在每个地址 + 4 处读取每 4 个字符来读取字符串。
通信代码如下:(我在Driver里面加了一些__try {} _except () {}所以不会蓝屏)
std::string str = "";
bool scanning = true;
for (int i = 0; i < 35; i++) {
if (!scanning) break;
msg = 0x095A2A28 + i * 0x4;
DWORD ReadBuffer2[50] = {0};
DeviceIoControl(hDevice, IOCTL_READPROCMEM_S, &msg, sizeof(msg), ReadBuffer2, sizeof(ReadBuffer2), &dwBytesRead, NULL);
char dtostr[4];
sprintf(dtostr, "%s", ReadBuffer2);
for (int l = 0; l < 4; l++) {
str += dtostr[l];
if (dtostr[l] == '[=10=]') {
scanning = false;
break;
}
}
}
std::cout << "~Message: " << str << std::endl;
欢迎来到"kernel land"。这个答案可能有点晚,但总比没有好吧?
您对 send/read 数据所做的操作既不安全又丑陋。
要将整个字符串发送到用户模式,这里是一个例子:
PCHAR data = "This String is from Device Driver !!!";
size_t datalen = strlen(data) + 1;//Length of data including null
RtlCopyBytes(Irp->AssociatedIrp.SystemBuffer, data, irpStack->Parameters.DeviceIoControl.OutputBufferLength);
假设您没有使用 UNICODE,请注意,尽管此示例 100% 有效,但它并不完整,需要改进。
尽情享受吧。