Assembly Language Implementation Techniques for Kernel and User Mode Communication

Basic Concepts of Device Objects and Symbolic Links

In kernel programming, a Device Object is the core entity for communication between the kernel and user-mode applications. Device objects are similar to windows in Windows GUI programming, being the only entities capable of receiving and processing requests (IRP). Each device object belongs to a Driver Object, and a driver object can generate multiple device objects, which are linked together in a unidirectional linked list via the <span>NextDevice</span> pointer.

A Symbolic Link serves as a bridge to expose kernel device objects to user-mode applications. It is akin to a shortcut in a file system, mapping a user-visible name (e.g., <span>\.\\MyDevice</span>) to a kernel device name (e.g., <span>\Device\MyDevice</span>).

Creation and Initialization of Device Objects

Detailed Explanation of the IoCreateDevice API

<span>IoCreateDevice</span> is the core API for creating device objects, with the following function prototype:

; IoCreateDevice function parameter description
; Input:
;   DriverObject    - Pointer to the driver object (PDRIVER_OBJECT)
;   DeviceExtensionSize - Size of the device extension structure (ULONG)
;   DeviceName      - Device name (PUNICODE_STRING)
;   DeviceType      - Device type (DEVICE_TYPE)
;   DeviceCharacteristics - Device characteristics (ULONG)
;   Exclusive       - Whether the device is exclusive (BOOLEAN)
; Output:
;   DeviceObject    - Pointer to the returned device object (PDEVICE_OBJECT *)
IoCreateDevice proc
    mov eax, [esp+4]       ; DriverObject
    mov ecx, [esp+8]       ; DeviceExtensionSize
    mov edx, [esp+12]      ; DeviceName
    mov ebx, [esp+16]      ; DeviceType
    mov esi, [esp+20]      ; DeviceCharacteristics
    mov edi, [esp+24]      ; Exclusive
    mov ebp, [esp+28]      ; DeviceObject
    ; Call kernel service...
    ret 28h
IoCreateDevice endp

The device name must start with <span>\Device\</span>, for example, <span>\Device\MyDDKDevice</span>. If no name is specified, the I/O manager will automatically assign a numeric name such as <span>\Device\00000001</span>.

Device Extension Structure

The Device Extension is a unique storage area for each device object, used to store device-specific information:

DEVICE_EXTENSION STRUCT
    pDevice         DWORD ?     ; Pointer to the device object
    ustrDeviceName  UNICODE_STRING <> ; Device name
    ustrSymLinkName UNICODE_STRING <> ; Symbolic link name
    NextStackDevice DWORD ?     ; Next lower device object
    ; Other custom fields...
DEVICE_EXTENSION ENDS

After creating the device, this area can be accessed via <span>DeviceObject->DeviceExtension</span>.

Creation of Symbolic Links

Detailed Explanation of the IoCreateSymbolicLink API

; IoCreateSymbolicLink function parameter description
; Input:
;   SymbolicLinkName - Symbolic link name (PUNICODE_STRING)
;   DeviceName      - Device name (PUNICODE_STRING)
IoCreateSymbolicLink proc
    mov eax, [esp+4]       ; SymbolicLinkName
    mov ecx, [esp+8]       ; DeviceName
    ; Call kernel service...
    ret 8h
IoCreateSymbolicLink endp

The symbolic link name must start with <span>\DosDevices\</span> or <span>\??\</span>, for example, <span>\DosDevices\MyDeviceLink</span>. In user mode, applications need to access these links using the <span>\.\</span>

Leave a Comment