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