{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Unit Name : Unit1
* Autor : Daniel Wischnewski
* Copyright : Copyright © 2001-2003 by gate(n)etwork. All Rights Reserved.
* Urheber : Daniel Wischnewski
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
// THIS CODE IS DERIVED FROM "Reghide.c" PUBLISHED BY SYSTEM INTERNALS
//
// Reghide.c
//
// by Mark Russinovich
// [url]http://www.sysinternals.com[/url]
//
// This program demonstrates how the Native API can be used to
// create object names that are inaccessible from the Win32 API. While
// there are many different ways to do this, the method used here it to
// include a terminating NULL that is explicitly made part of the key name.
// There is no way to describe this with the Win32 API, which treats a NULL
// as the end of the name string and will therefore chop it. Thus, Regedit
// and Regedt32 won't be able to access this key, though it will be visible.
//
unit uRegHide;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 =
class(TForm)
btnDemo: TButton;
procedure btnDemoClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
// DEFINE MISSING CONSTANTS
const
ntdll = '
ntdll.dll';
OBJ_CASE_INSENSITIVE = $00000040;
// DEFINE MISSING TYPE DECLARATIONS
type
USHORT = WORD;
NTSTATUS = ULONG;
PVOID = Pointer;
// TRANSLATE MACRO
function NT_SUCCESS(Status: Integer): WordBool;
begin
Result := Status >= 0;
end;
// DEFINE Native API UNICODE STRING
type
TUnicodeString =
packed record
Length: USHORT;
MaximumLength: USHORT;
Buffer: PWideChar;
end;
UNICODE_STRING = TUnicodeString;
PUNICODE_STRING = ^UNICODE_STRING;
// DEFINE Native API OBJECT ATTRIBUTES
TObjectAttributes =
packed record
Length: ULONG;
RootDirectory: THandle;
ObjectName: PUNICODE_STRING;
Attributes: ULONG;
SecurityDescriptor: PVOID;
// Points to type SECURITY_DESCRIPTOR
SecurityQualityOfService: PVOID;
// Points to type SECURITY_QUALITY_OF_SERVICE
end;
OBJECT_ATTRIBUTES = TObjectAttributes;
POBJECT_ATTRIBUTES = ^OBJECT_ATTRIBUTES;
// TRANSLATE MACRO
procedure InitializeObjectAttributes(
var p: TObjectAttributes; n:
PUNICODE_STRING; a: ULONG; r: THandle; s: PVOID);
begin
p.Length := SizeOf(OBJECT_ATTRIBUTES);
p.RootDirectory := r;
p.Attributes := a;
p.ObjectName := n;
p.SecurityDescriptor := s;
p.SecurityQualityOfService :=
nil;
end;
// IMPORT NTDLL FUNCTIONS
function NtCreateKey(
var KeyHandle: THandle; DesiredAccess: ULONG;
var
ObjectAttributes: OBJECT_ATTRIBUTES; TitleIndex: ULONG; Class_:
PUNICODE_STRING; CreateOptions: ULONG;
var Disposition: ULONG): NTSTATUS;
stdcall;
external ntdll
name '
NtCreateKey';
function NtSetValueKey(KeyHandle: THandle; ValueName: PUNICODE_STRING;
TitleIndex: ULONG; Type_: ULONG; Data: PVOID; DataSize: ULONG): NTSTATUS;
stdcall;
external ntdll
name '
NtSetValueKey';
function NtDeleteKey(KeyHandle: THandle): NTSTATUS;
stdcall;
external ntdll
name '
NtDeleteKey';
{$R *.dfm}
// DEFINE OUR REGISTY STRINGS
const
KeyNameBuffer: AnsiString = '
\Registry\Machine\SOFTWARE';
NewKeyNameBuffer: AnsiString = '
Systems Internals';
HiddenKeyNameBuffer: AnsiString = '
Can''
t touch me!'#0;
HiddenValueNameBuffer: AnsiString = '
Hidden Value';
// DEMONSTRATE
procedure TForm1.btnDemoClick(Sender: TObject);
var
KeyName, ValueName: UNICODE_STRING;
SoftwareKeyHandle, SysKeyHandle, HiddenKeyHandle: THandle;
Status: ULONG;
ObjectAttributes: OBJECT_ATTRIBUTES;
Disposition: ULONG;
Buffer:
array of WideChar;
begin
ShowMessage('
Reghide'#13#10 + '
Creates a Registry key that cannot be ' +
'
opened with Regedit/Regedt32'#13#10#13#10'
original by Mark Russinovich' +
#13#10'
Delphi-Version by Daniel Wischnewski'#13#10'
http://www.' +
'
sysinternals.com'#13#10'
http://www.gatenetwork.com');
//
// Open the Software key
//
SetLength(Buffer, Length(KeyNameBuffer));
MultiByteToWideChar(CP_UTF8, 0, @KeyNameBuffer[1], Length(KeyNameBuffer),
PWideChar(Buffer), Length(Buffer));
KeyName.Buffer := @Buffer[0];
KeyName.Length := Length(KeyNameBuffer) * SizeOf(WideChar);
InitializeObjectAttributes(ObjectAttributes, @KeyName, OBJ_CASE_INSENSITIVE,
0,
nil);
Status := NtCreateKey(SoftwareKeyHandle, KEY_ALL_ACCESS, ObjectAttributes, 0,
nil, REG_OPTION_NON_VOLATILE, Disposition);
if not NT_SUCCESS(Status)
then
raise Exception.Create('
Error: Couldn''
t open HKLM\Software');
//
// Create the "Systems Internals" key
//
SetLength(Buffer, Length(NewKeyNameBuffer));
MultiByteToWideChar(CP_THREAD_ACP, 0, @NewKeyNameBuffer[1], Length(
NewKeyNameBuffer), PWideChar(Buffer), Length(Buffer));
KeyName.Buffer := @Buffer[0];
KeyName.Length := Length(NewKeyNameBuffer) * SizeOf(WideChar);
InitializeObjectAttributes(ObjectAttributes, @KeyName, OBJ_CASE_INSENSITIVE,
SoftwareKeyHandle,
nil);
Status := NtCreateKey(SysKeyHandle, KEY_ALL_ACCESS, ObjectAttributes, 0,
nil, REG_OPTION_NON_VOLATILE, Disposition);
if not NT_SUCCESS(Status)
then
raise Exception.Create(
'
Error: Couldn''
t create HKLM\Software\Systems Internals');
//
// Create the Hidden key
//
SetLength(Buffer, Length(HiddenKeyNameBuffer));
MultiByteToWideChar(CP_UTF8, 0, @HiddenKeyNameBuffer[1], Length(
HiddenKeyNameBuffer), PWideChar(Buffer), Length(Buffer));
KeyName.Buffer := @Buffer[0];
KeyName.Length := Length(HiddenKeyNameBuffer) * SizeOf(WideChar);
InitializeObjectAttributes(ObjectAttributes, @KeyName, OBJ_CASE_INSENSITIVE,
SysKeyHandle,
nil);
Status := NtCreateKey(HiddenKeyHandle, KEY_ALL_ACCESS, ObjectAttributes, 0,
nil, REG_OPTION_NON_VOLATILE, Disposition);
if not NT_SUCCESS(Status)
then
raise Exception.Create(
'
Error: Couldn''
t create HKLM\Software\Systems Internals\RegHide');
//
// Create the hidden value
//
SetLength(Buffer, Length(HiddenValueNameBuffer));
MultiByteToWideChar(CP_UTF8, 0, @HiddenValueNameBuffer[1], Length(
HiddenValueNameBuffer), PWideChar(Buffer), Length(Buffer));
ValueName.Buffer := @Buffer[0];
ValueName.Length := Length(HiddenValueNameBuffer) * SizeOf(WideChar);
Status := NtSetValueKey(HiddenKeyHandle, @ValueName, 0, REG_SZ,
@HiddenValueNameBuffer[1], Length(HiddenValueNameBuffer) * SizeOf(WideChar));
if not NT_SUCCESS(Status)
then
begin
NtDeleteKey(HiddenKeyHandle);
raise Exception.Create('
Error: Couldn''
t create our hidden value');
end;
//
// Let the user try and open our key!
//
ShowMessage('
Try and open the key "HKLM\SOFTWARE\Systems Internals\Can''
t ' +
'
touch me!"'#13#10'
with Regedit or Regedt32 (or any other Registry ' +
'
editor). There is a value'#13#10'
in the key called "Hidden Value".' +
#13#10#13#10'
When done trying, press any key to have the key deleted ' +
'
and exit.');
//
// Cleanup the key
//
NtDeleteKey(HiddenKeyHandle);
end;
end.