Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

406 lines
9.5 KiB

#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
// #include <io.h>
#include <fcntl.h>
#include <malloc.h>
#include <sys\types.h>
#include <sys\stat.h>
#define SRV_PARAMETER_PATH \
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\LanmanServer\\Parameters"
#define PIPES_VALUE_KEY L"NullSessionPipes"
#define SHARES_VALUE_KEY L"NullSessionShares"
void
usage();
int
_CRTAPI1 main( int argc, char **argv )
{
PCHAR s;
BOOLEAN pipes;
BOOLEAN add = FALSE;
BOOLEAN delete = FALSE;
BOOLEAN list = FALSE;
BOOLEAN clear = FALSE;
OBJECT_ATTRIBUTES objAttr;
UNICODE_STRING keyName;
UNICODE_STRING valueKeyName;
HANDLE keyHandle = NULL;
NTSTATUS status;
ULONG length = 0;
ULONG lengthNeeded;
PWCHAR dataEntry;
PWCHAR p;
ANSI_STRING ansiResource;
UNICODE_STRING unicodeResource;
PKEY_VALUE_FULL_INFORMATION infoBuffer = NULL;
if ( argc < 3 ) {
usage( );
return(-1);
}
//
// Get the operation type
//
s = argv[1];
if ( (*s != '-') && (*s != '/') ) {
printf("Invalid operation %s.\n", s);
usage( );
return(-1);
}
s++;
if ( !_stricmp( s, "add" ) || !_stricmp( s, "a" ) ) {
add = TRUE;
} else if ( !_stricmp( s, "del" ) || !_stricmp( s, "d" ) ) {
delete = TRUE;
} else if ( !_stricmp( s, "list" ) || !_stricmp( s, "l" ) ) {
list = TRUE;
} else if ( !_stricmp( s, "clear" ) || !_stricmp( s, "c" ) ) {
clear = TRUE;
} else {
printf("Invalid operation %s.\n", s);
usage( );
return(-1);
}
//
// Get the resource type
//
s = argv[2];
if ( (*s != '-') && (*s != '/') ) {
printf("Invalid resource type %s.\n", s);
usage( );
return(-1);
}
s++;
if ( !_stricmp( s, "share" ) || !_stricmp( s, "s" ) ) {
pipes = FALSE;
} else if ( !_stricmp( s, "pipe" ) || !_stricmp( s, "p" ) ) {
pipes = TRUE;
} else {
printf("Invalid resource type %s.\n", s);
usage( );
return(-1);
}
if ( add | delete ) {
if ( argc < 4 ) {
usage( );
return(-1);
}
RtlInitAnsiString( &ansiResource, argv[3] );
RtlAnsiStringToUnicodeString(
&unicodeResource,
&ansiResource,
TRUE
);
} else {
RtlInitUnicodeString( &unicodeResource, NULL );
}
//
// Open the parameter key handle
//
RtlInitUnicodeString( &keyName, SRV_PARAMETER_PATH );
InitializeObjectAttributes(
&objAttr,
&keyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
status = NtOpenKey(
&keyHandle,
MAXIMUM_ALLOWED,
&objAttr
);
if ( !NT_SUCCESS(status) ) {
printf("Cannot open key %wZ. Status = %x\n", &keyName, status);
return(-1);
}
//
// Create the registry value
//
if ( pipes ) {
RtlInitUnicodeString( &valueKeyName, PIPES_VALUE_KEY );
} else {
RtlInitUnicodeString( &valueKeyName, SHARES_VALUE_KEY );
}
status = NtQueryValueKey(
keyHandle,
&valueKeyName,
KeyValueFullInformation,
NULL,
0,
&length
);
if ( status == STATUS_OBJECT_NAME_NOT_FOUND ) {
PWSTR data;
ULONG dataLength;
//
// We should only get this error if we are adding the first time.
//
if ( !add ) {
if ( list ) {
printf("No entries to list under %wZ.\n", &valueKeyName);
} else if ( clear ) {
printf("%wZ cleared.\n", &valueKeyName );
} else { // delete
printf("Registry value %wZ does not exist. Nothing to delete.\n", &valueKeyName);
}
goto done;
}
//
// If key not found, then set the value and we're done.
//
dataLength = unicodeResource.MaximumLength + sizeof(WCHAR);
data = LocalAlloc( 0, dataLength);
RtlCopyMemory(
data,
unicodeResource.Buffer,
unicodeResource.MaximumLength
);
data[unicodeResource.MaximumLength] = L'\0';
if ( data == NULL ) {
printf("Out of memory. Cannot perform requested operation.\n");
goto done;
}
status = NtSetValueKey(
keyHandle,
&valueKeyName,
0,
REG_MULTI_SZ,
data,
dataLength
);
LocalFree( data );
if ( !NT_SUCCESS(status)) {
printf("SetValueKey failed. Status = %x.\n", status);
} else {
printf("Added entry %wZ.\n", &unicodeResource);
}
goto done;
} else if ( status != STATUS_BUFFER_TOO_SMALL ) {
printf("Cannot query registry value %wZ. status = %x.\n",
&valueKeyName,
status );
goto done;
}
//
// Get the contents of the key
//
infoBuffer = LocalAlloc( 0, length + unicodeResource.MaximumLength );
if ( infoBuffer == NULL ) {
printf("Out of memory. Cannot perform requested operation.\n");
goto done;
}
//
// Do the query again. This should succeed.
//
status = NtQueryValueKey(
keyHandle,
&valueKeyName,
KeyValueFullInformation,
infoBuffer,
length,
&lengthNeeded
);
if ( !NT_SUCCESS(status) ) {
printf("Cannot query registry value %wZ. status = %x.\n",
&valueKeyName,
status );
goto done;
}
//
// do the right thing for list, clear, delete, and add.
//
length -= infoBuffer->DataOffset;
dataEntry = (PWCHAR)((PCHAR)infoBuffer + infoBuffer->DataOffset);
if ( list ) {
p = dataEntry;
if ( *p ) {
printf("List of entries under %wZ\n", &valueKeyName );
} else {
printf("No entries under %wZ\n", &valueKeyName );
}
while ( *p ) {
printf(" %ws\n", p);
p += (wcslen(p)+ 1);
}
goto done;
} else if ( clear ) {
//
// For clear, point the buffer to a null string
//
p = dataEntry;
p[0] = L'\0';
length = sizeof(WCHAR);
} else if ( delete ) {
//
// Find the entry.
//
p = dataEntry;
while ( *p ) {
if ( wcsicmp( p, unicodeResource.Buffer ) == 0 ) {
RtlCopyMemory(
p,
p + wcslen(p) + 1,
length - (ULONG)p + (ULONG)dataEntry
);
p = dataEntry;
length = length - (wcslen(p)+1) * sizeof(WCHAR);
goto do_set;
}
p += (wcslen(p) + 1);
}
printf("Entry does not exist. Delete ignored.\n", &unicodeResource);
status = STATUS_OBJECT_NAME_NOT_FOUND;
goto done;
} else if ( add ) {
//
// This is actually append. If the new entry is a duplicate,
// do nothing.
//
p = dataEntry;
while ( *p ) {
if ( wcsicmp( p, unicodeResource.Buffer ) == 0 ) {
printf("Duplicate entry %ws, ignored.\n", p);
goto done;
}
p += (wcslen(p) + 1);
}
RtlCopyMemory(p, unicodeResource.Buffer, unicodeResource.MaximumLength);
p = dataEntry;
length = length + unicodeResource.MaximumLength;
p[length] = L'\0';
}
do_set:
//
// Set the new value
//
status = NtSetValueKey(
keyHandle,
&valueKeyName,
0,
REG_MULTI_SZ,
p,
length
);
if ( NT_SUCCESS( status) ) {
if ( add ) {
printf("Added entry %wZ.\n", &unicodeResource);
} else if ( delete ) {
printf("Deleted entry %wZ.\n", &unicodeResource);
} else {
printf("%wZ cleared.\n", &valueKeyName );
}
} else {
printf("Cannot set registry value. Status = %x.\n", status);
}
done:
NtClose( keyHandle );
if ( infoBuffer != NULL ) {
LocalFree( infoBuffer );
}
if ( NT_SUCCESS(status)) {
return 0;
} else {
return -1;
}
}
void
usage()
{
printf("USAGE: srvnsp <operation> <resource type> <ValueName>\n");
printf("<operation>: \n");
printf(" -a (add)\n");
printf(" -c (clear)\n");
printf(" -d (delete)\n");
printf(" -l (list)\n\n");
printf("<resource type>: \n");
printf(" -s (share)\n");
printf(" -p (pipe)\n\n");
return;
}