Although I have went thru a few of these, this will be my first post on them.


The scenario:

During an email  spam mail filter outage an employee opened a malicious E-Mail.

Our mission:

To identify these items pertaining to the incident and to provide any other details.

Date and approximate time of the infection.
The infected computer’s IP address.
The infected computer’s MAC address.
The infected computer’s host name.
Which email the employee opened.


Infection Time: (Frame 85, DNS Query for Name: kennedy.sitoserver.com)
Arrival Time: Nov  6, 2015 16:22:38.340799000 Central Standard Time

Client IP address: (
Client MAC address: Dell_2d:90:81 (00:24:e8:2d:90:81)
Host Name: Strout-PC
Note: if we set a filter of “ bootp.option.hostname “ we can get this info from 1 frame.

Which Employee: arthur.stoyt@turkey-mania.co
Email Opened was: #4 
Dated Friday, November 06, 2015 3:05 PM
With Subject line of “You have received a new fax, document 000497762”

As we look at the traffic if we filter on “dns” then the first thing we see after the system trying to get an IP is this.


As we can see here “kennedy.sitoserver.com” with an IP of 174.121.246 is our first site to show up.

Going thru the emails we find an obfuscated java script in email 4 that was labeled “fax000497762.doc.js” and it looked like this. (if your antivirus doesn’t kill it first)


After spending way to much time de-obfuscating the script by hand  we end up with this.


It calls out to the 3 sites and if it connects then

it will down load a file to to the temp folder and attempt to run it so lets set a filter for the IP and see what all it does. “ ip.addr eq “


That’s still a little to much unneeded info so lets try a new filter

“ ip.addr eq and (http.request or http.response) “

Oh that’s better


Here we can see we narrowed down the traffic to just the get and response traffic for the suspect IP.

This appears to be downloading just gif files but if we look at the data in the display we see this.


This is a dead giveaway that it contains a programs code.

So what are these 3 files we extracted from the traffic.

The first on with a MD5 of “e2fc96114e61288fc413118327c76d93”  shows up on VirusTotal as a Trojan dropper and many other things.

This is the one I done all of my work on.

It is a VB5/6 file that makes it appear that it was from DHL by the info found it in.


The next one with a MD5 of “e2151a8411627ea2a288f2241735d0d0” shows up on VirusTotal as Trojan Generic on most of the list.

When Checked In PeStudio It does not have a Signature for this file what it was created with but the import makes it suspect as a MFC application. Original Name of pattern.exe


The third file with a MD5 of “35a09d67bee10c6aff48826717680c1c” shows up on VirusTotal as another Trojan / Info stealer.

When Checked in PeStudio this one does not have a Signature for the type either but viewing the imports I would assume that it is written in a form of C/C++.

This File Also pretends to be “VMware command line Toolbox”

I did not run the last 2 to see what all they did but the rest of this will be on the First one that was a VB5/6 file. This one appears to account for most of the traffic seen in Pcap

Here is a link to a previous Pcap on VirusTotal about it. It does contain some of the same sites detected in this search.


The VB Malware:

So what does this thing do ?

When run on a VM without the other 2 files running it will will blink and disappear not appearing to be doing anything.

I was not able to fully understand the decompiled code but after running the malware it is more clear.

The Malware creates a key in  “HKEY_CURRENT_USER\Software” I believe the name is as a result of a calculation  because I believe I’ve seen it changes every run.

Sets 2 values then then launches a process under WMI that starts MSHTA with a java script value that reads the value in the key decoding it and then launching Power shell with a environment variable to read another registry key  which then launches regsvr32.exe with the environment variable that is base 64 encoded. Launches another version with the base 64 string environment variable reads a previously created registry key .

Next it queries the Value of the RUN key and finds it is empty.

Next it sets the Value of the New Key

Next It query’s a value in the new key

Next it (regsvr32) locates the original malware file

Next the Original Malware file Deletes the original Registry key and  checks to see it is gone. Then it closes.

Next regsvr32 seem to be looking for Wireshark  and other tools.
(It does this several times)

Next it Query’s the new registry keys again  (It does this several times)

Then it Finally Creates Two Null Named Values in the registry under  The HKCU  Run key  which contain 2 separate Java Scripts.

It also attempts to delete a non existent key of.


Next it creates a new instance of regserver32.exe and reads the keys again.

Finally the First versions close then the original malware is deleted from the location where it was launched from.

This is also looking for a registry key “HKCU\Software\XK72 Ltd  folder” which appears to be another form of traffic monitor tool.

It keep this traffic pattern up over and over again in the Process Monitor Trace.

Sheww that is allot.

We can view the traffic generated live thru Process Explorer it sends a lot ‘ SYN “ packets.

The PowerShell Script

This power shell script that is base 64 decoded and then run appears to be a PowerShell, “Shell Script”, it will inject into several process and do its work. What ever that may be.

This script defiantly needs more research to see how it functions.

As mentioned above it loads 2 scripts from the HKCU  RUN key on boot to persist the infection and work it does.(I’m still not sure exactly what that is.) it will go thru the process of loading the values from it’s “Configuration” registry key launching mshta.exe,powershell, then the most likely injected regserver32.exe with what ever that “Shell Code” was.

Wow this thing is nasty.

Now lets go back and look at some of the traffic it produced.

If we look at the traffic under statistics –> Endpoints –> ipv4 then sort by packets we can see the result of just the “SYN’s sent and the multiple places they were sent to in the short time.

Here we see in Process Explorer some of the traffic in a different run. Do you notice what process it is running under ?



If we set a filter of “ ip.addr == “ whuch is for the Google public DNS server, we can see a repeating pattern with the exception of “Name: pomppondy.net” and a few others. We see that is repeats a search with a transaction ID starting with Hex 0x00000001 to 0x00000028 that is 1 to 40 decimal.

The sites that end in ddns.net are for sites thru noip.org

If we set a Filter for “ dns.flags == 0x8180 “ then we can see all  of the queries where there IP’s associated with them. If we go 1 step further and set a filter for

“ip.addr == and  dns.flags == 0x8180 “ then we can view only the queries that used the Google Public DNS. It still leaves 77 packets that returned valid IP’s.

If we set 1 more filter for “http.request.method == “POST” “ we see only 2 entries.

These 2 send some sort of encrypted or compressed data to the form page.

It has an IP of  “ “ so lets set a filter of  “ ip.addr == “ and see what it is doing.

It appears it is only sending that data and the interesting parts for me is it directly calling the IP address and didn’t look it up. So this may be the phone home call.

There is so much going on here it will make your head spin, and will require more time than would be allowed at a company to research it all.


So now after all of that how do we get rid of this thing.

If we try and open the registry with Regedit we see this

If we try and view this with Regedit we see this error(twice 1 for each value).


If we look at it with Autoruns we see this.


As you can see here both values are displayed in Autoruns as “Default” or no name.

A past try to get rid of this by deleting it with Autoruns didn’t work so well since the malware is injected into the system and most likely protecting the run key.

So the new way is to find the Configuration  key and delete it.


But first we have to kill the regsvr32 processes or the configuration key will automatically be replaced.


Once we delete this key and reboot the first scripts in the run key crashes since it can’t find that data in the configuration key to start the injection process.

I also disabled the network interface to stop it calling out.

If we see this then we know the configuration key stayed deleted.



Just click ‘NO”. and we get this. (twice, once for each script)


Next we fire up Autoruns (as Admin) again but we still can not delete the values with it.


So what do we do from here, By accident I discovered if we jump to the “RUN” key using Autoruns after the same error pops up that that we originally seen. Wow there are 2 values there now even though it says they are not set.


Note: When I tried to delete this key without jumping with Autoruns it would not allow it .

Now just delete the “RUN” key, restart the system  and then we see this.


The system put the real “Run” key back.

And to verify that it is real we turn back on the network card and run the verify command in Process explorer which verifies the file.

VMwaretools verified 

The loaded EXE  is verified, so now a little more searching should verify this nasty thing was cleaned from the VM system.

If you made it this far congratulations and thanks for keep reading.

I’m sure there is more traffic to look at but I’m wore out now.

This actually took several days to research and 1 more day to write up.

If this thing does this much to a system I would hate to see what happens if all 3 of them get launched on 1 system.

I hope others have learned from this as much as I have.

Posted in Malware | Tagged | Leave a comment

Under the hood of the ATI Ace Event Log

Or, Why is the event log maxing out the log with useless user information.

Anyone that has the Catalyst Control Center may have noticed the Ace Event Log.

Mine seems to stay full of errors and if you clear the log it will fill up again with just normal system use and not even opening the Catalyst Control Center to make any changes or to run any test. 

You can find this log by opening up the event viewer and then open the the application and services log and then you will see the Ace Event log.

Lets start with the test system specs.

Microsoft® Windows Vista™ Ultimate
Service Pack 2

AMD Phenom(tm) II X4 945 Processor
AMD64 Family 16 Model 4 Stepping 2    Revision 1026
64 bit Quad Core (Socket AM3) (125 watt)

ASUS M4A79T Deluxe Last available Bios Update(BIOS Date: 03/12/10 10:11:53 Ver: 08.00.15)

XFX HD-489X-ZSFC Radeon HD 4890 1GB 256-bit GDDR5 Pci Express 2.0 x16

Part Number: CM3X2048-1333C9 8GB (4 x 2 gig modules Paired)
Type:DDR3-SDRAM PC3-10700 (667MHz)  –  [DDR3-1333]

DirectX 11

Driver Packaging Version
Catalyst Version    13.1
Provider    Advanced Micro Devices, Inc.
2D Driver Version
2D Driver File Path    /REGISTRY/MACHINE/SYSTEM/ControlSet001/Control/CLASS/{4D36E968-E325-11CE-BFC1-08002BE10318}/0000
Direct3D Version
OpenGL Version
AMD VISION Engine Control Center Version    2012.1116.1515.27190

NOTE: On AMD CPU based systems it is now called “AMD Vision Engine Control Center” and on Intel CPU based systems it it is still called “Catalyst Control Center”


The Control Center is a module based system where the functionality is spread out among multiple modules.

Most of the modules are located in “C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static” and its sub folders. On my system Explorer says there are 341 files and 38 folder in the directory some folders are just language specific . That’s allot of files to keep track of and update for each new release.

If we take a look using Sysinternals Process Explorer We see that it starts with Mom.exe which in turn launches CCC.exe.


We can also see in the properties that these two are written in .Net clr version 2.0.50727

Using Process Explorer or a program I made to view the loaded modules we see that Mom.exe list 54 modules including, itself, the ATI modules and the .Net and system files required. Looking at CCC.exe it has 229 and over half of those are ATI modules.


Now lets get a look at the Ace Event Log.


One of the first things you notice is there are 731 events and they all have an event ID of “0” zero. Now that’s real helpful.

Another thing you may notice is , by the time stamps that they hit in groups.

So lets dig into a few of these and see if we can see why they are logged.


This is the error returned:
_IDEMDeviceDFP2Settings_0812.GetDFP2ITCFlag failed with status 2

By the function:

In order to dig in and see what is going on here we need to decompile the the modules and follow from module to module to get all of the information.

Here we will use a program called IlSpy which you can find here http://ilspy.net/ .

You can view the code and IL, C#, or VB.Net although some functions crashed the program while trying to view as VB.Net. I ended up staying in C# most of the time.

So how do we find this thing. Lets start by breaking down the function name.


ATI.ACE. = the folder name that the file is in (C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static) the Core-Static holds the bulk of these modules.

Next look in that folder for the file named ( CLI.Aspect.DeviceDFP.Graphics.Runtime )

Personally I copy the files I’m working with to a separate drive and folder and work with the copies.

Now we open this file with IlSpy and look for the class RT_DeviceDFP and then the function PrivateRefresh . Here is what we see.


The error shown here is not what was returned so lets dig deeper into the get method.

The get method traces down to the

// ATI.ACE.CLI.Aspect.DeviceDFP.Graphics.Runtime.RT_DeviceDFP
private void Parse(bool refreshDeviceInfo)


If we follow the get function we see:

// ATI.ACE.DEM.Graphics.IDEMDeviceDFP2Settings_0812
int GetDFP2ITCFlag(int demAdapterIndex, int displayIndex, ref bool itcFlagSupport, ref int itcFlag, ref int itcFlagDefault);

So it takes the parameters as input and somehow returns an integer value, perhaps it is adding the values or counting the ones that are not “0” zero. Without stepping thru this in a debugger it is difficult to know what the values are for the index’s.

The result was 2 in the error.

Looking at the code unless the index values are “0” zero then it will always throw this error because the other values are set to “0”, Boolean False = “0” .

This took almost a full day to sift thru the code and follow it thru multiple modules.

Next lets try an easier one (hopefully).



This one appears to be trying to subscribe to the registry key change event.

Looking thru the code on this one there are several problems with it.


First of all the path returned in the error, “HKCU;Software\wow6432node\ATI\ACE\Settings\AEM” does not exist on this system, this alone will cause it to fail every time.

For what ever reason they are using “;” instead of “\” in the output of the error message, perhaps to use a split Char later.  Also subscribe is misspelled in the error message.  (oops).

This function calls to the Windows API to open the registry key and does not appear to be checking for fails from those calls.

Those long numbers convert to the values of the default registry keys.



At this point I’m not sure where the sub key name came from so this is as far as I can go with this one.

Doing a string search it may be coming from:
C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static\CLIStart.exe

CLIStart.exe is a 32 bit unmanaged application so may be getting messed up with registry virtualization on a 64 bit system.


Lets try one more and we will call it a day.



This is the easiest one of all the file “ CLI.AIB.TutorialInfoCentre.Tutorial.Dashboard” just plain does not exist on this system. Thus the error that it can not be loaded.

I was not able to track down what tried to launch it to start with.


In conclusion this code base is so large and complicated that it is riddled with errors and it is also possible that due to the size of the code base and the registry keys that a previous version was not completely uninstalled and merged with the new version and is causing the problems. It would take a very long time to even attempt to track down the source of all of these errors.

If you don’t need the AMD/ATI user interface for overclocking  you could always uninstall it and just use the video drivers without the Catalyst Control Center.

I may test that next, after a normal uninstall and reboot see what is left and then cleaning all of the extra files and registry keys off the system .

That’s all for now I hope I was able to pass on some information oh how to dig into these although it can be difficult solve without being able to see the values in a debugger to solve some of them. There is a good chance you can not solve these without upgrading to a new version.

This version I’m using is already listed as legacy product. and it appears that there is another newer update since I last checked.


After uninstalling the old version, MSI crash and several reboots later and clearing the log file , there were still several files in the  windows\system32 folder.

Upon installing the new version with in and hour there were already over 230 new entry’s.

Go figure.

Posted in RootAdmin | Tagged | 2 Comments


Rootkits have become the most devious method of hiding malware on a system.

They are being employed to every sector from the home user to government to private industry.The monetary and information losses along with infrastructure disruption will continue to rise unless some way is developed to stop them.

What is a Rootkit ?

According to Wikipedia.

“A rootkit is a stealthy type of software, typically malicious, designed to hide the existence of certain processes or programs from normal methods of detection and enable continued privileged access to a computer.”

How do we stop them?

To stop them we have to understand how they work.

They, depending on how sophisticated they are can install a Windows service, Windows user mode driver, or a Windows kernel mode driver. They can also Infect the boot sector of a disk(boot kit), they can also create a hidden partition or volume to hide there files or even encrypt files so they are not easily identified about what they contain. They can also create task , either normal or WMI task to start at a given time or as a result to some action.I almost forgot about alternate data streams.

The basic idea is to install the driver or service so it can “Hide” itself and the other files registry keys and processes it needs to operate.

How it does this is by intercepting calls to list files or registry setting or process info or even disk info and can therefore remove from the results a predetermined set of files or registry or process entries  effectively hiding there existence so no one knows they are there by using normal means.

How do you find them?

They can be very difficult to find, again depending on how sophisticated they are.

First off you need to understand like in network analysis what is “Normal”  for a system.

The first step would be to determine if there is a process(s) running that do not conform to “Normal”, like multiple system process that should only have 1 copy of itself running, then you could check to see if there are items set to auto start on reboot that do not conform to “Normal” or any extra task that may have been added or network traffic to places it shouldn’t be going, also there are tools to check for encrypted files on the system.

Given what we know of the capability’s of these bad boys we can not be certain a system is “Clean” just because the system looks “Normal”. It could have these “Cloaking” drivers/ services running in the background.

The next step would start to delve into the world of computer forensics, where you would take a system off line and scan it for the traits previously mentioned, registry keys that shouldn’t be there, files that used to be hidden are now there or encrypted files where none should be, partitions that were not previously showing up thru the normal methods.

All of these and more could be a sign of some form of infection.(Or DRM Software)

I have been looking into service security and other information involved with them for over a year.

After reading several reverse engineering papers on different Rootkits and other malware one thing became clear and I developed a theory(educated guess).

The theory is a simple one . The implementation of it is not.

To the best of my knowledge every service or driver “Has” to “Register” with the system before it can do was it was intended to do. Whether or not it drops a file to disk or loads its code into memory and never touches the disk.

This is where I believe the weak point is.

The “Theory” is to have a service or driver “Listen” for services and  drivers being “Registered” with the system and, either scan it or at the very least log it and possibly send a administrator alert before it has a chance to infect a system and hide itself. The location of the log file would need to be well protected to keep anyone from removing it or changing its contents and thus continue to hide itself. Although the missing file itself would be a red flag that that system would need to be investigated further.If the file was changed or edited then it might prove difficult to verify what got changed in it and  thus back to the possible need to send an alert out also.

This way there will be a trail of what and when they got “Registered” with the system and possibly make the detection and removal faster. If it was somehow incorporated in a antivirus solution it may be even better as they already have a driver on the system.

The down side is if the system is already infected anything before that point would not be logged and any future ones may get filtered out by the Virus/Rootkit. You could also make a list of drivers not to be logged in order to keep down the log size but that would need to be protect also.

So far this is still a “Theory”, I still need to create a proof of concept program and build my malware lab to test against this “Theory” looking for any holes in it.

There are at least a few ways I can think of doing this and they start from the hard way to the very difficult as there seems to be no built in way to do this.

Lets see a little demonstration on how difficult it can be just to find a driver under normal conditions without being infected (that I know of ).

Have you ever wondered how Sysinternals Process Explorer works ?

In its most basic sense it just installs a device driver and listens for system calls and events and can report them back to the user application, Process Explorer, such as  process start or process end and information about each individual process and it’s threads and can give you a stack trace also for that moment in time and much more.

The question is how do you find this process or driver that it is using?

The driver does not show up in the MMC Services or in Device manager.

When using Process Monitor to view the launch of Process Explorer the driver name does not show up if it has already been launched once, it is still loaded into memory. Upon reboot run Process Monitor then run Process Explorer and then you can see the driver dropped to disk, loaded to memory then delete the file on disk.

On a 64 bit system Process Explorer starts the 32 bit version then extracts the 64 bit version to a temp folder then starts it and then extracts the driver to the system drivers folder to be loaded to memory before being deleted from disk.

So again how do we figure out what driver it is using. The easiest way it to also use the lower pane option of Process Explorer. If on a 64 bit system select the process “procexp64”  and select the view handles option on the toolbar.

Next sort by type then scroll down to the type “File” then look for an entry that starts with “\Device\drivername”.

In this case it is easy to spot. We are looking for “Device\PROCEXP 152” used with version 15.42 at least of Process Explorer.

Ok so how else can we find out what this driver name is.

If it is a normal driver install you can look into 2 places for the physical file.

“C:\Windows\System32\drivers” or if it is a 64 bit system “C:\Windows\SysWOW64\drivers” or one of the sub directory located in those folders but it could be dropped anywhere on the system, in the program files folder, in a temp folder, anywhere it may have read/write or read/execute access.

During my investigations I have created several tools to help with getting information more easily out of the registry and a system.

When a service or driver is registered it gets registered in the system registry under the keys:
“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services” and

The same name could possibly be loaded into both keys depending on the type of driver it is.

Lets start with what you see as the system normally shows you. The places that give information on installed services  are thru the MMC utility “Services” Which on my system shows 173 services(counting by hand). Using a program that utilizes the Service Process class also return 173 services, using WMI also returns the same number.

Then for the drivers you have Device Manager you also need to select the show hidden devices to show the Non Plug and play devices or “Legacy Devices’.

Viewing it this way in Device Manager is difficult to get a count on how many are there but what I want to relay is that using WMI Win32_SystemDriver only returns a list of 248 found on my system, but using the service process class again and selecting the type of driver instead of service it returns a list of 271 a difference of 23. I have created a new program to find the difference in what is missing. I can only assume that they are not listed thru WMI  because there is no physical file on disk for them (so far that I have found). Perhaps they are the ones that were uninstalled. I still have to track down each one and see what they do then build a database to log the information in.

Also the Process Explorer driver did not show up in either my regular tools or Device Manager to  reveal the name of the driver

Using this tool though:


Here we see that there were in fact three different versions of this driver registered with the system. All this tool does is enumerate the registry key. I have made it to be able to enumerate any control set numbers that it finds to check for any possible differences.

While writing this I had CurrentControlSet, Controlset001 and Controlset002. When I enumerated them the count was “1” different between CurrentControlSet, Controlset001 and Controlset002(diff). Viewing the list of both side by side I could not see the  difference so I saved a copy of the list for each and then rebooted into another OS partition loaded the registry key for this partition and then dumped it just in case something was hidden. Using my new List Diff tool with the first 2 list I saved before the reboot I was able to track the difference to a driver that I recently uninstalled .

Upon rebooting into this OS I then discovered there was no longer a ControlSet002 listed, instead there was a ControlSet003 and no ControlSet002 most likely because I did the uninstall and the list changed.

After a small test searching the system for files by name, the names that appears here in the list seems to be the actual name of the driver without the “LEGACY_” tacked on to the beginning.

Another tool I found while researching this, called DevManView from NirSoft, can get the same information from the registry once you enable the show non plug and play devices under the options tab.

I also tested if a Administrator could delete one of the entries. The current Security settings does not allow a “User” to change the security, take ownership or delete the key.

So in conclusion the best I can tell once a service or driver is installed on a system then it will stay on this list unless advanced methods are used to remove it or it gets uninstalled/unregistered and then system is rebooted. As long as the results of the enumeration are not filtered it should give a good history of what was loaded on the system and not uninstalled.

I am adding a link to my SkyDrive where I will have a zip files containing several tools the file name is BlogTools.zip. It will also have a readme file with the files names,description, and a how to use, most are pretty self explanatory on how to use.

Once this post gets consumed by the “RootAdmin” site I will try and add them there also.

I look forward to any comments or feedback.

Posted in RootAdmin | Tagged

How Do You Get A Service SID From A Service Name

Recently I have been trying to better understand Windows Service Security.

Starting with Windows Vista, Windows Services were able to have a SID Associated with the service so you could have Service Isolation and reduce the required privileges needed and to still have the ability to access the required registry and files it needed to, and also have the ability of restricting other SID’s to it’s resources.

So I was wondering, how do you get a SID for a service you create ?

The only built in tool I could find was the SC.Exe utility console application and use the command “sc.exe showsid ServiceName”

I then got wondering how does that program get the SID for the service ? Has it already been created and its just getting it from some location ?

After some internet searching I ran across a Wikipedia page for  Security Identifier and it said the the SID is created using the service name in uppercase and running it thru the SHA-1 Hash function.

So I created a small application that did that but it was not producing the same output as the SC.Exe utility. So I was still missing something.

I then started cmd.exe with a debugger, then ran the command “sc.exe showsid ServiceName” , that gave me a little bit of information but not enough to solve my problem of outputting the wrong results.

Next I turned to a Utility named EXE Explorer to view what the imports were for the Sc.exe utility and found that it imported a function from ntdll.dll named  RtlCreateServiceSid. That function Is undocumented.

Next I copied the ntdll.dll to another folder and opened it with a program named PEBrowser64 Professional. Then found and  decompiled that function and seen it was in fact using the Sha1 has function.

Next I Looked at the RFC 3174 SHA1 specification to see if they were doing anything different.(They were not,best I could tell)

Going back to PEBrowser64 Professional and after tracing that function thru several other functions you can get the basic steps required to output a Service SID from the input service name.

Basic Steps

1: Input service same.

2: Convert service name to upper case.

3: Get the Unicode bytes()  from the upper case service name.

4: Run bytes() thru the sha1 hash function.

5: Reverse the byte() string  returned from the SHA1 hash function (on Little Endian systems Not tested on Big Endian systems)

6: Split the reversed string into 5 blocks of 4 bytes each.

7: Convert each block of hex bytes() to Decimal

8: Reverse the Position of the blocks

9: Create the first part of the SID “S-1-5-80-“

10: Tack on each block of Decimal strings with a “-“ in between each block that was converted and reversed.

11: Finally out put the complete SID for the service.

This is not the exact order that the API call used but the order I used in my test application.

Here is what the final test application looks like.


This test application currently only takes input from the combo box that is filled with the service names it found.

The next problem was to figure out why I was getting a Different result so I broke down an Existing SID to Hex to be able to compare and to help figure this out.



391397178   = 0x17543F3A ,Reverse Order = 0x3A3F5417
1713532359 = 0x66226DC7 ,Reverse Order = 0xC76D2266
3388783719 = 0xC9FCBC67 ,Reverse Order = 0x67BCFCC9
1671243502 = 0x639D26EE ,Reverse Order = 0xEE269D63
2983178441 = 0xB1CFB0C9 ,Reverse Order = 0xC9B0CFB1

My initial output looked like.



Wrong results, But it agreed with all SHA1 Utility’s I tried.

After some more internet searching I ran across a question on Stack Overflow named Unicode, UTF, ASCII, ANSI format differences down at the bottom there was a link to another article named Joel on Software: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

After reading that I then searched on Code project for “RFC 3174” and ended up with this article http://www.codeproject.com/Articles/2463/CSHA1-A-C-Class-Implementation-of-the-SHA-1-Hash-A

I Read the article, downloaded the sample project and built it, and then ran it inputting the uppercase service name and it returned,

Enter the string to hash:

Hash of the ANSI representation of the string:

Hash of the Unicode representation of the string:

Now looking at that confirmed the the RtlCreateServiceSid function was not doing anything strange with the SHA1 function.

The top one matched what I was outputting in the original version but the bottom was lining up with the SID I had broken down.

So what was the problem of the different results ?

I then went back to my code and took a look and made a change on the Input Decoder from.

Dim encoder As New System.Text.ASCIIEncoding


Dim encoder As New System.Text.UnicodeEncoding

After that I was getting the results of .


Now I knew I was onto something and the rest was a matter of following the steps mentioned above.

Lets take a closer look to understand why I was getting the wrong results.

A while back I created a utility that input a string and output as hex string encoded with various Unicode encoders.


As you can see from the screenshot above that using the ASCII encoder output as :
4D 53 4D 50 53 56 43   And the Unicode output as 4D 0 53 0 4D 0 50 0 53 0 56 0 43 0

The first is 7 bytes long but the second one is padded with zeros and is 14 bytes long.
Looking thru the RFC 3174 you find that the whole thing starts with the length of the “message” in binary bits and using a different format will drastically change the outcome of the hash function due to the different lengths..

Another thing you may notice in this application is the BigEndianUnicode.


If you will take a close look of that, the bytes are going the same direction but the lead and trailing Zeros are on opposite ends.That would lead me to believe that the “Plain” Unicode is considered Little Endian byte order. Correct me if I am wrong.

The last part of the puzzle is after you create a SID how do you associate it with the service name ?

The answer can be found on Service Changes for Windows Vista under the sub section “Service Isolation”.

The last part reads : “To set the service SID, call ChangeServiceConfig2 with SERVICE_CONFIG_SERVICE_SID_INFO.”

In order to have your service have a SID set automatically you must set a value for “SERVICE_SID_INFO structure” to either “SERVICE_SID_TYPE_RESTRICTED” or “SERVICE_SID_TYPE_UNRESTRICTED” if you set it as “SERVICE_SID_TYPE_NONE” then it will not automatically be set and available for use by your service to aid in securing it.

Just being able to create a SID using this tool does not enable you to be able to use that SID without setting the required parameters above, It would only show you the same SID that the “sc.exe showsid ServiceName” does.

For instance If I was to run a service name like “mySuperService” thru the SC.exe utility it returns.

NAME: mySuperService
SERVICE SID: S-1-5-80-1956725871-603941828-2318551034-3950094706-3826225633

But that does not mean the service is installed on the system or the SID could be used.

It is just the SID created from the name.

Although it may help to know what it will be after being set or while building a Security Descriptor and setting the rights.

I have not found a command using the SC.Exe utility to set the service SID yet.

It may need to be done thru your service installer or a controller application.

The “Sc config servicename” does not seem to have the setting in it for setting the Service SID Type. I’m still looking into it.

That’s it for now I’m still working on a more overall service security article mainly aimed towards understanding why my program stopped working for shutting down Microsoft Security Essentials. Windows 8.1 has something new for Anti-Malware programs.

Posted in RootAdmin | Tagged

Get the last write time of a registry key in VB.Net using PInvoke

For a while I have been trying to find out how to get the last write time of a registry key but after digging thru the object browser in VS 2008 and .Net Framework 3.5 there appears to be no built in function to get the last write time for the registry.

After allot of internet searching using various search terms I finally decided to try to use Platform Invoke (PInvoke). I understand what it does but have never been able to get anything to work that wasn’t just a matter of copy paste and maybe some tweaking of the code to get it to do what I wanted.

The hardest part for me is the data types in unmanaged C/ C++ and in VB.Net and the Marshaling of them between managed and unmanaged. It can get very confusing on what they are wanting or how to do it.

A big help to get this project off the ground quickly was a Win API wrapper class on Code Project called VB.NET wrappers for much of the Windows API by andrewbb@gmail.com

I was able to just copy/paste the parts that I needed to a Class and then try to figure out the one function I needed that was not in the download.

The C++ Function I found to get the last write time is “ RegQueryInfoKey ” on MSDN.

LONG WINAPI RegQueryInfoKey( _In_ HKEY hKey, _Out_opt_ LPTSTR lpClass, _Inout_opt_ LPDWORD lpcClass, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPDWORD lpcSubKeys, _Out_opt_ LPDWORD lpcMaxSubKeyLen, _Out_opt_ LPDWORD lpcMaxClassLen, _Out_opt_ LPDWORD lpcValues, _Out_opt_ LPDWORD lpcMaxValueNameLen, _Out_opt_ LPDWORD lpcMaxValueLen, _Out_opt_ LPDWORD lpcbSecurityDescriptor, _Out_opt_ PFILETIME lpftLastWriteTime );

Reading thru the information of the MSDN page, you can not just use that function by itself you must first call one of four other another functions passing in the Base Key as a integer value and the sub key as a string, if it is not just a base key, and then return a handle to the key.
Since all I wanted to do was read an existing key and not set the value or write to a new one I used  “RegOpenKeyEx” on MSDN.

LONG WINAPI RegOpenKeyEx( _In_ HKEY hKey, _In_opt_ LPCTSTR lpSubKey, _Reserved_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult );

The input parameters of “RegOpenKeyEx” are the Integer value of the Base Registry key (below) as found in WINDDK in the file WINREG.h, Optional sub key as a string and the integer value of the “Registry Key Security and Access Rights” of   KEY_QUERY_VALUE (0x0001) Required to query the values of a registry key (see “RegQueryInfoKey”On MSDN ).

#define HKEY_CLASSES_ROOT (( HKEY ) (ULONG_PTR)((LONG)0x80000000) ) #define HKEY_CURRENT_USER (( HKEY ) (ULONG_PTR)((LONG)0x80000001) ) #define HKEY_LOCAL_MACHINE (( HKEY ) (ULONG_PTR)((LONG)0x80000002) ) #define HKEY_USERS (( HKEY ) (ULONG_PTR)((LONG)0x80000003) ) #define HKEY_PERFORMANCE_DATA (( HKEY ) (ULONG_PTR)((LONG)0x80000004) ) #define HKEY_PERFORMANCE_TEXT (( HKEY ) (ULONG_PTR)((LONG)0x80000050) ) #define HKEY_PERFORMANCE_NLSTEXT (( HKEY ) (ULONG_PTR)((LONG)0x80000060) ) #if(WINVER >= 0x0400) #define HKEY_CURRENT_CONFIG (( HKEY ) (ULONG_PTR)((LONG)0x80000005) ) #define HKEY_DYN_DATA (( HKEY ) (ULONG_PTR)((LONG)0x80000006) ) #define HKEY_CURRENT_USER_LOCAL_SETTINGS (( HKEY ) (ULONG_PTR)((LONG)0x80000007) )

You can add the list above as a public Enum in your API class I’m just using the 4 basic ones as supplied with the API wrapper class.

In VB.Net it might look like.

Public Enum Hives As Integer HKEY_CLASSES_ROOT = &H80000000 HKEY_CURRENT_USER = &H80000001 HKEY_LOCAL_MACHINE = &H80000002 HKEY_USERS = &H80000003 HKEY_PERFORMANCE_DATA = &H80000004 HKEY_PERFORMANCE_TEXT = &H80000050 HKEY_PERFORMANCE_NLSTEXT = &H80000060 '#if(WINVER >= 0x0400) HKEY_CURRENT_CONFIG = &H80000005 HKEY_DYN_DATA = &H80000006 HKEY_CURRENT_USER_LOCAL_SETTINGS = &H80000007 End Enum

Next use the handle returned from “RegOpenKeyEx” as input to “RegQueryInfoKey” and return just the parts of the function you want. Since all I want here is “Last write time” then all I needed was the pointer for input and a output variable of type “FILETIME”.

When looking at the the the unmanaged data type of “Long” , “Platform Invoke Data Types” we see that that data type in managed (CLR) is  System.Int32 and on Data Type Summary (Visual Basic) we see that the System.Int32 is Integer in VB.Net.
So the “Public Enum Hives As Integer” should be the correct data type.

Another thing I noticed, was when I tested changing from Integer to Uint32 which is what I thought it might be till I looked it up, I ended up with some strange errors, one was a math overflow and another was something about a number being to big or to small for the data type. After changing back to type Integer the problems were gone.
I was testing using a long set of sub keys and then reducing by 1 level till I got to the base key, it was there that the errors showed up until I changed the data type back to Integer.

Here is what the current test project looks like.


This version inputs a registry path to a key and then outputs what you see above.

I split the base key from the sub key section, Output what the value of the pointer was for the key returned by “RegOpenKeyEx”, returned the HResult for both API calls, if it returns anything but 0(Zero) for the Result then there is an error.
Next I have the returned File time listed as the high and low parts. Finally I output the converted “FILETIME” structure to date time using a API converter found in the  API Wrapper class.

I was wanting to do some kind of validation for the input so I created two crazy functions to parse the input.

The first thing I always test for is if the input text box has anything in it or not.

Next is when it gets strange, I was first testing with just longs paths that had several “\” in them so I was using that for my split character but when I tried to test just a base key I forgotten about that and had to add more handling of the input.

'Test first if we are dealing with a base key or malformed entry If Not input.Contains("\") Then If isabasekey(input) = True Then ' just do the work on the base key BaseKey = input ElseIf isabasekey(input) = False Then 'this is a messed up input tbOutput.Text = "Input not in Correct format" Exit Sub Else End If 'if the input has a base key and subkeys then parse the string to get the base key and the subkey values ElseIf input.Contains("\") Then BaseKey = input.Substring(0, input.IndexOf("\")) 'Trims everything to the right of and including the first "\" trimlength = input.IndexOf("\") 'The string index location of "\" SubKey = input.Substring(trimlength + 1) 'Trims everything to the Left of and including "\" End If

As you can see I have lots of comments in the code.
The First part takes the input string and if it contains a “\” then just proceeds on to the split function in the ElseIf statement , if it doesn't contain a “\” then is it a Base key or just a malformed entry. So it gets put thru the “isabasekey” function (great naming, I know)

Private Function isabasekey(ByVal akey As String) As Boolean Dim key As String = akey.ToUpper If _ key = "HKLM" OrElse _ key = "HKEY_LOCAL_MACHINE" OrElse _ key = "HKCU" OrElse _ key = "HKEY_CURRENT_USER" OrElse _ key = "HKCR" OrElse _ key = "HKEY_CLASSES_ROOT" OrElse _ key = "HKU" OrElse _ key = "HKEY_USERS" Then Return True Else Return False End If End Function

Here I simply take the input value and change it to upper case then compare the input to the allowed values and if it matches one it returns true if not then false.
Next after returning from the function if it is a valid allowed base key then just set the variable, BaseKey = input value. if it returns false then set the output text box text to the error message and then exit the sub, no reason to continue.

Next I take the “BaseKey” value and run it thru a function to validate it and return the integer value of the base key to use in the first API call.

Private Function ParseInput(ByVal key As String) As Integer Dim op As String If key.StartsWith("HKLM") OrElse key.StartsWith("HKEY_LOCAL_MACHINE") Then op = Hives.HKEY_LOCAL_MACHINE ElseIf key.StartsWith("HKCU") OrElse key.StartsWith("HKEY_CURRENT_USER") Then op = Hives.HKEY_CURRENT_USER ElseIf key.StartsWith("HKCR") OrElse key.StartsWith("HKEY_CLASSES_ROOT") Then op = Hives.HKEY_CLASSES_ROOT ElseIf key.StartsWith("HKU") OrElse key.StartsWith("HKEY_USERS") Then op = Hives.HKEY_USERS Else op = -1 '"Input Value Not Supported or Not in correct format" End If Return op End Function

Next we can finally make our first API call passing in the Integer value we just got for the BaseKey, the Sub Key string part that we split above if we are checking that along with the base key,then a variable to hold the return value for the pointer to the key.

Dim regkeyptr As Integer 'Here is our first API call to RegOpenKeyEx inputing the base key value and the subkeys value if any. 'openregkeyResult is th Hresult of the call. regkeyptr is the returned intptr for the input key. 'The fourth parameter is set at a default Constant value. Dim openregkeyResult As Integer = RegOpenKeyEx(BaseKeyValue, SubKey, 0, KEY_QUERY_VALUE, regkeyptr)

The third parameter is Reserved and the MSDN site says it must be set to 0(zero) the call also worked with it set as Nothing, but I changed it once rereading the description.

Next we can make our call to “RegQueryInfoKey” imputing the the pointer we got back and and a variable to hold the return value for the FILETIME structure.

'create a filetime structure to recieve the returned time Dim lpftLastWriteTime As System.Runtime.InteropServices.ComTypes.FILETIME Dim returnvalue As Integer returnvalue = RegQueryInfoKey( _ regkeyptr, _ Nothing, _ Nothing, _ Nothing, _ Nothing, _ Nothing, _ Nothing, _ Nothing, _ Nothing, _ Nothing, _ Nothing, _ lpftLastWriteTime)

As you can see above all the parameters we don’t need are set to nothing. Just the input of the pointer and output of the FILETIME have values. The “returnvalue” is the HResult and should be 0(zero) or else something went wrong.

Next we use a convert function supplied by the API class to convert this to a date time, then output and we are done.

While doing more testing I realized that I had forgotten to add one other input validation at the start, you always test in some way the users input path to see if it exist.  

See if you can see what is wrong here.


Now look close, what is wrong with the output here ? Compare the two if you need to.

Ok times up.

The first thing you may notice is the last letter is missing from the path.
The next thing you may notice is that the returned pointer from the first API call is 0(zero) ,this return should be non 0 ,bad sign.
Next the result from the open key API is 2 in decimal  System Error Codes (0-499) which translates to “ERROR_FILE_NOT_FOUND 2 (0x2) The system cannot find the file specified” which is kind of strange for this one. Next we see the result from the second API call as 6 in decimal. “ERROR_INVALID_HANDLE 6 (0x6) The handle is invalid.” now that one makes more sense.
The last thing you may notice is the output date/time.
The FILETIME structure page tells us.
”Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).” But looking at that is shows the low and high times as 0(zero) and the output is off 6 hours from what it should be. To answer that I just happen to be in the time zone –6 UTC but my current time offset is –5 for daylight saving time

Now that API class had two conversion functions, the one above should be for Local time without adjusting for Daylight Saving Time. The other returns the UTC time.


Now after changing which date/time converter was used all of the output is the same except the date/time output which now aligns with the date/time it is supposed to be for UTC time if the FILETIME value is not added to it.
Also if you input a path that contains a “Value Name” at the end it returns the same as if it was a bad path. So it only works with valid key paths.

One more thing.  After we get done using the ‘RegOpenKeyEx” function we need to close the key so we use the “RegCloseKey” function supplied by the API wrapper class.
Just pass in the handle returned from
‘RegOpenKeyEx” and that’s it.

So after a little more thought, time, and effort I should be able to turn this into a wrapper class to be able to drop into any project that requires the the ability to return the last write time of a registry key. Just input a valid path and get back a Date/Time and hide the rest of the nuts and bolts like most .Net classes do.

I hope someone found this useful.


RegOpenKeyEx function
RegQueryInfoKey function
FILETIME structure
System Error Codes
Platform Invoke Data Types
Registry Key Security and Access Rights
Data Type Summary (Visual Basic)
VB.NET wrappers for much of the Windows
RegCloseKey function

Posted in CodeProject | Tagged , ,

Add a new line instead of a new paragraph in Live Writer

I have been looking for some time on the best way to just start a new line instead of always adding a extra line when you hit the enter key.

Here is a sample.

Here after hitting the enter key.

New Sample.
After hitting Shift+Enter instead of just Enter.

You do not find this simple method listed in any of the keyboard Shortcut list.

Now I can format my post more the way I want.
Some times I have to hit the enter and back space a couple of times before it works.
Could be a wore out keyboard though.

I am posting this so I can find it again myself.

Posted in Uncategorized | Tagged

What’s in your toolbox (Environment Variables)

Over the years I have found several tools that make a good or great addition to my PC Repair toolbox. Some you use every day and others you only pull them out on occasion.

I hope to write up several that I have used.

This first one came when I was looking recently for a better way to check and modify the Environment Variables for the system.

The normal way is to go to Control Panel –> System –> Advanced System Settings –> Environment Variables . Then you could scroll and find the variable name you want in the list, and then select the name, and then click edit, then scroll the long string or copy paste to notepad then make the modifications, then copy paste back and save. As you can see below it is not easy to see what you have there especially if there are allot in one line.


Now that is not very handy for viewing the big picture. You can not even make the window bigger. Even if you click the edit button for a variable name it is hard to work with and you may still need to copy to notepad, edit it then copy back.

The most promising program I found on a internet search was one called “RapidEE” located here http://www.rapidee.com/en/download .

What I like the most is it comes as an Installer or as a Zip file so you can drop it on a flash drive and  use it portably without having to install it if you have several systems to look at.

This tool also has a built in crash report system. So if it crashes for some reason you can save the report locally or allow it to be sent to the creator if the need would arise.

When I first tested this program (Version 7.1 Build 841) it had a bug in it that crashed the application in a seemingly random way. After several emails back and forth with the Creator I was able to send the instructions to make the bug reproducible and gave my comments on what was displayed in the bug report and within a day they were able to find and correct the bug now that they could consistently reproduce the bug.

So if you tried that version (7.1 Build 841) and blew it off, try the latest version, as it works well.

So far I haven’t been able to break it again : )

The program starts up as standard user in Vista (the OS this was tested in) and you are able to edit the user variables but not the the system variables until you restart the program as an Administrator or right click and run as admin from the beginning.

It has a button to restart as admin. too.


As you can see by the screenshot above there are some variable names in red, that indicates that there is a bad path in the variable name.  If a program removes its environment variable path from the list it can still show up as red because a “Null” or Empty path will show as an  error. You see that when you have an entry like “path,,path”. The two commas side by side like that indicate that a environment variable path was removed from between the two paths.

You may also notice the warning icon at the bottom. That indicates that you are running the program as a standard user and would need to elevate in order to edit the system variables.

Before making any changes or if you are just curious where the settings are stored you may want to (run as admin) go to the file menu and select backup. This will back up all of the setting as a registry key backup for both the user and system environment variables.

By backing them up before hand you can restore them if you make a mistake or something goes wrong while editing them. Like me. I hate when the mouse jumps and you delete the wrong thing with out first backing it up. (That’s my story and I’m sticking to it.)

This tool will change them instantly after you press the save but they will not be reflected till the next boot if the variable path is currently in use, that I have found so far.

Lets talk about a few of the other features.

You may be able to see above that the variable names are displayed as a tree view. You can expand the individual variable name and edit or view the the individual paths. You can also narrow in on the item that caused the variable name to be flagged red.

As you install and uninstall programs sometimes the variable paths are left after uninstalling them leaving several bad paths. I should have taken a screen shot before I did the edit so you can see what variable path were left behind on my system from programs that were tested, there were several.

The two windows are for the user and the system variables that you can edit. The user variables can be edited with out being elevated. There are  several right click menu items for both sides.

When you first start out in standard user mode you will notice that there are some variable names that are greyed out and you can’t edit them, For the most part you would never need to edit those as the system takes care of those and might cause a few problems if you just deleted them. (good feature for those that don’t know what the variables do)

The right click options allow you to add new variable names, add new paths, reorder the path variables in the list, and more.

This can be a great tool for quickly going in and get a quick overview on what is there.

Checking for bad or missing paths, or for quickly adding a new path to a variable name.

If you haven’t already checked this one out then give it a spin.

This program is “Free Ware” / “Donation Ware” so if you like it, then you how that works. (there is a button for that too)

I hope others find this tool as useful as I did.

That’s it for this time.

Posted in RootAdmin