callach 发表于 2017-6-2 13:31:39

zwSetSystemInformation加载驱动


zwSetSystemInformation函数是个未公开的函数,调用38号会加载驱动

对应的第二个参数为SYSTEM_LOAD_AND_CALL_IMAGE结构体

第三个参数为SYSTEM_LOAD_AND_CALL_IMAGE结构体的长度

#include <Windows.h>
#include <stdio.h>

#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)

#define SystemLoadAndCallImage      38

typedef struct _UNICODE_STRING {
      USHORT Length;
      USHORT MaximumLength;
      PVOIDBuffer;
}UNICODE_STRING, *PUNICODE_STRING;

//typedef unsigned long      NTSTATUS;

typedef struct _SYSTEM_LOAD_AND_CALL_IMAGE{
      UNICODE_STRING ModuleName;
} SYSTEM_LOAD_AND_CALL_IMAGE,*PSYSTEM_LOAD_AND_CALL_IMAGE;

//声明三个函数的原型
typedef DWORD (CALLBACK* ZWSETSYSTEMINFORMATION)(DWORD, PVOID, LONG );
ZWSETSYSTEMINFORMATION ZwSetSystemInformation;
//typedef DWORD (CALLBACK* RTLINITUNICODESTRING)(PUNICODE_STRING, PCWSTR);
//RTLINITUNICODESTRING RtlInitUnicodeString;
typedef DWORD (CALLBACK* RTLANSISTRINGTOUNICODESTRING)(PVOID, PVOID, DWORD);
RTLANSISTRINGTOUNICODESTRING RtlAnsiStringToUnicodeString;

int main(int argc, char* argv)
{
      SYSTEM_LOAD_AND_CALL_IMAGE gregsImage;
      UNICODE_STRING TmpBuff;

      char szDrvFullPath;
      int iBufflen;

      //手工加载这三个函数
      //if (!(RtlInitUnicodeString = (RTLINITUNICODESTRING)GetProcAddress(GetModuleHandle("ntdll.dll"),"RtlInitUnicodeString")))
      //{
      //      printf("GetProcAddrss error:%d\n", GetLastError());
      //      exit(-1);
      //}
      if (!(RtlAnsiStringToUnicodeString = (RTLANSISTRINGTOUNICODESTRING)GetProcAddress(GetModuleHandle("ntdll.dll"),"RtlAnsiStringToUnicodeString")))
      {
                printf("GetProcAddrss error:%d\n", GetLastError());
                exit(-1);
      }
      if (!(ZwSetSystemInformation = (ZWSETSYSTEMINFORMATION)GetProcAddress(GetModuleHandle("ntdll.dll"),"ZwSetSystemInformation")))
      {
                printf("GetProcAddrss error:%d\n", GetLastError());
                exit(-1);
      }

      //ring 0 访问磁盘时要用\\??\\%s 的方式, 以前出错时少了一个?
      iBufflen = sprintf(szDrvFullPath, "\\??\\%s", "c:\\aaa.sys");
      szDrvFullPath = 0;

      TmpBuff.Buffer = (PVOID)szDrvFullPath;
      TmpBuff.Length = iBufflen;

      RtlAnsiStringToUnicodeString(&amp;(gregsImage.ModuleName), &amp;TmpBuff, 1);
      if (NT_SUCCESS(ZwSetSystemInformation(SystemLoadAndCallImage, &amp;gregsImage, sizeof(SYSTEM_LOAD_AND_CALL_IMAGE))))
      {
                printf("drive %s was loaded....", szDrvFullPath);
      }
      else
      {
                printf("dirve load error...");
      }
      getchar();
      return 1;
}



其中,aaa.sys的代码为:

#include <ntddk.h>

DRIVER_UNLOAD Unload;

VOID Unload( __instruct _DRIVER_OBJECT *DriverObjec t)
{
      KdPrint(("unload ....."));
}

NTSTATUS DriverEntry( __inPDRIVER_OBJECT DriverObject, __inPUNICODE_STRING RegistryPath )
{
      DriverObject->DriverUnload = Unload;
      KdPrint(("dirver entry...."));
      return STATUS_SUCCESS;
}

将生成的aaa.sys放到C盘根目录,运行ring 3的程序。
页: [1]
查看完整版本: zwSetSystemInformation加载驱动