Member 14177389 Ответов: 2

Отправка структуры с mapviewoffile и чтение неизвестного значения (общая память)


что я делаю в своем приложении пользовательского режима :

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

	}


режим ядра :
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); 




Что я уже пробовал:

Конечно, я отображаю память и все такое, но это именно то, чего я хочу достичь, но терплю неудачу с 3 вещами

1 - это действительно плохой код , и он даст bsod 100%, потому что я ничего не жду, я просто пытаюсь прочитать то, что есть в этом разделе . (я думаю, что здесь нужен мьютекс)

2 - я не могу отправить вывод считывания из моего драйвера ядра в мой пользовательский режим или я не могу прочитать его, потому что его значение изменится, поэтому idk, как его получить.

3 - он будет продолжать создавать отображенный раздел каждый раз, когда я вызываю функцию RPM (чтение памяти)

так что ИДК любые предложения ребят очень ценит.

2 Ответов

Рейтинг:
2

Rick York

Если вы никогда не закроете эти ручки, то в конце концов они закончатся. Я сделал небольшой класс, который делает отображение, а затем разматывает и закрывает ручку на уничтожение, так что это происходит автоматически. Я рекомендую вам сделать то же самое. Вы можете использовать RPM в качестве конструктора.

Чтобы помочь синхронизировать вещи, я бы добавил счетчик, который вы можете использовать для сигнализации новых запросов. Вы можете оставаться привязанным к общей памяти таким образом, если хотите, и нет никаких причин не делать этого, которые я могу придумать. Он может быть увеличен, Когда делается новый запрос, и снова, когда он был обслужен. Если вы не хотите этого делать, событие может быть использовано для сигнализации запросов.


Member 14130865

@Rick York итак , могу ли я использовать мьютекс внутри моей функции RPM и поделиться им с драйвером ядра, а затем, когда мой драйвер ядра выполнит этот запрос "read_shared_memory", он освободит мьютекс, и я смогу использовать его обратно для чтения файла из ядра, который имеет выход считывания . это сбивает с толку ТБХ

Rick York

Да, вы могли бы, но это не обязательно должен быть мьютекс. Это может быть событием. В любом случае это должно быть именованное возражение. Похоже, что ваши программы На самом деле не ждут эксклюзивного доступа. Ваша программа/драйвер ждут сигнала, который говорит, что есть что-то делать. В чем я не уверен, так это в том, что драйвер уровня ядра может получить доступ к стандартному объекту ОС, потому что я никогда не работал с драйвером ядра. Это то, что вы должны будете проверить и проверить.

Рейтинг:
2

Richard MacCutchan

Вы тот же самый человек, что и я? Участник 14130865 - Профиль Специалиста[^], кто опубликовал очень похожий вопрос? Если это так, Пожалуйста, удалите свою дублирующую учетную запись и используйте оригинальную.