940 lines
20 KiB
C
940 lines
20 KiB
C
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1992 - 1997.
|
||
|
//
|
||
|
// File: wxcli.c
|
||
|
//
|
||
|
// Contents:
|
||
|
//
|
||
|
// Classes:
|
||
|
//
|
||
|
// Functions:
|
||
|
//
|
||
|
// History: 4-18-97 RichardW Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#include <nt.h>
|
||
|
#include <ntrtl.h>
|
||
|
#include <nturtl.h>
|
||
|
#include <ntsam.h>
|
||
|
#include <ntsamp.h>
|
||
|
#include <ntlsa.h>
|
||
|
#include <caiseapi.h>
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <windef.h>
|
||
|
#include <md5.h>
|
||
|
|
||
|
#include <wxlpc.h>
|
||
|
#include <wxlpcp.h>
|
||
|
|
||
|
#include "rng.h"
|
||
|
|
||
|
#define safe_min(x,y) ( x < y ? x : y )
|
||
|
|
||
|
NTSTATUS
|
||
|
WxConnect(
|
||
|
PHANDLE Handle
|
||
|
)
|
||
|
{
|
||
|
NTSTATUS Status ;
|
||
|
UNICODE_STRING PortName ;
|
||
|
SECURITY_QUALITY_OF_SERVICE DynamicQos;
|
||
|
|
||
|
//
|
||
|
// Set up the security quality of service parameters to use over the
|
||
|
// port. Use the most efficient (least overhead) - which is dynamic
|
||
|
// rather than static tracking.
|
||
|
//
|
||
|
|
||
|
DynamicQos.ImpersonationLevel = SecurityImpersonation;
|
||
|
DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
|
||
|
DynamicQos.EffectiveOnly = TRUE;
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// Connect to the Winlogon server thread
|
||
|
//
|
||
|
|
||
|
RtlInitUnicodeString(&PortName, WX_PORT_NAME );
|
||
|
Status = NtConnectPort(
|
||
|
Handle,
|
||
|
&PortName,
|
||
|
&DynamicQos,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
0
|
||
|
);
|
||
|
|
||
|
if ( !NT_SUCCESS(Status) )
|
||
|
{
|
||
|
// DbgPrint("WX: Connection failed %lx\n",Status);
|
||
|
}
|
||
|
|
||
|
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
WxGetKeyData(
|
||
|
IN HANDLE Handle,
|
||
|
IN WX_AUTH_TYPE ExpectedAuthSource,
|
||
|
IN ULONG BufferSize,
|
||
|
OUT PUCHAR Buffer,
|
||
|
OUT PULONG BufferData
|
||
|
)
|
||
|
{
|
||
|
WXLPC_MESSAGE Message ;
|
||
|
NTSTATUS Status ;
|
||
|
WXLPC_GETKEYDATA * Parameters ;
|
||
|
|
||
|
PREPARE_MESSAGE( Message, WxGetKeyDataApi );
|
||
|
|
||
|
Parameters = &Message.Parameters.GetKeyData ;
|
||
|
|
||
|
Parameters->ExpectedAuth = ExpectedAuthSource ;
|
||
|
Parameters->BufferSize = BufferSize ;
|
||
|
|
||
|
Status = NtRequestWaitReplyPort(
|
||
|
Handle,
|
||
|
&Message.Message,
|
||
|
&Message.Message );
|
||
|
|
||
|
if ( !NT_SUCCESS( Status ) )
|
||
|
{
|
||
|
return Status ;
|
||
|
}
|
||
|
|
||
|
if ( NT_SUCCESS( Message.Status ) )
|
||
|
{
|
||
|
RtlCopyMemory( Buffer,
|
||
|
Parameters->Buffer,
|
||
|
safe_min( Parameters->BufferData, BufferSize ) );
|
||
|
}
|
||
|
|
||
|
return Message.Status ;
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
WxReportResults(
|
||
|
IN HANDLE Handle,
|
||
|
IN NTSTATUS ResultStatus
|
||
|
)
|
||
|
{
|
||
|
WXLPC_MESSAGE Message ;
|
||
|
NTSTATUS Status ;
|
||
|
WXLPC_REPORTRESULTS * Parameters ;
|
||
|
|
||
|
PREPARE_MESSAGE( Message, WxReportResultsApi );
|
||
|
|
||
|
Parameters = &Message.Parameters.ReportResults ;
|
||
|
|
||
|
Parameters->Status = ResultStatus ;
|
||
|
|
||
|
Status = NtRequestWaitReplyPort(
|
||
|
Handle,
|
||
|
&Message.Message,
|
||
|
&Message.Message );
|
||
|
|
||
|
if ( !NT_SUCCESS( Status ) )
|
||
|
{
|
||
|
return Status ;
|
||
|
}
|
||
|
|
||
|
return Message.Status ;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/*++
|
||
|
|
||
|
The following code was moved from syskey to wxcli so as to commonalize this code
|
||
|
between syskey and samsrv.dll
|
||
|
|
||
|
--*/
|
||
|
#if DBG
|
||
|
#define HIDDEN
|
||
|
#else
|
||
|
#define HIDDEN static
|
||
|
#endif
|
||
|
|
||
|
HIDDEN
|
||
|
UCHAR KeyShuffle[ 16 ] = { 8, 10, 3, 7, 2, 1, 9, 15, 0, 5, 13, 4, 11, 6, 12, 14 };
|
||
|
|
||
|
HIDDEN
|
||
|
CHAR HexKey[ 17 ] = "0123456789abcdef" ;
|
||
|
|
||
|
#define ToHex( f ) (HexKey[f & 0xF])
|
||
|
|
||
|
#define SYSTEM_KEY L"SecureBoot"
|
||
|
|
||
|
|
||
|
|
||
|
HIDDEN BOOLEAN
|
||
|
WxpDeleteLocalKey(VOID)
|
||
|
/*++
|
||
|
|
||
|
Routine Description
|
||
|
|
||
|
Deletes the syskey stored on the local machine
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
HKEY LsaKey;
|
||
|
ULONG err;
|
||
|
|
||
|
err = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
|
||
|
L"System\\CurrentControlSet\\Control\\Lsa",
|
||
|
0,
|
||
|
KEY_READ | KEY_WRITE,
|
||
|
& LsaKey );
|
||
|
|
||
|
if (0!=err)
|
||
|
{
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
(void) RegDeleteKey( LsaKey, TEXT("Data") );
|
||
|
(void) RegDeleteKey( LsaKey, TEXT("Skew1") );
|
||
|
(void) RegDeleteKey( LsaKey, TEXT("GBG") );
|
||
|
(void) RegDeleteKey( LsaKey, TEXT("JD") );
|
||
|
|
||
|
RegCloseKey(LsaKey);
|
||
|
|
||
|
return STATUS_SUCCESS ;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
HIDDEN BOOLEAN
|
||
|
WxpObfuscateKey(
|
||
|
PWXHASH Hash
|
||
|
)
|
||
|
{
|
||
|
HKEY Key ;
|
||
|
HKEY Key2 ;
|
||
|
int Result ;
|
||
|
WXHASH H ;
|
||
|
CHAR Classes[ 9 ];
|
||
|
int i ;
|
||
|
WXHASH R ;
|
||
|
PCHAR Class ;
|
||
|
DWORD Disp ;
|
||
|
DWORD FailCount = 0;
|
||
|
HKEY LsaKey;
|
||
|
ULONG err=0;
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
err = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
|
||
|
L"System\\CurrentControlSet\\Control\\Lsa",
|
||
|
0,
|
||
|
KEY_READ | KEY_WRITE,
|
||
|
& LsaKey );
|
||
|
|
||
|
if (0!=err)
|
||
|
{
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
for (Result = 0 ; Result < 16 ; Result++ )
|
||
|
{
|
||
|
H.Digest[Result] = Hash->Digest[ KeyShuffle[ Result ] ];
|
||
|
}
|
||
|
|
||
|
WxpDeleteLocalKey();
|
||
|
|
||
|
Classes[8] = '\0';
|
||
|
|
||
|
STGenerateRandomBits( R.Digest, 16 );
|
||
|
|
||
|
Class = Classes ;
|
||
|
|
||
|
for ( i = 0 ; i < 4 ; i++ )
|
||
|
{
|
||
|
*Class++ = ToHex( (H.Digest[ i ] >> 4) );
|
||
|
*Class++ = ToHex( H.Digest[ i ] );
|
||
|
}
|
||
|
|
||
|
Result = RegCreateKeyExA( LsaKey,
|
||
|
"JD",
|
||
|
0,
|
||
|
Classes,
|
||
|
REG_OPTION_NON_VOLATILE,
|
||
|
KEY_WRITE,
|
||
|
NULL,
|
||
|
&Key,
|
||
|
&Disp );
|
||
|
|
||
|
if ( Result == 0 )
|
||
|
{
|
||
|
RegSetValueEx( Key, TEXT("Lookup"), 0,
|
||
|
REG_BINARY, R.Digest, 6 );
|
||
|
|
||
|
RegCloseKey( Key );
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
RegCloseKey(LsaKey);
|
||
|
return FALSE ;
|
||
|
}
|
||
|
|
||
|
Class = Classes ;
|
||
|
|
||
|
for ( i = 0 ; i < 4 ; i++ )
|
||
|
{
|
||
|
STGenerateRandomBits( R.Digest, 16 );
|
||
|
|
||
|
*Class++ = ToHex( (H.Digest[ i+4 ] >> 4 ) );
|
||
|
*Class++ = ToHex( H.Digest[ i+4 ] );
|
||
|
}
|
||
|
|
||
|
Result = RegCreateKeyExA( LsaKey,
|
||
|
"Skew1",
|
||
|
0,
|
||
|
Classes,
|
||
|
REG_OPTION_NON_VOLATILE,
|
||
|
KEY_WRITE,
|
||
|
NULL,
|
||
|
&Key,
|
||
|
&Disp );
|
||
|
|
||
|
if ( Result == 0 )
|
||
|
{
|
||
|
RegSetValueEx( Key, TEXT("SkewMatrix"), 0,
|
||
|
REG_BINARY, R.Digest, 16 );
|
||
|
|
||
|
RegCloseKey( Key );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
FailCount++;
|
||
|
}
|
||
|
|
||
|
STGenerateRandomBits( R.Digest, 16 );
|
||
|
|
||
|
for ( i = 0, Class = Classes ; i < 4 ; i++ )
|
||
|
{
|
||
|
*Class++ = ToHex( (H.Digest[ i+8 ] >> 4 ));
|
||
|
*Class++ = ToHex( H.Digest[i+8] );
|
||
|
}
|
||
|
|
||
|
Result = RegCreateKeyExA( LsaKey,
|
||
|
"GBG",
|
||
|
0,
|
||
|
Classes,
|
||
|
REG_OPTION_NON_VOLATILE,
|
||
|
KEY_WRITE,
|
||
|
NULL,
|
||
|
&Key,
|
||
|
&Disp );
|
||
|
|
||
|
if ( Result == 0 )
|
||
|
{
|
||
|
RegSetValueEx( Key, TEXT("GrafBlumGroup"), 0,
|
||
|
REG_BINARY, R.Digest, 9 );
|
||
|
|
||
|
RegCloseKey( Key );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
FailCount++;
|
||
|
}
|
||
|
|
||
|
STGenerateRandomBits( H.Digest, 8 );
|
||
|
|
||
|
Class = Classes ;
|
||
|
|
||
|
STGenerateRandomBits( R.Digest, 16 );
|
||
|
|
||
|
for ( i = 0 ; i < 4 ; i++ )
|
||
|
{
|
||
|
*Class++ = ToHex( (H.Digest[ i+12 ] >> 4 ) );
|
||
|
*Class++ = ToHex( H.Digest[ i+12 ] );
|
||
|
}
|
||
|
|
||
|
Result = RegCreateKeyExA( LsaKey,
|
||
|
"Data",
|
||
|
0,
|
||
|
Classes,
|
||
|
REG_OPTION_NON_VOLATILE,
|
||
|
KEY_WRITE,
|
||
|
NULL,
|
||
|
&Key,
|
||
|
&Disp );
|
||
|
|
||
|
if ( Result == 0 )
|
||
|
{
|
||
|
STGenerateRandomBits( H.Digest, 16 );
|
||
|
|
||
|
RegSetValueEx( Key, TEXT("Pattern"), 0,
|
||
|
REG_BINARY, R.Digest, 64 );
|
||
|
|
||
|
RegCloseKey( Key );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
FailCount++;
|
||
|
}
|
||
|
|
||
|
RegCloseKey(LsaKey);
|
||
|
return TRUE ;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
#define FromHex( c ) ( ( ( c >= '0' ) && ( c <= '9') ) ? c - '0' : \
|
||
|
( ( c >= 'a' ) && ( c <= 'f') ) ? c - 'a' + 10: \
|
||
|
( ( c >= 'A' ) && ( c <= 'F' ) ) ? c - 'A' + 10: -1 )
|
||
|
|
||
|
HIDDEN BOOLEAN
|
||
|
WxpDeObfuscateKey(
|
||
|
HKEY Keylocation,
|
||
|
PWXHASH Hash
|
||
|
)
|
||
|
{
|
||
|
WXHASH ProtoHash ;
|
||
|
int Result ;
|
||
|
CHAR Class[ 9 ];
|
||
|
HKEY Key ;
|
||
|
DWORD Size ;
|
||
|
DWORD i ;
|
||
|
PUCHAR j ;
|
||
|
int t;
|
||
|
int t2 ;
|
||
|
HKEY LsaKey;
|
||
|
ULONG err;
|
||
|
|
||
|
|
||
|
if (Keylocation!=NULL) {
|
||
|
|
||
|
DWORD Type=REG_DWORD;
|
||
|
DWORD Data;
|
||
|
DWORD cbData=sizeof(DWORD);
|
||
|
WCHAR Controlset[256];
|
||
|
|
||
|
err = RegOpenKeyExW( Keylocation,
|
||
|
L"Select",
|
||
|
0,
|
||
|
KEY_READ | KEY_WRITE,
|
||
|
& LsaKey );
|
||
|
if (0!=err)
|
||
|
{
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
err = RegQueryValueExW(
|
||
|
LsaKey,
|
||
|
L"Default",
|
||
|
NULL,
|
||
|
&Type,
|
||
|
(LPBYTE)&Data,
|
||
|
&cbData
|
||
|
);
|
||
|
RegCloseKey(LsaKey);
|
||
|
if (0!=err)
|
||
|
{
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
if(Data==1){
|
||
|
err = RegOpenKeyExW( Keylocation,
|
||
|
L"ControlSet001\\Control\\Lsa",
|
||
|
0,
|
||
|
KEY_READ | KEY_WRITE,
|
||
|
& LsaKey );
|
||
|
} else {
|
||
|
err = RegOpenKeyExW( Keylocation,
|
||
|
L"ControlSet002\\Control\\Lsa",
|
||
|
0,
|
||
|
KEY_READ | KEY_WRITE,
|
||
|
& LsaKey );
|
||
|
}
|
||
|
if (0!=err)
|
||
|
{
|
||
|
RegCloseKey(LsaKey);
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
err = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
|
||
|
L"System\\CurrentControlSet\\Control\\Lsa",
|
||
|
0,
|
||
|
KEY_READ | KEY_WRITE,
|
||
|
& LsaKey );
|
||
|
|
||
|
if (0!=err)
|
||
|
{
|
||
|
return (FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Result = RegOpenKeyEx( LsaKey, TEXT("JD"), 0,
|
||
|
KEY_READ, &Key );
|
||
|
j = ProtoHash.Digest ;
|
||
|
|
||
|
if ( Result == 0 )
|
||
|
{
|
||
|
Size = 9 ;
|
||
|
|
||
|
Result = RegQueryInfoKeyA( Key,
|
||
|
Class,
|
||
|
&Size,
|
||
|
NULL, NULL, NULL,
|
||
|
NULL, NULL, NULL,
|
||
|
NULL, NULL, NULL );
|
||
|
|
||
|
RegCloseKey( Key );
|
||
|
|
||
|
if ( Result == 0 )
|
||
|
{
|
||
|
for ( i = 0 ; i < 8 ; i += 2 )
|
||
|
{
|
||
|
t = FromHex( Class[ i ] );
|
||
|
t2 = FromHex( Class[ i+1 ] );
|
||
|
if ( (t >= 0 ) && ( t2 >= 0 ) )
|
||
|
{
|
||
|
*j++ = (t << 4) + t2 ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
RegCloseKey(LsaKey);
|
||
|
return FALSE ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
Result = RegOpenKeyEx( LsaKey, TEXT("Skew1"), 0,
|
||
|
KEY_READ, &Key );
|
||
|
|
||
|
if ( Result == 0 )
|
||
|
{
|
||
|
Size = 9 ;
|
||
|
|
||
|
Result = RegQueryInfoKeyA( Key,
|
||
|
Class,
|
||
|
&Size,
|
||
|
NULL, NULL, NULL,
|
||
|
NULL, NULL, NULL,
|
||
|
NULL, NULL, NULL );
|
||
|
|
||
|
RegCloseKey( Key );
|
||
|
|
||
|
if ( Result == 0 )
|
||
|
{
|
||
|
for ( i = 0 ; i < 8 ; i += 2 )
|
||
|
{
|
||
|
t = FromHex( Class[ i ] );
|
||
|
t2 = FromHex( Class[ i+1 ] );
|
||
|
if ( (t >= 0 ) && ( t2 >= 0 ) )
|
||
|
{
|
||
|
*j++ = (t << 4) + t2 ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
RegCloseKey(LsaKey);
|
||
|
return FALSE ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
Result = RegOpenKeyEx( LsaKey, TEXT("GBG"), 0,
|
||
|
KEY_READ, &Key );
|
||
|
|
||
|
if ( Result == 0 )
|
||
|
{
|
||
|
Size = 9 ;
|
||
|
|
||
|
Result = RegQueryInfoKeyA( Key,
|
||
|
Class,
|
||
|
&Size,
|
||
|
NULL, NULL, NULL,
|
||
|
NULL, NULL, NULL,
|
||
|
NULL, NULL, NULL );
|
||
|
|
||
|
RegCloseKey( Key );
|
||
|
|
||
|
if ( Result == 0 )
|
||
|
{
|
||
|
for ( i = 0 ; i < 8 ; i += 2 )
|
||
|
{
|
||
|
t = FromHex( Class[ i ] );
|
||
|
t2 = FromHex( Class[ i+1 ] );
|
||
|
if ( (t >= 0 ) && ( t2 >= 0 ) )
|
||
|
{
|
||
|
*j++ = (t << 4) + t2 ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
RegCloseKey(LsaKey);
|
||
|
return FALSE ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
Result = RegOpenKeyEx( LsaKey, TEXT("Data"), 0,
|
||
|
KEY_READ, &Key );
|
||
|
|
||
|
if ( Result == 0 )
|
||
|
{
|
||
|
Size = 9 ;
|
||
|
|
||
|
Result = RegQueryInfoKeyA( Key,
|
||
|
Class,
|
||
|
&Size,
|
||
|
NULL, NULL, NULL,
|
||
|
NULL, NULL, NULL,
|
||
|
NULL, NULL, NULL );
|
||
|
|
||
|
RegCloseKey( Key );
|
||
|
|
||
|
if ( Result == 0 )
|
||
|
{
|
||
|
for ( i = 0 ; i < 8 ; i += 2 )
|
||
|
{
|
||
|
t = FromHex( Class[ i ] );
|
||
|
t2 = FromHex( Class[ i+1 ] );
|
||
|
if ( (t >= 0 ) && ( t2 >= 0 ) )
|
||
|
{
|
||
|
*j++ = (t << 4) + t2 ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
RegCloseKey(LsaKey);
|
||
|
return FALSE ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
for ( i = 0 ; i < 16 ; i++ )
|
||
|
{
|
||
|
Hash->Digest[ KeyShuffle[ i ] ] = ProtoHash.Digest[ i ] ;
|
||
|
}
|
||
|
|
||
|
RegCloseKey(LsaKey);
|
||
|
return TRUE ;
|
||
|
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
WxSaveSysKey(
|
||
|
IN ULONG Keylen,
|
||
|
IN PVOID Key
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description
|
||
|
|
||
|
This routine is used to store the syskey
|
||
|
in the registry
|
||
|
|
||
|
Paramaeters
|
||
|
|
||
|
Keylen - the length of the key
|
||
|
Key the actual key itself
|
||
|
|
||
|
Return Values
|
||
|
|
||
|
STATUS_SUCCESS
|
||
|
STATUS_UNSUCCESSFUL
|
||
|
--*/
|
||
|
{
|
||
|
WXHASH H;
|
||
|
|
||
|
//
|
||
|
// key should be 128 bits
|
||
|
//
|
||
|
|
||
|
if (Keylen!=sizeof(H.Digest))
|
||
|
return (STATUS_INVALID_PARAMETER);
|
||
|
|
||
|
RtlCopyMemory(&H.Digest,
|
||
|
Key,
|
||
|
Keylen
|
||
|
);
|
||
|
|
||
|
if (WxpObfuscateKey(&H))
|
||
|
{
|
||
|
|
||
|
return(STATUS_SUCCESS);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return(STATUS_UNSUCCESSFUL);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
NTSTATUS
|
||
|
WxReadSysKey(
|
||
|
IN OUT PULONG BufferLength,
|
||
|
OUT PVOID Key
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description
|
||
|
|
||
|
This routine is used to retrieve the syskey from
|
||
|
the registry
|
||
|
|
||
|
Paramaeters
|
||
|
|
||
|
BufferLength is filled in with the length required on output
|
||
|
is used to indicate the size of the buffer
|
||
|
pointed to by Key.
|
||
|
Key Points to a buffer into which the key is recieved
|
||
|
|
||
|
Return Values
|
||
|
|
||
|
STATUS_SUCCESS
|
||
|
STATUS_UNSUCCESSFUL
|
||
|
--*/
|
||
|
{
|
||
|
return WxReadSysKeyEx(
|
||
|
NULL,
|
||
|
BufferLength,
|
||
|
Key
|
||
|
);
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
WxReadSysKeyEx(
|
||
|
IN HKEY Handle,
|
||
|
IN OUT PULONG BufferLength,
|
||
|
OUT PVOID Key
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description
|
||
|
|
||
|
This routine is used to retrieve the syskey from
|
||
|
the registry
|
||
|
|
||
|
Paramaeters
|
||
|
|
||
|
Handle Contains a pointer to the syskey in the old registry
|
||
|
|
||
|
BufferLength is filled in with the length required on output
|
||
|
is used to indicate the size of the buffer
|
||
|
pointed to by Key.
|
||
|
Key Points to a buffer into which the key is recieved
|
||
|
|
||
|
Return Values
|
||
|
|
||
|
STATUS_SUCCESS
|
||
|
STATUS_UNSUCCESSFUL
|
||
|
--*/
|
||
|
{
|
||
|
WXHASH H;
|
||
|
|
||
|
if ((NULL==Key) || (*BufferLength <sizeof(H.Digest)))
|
||
|
{
|
||
|
*BufferLength = sizeof(H.Digest);
|
||
|
return(STATUS_BUFFER_OVERFLOW);
|
||
|
}
|
||
|
|
||
|
if (WxpDeObfuscateKey(Handle,&H))
|
||
|
{
|
||
|
*BufferLength = sizeof(H.Digest);
|
||
|
RtlCopyMemory(
|
||
|
Key,
|
||
|
&H.Digest,
|
||
|
*BufferLength
|
||
|
);
|
||
|
|
||
|
return(STATUS_SUCCESS);
|
||
|
}
|
||
|
|
||
|
return (STATUS_UNSUCCESSFUL);
|
||
|
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
WxLoadSysKeyFromDisk(OUT PVOID Key,
|
||
|
OUT PULONG BufferLength
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description
|
||
|
|
||
|
This routine is used to read the syskey
|
||
|
from the Disk
|
||
|
|
||
|
Paramaeters
|
||
|
|
||
|
Key - buffer where the key will be read into
|
||
|
|
||
|
BufferLength - size of the returned key
|
||
|
|
||
|
Return Values
|
||
|
|
||
|
STATUS_OBJECT_NAME_NOT_FOUND
|
||
|
STATUS_FILE_CORRUPT_ERROR
|
||
|
STATUS_UNSUCCESSFUL
|
||
|
--*/
|
||
|
{
|
||
|
HANDLE hFile ;
|
||
|
ULONG Actual ;
|
||
|
ULONG ErrorMode ;
|
||
|
|
||
|
LPSTR SysKeyFileName = "A:\\startkey.key";
|
||
|
|
||
|
ErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX );
|
||
|
|
||
|
hFile = CreateFileA( SysKeyFileName,
|
||
|
GENERIC_READ,
|
||
|
0,
|
||
|
NULL,
|
||
|
OPEN_EXISTING,
|
||
|
FILE_ATTRIBUTE_NORMAL,
|
||
|
NULL );
|
||
|
|
||
|
|
||
|
|
||
|
if ( hFile == INVALID_HANDLE_VALUE )
|
||
|
{
|
||
|
SetErrorMode( ErrorMode );
|
||
|
|
||
|
return STATUS_OBJECT_NAME_NOT_FOUND ;
|
||
|
}
|
||
|
|
||
|
if (!ReadFile( hFile, Key, SYSKEY_SIZE, &Actual, NULL ) ||
|
||
|
(Actual != SYSKEY_SIZE ))
|
||
|
{
|
||
|
SetErrorMode( ErrorMode );
|
||
|
|
||
|
CloseHandle( hFile );
|
||
|
|
||
|
return STATUS_FILE_CORRUPT_ERROR ;
|
||
|
|
||
|
}
|
||
|
|
||
|
SetErrorMode( ErrorMode );
|
||
|
|
||
|
CloseHandle( hFile );
|
||
|
|
||
|
*BufferLength = SYSKEY_SIZE;
|
||
|
return STATUS_SUCCESS;
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
WxHashKey(
|
||
|
IN OUT LPWSTR key, //will be killed
|
||
|
OUT PVOID SysKey,
|
||
|
IN OUT DWORD cbSysKey
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description
|
||
|
|
||
|
This routine is used to store the boot type
|
||
|
in the registry
|
||
|
|
||
|
Paramaeters
|
||
|
|
||
|
NewType Indicates the new boot type
|
||
|
|
||
|
Return Values
|
||
|
|
||
|
STATUS_SUCCESS
|
||
|
STATUS_UNSUCCESSFUL
|
||
|
--*/
|
||
|
{
|
||
|
MD5_CTX Md5;
|
||
|
if(cbSysKey<SYSKEY_SIZE) {
|
||
|
return STATUS_BUFFER_TOO_SMALL;
|
||
|
}
|
||
|
cbSysKey=wcslen(key)*sizeof(WCHAR);
|
||
|
|
||
|
MD5Init( &Md5 );
|
||
|
MD5Update( &Md5, (PUCHAR) key, cbSysKey );
|
||
|
MD5Final( &Md5 );
|
||
|
|
||
|
ZeroMemory( key, cbSysKey );
|
||
|
|
||
|
cbSysKey=SYSKEY_SIZE;
|
||
|
CopyMemory( SysKey, Md5.digest, cbSysKey );
|
||
|
|
||
|
return STATUS_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
NTSTATUS
|
||
|
WxSaveBootOption( WX_AUTH_TYPE NewType )
|
||
|
/*++
|
||
|
|
||
|
Routine Description
|
||
|
|
||
|
This routine is used to store the boot type
|
||
|
in the registry
|
||
|
|
||
|
Paramaeters
|
||
|
|
||
|
NewType Indicates the new boot type
|
||
|
|
||
|
Return Values
|
||
|
|
||
|
STATUS_SUCCESS
|
||
|
STATUS_UNSUCCESSFUL
|
||
|
--*/
|
||
|
{
|
||
|
HKEY LsaKey;
|
||
|
ULONG err;
|
||
|
|
||
|
err = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
|
||
|
L"System\\CurrentControlSet\\Control\\Lsa",
|
||
|
0,
|
||
|
KEY_READ | KEY_WRITE,
|
||
|
& LsaKey );
|
||
|
|
||
|
if (0!=err)
|
||
|
{
|
||
|
return (STATUS_UNSUCCESSFUL);
|
||
|
}
|
||
|
|
||
|
err = RegSetValueExW(
|
||
|
LsaKey,
|
||
|
SYSTEM_KEY,
|
||
|
0,
|
||
|
REG_DWORD,
|
||
|
(PUCHAR) &NewType,
|
||
|
sizeof( NewType )
|
||
|
);
|
||
|
|
||
|
if (0!=err)
|
||
|
{
|
||
|
RegCloseKey(LsaKey);
|
||
|
return (STATUS_UNSUCCESSFUL);
|
||
|
}
|
||
|
|
||
|
RegCloseKey(LsaKey);
|
||
|
|
||
|
return ( STATUS_SUCCESS);
|
||
|
|
||
|
}
|
||
|
|