Scripting. Stuff. (By Froosh)

October 21, 2005

Hex SID to Decimal SID Translation

Filed under: VBScript — Robin Frousheger @ 11:46 am

Update: I’ve rolled this into a VBScript class and a Windows Script Component.

If you’ve ever played with SIDs in VBScript, you will have needed to convert a binary SID to the usual slightly-human-readable decimal format (e.g. S-1-5-21-xxxxxxxx-etc). Since I couldn’t find any examples of VBScript to do this, I’ve had to create it myself – and I post it here to use, poke fun at, or ignore at your leisure 😀

The two main references I needed to make this possible are from two of the very best programming blogs I read: The Old New Thing: How do I convert a SID between binary and string forms? and Fabulous Adventures In Coding: Integer Arithmetic in VBScript, Part Two. Also useful are the MSDN article on Well Known SIDs and my previous posting here VBScript vs. Byte().

The guts of the script is based on this excerpt from The Old New Thing:

If your SID is S-1-5-21-2127521184-1604012920-1887927527-72713, then your raw hex SID is 010500000000000515000000A065CF7E784B9B5FE77C8770091C0100

This breaks down as follows:
01 S-1
05 (seven dashes, seven minus two = 5)
000000000005 (5 = 0x000000000005, big-endian)
15000000 (21 = 0x00000015, little-endian)
A065CF7E (2127521184 = 0x7ECF65A0, little-endian)
784B9B5F (1604012920 = 0x5F9B4B78, little-endian)
E77C8770 (1887927527 = 0X70877CE7, little-endian)
091C0100 (72713 = 0x00011c09, little-endian)

And without further ado, here is the code to convert a hex string representation of a SID to the decimal format (and back again). Also included is the little helper function to swap between big- and little-endian representations. Note: Lines may be wrapped – it’s not worth my effort right now to format it nicely. Leave a comment if you want me to e-mail it to you.

Function ConvertHexStringToSidString(strHex)
  Const intSidVersionLength = 2
  Const intSubAuthorityCountLength = 2
  Const intAuthorityIdentifierLength = 12
  Const intSubAuthorityLength = 8

  Dim intStringPosition, bytSidVersion, lngAuthorityIdentifier, bytSubAuthorityCount, lngTempSubAuthority

  intStringPosition = 1

  bytSidVersion = CByte("&h" & Mid(strHex, intStringPosition, intSidVersionLength))
  intStringPosition = intStringPosition + intSidVersionLength

  bytSubAuthorityCount = CByte("&h" & Mid(strHex, intStringPosition, intSubAuthorityCountLength))
  intStringPosition = intStringPosition + intSubAuthorityCountLength

  lngAuthorityIdentifier = CLng("&h" & Mid(strHex, intStringPosition, intAuthorityIdentifierLength))
  intStringPosition = intStringPosition + intAuthorityIdentifierLength

  ConvertHexStringToSidString = "S-" & bytSidVersion & "-" & lngAuthorityIdentifier

  Do Until bytSubAuthorityCount = 0
    lngTempSubAuthority = CLng("&h" & EndianReverse(Mid(strHex, intStringPosition, intSubAuthorityLength)))
    intStringPosition = intStringPosition + intSubAuthorityLength

    If lngTempSubAuthority < 0 Then lngTempSubAuthority = lngTempSubAuthority + 2^32

    ConvertHexStringToSidString = ConvertHexStringToSidString & "-" & lngTempSubAuthority

    bytSubAuthorityCount = bytSubAuthorityCount - 1
  Loop
End Function

Function ConvertSidStringToHexString(strSID)
  Const intSidVersionLength = 2
  Const intSubAuthorityCountLength = 2
  Const intAuthorityIdentifierLength = 12
  Const intSubAuthorityLength = 8

  Dim intCounter, arrSplitSid, bytSidVersion, lngAuthorityIdentifier, bytSubAuthorityCount, dblTempSubAuthority

  arrSplitSid = Split(strSID, "-")

  bytSidVersion = CByte(arrSplitSid(LBound(arrSplitSid) + 1))
  bytSubAuthorityCount = CByte(UBound(arrSplitSid) - LBound(arrSplitSid) - 2)
  lngAuthorityIdentifier = CLng(arrSplitSid(LBound(arrSplitSid) + 2))

  ConvertSidStringToHexString = Right(String(intSidVersionLength, "0") & Hex(bytSidVersion), intSidVersionLength)
  ConvertSidStringToHexString = ConvertSidStringToHexString & Right(String(intSubAuthorityCountLength, "0") & Hex(bytSubAuthorityCount), intSubAuthorityCountLength)
  ConvertSidStringToHexString = ConvertSidStringToHexString & Right(String(intAuthorityIdentifierLength, "0") & Hex(lngAuthorityIdentifier), intAuthorityIdentifierLength)

  For intCounter = (LBound(arrSplitSid) + 3) to UBound(arrSplitSid)
    dblTempSubAuthority = CDbl(arrSplitSid(intCounter))
    If dblTempSubAuthority > 2^31 - 1 Then dblTempSubAuthority = dblTempSubAuthority - 2^32
    ConvertSidStringToHexString = ConvertSidStringToHexString & EndianReverse(Right(String(intSubAuthorityLength, "0") & Hex(dblTempSubAuthority), intSubAuthorityLength))
  Next
End Function

Function EndianReverse(strHex)
  Dim intCounter

  For intCounter = Len(strHex) to 1 Step - 2
    EndianReverse = EndianReverse & Mid(strHex, intCounter - 1, 2)
  Next
End Function

Enjoy! (I may comment these in the future for clarity, but don’t count on it.)

Update 4-Sep-2007: Wow, I must have had a bad day when I posted this – it was completely borkened. Updated with (I hope) actual working script and the mirror function to convert them back to strings. Oh, and using the new built-in syntax highlighter. Look out for the &amp; &lt; and &gt; in the code above as they need to be replaced with actual & < and > symbols. It seems the editor is munging the code when the syntax highlighter instructions tell us not to worry about the HTML entities.

Update 8-May-2008: Looks like the syntax highlighter was updated some time in the past to handle the HTML elements and the ‘copy to clipboard’ option also works perfectly.

Update 12-Aug-2008: Sigh.  It seems the the code keeps getting messed up.  I’m still happy to e-mail out the scriptlet, though sometimes I’m a bit laggy.

28 Comments »

  1. Would you email me this script to [address redacted]
    thanks

    Comment by Geoff — August 2, 2006 @ 10:38 pm

  2. Thanks for your script. That I needed !!

    Comment by DeadDingo — October 5, 2006 @ 1:55 pm

  3. Could you email the script to me. Thanks.
    I had issues when I copied and pasted from the webpage.

    Comment by Keane — October 16, 2006 @ 1:56 pm

  4. Wow… I wasted quite a while trying to make your script work. I think the formatting might have screwed the code.

    Either way, it’s mostly a time waster.

    Comment by Cameron Fairbairn — November 30, 2006 @ 8:22 am

  5. Here’s a link to some working code for anyone who falls into the same trap.

    Comment by Cameron Fairbairn — November 30, 2006 @ 8:42 am

  6. http://www.appdeploy.com/messageboards/printable.asp?m=9949

    Comment by Cameron Fairbairn — November 30, 2006 @ 8:43 am

  7. This SCRIPT worked for me! I was looking EVERYWHERE on the net and this is the only place I found one which worked! Thanks. Great script – very clever.

    Comment by Alan Sommerville — June 27, 2007 @ 7:20 pm

  8. Thanks. The script worked a treat. This is much appreciated.

    Comment by M@ — September 26, 2007 @ 11:13 pm

  9. Could you email the script to me. Thanks.

    Comment by Victor — February 21, 2008 @ 3:42 am

  10. I also need the script e-mailed to me too please. Also do I need to enter the SID i have when i run the script?

    Comment by Matt — March 7, 2008 @ 1:26 am

  11. I would like this script emailed to me also. Thank you.

    Comment by Jason Siatkowski — May 7, 2008 @ 11:34 pm

  12. Can I get a copy of this script emailed to me? thx.

    Comment by Jim — June 10, 2008 @ 2:29 am

  13. I would like this script emailed to me also. Thank you.

    Comment by Ann — June 28, 2008 @ 1:32 am

  14. I can’t seem to get it to work either from copy/paste, could you please E-mail it to me as well? Thank you.

    Comment by Nicklas — August 12, 2008 @ 6:59 pm

  15. Hi, Can you please email me a copy of the script?

    Great work. Thanks heaps.

    Comment by Mattew Farrin — January 16, 2009 @ 12:48 pm

  16. Can I get a copy of the script.

    Thanks.

    Comment by Matt — February 6, 2009 @ 8:50 am

  17. […] is a little like Marge re-using the 1 stylish dress she found, I’ve wrapped my old Byte() and SID manipulation code into a VBScript Class and a Windows Script […]

    Pingback by Byte Array and SID manipulation class and component « Scripting. Stuff. (By Froosh) — February 6, 2009 @ 11:02 am

  18. Can you send me a copy of this?

    Thanks.

    Comment by Don — March 4, 2009 @ 3:22 am

  19. Hi,
    Can you mail me the script to convert the SID to hexadecimal format.

    TIA.

    Comment by Amit — August 4, 2009 @ 5:54 pm

  20. Hey, I’d love a copy of your script, In need of exactly what it does. I’ve copied it into VBA but I get an error with EndianReverse, apparently it is not a recognised command? Am I right on this?

    CLng(“&h” & EndianReverse(Mid(strHex, intStringPosition, intSubAuthorityLength)

    Many, many, thanks!

    Comment by Steve C — August 27, 2009 @ 4:26 am

  21. Hello,

    Hi,
    Can you mail me the script to convert the SID to hexadecimal format.

    Many Thanks In Advance
    Hans

    Comment by Hans — October 8, 2009 @ 7:01 pm

  22. could you email the script also zip it or our spam catcher will grab it. or rename with txt extentsion.

    Comment by Matt — February 6, 2010 @ 6:19 am

  23. can you please mail me a copy?

    Comment by blake — February 20, 2010 @ 5:32 am

  24. Hi. Seems to fill my needs. Can you email me the script?

    Thanks

    Comment by Jean-Yves — June 15, 2010 @ 11:42 pm

  25. Hello, Froosh.
    I just want to say that i greatly appreciate this peace of code from you!
    I have spent few days searching the web for some tool to do this conversion (i need it in batch file) and i was actually jumping when i’ve found this post =)
    Respect!

    Comment by Plastikat — July 5, 2010 @ 8:54 pm

  26. Hi all,

    to convert a SID string to Hex format this can be done without any math formulas:

    Public Function ConvertSidStringToHexString(ByVal SID As String) As String
    Dim sec As New SecurityIdentifier(SID)
    Dim bSID As Byte() = New Byte(sec.BinaryLength – 1) {}
    sec.GetBinaryForm(bSID, 0)

    Dim strSID As String = String.Empty
    For Each b As Byte In bSID
    strSID &= b.ToString(“X2”)
    Next

    Return (strSID)
    End Function

    Comment by Juergen Geiß — May 23, 2011 @ 8:10 am

  27. Thanks for your script. That I needed !!

    Comment by chc — January 4, 2012 @ 7:18 am

  28. Another version which might also work. And doesn’t require emailing, just to save your time 🙂
    http://poshcode.org/3181

    Comment by Dormidont — November 14, 2012 @ 12:30 am


RSS feed for comments on this post. TrackBack URI

Leave a reply to Matt Cancel reply

Create a free website or blog at WordPress.com.