Log in

View Full Version : WTF has DST got to do with RCE?


Kayaker
April 4th, 2006, 00:23
"An immense sum, that the city of Paris might save every year."
Benjamin Franklin
http://webexhibits.org/daylightsaving/franklin.html

Just as sunflowers turn their heads to catch every sunbeam, so too have we discovered a simple way to get more from our sun. We've learned to save energy and enjoy sunny summer evenings by switching our clocks an hour forward in the summer.


OK this may be
1. waaayy off topic, or
2. Not so way off topic..

Like many others in North America, the European Union and possibly Lower Slobovia, I changed my clocks ahead the other day for Daylight Saving Time (DST). In fact it was my computer clock and the automatic DST setting that reminded me I had to do this. Yes, yes, the usual twice yearly resetting of every flipping timepiece inside or outside the house. You know the drill, Spring forward, Fall back. The DST 'equinox' is also a great time to change the batteries in your smoke detectors, recharge the fire extinguishers, and change your undershorts after the long winter.

Beginning in 2007 both Canada and the US will be changing the dates for DST. DST will begin 3 weeks earlier on the second Sunday of March, and end one week later on the first Sunday of November.

Here are the new settings:
Code:

(due to U.S. Energy Policy Act of 2005)
N.A. (DST begins/ends) 1 a.m.
2006 April 2 October 29
2007 March 11 November 4

E.U. (Summertimeperiod begins/ends) 2 a.m.
2006 March 26 October 29
2007 March 25 October 28



What is going to happen on March 11, 2007?

Oh NO, this is going to break Windows automatic DST settings code! Oh what shall we do?, it's Y2K all over again!! Aaaah.. panic in the streets, the stock market reacts, people leaping from tall buildings, cats and dogs living in sin, it will be terrible just terrible.


So what can we as reversers do about it? Ah, glad you asked. Should we wait for MS to issue a patch or should we design our own? I did a small amount of research into this pressing problem ;-)

Windows controls the DST settings through the timedate.cpl Control panel extension. The information is kept in the registry, the code determines how it is used.

Code:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation]
"Bias"=dword:0000012c
"StandardName"="Eastern Standard Time"
"StandardBias"=dword:00000000
"StandardStart"=hex:00,00,0a,00,05,00,02,00,00,00,00,00,00,00,00,00
"DaylightName"="Eastern Daylight Time"
"DaylightBias"=dword:ffffffc4
"DaylightStart"=hex:00,00,04,00,01,00,02,00,00,00,00,00,00,00,00,00
"ActiveTimeBias"=dword:000000f0



Heh, this was just going to be in the Off Topic forum but I think I'll leave it as a Project. Let's call it a mental or practical challenge - as to the best approach if you were assigned the job of creating a patch for this soon-to-be issue. Someone at Microsoft is probably already thinking about it.

One could change the registry settings, but what do you change and how? How does the timedate.cpl code use TimeZone / Locale information with the various registry settings to determine when to reset your system clock for Daylight Saving Time? Is there a 'hardcoded' list of the "normal" dates of DST (or Summertimeperiod) for various parts of the World, either to be used during first install or afterwards?

In short, how would you fix YOUR computer, or does anything really need fixing? This also affects software such as the vBulletin php code used to run this board, some members may have noticed it changing your DST settings the last time you logged in.

Top prize wins...?

Cheers,
Kayaker


Benjamin Franklin's
Essay on Daylight Saving

Letter to the Editor of the Journal of Paris, 1784
http://webexhibits.org/daylightsaving/franklin3.html

Brilliant reading btw. Ol' Ben was a clever writer. I'm not sure if he's dead serious or writing with a sardonic wit of the times. It seems that Ben, party animal and man-about-town that he was, rarely woke before Noon. One day he got woken up early and, well...


"I was pleased to see this general concern for economy, for I love economy exceedingly.

I went home, and to bed, three or four hours after midnight, with my head full of the subject. An accidental sudden noise waked me about six in the morning, when I was surprised to find my room filled with light; and I imagined at first, that a number of those lamps had been brought into it; but, rubbing my eyes, I perceived the light came in at the windows. I got up and looked out to see what might be the occasion of it, when I saw the sun just rising above the horizon, from whence he poured his rays plentifully into my chamber, my domestic having negligently omitted, the preceding evening, to close the shutters.

I looked at my watch, which goes very well, and found that it was but six o'clock; and still thinking it something extraordinary that the sun should rise so early, I looked into the almanac, where I found it to be the hour given for his rising on that day. I looked forward, too, and found he was to rise still earlier every day till towards the end of June; and that at no time in the year he retarded his rising so long as till eight o'clock. Your readers, who with me have never seen any signs of sunshine before noon, and seldom regard the astronomical part of the almanac, will be as much astonished as I was, when they hear of his rising so early; and especially when I assure them, that he gives light as soon as he rises. I am convinced of this. I am certain of my fact. One cannot be more certain of any fact. I saw it with my own eyes. And, having repeated this observation the three following mornings, I found always precisely the same result."

ZaiRoN
April 4th, 2006, 05:59
Unusual projects are always the best, excellent idea Kayaker!


[Hint: there Is a 'hardcoded' list of the "normal" dates of DST...]

disavowed
April 4th, 2006, 11:03
Good post, but I would be shocked if MS didn't release an update for this via Windows Update.

LLXX
April 4th, 2006, 20:58
Annotated:
Code:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation]
"Bias"=dword:0000012c - 300 minutes i.e. 5 hours: eastern time is GMT -5
"StandardName"="Eastern Standard Time"
"StandardBias"=dword:00000000 - extra bias to be applied to time
"StandardStart"=hex:00,00,0a,00,05,00,02,00,00,00,00,00,00,00,00,00 <- date of start standard time
"DaylightName"="Eastern Daylight Time"
"DaylightBias"=dword:ffffffc4 <- -60 minutes?
"DaylightStart"=hex:00,00,04,00,01,00,02,00,00,00,00,00,00,00,00,00 <- date of start daylight time
"ActiveTimeBias"=dword:000000f0 <- current bias: 240 i.e. GMT -6 hr
Not really RCE, but "RDE" - reverse data engineering? The two *Start registry keys seem to be of particular importance here. Anyone know a 16-byte representation of time? That's the only missing piece of the puzzle right now.

wtbw
April 4th, 2006, 22:51
I guess it's not really in the spirit of the challenge, but we do all search for our answers, don't we?

http://www.jsifaq.com/SUBA/tip0300/rh0398.htm ("http://www.jsifaq.com/SUBA/tip0300/rh0398.htm")

Will

LLXX
April 4th, 2006, 23:59
Well, it does say "READ THE FAQ AND SEARCH BEFORE POSTING!"

But it was straightforward to reverse the data even without that useful link (of which the information contained within was probably obtained through reversing the data as well).

ZaiRoN
April 5th, 2006, 04:25
No need to search around when you have Ida

Did you try to load the file timedata.cpl inside Ida? Once loaded in Ida look at the structures window, you'll surely find out the structures:
Code:
00000000 TIME_ZONE_INFORMATION struc ; (sizeof=0xAC, standard type)
00000000 Bias dd ?
00000004 StandardName dw 32 dup(?)
00000044 StandardDate SYSTEMTIME ?
00000054 StandardBias dd ?
00000058 DaylightName dw 32 dup(?)
00000098 DaylightDate SYSTEMTIME ?
000000A8 DaylightBias dd ?
000000AC TIME_ZONE_INFORMATION ends

0000 SYSTEMTIME struc ; (sizeof=0x10, standard type, variable size)
0000 wYear dw ?
0002 wMonth dw ?
0004 wDayOfWeek dw ?
0006 wDay dw ?
0008 wHour dw ?
000A wMinute dw ?
000C wSecond dw ?
000E wMilliseconds dw ?
0010 SYSTEMTIME ends
I think it's enough but if you want the formal structures definition you can take a look at msdn:
Code:
typedef struct _TIME_ZONE_INFORMATION {
LONG Bias;
WCHAR StandardName[32];
SYSTEMTIME StandardDate;
LONG StandardBias;
WCHAR DaylightName[32];
SYSTEMTIME DaylightDate;
LONG DaylightBias;
} TIME_ZONE_INFORMATION, *PTIME_ZONE_INFORMATION;


typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME;

Kayaker
April 5th, 2006, 16:53
Cool, so the Official RCE Messageboard's Regroupment DST Patch v1.0 release will be imminent then? All right! We'll have to make sure it comes complete with .nfo file and ascii art, maybe some cool gfx and MOD music as well.

Heheh, I'll bet we've beat the competition by 6 months at least. Yeah, then we can post it on nforce and they can get spammed instead

Maybe it's just me but I'm not big on downloading the MS updates, for something like this I think I'd just as soon have another option at hand such as a self made patch, ready for use when the time comes.

I was actually hoping for a patch of timedate.cpl...

K.

Woodmann
April 5th, 2006, 19:22
Hold up a second,

I don't know about the rest of the world BUT, some other things have changed this year.

Indiana now has more county's participating in DST. I think Arizona may have a few changes also. Alaska and Hawaii should be unchanged.

How does one solve this problem if they live in Indiana where the entire state does not participate in DST ?

Should it be changed to effect the majority? Do the people in Indiana who do not participate in DST just pick another region when setting their system clock ?

What about Europe ?

Remember, this should be a complete patch, not just a partial fix.

Woodmann

wtbw
April 5th, 2006, 20:09
I think the answer is that places with different rules are counted as different timezones... this setting is a "per timezone" one. I don't know which is which, but there are certainly many possibilities for the same basic GMT offset listed... for example "Indiana (East)" and "Eastern Time" are both listed for GMT-05:00.

Cheers,

Will

LLXX
April 5th, 2006, 21:59
To summarise, there are two solutions to this problem:

1. Change the registry keys with new settings. Easy.

2. Edit the table of settings. It is also stored in the registry - I found it by using Regmon on the date/time control panel applet. It's in HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Time Zones\* and you can easily add a new one there.

Either way, it's not much difficulty to fix this.

Woodmann
April 5th, 2006, 23:11
Howdy,

Ummm....... I dont want to be the asshole but,
Editing the reg files is all nice and what not. I think the bigger challenge is to come up with a patch that will apply ALL changes.

Woodmann

wtbw
April 6th, 2006, 01:10
What do you mean "apply ALL changes"? By editing the registry you're able to alter the settings for any or all regions... I don't see what else there is to do!

disavowed
April 6th, 2006, 01:20
Be careful when playing with undocumented registry values. The values' location, format, usage, etc. can change without notice with future patches and/or versions of Windows.

Woodmann
April 6th, 2006, 22:27
Howdy,

All changes means all the new changes to DST.
If editing the registry to modify Eastern DST was the goal,
that would not be a problem for those of us who are in this place.

What about the people who dont have the ability to modify the registry ?

Micro will of course include the needed changes in a future upgrade.
That upgrade will not be the instructions on how to edit your registry.

Will they break it down by county for Indiana ? Who knows.
What about the rest of the world ? I dont think they will all be observing DST like those of us here in the USA.

But, what if some of those European countries do decide to participate in our new DST ?
Now we will have 10 times as many options when selecting date and time properties. (That might be overkill but, you know what I mean).

This is not about editing the registry, it is about patching the timedate.cpl.

Woodmann

wtbw
April 6th, 2006, 22:51
I'm still not sure what's to be gained by patching timedate.cpl... that just gets the info from the time zone registry entries, which have the start/end date if applicable, or not. Are you suggesting we produce a patch to "force" it on that only people who want or don't want DST apply?

EST is just the example we were looking at. All of the zones are listed in the registry at HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Time Zones\ , as LLXX (almost!) said. The dogwork is simply to go through each Time Zone and correct the StandardStart/DaylightStart entries for each zone (not every one is changed by one setting, is that what you were thinking?).

Incidentally, if you're local you might know better, but wikipedia says "On April 29, 2005, the Indiana legislature voted to begin observing daylight saving time statewide in 2006", and http://www.in.gov/sic/pdfs/TimeZones.pdf ("http://www.in.gov/sic/pdfs/TimeZones.pdf") shows which counties are in which zone... I think Microsoft will assume that users know whether they are in Eastern or Central and leave it at that...

You say "Now we will have 10 times as many options when selecting date and time properties", but what alternative is there that we gain by patching the cpl? The user still has to choose the option that applies to them, we can't be psychic... and I don't think the changes have introduced that many new options, if any... everywhere in the USA changes from their current dates for switching to this: "Beginning in 2007, DST will start on the second Sunday in March, and change back to standard time on the first Sunday in November."

Europe's system doesn't change at all, it's different anyway already, and the registry has those details already... if they do change as well, that'll be a new time zone and a new option. How is this avoidable?

MS's update might not be "the instructions on how to edit your registry", but I would bet it'd just be an exe that does the changes automatically.

As far as I can see, all that's left to do is go through each zone that has changed and produce the registry entries for it, and maybe an exe to apply them. That's not a reversing challenge, for me at least

Confusedly yours, ()

Will

*edit* correct reg entry

LLXX
April 6th, 2006, 23:04
Quote:
[Originally Posted by wtbw]As far as I can see, all that's left to do is go through each zone that has changed and produce the registry entries for it, and maybe an exe to apply them.
Not even a program... just a .REG would do fine. The install instructions would be "double click the file and say Yes to merging it into the registry". In fact, Googling already turns up a few...
Quote:
[Originally Posted by wtbw]That's not a reversing challenge, for me at least
Same here. Whatever challenge it is seems to be over now.

Kayaker
April 7th, 2006, 00:32
This is a little weird. If you look at the TIME_ZONE_INFORMATION spec in the MSDN it describes how the SYSTEMTIME registry entries should break down when used with DST:

-------------
To select the correct day in the month, set the wYear member to zero, the wHour and wMinute members to the transition time, the wDayOfWeek member to the appropriate weekday, and the wDay member to indicate the occurence of the day of the week within the month (first through fifth).

Using this notation, specify the 2:00a.m. on the first Sunday in April as follows: wHour = 2, wMonth = 4, wDayOfWeek = 0, wDay = 1. Specify 2:00a.m. on the last Thursday in October as follows: wHour = 2, wMonth = 10, wDayOfWeek = 4, wDay = 5.
-------------

If we take a look at the example from my computer (or better yet your own), I seem to interpret it this way:

Code:

Current 2006 dates:

DaylightStart - April 2 (1st Sunday in Apr)
StandardStart - October 29 (5th Sunday in Oct)

Registry entries:

"DaylightStart"=hex:00,00,04,00,01,00,02,00,00,00,00,00,00,00,00,00
"StandardStart"=hex:00,00,0a,00,05,00,02,00,00,00,00,00,00,00,00,00
"DaylightName"="Eastern Daylight Time"


SYSTEMTIME breakdown, noting changes per MSDN:

DaylightStart
00 00 wYear set to zero
04 00 wMonth (Apr=4)
01 00 wDayOfWeek (Monday=1) ??
02 00 wDay set in range 1-5

DESIGNATE: Sunday April 2 from the previous 2 entries

-----

StandardStart
00 00 wYear
0a 00 wMonth (Oct=10)
05 00 wDayOfWeek (Friday=5) ??
02 00 wDay

DESIGNATE: Sunday October 29 from the previous 2 entries


Now let's take a look at the example from the reference Will gave:

Code:

Western Europe Standard Time
00 00 0A 00 00 00 05 00 03 00 00 00 00 00 00 00
Switch to Standard time (last Sun in Oct, 3:00 am)

00 00 wYear
0A 00 wMonth (Oct)
00 00 wDayOfWeek (Sunday=0)
05 00 wDay - for DST this is week in month (1-5)
03 00 wHour 3:00 am
00 00 wMinute
00 00 wSecond
00 00 wMilliseconds


Notice this example is a little different still, it even includes the hour. Basically it makes complete sense. I can "read" ("last Sun in Oct, 3:00 am" from this registry entry.


My calculations don't seem to match what the MSDN specifies, but I can "interpret" the registry values differently so they make 'logical' sense if wDayOfWeek is reconsidered.. If that's correct then the timedate.cpl code doesn't follow the MSDN specs to the letter either. (do I hear disavowed? )

Try doing the same thing with your registry settings and your local DST settings and see if you can make sense of it. The next step would have to be seeing how the code actually interprets the registry values directly to be certain how they are really being used.

Kayaker

wtbw
April 7th, 2006, 01:12
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Time Zones\ has the values (apart from the strings) packed into one binary member called TZI. The strings are separate, and the order is different... and the way SYSTEMTIME is used is different!

Compare the TZI for Eastern Time with the other:
Code:

0000: 2C 01 00 00 00 00 00 00
0008: C4 FF FF FF 00 00 0A 00
0010: 00 00 05 00 02 00 00 00
0018: 00 00 00 00 00 00 04 00
0020: 00 00 01 00 02 00 00 00
0028: 00 00 00 00

"Bias"=dword:0000012c
0000-0004: dd 0000012c

"StandardBias"=dword:00000000
0004-0008: dd 00000000

"DaylightBias"=dword:ffffffc4
0008-000C: dd ffffffc4

"StandardStart"=hex:
00,00,0a,00,05,00,02,00,00,00,00,00,00,00,00,00

000C-001C: db
00,00,0a,00,00,00,05,00,02,00,00,00,00,00,00,00

"DaylightStart"=hex
00,00,04,00,01,00,02,00,00,00,00,00,00,00,00,00

001C-002C: db
00,00,04,00,00,00,01,00,02,00,00,00,00,00,00,00



Using the info direct from the TZI, we get the following breakdown which fits fine with MSDN and solves your DayOfWeek/Day problems Kayaker.
Code:

0000 SYSTEMTIME struc ; (sizeof=0x10, standard type, variable size)
0000 wYear dw 00
0002 wMonth dw 04 (4th, april)
0004 wDayOfWeek dw 00 (sunday)
0006 wDay dw 01 (1st, first in month)
0008 wHour dw 02 (2am)
000A wMinute dw 00
000C wSecond dw 00
000E wMilliseconds dw 00
0010 SYSTEMTIME ends
(the 1st Sunday in Apr and the 2nd week of the month for 2006)

0000 SYSTEMTIME struc ; (sizeof=0x10, standard type, variable size)
0000 wYear dw 00
0002 wMonth dw 0a (10th, october)
0004 wDayOfWeek dw 00 (sunday)
0006 wDay dw 05 (5th, last in month)
0008 wHour dw 02 (2am)
000A wMinute dw 00
000C wSecond dw 00
000E wMilliseconds dw 00
0010 SYSTEMTIME ends
(the 5th Sunday in Apr and the 5th week of the month for 2006)


So DayOfWeek is cut out and everything moved up a word? But the size of the structure is the same... is there no way to set the DayOfWeek then? Let's go hunting in the cpl (or in kernel32 where GetTimeZoneInformation is)! Wait, I'll post this first so others can do the same.

Busily,

Will

Kayaker
April 7th, 2006, 01:17
Quote:
[Originally Posted by wtbw]So DayOfWeek is cut out and everything moved up a word?


That's what first struck me

wtbw
April 7th, 2006, 01:51
Solved it

The place to look is SetTimeZoneInformation in kernel32, where it takes a TIME_ZONE_INFORMATION (and inside it, normal SYSTEMTIMEs) and translates it into an internal structure that seems to be called RTL_TIME_ZONE_INFORMATION (not sure what the internal almost-SYSTEMTIME is called, let's call it RTL_SYSTEMTIME).

Code:
.text:7C859292 mov ax, [esi+44h]
.text:7C859296 mov [ebp+var_6C], ax
.text:7C85929A mov ax, [esi+46h]
.text:7C85929E mov [ebp+var_6A], ax
.text:7C8592A2 mov ax, [esi+48h]
.text:7C8592A6 mov [ebp+var_5E], ax
.text:7C8592AA mov ax, [esi+4Ah]
.text:7C8592AE mov [ebp+var_68], ax
.text:7C8592B2 mov ax, [esi+4Ch]
.text:7C8592B6 mov [ebp+var_66], ax
.text:7C8592BA mov ax, [esi+4Eh]
.text:7C8592BE mov [ebp+var_64], ax
.text:7C8592C2 mov ax, [esi+50h]
.text:7C8592C6 mov [ebp+var_62], ax
.text:7C8592CA mov ax, [esi+52h]
.text:7C8592CE mov [ebp+var_60], ax


Here the translation is done from one structure to the other (reading SYSTEMTIME, writing RTL_SYSTEMTIME) to pass to RtlSetTimeZoneInformation. The offsets linked are:

Code:

read write
+44 to -6c
+46 to -6a
+48 to -5e
+4a to -68
+4c to -66
+4e to -64
+50 to -62
+52 to -60


Make them zero-based:

Code:

r w
0 0
2 2
4 E
6 4
8 6
A 8
C A
E C


So you can see, as we expected, the DayOfWeek element (at offset 4 in SYSTEMTIME) is put later at the end.

Here's them both laid out as before for clarity:

Code:
0000 SYSTEMTIME struc ; (sizeof=0x10, standard type, variable size)
0000 wYear dw ?
0002 wMonth dw ?
0004 wDayOfWeek dw ?
0006 wDay dw ?
0008 wHour dw ?
000A wMinute dw ?
000C wSecond dw ?
000E wMilliseconds dw ?
0010 SYSTEMTIME ends


00 RTL_SYSTEMTIME struc ; (sizeof=0x10, standard type, variable size)
0000 wYear dw ?
0002 wMonth dw ?
0004 wDay dw ?
0006 wHour dw ?
0008 wMinute dw ?
000A wSecond dw ?
000C wMilliseconds dw ?
000E wDayOfWeek dw ?
0010 RTL_SYSTEMTIME ends


So StandardStart and DaylightStart are actually stored as "RTL_SYSTEMTIME", not SYSTEMTIME as was previously reported. Good catch that it wasn't quite right, Kayaker

*edit* Hmm, google suggests that people think it's called RTL_SYSTEM_TIME, but wine/reactos seem to say that it (and therefore RTL_TIME_ZONE_INFORMATION) is the same as the non RTL version. How wrong they are! I do wonder why MS did it this way though...

Well, that was fun

Will

Kayaker
April 7th, 2006, 23:55
Nice analysis Will, that certainly clears things up. The only reason I can think of to use a modified internal structure is to simplify coding - it looks like the assumption was made that since *all* DST changeovers occur on a Sunday, that particular snippet of code check could be eliminated. Save a few bytes here.. save a few bytes there.. type of coding I guess. Maybe Reactos was going for their own implementation of it rather than precisely duplicating the MS code.


It looks like when you change TimeZone settings through
Software\Microsoft\Windows NT\CurrentVersion\Time Zones

The other registry entry is only updated after a reboot
System\CurrentControlSet\Control\TimeZoneInformation

It's possible this is the information timedate.cpl uses on a day-to-day basis, likely on each boot up it compares the system time with the DST settings to see if today is the day to switch over. Or it might be a little more involved than this.

In terms of a universal patch then simply modifying the TZI structures for all the applicable world zones, by providing a new .reg file or whatever, isn't enough by itself. You'd also need to prompt the user to reset/update the time zone and optionally perform a reboot, or modify the TimeZoneInformation registry setting as well and hope you got everything right.

Cheers,
Kayaker

wtbw
April 8th, 2006, 00:01
I'm pretty certain I've had it update for DST without a reboot. I would think when you update the Time Zones you need to call SetTimeZoneInformation with the new information for the current zone, rather than updating the entry in CurrentControlSet yourself.

Will