Results 1 to 14 of 14

Thread: [VB6] - Kernel mode driver.

Threaded View

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Feb 2015

    [VB6] - Kernel mode driver.

    Hello everyone (sorry my English). There was a time, and decided to write something unusual on VB6, namely to try to write a driver. I must say before that I never wrote a driver and have no programming experience in kernel mode. The driver, according to my idea, will have to read the memory is not available in user mode, namely in the range 0x80000000 - 0xffffffff (in default mode, without IMAGE_FILE_LARGE_ADDRESS_AWARE). Immediately give the driver source code which is obtained:
    ' // modTrickMemReader.bas  - driver module
    ' //  Krivous Anatoly Anatolevich (The trick), 2014
    Option Explicit
    Public Enum NT_STATUS
        STATUS_SUCCESS = 0
    End Enum
    Public Type UNICODE_STRING
        Length              As Integer
        MaximumLength       As Integer
        lpBuffer            As Long
    End Type
    Public Type LIST_ENTRY
        Flink               As Long
        Blink               As Long
    End Type
    Public Type KDEVICE_QUEUE
        Type                As Integer
        Size                As Integer
        DeviceListHead      As LIST_ENTRY
        Lock                As Long
        Busy                As Long
    End Type
    Public Type KDPC
        Type                As Byte
        Importance          As Byte
        Number              As Integer
        DpcListEntry        As LIST_ENTRY
        DeferredRoutine     As Long
        DeferredContext     As Long
        SystemArgument1     As Long
        SystemArgument2     As Long
        DpcData             As Long
    End Type
        Lock                As Long
        SignalState         As Long
        WaitListHead        As LIST_ENTRY
    End Type
    Public Type KEVENT
        Header              As DISPATCHER_HEADER
    End Type
    Public Type IO_STATUS_BLOCK
        StatusPointer       As Long
        Information         As Long
    End Type
    Public Type Tail
        DriverContext(3)    As Long
        Thread              As Long
        AuxiliaryBuffer     As Long
        ListEntry           As LIST_ENTRY
        lpCurStackLocation  As Long
        OriginalFileObject  As Long
    End Type
    Public Type IRP
        Type                As Integer
        Size                As Integer
        MdlAddress          As Long
        Flags               As Long
        AssociatedIrp       As Long
        ThreadListEntry     As LIST_ENTRY
        IoStatus            As IO_STATUS_BLOCK
        RequestorMode       As Byte
        PendingReturned     As Byte
        StackCount          As Byte
        CurrentLocation     As Byte
        Cancel              As Byte
        CancelIrql          As Byte
        ApcEnvironment      As Byte
        AllocationFlags     As Byte
        UserIosb            As Long
        UserEvent           As Long
        Overlay             As Currency
        CancelRoutine       As Long
        UserBuffer          As Long
        Tail                As Tail
    End Type
    Public Type DEVICEIOCTL
        OutputBufferLength  As Long
        InputBufferLength   As Long
        IoControlCode       As Long
        Type3InputBuffer    As Long
    End Type
        MajorFunction       As Byte
        MinorFunction       As Byte
        Flags               As Byte
        Control             As Byte
        ' Поле DeviceIoControl из объединения
        DeviceIoControl     As DEVICEIOCTL
        pDeviceObject       As Long
        pFileObject         As Long
        pCompletionRoutine  As Long
        pContext            As Long
    End Type
    Public Type DRIVER_OBJECT
        Type                As Integer
        Size                As Integer
        pDeviceObject       As Long
        Flags               As Long
        DriverStart         As Long
        DriverSize          As Long
        DriverSection       As Long
        DriverExtension     As Long
        DriverName          As UNICODE_STRING
        HardwareDatabase    As Long
        FastIoDispatch      As Long
        DriverInit          As Long
        DriverStartIo       As Long
        DriverUnload        As Long
        MajorFunction(27)   As Long
    End Type
    Public Type DEVICE_OBJECT
        Type                As Integer
        Size                As Integer
        ReferenceCount      As Long
        DriverObject        As Long
        NextDevice          As Long
        AttachedDevice      As Long
        CurrentIrp          As Long
        Timer               As Long
        Flags               As Long
        Characteristics     As Long
        Vpb                 As Long
        DeviceExtension     As Long
        DeviceType          As Long
        StackSize           As Byte
        Queue(39)           As Byte
        AlignRequirement    As Long
        DeviceQueue         As KDEVICE_QUEUE
        Dpc                 As KDPC
        ActiveThreadCount   As Long
        SecurityDescriptor  As Long
        DeviceLock          As KEVENT
        SectorSize          As Integer
        Spare1              As Integer
        DeviceObjExtension  As Long
        Reserved            As Long
    End Type
    Private Type BinaryString
        D(255)              As Integer
    End Type
    Public Const FILE_DEVICE_UNKNOWN    As Long = &H22
    Public Const IO_NO_INCREMENT        As Long = &H0
    Public Const IRP_MJ_CREATE          As Long = &H0
    Public Const IRP_MJ_CLOSE           As Long = &H2
    Public Const IRP_MJ_DEVICE_CONTROL  As Long = &HE
    Public Const FILE_DEVICE_MEMREADER  As Long = &H8000&
    Public Const IOCTL_READ_MEMORY      As Long = &H80002000
    Public DeviceName       As UNICODE_STRING   ' // Device name unicode string
    Public DeviceLink       As UNICODE_STRING   ' // Device link unicode string
    Public Device           As DEVICE_OBJECT    ' // Device object
    Dim strName As BinaryString     ' // Device name string
    Dim strLink As BinaryString     ' // Device link string
    Public Sub Main()
    End Sub
    ' // If error - false
    Public Function NT_SUCCESS( _
                    ByVal Status As NT_STATUS) As Boolean
    End Function
    ' // Get pointer to IRP stack
    Public Function IoGetCurrentIrpStackLocation( _
                    ByRef pIrp As IRP) As Long
        IoGetCurrentIrpStackLocation = pIrp.Tail.lpCurStackLocation
    End Function
    ' // Entry point of driver
    Public Function DriverEntry( _
                    ByRef DriverObject As DRIVER_OBJECT, _
                    ByRef RegistryPath As UNICODE_STRING) As NT_STATUS
        Dim Status As NT_STATUS
        ' // Strings initialization
        Status = Init()
        ' // This checking is not required but i left it because you can improve Init function
        If Not NT_SUCCESS(Status) Then
            DriverEntry = Status
            Exit Function
        End If
        ' // Create new device
        Status = IoCreateDevice(DriverObject, 0, DeviceName, FILE_DEVICE_MEMREADER, 0, False, Device)
        ' // Check if device has been created
        If Not NT_SUCCESS(Status) Then
            DriverEntry = Status
            Exit Function
        End If
        ' // Create link, in order to access to object from user mode
        Status = IoCreateSymbolicLink(DeviceLink, DeviceName)
        ' // Check if link has been created
        If Not NT_SUCCESS(Status) Then
            ' // If is not created then delete device
            IoDeleteDevice Device
            DriverEntry = Status
            Exit Function
        End If
        ' // Set callback functions
        DriverObject.DriverUnload = GetAddr(AddressOf DriverUnload)                                 ' // Driver unloading
        DriverObject.MajorFunction(IRP_MJ_CREATE) = GetAddr(AddressOf DriverCreateClose)            ' // When CreateFile is being called
        DriverObject.MajorFunction(IRP_MJ_CLOSE) = GetAddr(AddressOf DriverCreateClose)             ' // When CloseHandle is being called
        DriverObject.MajorFunction(IRP_MJ_DEVICE_CONTROL) = GetAddr(AddressOf DriverDeviceControl)  ' // When DeviceIoControl is being called
        ' // Everything fine
        DriverEntry = STATUS_SUCCESS
    End Function
    ' // Unloading driver procedure
    Public Sub DriverUnload( _
               ByRef DriverObject As DRIVER_OBJECT)
        ' // Delete link
        IoDeleteSymbolicLink DeviceLink
        ' // Delete device
        IoDeleteDevice ByVal DriverObject.pDeviceObject
    End Sub
    ' // This function is being called during opening/closing driver
    Public Function DriverCreateClose( _
                    ByRef DeviceObject As DEVICE_OBJECT, _
                    ByRef pIrp As IRP) As NT_STATUS
        pIrp.IoStatus.Information = 0
        pIrp.IoStatus.StatusPointer = STATUS_SUCCESS
        ' // Return IRP packet to IO manager
        IoCompleteRequest pIrp, IO_NO_INCREMENT
        ' // Success
        DriverCreateClose = STATUS_SUCCESS
    End Function
    ' // IOCTL processing procedure
    Public Function DriverDeviceControl( _
                    ByRef DeviceObject As DEVICE_OBJECT, _
                    ByRef pIrp As IRP) As NT_STATUS
        Dim lpStack As Long
        Dim ioStack As IO_STACK_LOCATION
        ' // Get pointer to IRP stack
        lpStack = IoGetCurrentIrpStackLocation(pIrp)
        ' // If valid pointer
        If lpStack Then
            ' // Copy to local variable
            memcpy ioStack, ByVal lpStack, Len(ioStack)
            ' // Check IOCTL and AssociatedIrp union that contains SystemBuffer
            ' // SystemBuffer contains the buffer passed from DeviceIoControl
            If ioStack.DeviceIoControl.IoControlCode = IOCTL_READ_MEMORY And _
                pIrp.AssociatedIrp <> 0 Then
                Dim lpPointer   As Long
                Dim DataSize    As Long
                ' // Copy parameters from SystemBuffer
                memcpy lpPointer, ByVal pIrp.AssociatedIrp, 4
                memcpy DataSize, ByVal pIrp.AssociatedIrp + 4, 4
                ' П// Check buffer size
                If DataSize <= ioStack.DeviceIoControl.OutputBufferLength Then
                    ' // Get the number of allowed pages
                    Dim lpStart As Long
                    Dim pgCount As Long
                    Dim pgSize  As Long
                    Dim pgOfst  As Long
                    ' // Get first address of page
                    lpStart = lpPointer And &HFFFFF000
                    ' // Get offset at beginning of page
                    pgOfst = lpPointer And &HFFF&
                    ' // Go thru pages and check PageFault error
                    Do While MmIsAddressValid(ByVal lpStart) And (pgSize - pgOfst < DataSize)
                        lpStart = lpStart + &H1000
                        pgCount = pgCount + 1
                        pgSize = pgSize + &H1000
                    ' // If there are allowed pages
                    If pgCount Then
                        ' // Get size in bytes
                        pgSize = pgCount * &H1000 - pgOfst
                        ' // Fix size
                        If DataSize > pgSize Then DataSize = pgSize
                        ' // Return total read bytes
                        pIrp.IoStatus.Information = DataSize
                        ' // Success to DeviceIoControl
                        pIrp.IoStatus.StatusPointer = STATUS_SUCCESS
                        ' Copy data to system buffer
                        memcpy ByVal pIrp.AssociatedIrp, ByVal lpPointer, DataSize
                        ' // Return IRP packet to IO manager
                        IoCompleteRequest pIrp, IO_NO_INCREMENT
                        ' // Success
                        DriverDeviceControl = STATUS_SUCCESS
                        ' // Exit
                        Exit Function
                    End If
                End If
            End If
        End If
        ' // Return real size of read bytes
        pIrp.IoStatus.Information = 0
        ' // Error to DeviceIoControl
        pIrp.IoStatus.StatusPointer = STATUS_INVALID_PARAMETER
        ' // Return IRP packet to IO manager
        IoCompleteRequest pIrp, IO_NO_INCREMENT
        ' // Error
        DriverDeviceControl = STATUS_INVALID_PARAMETER
    End Function
    ' // Initialize all strings
    Private Function Init() As NT_STATUS
        ' // Initialize device name "\Device\TrickMemReader"
        strName.D(0) = &H5C:    strName.D(1) = &H44:    strName.D(2) = &H65:    strName.D(3) = &H76:    strName.D(4) = &H69:
        strName.D(5) = &H63:    strName.D(6) = &H65:    strName.D(7) = &H5C:    strName.D(8) = &H54:    strName.D(9) = &H72:
        strName.D(10) = &H69:   strName.D(11) = &H63:   strName.D(12) = &H6B:   strName.D(13) = &H4D:   strName.D(14) = &H65:
        strName.D(15) = &H6D:   strName.D(16) = &H52:   strName.D(17) = &H65:   strName.D(18) = &H61:   strName.D(19) = &H64:
        strName.D(20) = &H65:   strName.D(21) = &H72
        ' // Fill UNICODE_STRING structure
        RtlInitUnicodeString DeviceName, strName
        ' // Initialize device link for user mode "\DosDevices\TrickMemReader"
        strLink.D(0) = &H5C:    strLink.D(1) = &H44:    strLink.D(2) = &H6F:    strLink.D(3) = &H73:    strLink.D(4) = &H44:
        strLink.D(5) = &H65:    strLink.D(6) = &H76:    strLink.D(7) = &H69:    strLink.D(8) = &H63:    strLink.D(9) = &H65:
        strLink.D(10) = &H73:   strLink.D(11) = &H5C:   strLink.D(12) = &H54:   strLink.D(13) = &H72:   strLink.D(14) = &H69:
        strLink.D(15) = &H63:   strLink.D(16) = &H6B:   strLink.D(17) = &H4D:   strLink.D(18) = &H65:   strLink.D(19) = &H6D:
        strLink.D(20) = &H52:   strLink.D(21) = &H65:   strLink.D(22) = &H61:   strLink.D(23) = &H64:   strLink.D(24) = &H65
        strLink.D(25) = &H72
        ' // Fill UNICODE_STRING structure
        RtlInitUnicodeString DeviceLink, strLink
    End Function
    ' // Return passed value
    Private Function GetAddr( _
                     ByVal Value As Long) As Long
        GetAddr = Value
    End Function
    So, the driver must have an entry point DriverEntry, which causes the controller I/O driver is loaded. In the parameters of a pointer to an object-driver and a pointer to a string containing the name of the registry key corresponding to the loadable driver. In the Init procedure, we create two lines, one with the name of the device, the other with reference to the device name. Because we can not use the runtime kernel mode, it is necessary to create a string in the form of a static array, wrapped in a user-defined type, thereby VB6 allocates memory for the array on the stack. If you use a string that will inevitably be caused by one of the functions for runtime and copy assignment line, and we can not allow that. Then we can call IoCreateDevice, which creates a device object. Device object is the recipient of I/O requests and to him we will access when calling CreateFile function from user mode.
    Last edited by The trick; Jul 30th, 2016 at 08:13 AM. Reason: New version/translation to English

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

Click Here to Expand Forum to Full Width