I'm attempting to read a string from a dummy program with a kernel driver. But only the first 4 char's are being read, I can't figure out why.
Part of the IOCTL code for reading the string:
else if (ControlCode = IO_READ_STRING_REQUEST)
{
PREAD_REQUEST Values = (PREAD_REQUEST)buffer;
PREAD_REQUEST ValuesOutput = (PREAD_REQUEST)buffer;
PEPROCESS process;
if (NT_SUCCESS(PsLookupProcessByProcessId(PID, &process)))
{
KeReadProcessMemory(process, Values->Address, &ValuesOutput->buffer, Values->Size);
DbgPrint((PCSTR)Values->buffer);
status = STATUS_SUCCESS;
}
else
status = STATUS_INVALID_PARAMETER;
BytesIO = sizeof(READ_REQUEST);
}
This is the read struct:
typedef struct ReadStruct
{
ULONGLONG Address;
ULONGLONG Response;
ULONGLONG Size;
char buffer[128];
} READ_REQUEST, *PREAD_REQUEST;
The DbgPrint always prints stri when it's supposed to print stringChar, and stri is returned to the usermode.
This is how it's called from usermode:
void ReadString(std::string *string, DWORD64 address)
{
ReadValues Values;
std::memset(Values.buffer, '\0', 128);
Values.Address = address;
Values.Response = 0;
Values.Size = sizeof(128);
if (!(DeviceIoControl(hDriver, IO_READ_STRING_REQUEST, &Values, sizeof(Values), &Values, sizeof(Values), 0, 0)))
{
std::cout << "RPM Failed!\n";
exit(1);
}
*string = (std::string)Values.buffer;
}
The struct is the same:
struct ReadValues
{
ULONGLONG Address;
ULONGLONG Response;
ULONGLONG Size;
char buffer[128];
};
I thought it was the size, but when I specified the size to 11 (10 + \0) it also read only 4 chars.
The problem is here:
Values.Size = sizeof(128);
^^^^^^^^^^^
This is the same as sizeof(int)
(which, I would guess, is 4
in your platform).
Either use 128
or sizeof(buffer)
(the latter is arguably better since you won't be hard-coding the same constant in several places).