$theTitle=wp_title(" - ", false); if($theTitle != "") { ?>
About Virtualization, VDI, SBC, Application Compatibility and anything else I feel like
Some time ago I wrote about the PNAgent data that is stored in the registry in XML format.
After that post Andrew Morgan asked me if I could extract the PNAgent icons from the XML data.
That got me interested so let’s look at this data!
If you look at XML from PNAgent the icondata as in the AppData.Details.Icon node you’ll see something like this:
Seems like the icon data is stored/encrypted in a proprietary format.
Histogram
When reversing binary data, a histogram is often a very good method to visualize the data and draw some first conclusions. This is the Histogram of my Icon data:
We can see that only the characters A..P occur and that A has by far the highest occurrence (40%).
So assuming there were both a 16×16 icon and a 32×32 icon in there but I didn’t know in what order!
So I wrote some testcode to draw a 32×32 icon from the data starting at offset one and at offset 256. Offset 0 clearly produced an incorrect image:
So the 16*16 icon comes first and the 32×32 icon second. But I didn’t yet know the correct colours.
I did some experiments by presenting a full black icon, a full white icon and a checkerboard icon. After some experimenting I found out that PNAgent uses the Windows default 16-colour palette:
That look’s better:
I implemented drawing the icon by declaring the palette in an array indexed by the ASCII character:
1 2 3 4 | const CtxPalette: array[65..80] of TColor = (clBlack, clMaroon, clGreen, clOlive, clNavy, clPurple, clTeal, clSilver, clGray, clRed, clLime, clYellow, clBlue, clFuchsia, clAqua, clWhite); |
This makes drawing the icon very easy and fast:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | procedure DrawIcon32(const IconData: String); var Bitmap: TBitmap; x, y: Integer; Idx: Integer; begin // Image dimensions are fixed to 32x32 Image1.Width := 32; Image1.Height := 32; // Create a bitmap Bitmap := TBitmap.Create; try // Set bitmap dimensions Bitmap.Width := 32; Bitmap.Height := 32; // Fill the bitmap pixel by pixel, using scanline is a lot faster but this // is just for POC Idx := Length(IconData) - 1024; Assert(Idx > 0); for y := 0 to Bitmap.Height-1 do begin for x := 0 to Bitmap.Width-1 do begin // Get Color name from the Palette array Bitmap.Canvas.Pixels[x, y] := CtxPalette[Byte(IconData[Idx])]; Inc(Idx); end; end; // Assign the bitmap to the Image (box) on the form Image1.Picture.Graphic := Bitmap; finally // Free the bitmap Bitmap.Free; end; end; |
To my disappointment the high resolution png icons are not in the xml data but can be requested from PNAgent by XML.
See Nicholas Dille’s post on the XMLServiceExplorer for more info.
Leave a reply