Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to detect if the system clock has been changed backwards in windows?

Tags:

windows

winapi

On a windows machine, is there a way to find out if the time has been changed backwards without continually monitoring for WM_TIMECHANGE messages?

For example, I would like to make the first thing my application does on startup is see if the time has been changed back since I last run the application.

As far as I can tell, the only way to see a change is to look at the WM_TIMECHANGE message, but I will only see that if my application is running.

like image 884
Nick Randell Avatar asked Oct 21 '11 16:10

Nick Randell


4 Answers

Yes. You can read the Windows Event Logs and look for changes to system time. (System time changes are one of the system events that are automatically logged.) For example, I just tweaked my system time by a few seconds and the following appeared in the System Event log:

Information 10/21/2011 11:16:26 AM Kernel-General 1 None

The system time has changed to ‎2011‎-‎10‎-‎21T16:16:26.000000000Z from ‎2011‎-‎10‎-‎21T16:16:26.000000000Z.

You can use the Win32 API to get access to the event logs then query for these events to determine if the time was indeed altered. What's great about this solution is that it's built-in and always running. No need to monitor events via a custom service etc. You just query the OS's data.

This is still not a bullet-proof solution since people with admin rights can chance settings, clear logs etc. But you would definitely layperson-proof your app. System event logs are not something regular Windows users think about.

The XML for that particular event: (de-identified for privacy & security)

  <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
  <Provider Name="Microsoft-Windows-Kernel-General" 
        Guid="{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" /> 
  <EventID>1</EventID> 
  <Version>0</Version> 
  <Level>4</Level> 
  <Task>0</Task> 
  <Opcode>0</Opcode> 
  <Keywords>0x8000000000000010</Keywords> 
  <TimeCreated SystemTime="2011-10-21T16:16:26.001000000Z" /> 
  <EventRecordID>138478</EventRecordID> 
  <Correlation /> 
  <Execution ProcessID="40044" ThreadID="50016" /> 
  <Channel>System</Channel> 
  <Computer>xxxxx.xxxxxxxxx.org</Computer> 
  <Security UserID="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" /> 
  </System>
  <EventData>
  <Data Name="NewTime">2011-10-21T16:16:26.000000000Z</Data> 
  <Data Name="OldTime">2011-10-21T16:16:26.000000000Z</Data> 
  </EventData>
  </Event>
like image 194
Paul Sasik Avatar answered Oct 07 '22 12:10

Paul Sasik


No, you can't. That's why time-sensitive DRM schemes are in general rather useless.

You could try to work around it by using a service, and then you'd have to work around the service's downtime by using another hack, and another hack on top of that as well.

Anyway, if that's all you're trying to do then simply storing somewhere (encrypted, possibly) the value of the system time on your program's shutdown, then making sure that it has not been passed on program startup should be enough. It won't stop users that basically "froze" the time from shutdown to startup, but it'll be enough for 9/10 of the people trying to get past your timed trial.

like image 28
Mahmoud Al-Qudsi Avatar answered Oct 07 '22 11:10

Mahmoud Al-Qudsi


You could have your app (while it happens to be running) periodically compare the system time with a time fetched from a server resource somewhere. If you suddenly see that the difference between system time and server time has increased, that means the system time has been set back.

Obviously this wouldn't work on a machine with no Internet access.

like image 23
MusiGenesis Avatar answered Oct 07 '22 11:10

MusiGenesis


One idea to that above (while I note that checking against an external clock is the definitive answer if feasible) - you can also periodically read the system clock and store it, perhaps encrypted, in a hidden file somewhere. Each time you do this you check to make sure the new value is more recent than the one in the file. The trigger to doing this could be at every startup etc.

Like all internal methods this one is vulnerable to someone figuring out the hidden file. You can also therefore flag a problem if the hidden file is missing, or if its date stamp doesn't match its contents.

like image 20
Dominic Haigh Avatar answered Oct 07 '22 13:10

Dominic Haigh