PE Header Reader and Hotfix INF Generator

Questions about Update Pack making? Ask here.
Post Reply
User avatar
code65536
Posts: 735
Joined: Wed Mar 14, 2007 2:58 pm
Location: .us
Contact:

PE Header Reader and Hotfix INF Generator

Post by code65536 » Sat Jul 07, 2007 2:43 am

So while I was building my post-RVM2.1.11 update pack, I discovered pretty quickly that it was very tedious to build the INF files. Especially getting the build checksums and timestamps. I had to install every update in a VPC with the /b flag, then dump the REG, and convert the REG to an INF, and then clean up the INF. So I decided to whip up a quick-and-dirty Perl script that generated INFs without any installing, dumping, converting, etc.

I have since cleaned the script up a bit and made it presentable, and if people are interested, they can grab a copy. I don't know if Ryan or the people making localized update packs have some sort of automation that they use to overcome this tedium. If you guys already have an automated method to get the timestamps, build checksums, and versions and then dump them into an INF, then this script would most likely be of very little interest to you. But if not, it might save you some time the next time you make a pack.

Anyway, the file is here.

Usage:
Consider this directory structure:

Code: Select all

WorkFolder
|- kbreg_gen.pl (and supporting files)
|- KB933251
|  |- msxml3.dll
|- KB935989
   |- shell32.dll
   |- xpsp3res.dll
Running kbreg_gen.pl in this case will generate an INF template (kbreg_new.inf) that looks like this:

Code: Select all

[KB933251.AddReg]
HKLM,"%SP3UPDATES%\KB933251","Description",0,"%UPDATE% (KB933251)"
HKLM,"%SP3UPDATES%\KB933251","InstalledBy",0,"%NAME%"
HKLM,"%SP3UPDATES%\KB933251","InstalledDate",0,"%VERSION%"
HKLM,"%SP3UPDATES%\KB933251","Type",0,"Update"
HKLM,"%SP3UPDATES%\KB933251\Filelist\0","BuildCheckSum",0,"111925"
HKLM,"%SP3UPDATES%\KB933251\Filelist\0","BuildDate",0,"Tue Apr 10 02:55:03 2007"
HKLM,"%SP3UPDATES%\KB933251\Filelist\0","FileName",0,"msxml3.dll"
HKLM,"%SP3UPDATES%\KB933251\Filelist\0","Location",0,"%11%"
HKLM,"%SP3UPDATES%\KB933251\Filelist\0","Version",0,"8.90.1010.0"
HKLM,"%HFREGPATH%\KB933251","Backup Dir",0,""
HKLM,"%HFREGPATH%\KB933251","Comments",0,"%UPDATE% (KB933251)"
HKLM,"%HFREGPATH%\KB933251","Fix Description",0,"%UPDATE% (KB933251)"
HKLM,"%HFREGPATH%\KB933251","Installed",0x10001,1
HKLM,"%HFREGPATH%\KB933251","Installed By",0,"%NAME%"
HKLM,"%HFREGPATH%\KB933251","Installed On",0,"%VERSION%"
HKLM,"%HFREGPATH%\KB933251","Service Pack",0x10001,3
HKLM,"%HFREGPATH%\KB933251","Valid",0x10001,1
HKLM,"%HFREGPATH%\KB933251\File 1","Flags",0,""
HKLM,"%HFREGPATH%\KB933251\File 1","New File",0,""
HKLM,"%HFREGPATH%\KB933251\File 1","New Link Date",0,""
HKLM,"%HFREGPATH%\KB933251\File 1","Old Link Date",0,""

[KB935989.AddReg]
HKLM,"%SP3UPDATES%\KB935989","Description",0,"%UPDATE% (KB935989)"
HKLM,"%SP3UPDATES%\KB935989","InstalledBy",0,"%NAME%"
HKLM,"%SP3UPDATES%\KB935989","InstalledDate",0,"%VERSION%"
HKLM,"%SP3UPDATES%\KB935989","Type",0,"Update"
HKLM,"%SP3UPDATES%\KB935989\Filelist\0","BuildCheckSum",0,"81810b"
HKLM,"%SP3UPDATES%\KB935989\Filelist\0","BuildDate",0,"Thu May 17 06:11:25 2007"
HKLM,"%SP3UPDATES%\KB935989\Filelist\0","FileName",0,"shell32.dll"
HKLM,"%SP3UPDATES%\KB935989\Filelist\0","Location",0,"%11%"
HKLM,"%SP3UPDATES%\KB935989\Filelist\0","Version",0,"6.0.2900.3139"
HKLM,"%SP3UPDATES%\KB935989\Filelist\1","BuildCheckSum",0,"463b8"
HKLM,"%SP3UPDATES%\KB935989\Filelist\1","BuildDate",0,"Wed May 16 11:32:09 2007"
HKLM,"%SP3UPDATES%\KB935989\Filelist\1","FileName",0,"xpsp3res.dll"
HKLM,"%SP3UPDATES%\KB935989\Filelist\1","Location",0,"%11%"
HKLM,"%SP3UPDATES%\KB935989\Filelist\1","Version",0,"5.1.2600.3139"
HKLM,"%HFREGPATH%\KB935989","Backup Dir",0,""
HKLM,"%HFREGPATH%\KB935989","Comments",0,"%UPDATE% (KB935989)"
HKLM,"%HFREGPATH%\KB935989","Fix Description",0,"%UPDATE% (KB935989)"
HKLM,"%HFREGPATH%\KB935989","Installed",0x10001,1
HKLM,"%HFREGPATH%\KB935989","Installed By",0,"%NAME%"
HKLM,"%HFREGPATH%\KB935989","Installed On",0,"%VERSION%"
HKLM,"%HFREGPATH%\KB935989","Service Pack",0x10001,3
HKLM,"%HFREGPATH%\KB935989","Valid",0x10001,1
HKLM,"%HFREGPATH%\KB935989\File 1","Flags",0,""
HKLM,"%HFREGPATH%\KB935989\File 1","New File",0,""
HKLM,"%HFREGPATH%\KB935989\File 1","New Link Date",0,""
HKLM,"%HFREGPATH%\KB935989\File 1","Old Link Date",0,""
You can then work from the template, adding in registrations from the hotfix's INF, making sure that the location is correct (the script will choose a default location based on the extension; this will sometimes have to be adjusted, of course), etc.

Timestamps:
In the PE header, the build timestamp is stored as a 32-bit unsigned integer representing the number of seconds that have elapsed since the epoch (1 Jan 1970 00:00:00 UTC). This means that when the timestamp is converted to a human-readable string, a time zone would need to be specified. The BuildDate strings set by hotfix installers always express the time in local time of the installing machine, but the problem with using local time is that this isn't portable across time zones. If I installed the hotfix in my time zone (US Eastern Daylight), I would get BuildDate string that's 3 hours off compared what someone at Microsoft headquarters in Redmond would get (PDT). The script can be configured to express the time in either local time or UTC. MSKB articles always list time in UTC. I opted to use local time for the pack that I made since I'm in the same time zone as Ryan and since Ryan's packs already use timestamps in US Eastern Time. In the example above, I used UTC since that's easier to compare with what Microsoft lists in MSKB.

Technical notes:
It's written in Perl, so you'll need to have Perl on your system to run it. The INF generator is kbreg_gen.pl, and it calls the get_pe_data() function found in get_pe_data.pl. The get_pe_data() function, which can be re-used in other Perl scripts, will return the checksum (as a 32-bit int), the build date (as a 32-bit int of the seconds since the epoch), and the file version (as an array of four 16-bit ints). Because the checksum, timestamp, and version data are all read directly from the PE's data structures, they are all 100% accurate and correct.
Last edited by code65536 on Mon Aug 13, 2007 9:19 pm, edited 4 times in total.

User avatar
RyanVM
Site Admin
Posts: 5187
Joined: Tue Nov 23, 2004 6:03 pm
Location: Pennsylvania
Contact:

Post by RyanVM » Sat Jul 07, 2007 8:50 am

Nifty! I've actually been thinking about switching to using the time epochs myself (and have them be generated during integration in the local user's time zone), but haven't had the time to see it to fruition.
Get up to $200 off on hosting from the same people who host this website!
http://www.ryanvm.net/forum/viewtopic.php?t=2357

User avatar
code65536
Posts: 735
Joined: Wed Mar 14, 2007 2:58 pm
Location: .us
Contact:

Post by code65536 » Mon Jul 09, 2007 2:38 am

RyanVM wrote:Nifty! I've actually been thinking about switching to using the time epochs myself (and have them be generated during integration in the local user's time zone), but haven't had the time to see it to fruition.
Hey, that's a really good idea!

Shouldn't be hard to implement, either...

1) Store the raw time in the BuildDate field.
2) Make a list of the BuildDate fields that have a raw time stored.
3) Run something from svcpack.inf to go through these fields and convert the raw time to the local time.

Okay, so step 1 should be easy with my script; just change the time output to show the raw data instead of the formatted string. Using the example from my original post, the INF would look like:

Code: Select all

[...snip...]
HKLM,"%SP3UPDATES%\KB933251\Filelist\0","BuildCheckSum",0,"111925"
HKLM,"%SP3UPDATES%\KB933251\Filelist\0","BuildDate",0,"461afc87"
HKLM,"%SP3UPDATES%\KB933251\Filelist\0","FileName",0,"msxml3.dll"
[...snip...]
HKLM,"%SP3UPDATES%\KB935989\Filelist\0","BuildCheckSum",0,"81810b"
HKLM,"%SP3UPDATES%\KB935989\Filelist\0","BuildDate",0,"464bf20d"
HKLM,"%SP3UPDATES%\KB935989\Filelist\0","FileName",0,"shell32.dll"
[...snip...]
HKLM,"%SP3UPDATES%\KB935989\Filelist\1","BuildCheckSum",0,"463b8"
HKLM,"%SP3UPDATES%\KB935989\Filelist\1","BuildDate",0,"464aebb9"
HKLM,"%SP3UPDATES%\KB935989\Filelist\1","FileName",0,"xpsp3res.dll"
[...snip...]
For step 2, let's create a file that, for lack of a better name, I'll call tsreg.ini. This file would be generated alongside the INF. It'll look like:

Code: Select all

SOFTWARE\Microsoft\Updates\Windows XP\SP3\KB933251\Filelist\0
SOFTWARE\Microsoft\Updates\Windows XP\SP3\KB935989\Filelist\0
SOFTWARE\Microsoft\Updates\Windows XP\SP3\KB935989\Filelist\1
And then for step 3, all we need is a simple Win32 app to read the INI we generated for step 2, loop through all the listed keys, and for each key, read in the raw value stored in the registry, convert it to a localized string, and store that string back into the registry. Here's some C that would do just that:
tsreg.c (or tsreg2.c; variant where seconds is stored in ini; this is what I actually use)

(PS: I tried posting the code in the text as a code box, but every time I tried, I got a 503 Error. Remove the code, and it'll allow me to post... and it's not a matter of size, either, since the C file is only 673 bytes long and it still won't let me post it even after I removed over 1K worth of other stuff from this post; how odd!)
Last edited by code65536 on Mon Aug 13, 2007 9:20 pm, edited 6 times in total.

User avatar
RyanVM
Site Admin
Posts: 5187
Joined: Tue Nov 23, 2004 6:03 pm
Location: Pennsylvania
Contact:

Post by RyanVM » Mon Jul 09, 2007 8:28 am

code65536 wrote:[1) Store the raw time in the BuildDate field.
2) Make a list of the BuildDate fields that have a raw time stored.
3) Run something from svcpack.inf to go through these fields and convert the raw time to the local time.
So uh, you know, there's this nifty program on my site called the Integrator which is quite capable of editing lots of different types of things...;)

Like I said, I've already thought about how I want to do it. I just haven't had the time/motivation to see it through. Maybe if I get bored some time this fall...
Get up to $200 off on hosting from the same people who host this website!
http://www.ryanvm.net/forum/viewtopic.php?t=2357

Post Reply