• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1287
  • Last Modified:

Convert SID to Hex

Hi,

Anyone has Delphi function to convert SID to Hex (string)?

What I meant with SID is the SID value of Windows account that we could retrieve using "LookupAccountName()" Win32 API.

I got some codes from here:
http://www.delphi3000.com/articles/article_3391.asp?SK=

That converts the SID to STRING.

What I want is a HEX string ... for example:

0x0105000000000005150000009C4A9809E221B876E0276300E8250000

Note that the function should be compatible with Windows 2000 and Windows 2003.

Thanks
0
klompen
Asked:
klompen
  • 3
1 Solution
 
ChristianWimmerCommented:
A sid is not a number but a identifier as a string. It is saved in a variable length structure (usually a record or array) and contains the letter 'S' to identify the SID as a SID.
There are routines like ConvertStringSidToSid which support SID strings and their variable length structures. I think you should use them instead. Or do you have a very good reason to use a hex value which is also a string like the SID string?
0
 
MichaelSteinerCommented:
Take a look at ConvertSidToStringSid Should work from Windows 2000 to Windows 2008.
0
 
klompenAuthor Commented:
MichaelSteiner, do you have a working example?
0
 
MichaelSteinerCommented:
Here is a working example, Hope this helps:

function UInt64ToHex(Value: UInt64; Digits: Integer): string;
begin
 FmtStr(Result, '%.*x', [Digits, Value]);
end;

function UInt64ToHexLE(Value: UInt64; Digits: Integer): string;
var
 i,p,l : Integer;
 s : String;
begin
 FmtStr(s, '%.*x', [Digits, Value]);
 l := Length(s);
 p := l;
 SetLength(Result,l);

 repeat
  Result := Copy(s,p-1,2);
  dec(p,2);
 until p=0;
end;

function GetSIDAsHex: String;
var
 UserName : array[0..255] of Char;
 BufferLen,SidSize,DomainSize,SubAuthorities,Counter : DWORD;
 Sid : PSID;
 AccountType : SID_NAME_USE;
 Domain : array[0..1024] of Char;
 psia : Windows.PSIDIDENTIFIERAUTHORITY;
begin
 Result := 'Error';
 BufferLen := sizeof(UserName);
 DomainSize := sizeof(Domain);
 SidSize := 0;

 if GetUserName(UserName, BufferLen) = true then
  begin
   LookupAccountName(nil, UserName, Sid, SidSize, Domain, DomainSize, AccountType);
   if SidSize <> 0 then
    begin
     GetMem(Sid,SidSize);
     if LookupAccountName(nil, UserName, Sid, SidSize, Domain, DomainSize, AccountType) = true then
      if IsValidSid(Sid) = true then
       begin
        psia := GetSidIdentifierAuthority(Sid);
        SubAuthorities := GetSidSubAuthorityCount(Sid)^;
        Result := UInt64ToHex(1,2) + UInt64ToHex(SubAuthorities,2)+
            UInt64ToHex(DWORD(psia^.Value [5])+DWORD(psia^.Value [4] shl 8) +
                                          DWORD(psia^.Value [3] shl 16)+DWORD(psia^.Value [2] shl 24),12);
        for Counter := 0 to SubAuthorities - 1 do
         Result := Result + UInt64ToHex(GetSidSubAuthority(sid,Counter)^,8);
       end;
    end;
  end;
end;
0
 
MichaelSteinerCommented:
Sorry for that last post. It had been awhile sine I had tried this code. Here's the corrected code:

function UInt64ToHex(Value: UInt64; Digits: Integer): string;
begin
 FmtStr(Result, '%.*x', [Digits, Value]);
end;

function UInt64ToHexLE(Value: UInt64; Digits: Integer): string;
var
 i,p,l : Integer;
 s : String;
 t : array of Char;
begin
 FmtStr(s, '%.*x', [Digits, Value]);
 l := Length(s);
 p := l;
 SetLength(t,l);
 i := 0;

 repeat
  t[i] := s[p-1];
  t[i+1] := s[p];
  inc(i,2);
  dec(p,2);
 until p=0;
 Result := String(t);
end;

function GetSIDAsHex: String;
var
 UserName : array[0..255] of Char;
 BufferLen,SidSize,DomainSize,SubAuthorities,Counter : DWORD;
 Sid : PSID;
 AccountType : SID_NAME_USE;
 Domain : array[0..1024] of Char;
 psia : Windows.PSIDIDENTIFIERAUTHORITY;
begin
 Result := 'Error';
 BufferLen := sizeof(UserName);
 DomainSize := sizeof(Domain);
 SidSize := 0;

 if GetUserName(UserName, BufferLen) = true then
  begin
   LookupAccountName(nil, UserName, Sid, SidSize, Domain, DomainSize, AccountType);
   if SidSize <> 0 then
    begin
     GetMem(Sid,SidSize);
     if LookupAccountName(nil, UserName, Sid, SidSize, Domain, DomainSize, AccountType) = true then
      if IsValidSid(Sid) = true then
       begin
        psia := GetSidIdentifierAuthority(Sid);
        SubAuthorities := GetSidSubAuthorityCount(Sid)^;
        Result := UInt64ToHex(1,2) + UInt64ToHex(SubAuthorities,2)+
            UInt64ToHex(DWORD(psia^.Value [5])+DWORD(psia^.Value [4] shl 8) +
                                          DWORD(psia^.Value [3] shl 16)+DWORD(psia^.Value [2] shl 24),12);
        for Counter := 0 to SubAuthorities - 1 do
         Result := Result + UInt64ToHexLE(GetSidSubAuthority(sid,Counter)^,8);
       end;
    end;
  end;
end;
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now