DeviceIoControl возвращает ERROR_ACCESS_DENIED - PullRequest
2 голосов
/ 02 мая 2020

Я пытаюсь взаимодействовать с драйвером для создания интерфейсов TUN (WinTun), но для отправки и получения от них данных мне нужно зарегистрировать кольцевой буфер. Код, который я использую, выглядит примерно так (я пропустил ту часть, где я создаю устройство с помощью SetupApi, поскольку это, кажется, работает):

#include <windows.h>
#include <winioctl.h>
#include <stdio.h>

#define REGISTER_RINGS_IOCTL CTL_CODE(51820U, 0x970U, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)

#define BUF_CAPACITY 0x20000
#define BUF_TRAILING 0x10000

typedef struct {
    volatile ULONG Head;
    volatile ULONG Tail;
    volatile LONG Alertable;
    UCHAR Data[BUF_CAPACITY + BUF_TRAILING];
} TUN_RING;

typedef struct {
    ULONG Size;
    UCHAR Data;
} TUN_PACKET;

typedef struct {
    struct {
        ULONG RingSize;
        TUN_RING *Ring;
        HANDLE TailMoved;
    } Send, Receive;
} TUN_REGISTER_RINGS;

int main() {

    HANDLE device = CreateFileW(
        L"\\\\?\\ROOT#NET#0006#{cac88484-7515-4c03-82e6-71a87abac361}",
        // ^^ This comes from the omitted code ^^
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
        NULL,
        OPEN_EXISTING,
        0,
        NULL
    );

    if(device == INVALID_HANDLE_VALUE) {
        printf("The device does not exist\n");
        return -1;
    }

    TUN_RING Send, Receive = {0};

    TUN_REGISTER_RINGS params = {
        .Send.RingSize = sizeof(TUN_RING),
        .Send.Ring = &Send,
        .Send.TailMoved = CreateEventW(NULL, FALSE, FALSE, NULL),

        .Receive.RingSize = sizeof(TUN_RING),
        .Receive.Ring = &Receive,
        .Receive.TailMoved = CreateEventW(NULL, FALSE, FALSE, NULL),
    };

    DWORD bytes;

    BOOL ret = DeviceIoControl(
        device,
        REGISTER_RINGS_IOCTL,
        &params,
        sizeof(TUN_REGISTER_RINGS),
        NULL,
        0,
        &bytes,
        NULL
    );

    if(ret == 0) {
        printf("Err: %d\n", GetLastError());
        return -2;
    }

    return 0;
}

Моя проблема заключается в том, что этот код завершается с ошибкой DeviceIoControl с ошибкой 5, которая соответствует ERROR_ACCESS_DENIED.

Я понятия не имею, почему это происходит, поскольку программа уже запущена с правами администратора, и дескриптор устройства был открыт с рекомендованными атрибутами (, как вы можете видеть здесь ). Извините за отсутствие дополнительной информации, но у меня нет большого опыта, когда дело доходит до windows драйверов, и я не знаю, как отлаживать это дальше.

Я думаю, что проблема может быть связана с этой проверкой в исходном коде драйвера , так как он, кажется, останавливается перед проверкой входного буфера (он должен повторно вызывать INVALID_PARAMETER, когда я ставлю мусор во входном буфере, но этого не происходит).

Опять, извините, если я что-то неправильно понял или пропустил что-то критическое, но я изучаю все это как я go, заранее спасибо!

1 Ответ

1 голос
/ 02 мая 2020

Нашел решение. Как описано в @RbMm, код , который создает дескриптор безопасности , разрешает только доступ к LocalSystem. Это означает, что это единственная учетная запись, которой разрешено общаться с водителем.

...