123456790 发表于 2021-5-5 16:59:57

Ring3与Ring0通信源码


ring0程序:

#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)

NTSTATUS DispatchCreateClose(PDEVICE_OBJECT DeviceObject, PIRP pIrp);
NTSTATUS DispatchIoctl(PDEVICE_OBJECT DeviceObject, PIRP pIrp);
VOID DriverUnload(PDRIVER_OBJECT DriverObject);

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
      NTSTATUS status = STATUS_SUCCESS;
      UNICODE_STRING ustrDevName;
      UNICODE_STRING ustrLinkName;
      PDEVICE_OBJECT pDevObj = NULL;

      DriverObject->MajorFunction = DispatchCreateClose;
      DriverObject->MajorFunction = DispatchCreateClose;
      DriverObject->MajorFunction = DispatchIoctl;
      DriverObject->DriverUnload = DriverUnload;

      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))
      {
                IoDeleteDevice(pDevObj);
                return status;
      }

      return STATUS_SUCCESS;
}

VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
      UNICODE_STRING ustrLinkName;

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

      IoDeleteDevice(DriverObject->DeviceObject);
}

NTSTATUS DispatchCreateClose(PDEVICE_OBJECT DeviceObject, PIRP pIrp)
{
      pIrp->IoStatus.Status = STATUS_SUCCESS;

      IoCompleteRequest(pIrp, IO_NO_INCREMENT);
      return STATUS_SUCCESS;
}

NTSTATUS DispatchIoctl(PDEVICE_OBJECT DeviceObject, PIRP pIrp)
{
      NTSTATUS status = STATUS_NOT_SUPPORTED;
      PVOID pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
      PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
      ULONG outSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
      ULONG 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
                        }

                        //RtlCopyMemory(pIoBuffer, (PVOID)&amp;g_swNiceToMeetYouToo, 512);
                        READ_PORT_BUFFER_USHORT((PUSHORT)0x1f0, (PUSHORT)pIoBuffer, 256);
                        pIrp->IoStatus.Information = 512;
                        status = STATUS_SUCCESS;
                }
                else
                {
                        pIrp->IoStatus.Information = 0;
                        status = STATUS_BUFFER_TOO_SMALL;
                }
                break;
      }
      
      pIrp->IoStatus.Status = status;
      IoCompleteRequest(pIrp, IO_NO_INCREMENT);
      return status;
}




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

#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)

int main(int argc, char* argv[])
{      
      DWORD dwBytesReturned = 0;
      BYTE bytBuffer_1;
      BYTE bytBuffer_2;
      CHAR string;
      HANDLE hDevice, hDriver;
      BOOL bRet;

      hDevice = CreateFile("\\\\.\\PhysicalDrive0", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
                NULL, OPEN_EXISTING, 0, NULL);

      if(hDevice == INVALID_HANDLE_VALUE)
      {
                printf("\nFailed - CreateFile - Open the PhysicalDrive0.\n");
                return 0;
      }

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

      if(bRet == FALSE)
      {
                printf("\nFailed - ReadFile - the first one.\n");
                return 0;
      }

      printf("\nRead MBR using the ReadFile function...\n");
      printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - -");

      sprintf(string, "\n");

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

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

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

      printf("%s", string);

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

      hDriver = CreateFile("\\\\.\\KillHDDGMon", GENERIC_READ|GENERIC_WRITE,
                0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

      if(hDriver == INVALID_HANDLE_VALUE)
      {
                printf("\nFailed - CreateFile - Open the Driver.\n");
                return 0;
      }

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

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

      sprintf(string, "\n");

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

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

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

      printf("%s", string);

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

      bRet = DeviceIoControl(hDriver, IOCTL_WRITE, (LPVOID)bytBuffer_1, 512,
                NULL, 0, &amp;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, &amp;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);

                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);

                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;
}
页: [1]
查看完整版本: Ring3与Ring0通信源码