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