About Terminal Server, Citrix, Delphi and other stuff
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.
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:
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:
procedure DrawIcon32(const IconData: String);
x, y: Integer;
// Image dimensions are fixed to 32x32
Image1.Width := 32;
Image1.Height := 32;
// Create a bitmap
Bitmap := TBitmap.Create;
// 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
for x := 0 to Bitmap.Width-1 do
// Get Color name from the Palette array
// Assign the bitmap to the Image (box) on the form
Image1.Picture.Graphic := Bitmap;
// Free the bitmap
To my disappointment the high resolution png icons are not in the xml data but can be requested from PNAgent by XML.
.NET .NET FrameWork Active Directory Altiris Automation Manager Citrix Dell Delphi Excel Exchange Exchange2003 Exchange2010 Hack HP iOS Java LinkedIn Linux Lync Management Pack MSI Office Office 2010 Passat Password PowerPoint PowerShell RES RNS510 SasLibEx SCOM Security Terminal Server ThinApp TSAdminEx VBS VCDS Visual Basic Visual Studio VMWare Volkswagen VSAE Windows PE Wordpress XenApp