Click here to Skip to main content
15,867,765 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
what i am doing in my user mode app :

C++
typedef struct KM_READ_REQUEST
{
	ULONG ProcessId;

	UINT_PTR Address;
	UINT_PTR Size;
	void* Output;

} KM_READ_REQUEST, *PKM_READ_REQUEST;


template <typename type>
	type RPM(UINT_PTR ReadAddress)
	{
		if (hDriver == INVALID_HANDLE_VALUE) {
			return {};
		}

		DWORD64 Bytes;
		KM_READ_REQUEST ReadRequest{};

		type response{};

		ReadRequest.ProcessId = PID;
		ReadRequest.Address = ReadAddress;
		ReadRequest.Size = sizeof(type);
		ReadRequest.Output = &response;

		// i need to return response;

              hMapFile = OpenFileMappingA(FILE_MAP_WRITE, FALSE, "Global\\SharedMem");
	if (!hMapFile || hMapFile == INVALID_HANDLE_VALUE)
	{
		printf("OpenFileMappingA(write) fail! Error: %u\n", GetLastError());
		return 0;
	}

        // i need to send ReadRequest to my mapped section aka to kernel mode
	pBuf = (ReadRequest)MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 4096);
	if (!pBuf)
	{
		printf("OpenFileMappingA(write) fail! Error: %u\n", GetLastError());
		return 0;
	}

// copied data to the mapped section
         memcpy(pBuf,&ReadRequest,sizeof(ReadRequest));

      // now i need to trigger the kernel xD

        auto szMessage		= std::string("");
	auto dwWriteCount	= 0UL;

        szMessage = "read_shared_memory";

	dwWriteCount = 0UL;
	if (WriteFile(hDriver, szMessage.c_str(), szMessage.size() + 1, &dwWriteCount, NULL) == FALSE)
	{
		printf("WriteFile(read) fail! Error: %u\n", GetLastError());
		return false;
	}


       // now i call readsharedmemory from my kernel to read the shared memory section and to call my read memory function.
// then i read the output like this

auto hMapFile = OpenFileMappingA(FILE_MAP_READ, FALSE, "Global\\SharedMemoryTest");
	if (!hMapFile || hMapFile == INVALID_HANDLE_VALUE)
	{
		printf("OpenFileMappingA(read) fail! Error: %u\n", GetLastError());
		return 0;
	}

// idk how to read an unkown value () <- i need to cast it or smth. trying to read [ Readoutput from kernel ]

	auto pBuf = ()MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 4096);
	if (!pBuf)
	{
		printf("OpenFileMappingA(read) fail! Error: %u\n", GetLastError());
		return 0;
	}

// now i can read that  pBuf or assign it to response; but i guess i need a mutex because this whole thing is missed up and if 
// i tried to read it would execute so fast and i would either crash or get a random value

	}


kernel mode :
KGUARDED_MUTEX g_IrpReadMutex;
PVOID SharedSection = NULL;
HANDLE Sectionhandle;

VOID ReadSharedMemory()
{
	if (Sectionhandle)
		return;

	if (g_pSharedSection)
		ZwUnmapViewOfSection(NtCurrentProcess(), SharedSection);

	SIZE_T ulViewSize = 1024 * 10;
	NTSTATUS ntStatus = ZwMapViewOfSection(g_hSection, NtCurrentProcess(), &SharedSection, 0, ulViewSize, NULL, &ulViewSize, ViewShare, 0, PAGE_READWRITE | PAGE_NOCACHE);
	if (ntStatus != STATUS_SUCCESS)
	{
		DbgPrint("ZwMapViewOfSection fail! Status: %p\n", ntStatus);
		ZwClose(Sectionhandle);
		return;
	}
	DbgPrint("ZwMapViewOfSection completed!\n");

	DbgPrint("Shared memory read data: %s\n", SharedSection);
}


typedef struct KM_READ_REQUEST
{
	ULONG ProcessId;

	UINT_PTR Address;
	UINT_PTR Size;
	void* Output;

} KM_READ_REQUEST, *PKM_READ_REQUEST;



NTSTATUS ReadKernelMemory(PEPROCESS Process, PVOID SourceAddress, PVOID TargetAddress, SIZE_T Size)
{
	PSIZE_T Bytes;
	if (NT_SUCCESS(MmCopyVirtualMemory(Process, SourceAddress, PsGetCurrentProcess(),
		TargetAddress, Size, KernelMode, &Bytes)))
		return STATUS_SUCCESS;
	else
		return STATUS_ACCESS_DENIED;
}



NTSTATUS OnIRPWrite(PDEVICE_OBJECT pDriverObject, PIRP pIrp)
{
	UNREFERENCED_PARAMETER(pDriverObject);

	char szBuffer[255] = { 0 };
	strcpy(szBuffer, pIrp->AssociatedIrp.SystemBuffer);
	DbgPrint("User message received: %s(%u)", szBuffer, strlen(szBuffer));

	if (strcmp(szBuffer, "read_shared_memory"))
	{
                KeAcquireGuardedMutex (&g_IrpReadMutex);
		ReadSharedMemory(); // reads shared memory the one i have copied before using memcpy.
          
		PKM_READ_REQUEST ReadInput = (PKM_READ_REQUEST)SharedSection;
		void* ReadOutput = ReadInput->Output;

		PEPROCESS Process;
		// Get our process
		if (NT_SUCCESS(PsLookupProcessByProcessId(ReadInput->ProcessId, &Process))) {
			Status = ReadKernelMemory(Process, ReadInput->Address, ReadOutput, ReadInput->Size);
		}
		else {
			Status = STATUS_ACCESS_DENIED;
			ObDereferenceObject(Process);
			return Status;
		}

		//DbgPrintEx(0, 0, "Read Params:  %lu, %#010x \n", ReadInput->ProcessId, ReadInput->Address);


                // clears sharedSection var so we can use it again
                RtlZeroMemory(SharedSection,sizeof(SharedSection));

                // copies the ReadOutput value to our mapped section 
               memcpy(SharedSection,&ReadOutput,sizeof(ReadOutput));

                KeReleaseGuardedMutex (&g_IrpReadMutex);
	}

	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = strlen(szBuffer);
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}

NTSTATUS OnMajorFunctionCall(PDEVICE_OBJECT pDriverObject, PIRP pIrp)
{
	UNREFERENCED_PARAMETER(pDriverObject);

	PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
	switch (pStack->MajorFunction)
	{
		case IRP_MJ_WRITE:
			OnIRPWrite(pDriverObject, pIrp);
			break;

		default:
			pIrp->IoStatus.Status = STATUS_SUCCESS;
			IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	}
	return STATUS_SUCCESS;
}




// in our driver entry 
KeInitializeGuardedMutex(&g_IrpReadMutex); 




What I have tried:

Of course am mapping memory and stuff but this is just what i want to achieve, but failing with 3 things

1 - its really bad code , and it will give bsod 100% because i don't wait for anything i just try to read what is in the section . (i guess a mutex is needed here)

2 - i can't send ReadOutput from my kernel driver to my user mode or i can't read it because the value of it will change so idk how to get it.

3 - it will keep creating a mapped section everytime i call RPM function (read memory)

so idk any suggestions guys is much appreciated.
Posted
Updated 10-Mar-19 12:03pm
v2

If you never close those handles you will eventually run out of them. I made a little class that does the mapping and then unmaps and closes the handle on destruction so it is automatic. I recommend you do the same. You can use RPM as the constructor.

To help synchronize things, I would add a counter you can use to signal new requests. You can stay mapped to the shared memory that way if you want to and there is no reason not to that I can think of. It can be incremented when a new request is made and again when it has been serviced. If you don't want to do that, an event could be used to signal requests.
 
Share this answer
 
Comments
Member 14130865 11-Mar-19 13:56pm    
@Rick York so could i use a mutex inside my RPM function and share it with kernel driver then when my kernel driver executes that "read_shared_memory" request , it will release the mutex and i can use it back to read the file from kernel that has the Readoutput . its confusing tbh
Rick York 11-Mar-19 14:17pm    
Yes, you could, but it doesn't have to be a mutex. It can be an event. It has to be a named objected in either case. It seems that your programs aren't actually waiting for exclusive access. Your program/driver are waiting for a signal that says there is something to do. What I am not sure of is if a kernel level driver can access a standard OS object because I have never worked on a kernel driver. That is something you will have to test and verify.
Are you the same person as Member 14130865 - Professional Profile[^], who posted a very similar question? If so please delete your duplicate account and use the original one.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900