Загрузка данных
#include <windows.h>
typedef struct _KSYSTEM_TIME
{
ULONG LowPart;
LONG High1Time;
LONG High2Time;
} KSYSTEM_TIME, *PKSYSTEM_TIME;
typedef struct _KUSER_SHARED_DATA
{
ULONG TickCountLowDeprecated;
ULONG TickCountMultiplier;
volatile KSYSTEM_TIME InterruptTime;
volatile KSYSTEM_TIME SystemTime;
volatile KSYSTEM_TIME TimeZoneBias;
USHORT ImageNumberLow;
USHORT ImageNumberHigh;
WCHAR NtSystemRoot[260];
ULONG MaxStackTraceDepth;
ULONG CryptoExponent;
ULONG TimeZoneId;
ULONG LargePageMinimum;
ULONG AitSamplingValue;
ULONG AppCompatFlag;
ULONGLONG RNGSeedVersion;
ULONG GlobalValidationRunlevel;
LONG TimeZoneBiasStamp;
ULONG NtBuildNumber;
NT_PRODUCT_TYPE NtProductType;
BOOLEAN ProductTypeIsValid;
BOOLEAN Reserved0[1];
USHORT NativeProcessorArchitecture;
ULONG NtMajorVersion;
ULONG NtMinorVersion;
BOOLEAN ProcessorFeatures[64];
ULONG Reserved1;
ULONG Reserved3;
volatile ULONG TimeSlip;
ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture;
ULONG BootId;
LARGE_INTEGER SystemExpirationDate;
ULONG SuiteMask;
BOOLEAN KdDebuggerEnabled;
union
{
UCHAR MitigationPolicies;
UCHAR CycleDivider;
};
USHORT ActiveConsoleId;
volatile USHORT DismountCount;
ULONG ComPlusPackage;
ULONG LastSystemRITEventTickCount;
ULONG NumberOfPhysicalPages;
BOOLEAN SafeBootMode;
UCHAR VirtualizationFlags;
ULONG TraceLogging;
ULONGLONG TestRetInstruction;
LONGLONG SystemCall;
ULONG SystemCallReturn;
ULONGLONG SystemCallPad[3];
union
{
volatile KSYSTEM_TIME TickCount;
volatile ULONGLONG TickCountQuad;
};
ULONG Cookie;
ULONG ConsoleHandle;
ULONGLONG TimeUpdateLock;
ULONGLONG BaselineSystemTimeQpc;
ULONGLONG BaselineInterruptTimeQpc;
ULONGLONG ReservedForFutureUse;
ULONGLONG ReservedForFutureUse2;
} KUSER_SHARED_DATA, *PKUSER_SHARED_DATA;
struct SavedState
{
ULONGLONG InterruptTime;
ULONGLONG SystemTime;
LONGLONG TimeZoneBias;
ULONG LastSystemRITEventTickCount;
ULONGLONG TickCount;
ULONGLONG TickCountMultiplier;
ULONGLONG BaselineSystemTimeQpc;
ULONGLONG BaselineInterruptTimeQpc;
};
SavedState LoadFromBuffer(BYTE* kuser_old)
{
PKUSER_SHARED_DATA old = (PKUSER_SHARED_DATA)kuser_old;
SavedState state;
state.InterruptTime = ((ULONGLONG)old->InterruptTime.High1Time << 32) | old->InterruptTime.LowPart;
state.SystemTime = ((ULONGLONG)old->SystemTime.High1Time << 32) | old->SystemTime.LowPart;
LONGLONG BiasHigh = ((LONGLONG)old->TimeZoneBias.High1Time << 32);
state.TimeZoneBias = BiasHigh | old->TimeZoneBias.LowPart;
state.LastSystemRITEventTickCount = old->LastSystemRITEventTickCount;
state.TickCount = ((ULONGLONG)old->TickCount.High1Time << 32) | old->TickCount.LowPart;
state.TickCountMultiplier = old->TickCountMultiplier;
state.BaselineSystemTimeQpc = old->BaselineSystemTimeQpc;
state.BaselineInterruptTimeQpc = old->BaselineInterruptTimeQpc;
return state;
}
void UpdateLoop(SavedState* state, DWORD update_interval_ms, BOOL* stop_flag)
{
PKUSER_SHARED_DATA kuser = (PKUSER_SHARED_DATA)0x7FFE0000;
LARGE_INTEGER PerfFreq;
QueryPerformanceFrequency(&PerfFreq);
ULONGLONG PerfFreqQuad = PerfFreq.QuadPart;
while (!*stop_flag)
{
LARGE_INTEGER CurrentPerfCounter;
QueryPerformanceCounter(&CurrentPerfCounter);
ULONGLONG ElapsedQpc = CurrentPerfCounter.QuadPart - state->BaselineSystemTimeQpc;
ULONGLONG ElapsedMs = (ElapsedQpc * 10000) / PerfFreqQuad;
state->InterruptTime += ElapsedMs;
state->SystemTime += ElapsedMs;
ULONGLONG ElapsedTickCount = (ElapsedQpc * state->TickCountMultiplier) >> 32;
state->TickCount += ElapsedTickCount;
state->LastSystemRITEventTickCount += (ULONG)ElapsedTickCount;
state->BaselineSystemTimeQpc = CurrentPerfCounter.QuadPart;
state->BaselineInterruptTimeQpc = CurrentPerfCounter.QuadPart;
kuser->InterruptTime.LowPart = (ULONG)state->InterruptTime;
kuser->InterruptTime.High1Time = (LONG)(state->InterruptTime >> 32);
kuser->InterruptTime.High2Time = (LONG)(state->InterruptTime >> 32);
kuser->SystemTime.LowPart = (ULONG)state->SystemTime;
kuser->SystemTime.High1Time = (LONG)(state->SystemTime >> 32);
kuser->SystemTime.High2Time = (LONG)(state->SystemTime >> 32);
ULONGLONG AbsBias = (state->TimeZoneBias < 0) ? (-state->TimeZoneBias) : state->TimeZoneBias;
kuser->TimeZoneBias.LowPart = (ULONG)AbsBias;
kuser->TimeZoneBias.High1Time = (LONG)(AbsBias >> 32);
kuser->TimeZoneBias.High2Time = (LONG)(AbsBias >> 32);
kuser->LastSystemRITEventTickCount = state->LastSystemRITEventTickCount;
kuser->TickCount.LowPart = (ULONG)state->TickCount;
kuser->TickCount.High1Time = (LONG)(state->TickCount >> 32);
kuser->TickCount.High2Time = (LONG)(state->TickCount >> 32);
kuser->BaselineSystemTimeQpc = CurrentPerfCounter.QuadPart;
kuser->BaselineInterruptTimeQpc = CurrentPerfCounter.QuadPart;
Sleep(update_interval_ms);
}
}
int main()
{
BYTE kuser_old[sizeof(KUSER_SHARED_DATA)];
PKUSER_SHARED_DATA current = (PKUSER_SHARED_DATA)0x7FFE0000;
memcpy(kuser_old, (PVOID)current, sizeof(KUSER_SHARED_DATA));
SavedState state = LoadFromBuffer(kuser_old);
BOOL stop = FALSE;
UpdateLoop(&state, 15, &stop);
return 0;
}