Задать вопрос
@C4ke
Программист

Выделение исполняемой памяти?

Не так давно начал изучать программирование для драйверов EFI Shell.
Как и было понятно столкнулся я с путаницей, тесты проводил на Windows 1903 и выделение памяти работало успешно.
Как только перешел на версию 1909 столкнулся с ошибкой PAGE_FAULT_IN_NONPAGED_AREA, часть кода:

Клиент:
void* local_image_base = VirtualAlloc(nullptr, image_size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
	uint64_t kernel_image_base = efi_driver::AllocatePool(iqvw64e_device_handle, nt::NonPagedPool, image_size);//Выделяем исполняемый пул
	
	do
	{
		if (!kernel_image_base)
		{
			std::cout << "[-] Ошибка при выделение памяти" << std::endl;
			break;
		}
		memcpy(local_image_base, raw_image.data(), nt_headers->OptionalHeader.SizeOfHeaders);
		const PIMAGE_SECTION_HEADER current_image_section = IMAGE_FIRST_SECTION(nt_headers);
		for (auto i = 0; i < nt_headers->FileHeader.NumberOfSections; ++i)
		{
			auto local_section = reinterpret_cast<void*>(reinterpret_cast<uint64_t>(local_image_base) + current_image_section[i].VirtualAddress);
			memcpy(local_section, reinterpret_cast<void*>(reinterpret_cast<uint64_t>(raw_image.data()) + current_image_section[i].PointerToRawData), current_image_section[i].SizeOfRawData);
		}
		RelocateImageByDelta(portable_executable::GetRelocs(local_image_base), kernel_image_base - nt_headers->OptionalHeader.ImageBase);
		
		if (!ResolveImports(iqvw64e_device_handle, portable_executable::GetImports(local_image_base)))
		{
			std::cout << "[-] Ошибка при исправление импорта" << std::endl;
			break;
		}

		if (!efi_driver::WriteMemory(iqvw64e_device_handle, kernel_image_base, local_image_base, image_size))
		{
			std::cout << "[-] Ошибка записи в память" << std::endl;
			break;
		}

		VirtualFree(local_image_base, 0, MEM_RELEASE);

		const uint64_t address_of_entry_point = kernel_image_base + nt_headers->OptionalHeader.AddressOfEntryPoint;
		long status = 0; // NTSTATUS
		efi_driver::MemoryCommand* cmd = new efi_driver::MemoryCommand();
		cmd->operation = 5;
		cmd->magic = COMMAND_MAGIC;

		uintptr_t data[10];
		data[0] = address_of_entry_point;
		data[1] = (uintptr_t)&status;

		memcpy(&cmd->data, &data[0], sizeof(data));

		efi_driver::SendCommand(cmd);//Ошибка


Драйвер:
if (cmd->operation == 0) 
    {
        CopyMem(cmd->data[0], cmd->data[1], cmd->size);    

        return EFI_SUCCESS;
    }

    // Вызов ExAllocatePool
    if (cmd->operation == 1) 
    {
        void* function = cmd->data[0]; // Получение адреса функции (через клиент)
        ExAllocatePool exalloc = (ExAllocatePool)function;
        int temp = cmd->data[1];
        uintptr_t allocbase = exalloc(temp, cmd->data[2]);
        *(uintptr_t*)cmd->data[3] = allocbase;
    }

    // Вызов ExFreePool
    if (cmd->operation == 2) 
    {
        void* function = cmd->data[0];
        ExFreePool exfree = (ExFreePool)function;
        exfree(cmd->data[1]);
    }

    // Вызов любой функции (__stdcall)
    if (cmd->operation == 3) 
    {
        void* function = cmd->data[0];
        StandardFuncStd stand = (StandardFuncStd)function;
        stand();
    }

    // Вызов любой функции (__fastcall)
    if (cmd->operation == 4) 
    {
        void* function = cmd->data[0];
        StandardFuncFast stand = (StandardFuncFast)function;
        stand();
    }

    // Вызов точки входа в драйвер
    if (cmd->operation == 5) 
    {
        void* function = cmd->data[0];
        DriverEntry entry = (DriverEntry)function;
        int status = entry(0, 0);
        *(int*)cmd->data[1] = status;
    }


Ошибка (фото)
5ee6209ac6227885244235.png

Процессор: Intel i9-9900k
Материнская плата: Z390

Есть варианты решения проблемы?
  • Вопрос задан
  • 167 просмотров
Подписаться 2 Сложный Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы