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函數
- ** KeQuerySystemTime ** 得到當前的格林威治時間
- ** ExSystemTimeToLocalTime** 將格林威治事件轉化為本地時間
- ** 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; }