64位内核第十四讲,获取系统滴答数与日期时间

  • 2019 年 10 月 8 日
  • 笔记

目录

一丶简介

在ring3层中.我们会使用 ** GetTickCount** 这个函数,返回系统自启动到现在所经历的毫秒数.在驱动中也有一个对应的函数 ** KeQueryTickCount**

二丶 获取系统滴答数,并进行转换.

2.1 获取滴答数与毫秒数

上面说了有对应函数获取. 但是 这个函数返回的 TickCount 并不是简单的毫秒数,所以必须结合 ** KeQueryTimeinCrement **函数来求得具体的纳秒数.

如下代码.求得实际的毫秒数. 两个函数结合使用.

代码如下;

void MyGetTickCount(PULONG  msec) //进行传出  {      LARGE_INTEGER la;      ULONG MyInc;      MyInc = KeQueryTimeIncrement(); //返回滴答数        //下方 KeQueryTickCount 的宏的原型.        KeQueryTickCount(&la);        la.QuadPart *= MyInc;      la.QuadPart /= 10000;        *msec = la.LowPart;    }

获得毫秒等是远远不够的.还要获取当前系统的时间

2.2 获取年月日

上面的获取是远远不够的. 如果向进一步获取详细信息. 那么驱动中提供了一个结构

** TIME_FIELDS ** 这个结构里面提供了相信的信息.

结构如下:

typedef struct _TIME_FIELDS {      CSHORT Year;        // range [1601...]      CSHORT Month;       // range [1..12]      CSHORT Day;         // range [1..31]      CSHORT Hour;        // range [0..23]      CSHORT Minute;      // range [0..59]      CSHORT Second;      // range [0..59]      CSHORT Milliseconds;// range [0..999]      CSHORT Weekday;     // range [0..6] == [Sunday..Saturday]  } TIME_FIELDS;

想要进行获取.需要三个API函数

  1. ** KeQuerySystemTime ** 得到当前的格林威治时间
  2. ** ExSystemTimeToLocalTime** 将格林威治事件转化为本地时间
  3. ** RtlTimerToTimeFields ** 转化为人们可以阅读的 Time_File类型的事件.

函数原型:

Ps 64为下跟32位的函数是一样的.但是64位下会替换为宏.但是不影响你使用.

VOID  KeQuerySystemTime (      _Out_ PLARGE_INTEGER CurrentTime      );                                   //64位下会替换为宏,没有此函数类型.      NTKERNELAPI  VOID  ExSystemTimeToLocalTime (      _In_ PLARGE_INTEGER SystemTime,      _Out_ PLARGE_INTEGER LocalTime      );      NTSYSAPI  VOID  NTAPI  RtlTimeToTimeFields (      _In_ PLARGE_INTEGER Time,      _Out_ PTIME_FIELDS TimeFields      );

前两个函数的转化得到的都是 PLARGE_INTEGER 类型.并不是人们所能直观看到的.所以利用最后一个函数进行转化即可.

PTCHAR GetTimeYMS()  {      //获取年月日.      LARGE_INTEGER SystemTime;      LARGE_INTEGER LocalTime;      TIME_FIELDS TimeFiled;      TCHAR *time_str = ExAllocatePoolWithTag(PagedPool, 32, 0);        KeQuerySystemTime(&SystemTime);      ExSystemTimeToLocalTime(&SystemTime,&LocalTime);      RtlTimeToTimeFields(&LocalTime,&TimeFiled);  #ifdef UNICODE  #define RtlStringCchPrintf RtlStringCchPrintfW  #else  #define RtlStringCchPrintf RtlStringCchPrintfA  #endif // UNICODE        RtlStringCchPrintf(          time_str,          32,          TEXT("%4d-%2d-%2d %2d-%2d-%2d"),          TimeFiled.Year,          TimeFiled.Month,          TimeFiled.Day,              //年月日时分秒          TimeFiled.Hour,          TimeFiled.Minute,          TimeFiled.Second);      return time_str;  }  NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegPath)  {                PTCHAR pTime = NULL;      pDriverObj->DriverUnload = DriverUnLoad;        pTime = GetTimeYMS();          DbgPrint("%Ls rn", pTime);      return STATUS_SUCCESS;  }