Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
-Delphi/Pascal
-CBuilder/C++
-C#Builder/C#
-JBuilder/Java
-Kylix
Member Area
-Home
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Login/Logout
-Become a Member
-Why sign up!
-Newsletter
-Chat Online!
-Indexes NEW!!
Employment
-Build your resume
-Find a job
-Post a job
-Resume Search
Contacts
-Contacts
-Feedbacks
-Link to us
-Privacy/Disclaimer
Embarcadero
Visit Embarcadero
Embarcadero Community
JEDI
Links
Creating "Hidden" Registry Values Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
28-May-03
Category
Win API
Language
Delphi 5.x
Views
217
User Rating
No Votes
# Votes
0
Replies
0
Publisher:
DSP, Administrator
Reference URL:
DKB
			Author: Daniel Wischnewski 

This article is based upon the information published in a source code sample at 
Sysinternals Freeware http://www.sysinternals.com/ntw2k/info/tips.shtml. This code 
will show you how to access and use the MS Native API functions.

Answer:

Today, I came across the Sysinternals Freewarehttp://www.sysinternals.com/ website 
and stopped cold reading the articles on what all you can do with a Windows NT/2K 
system. A lot of interesting aspects were told there. 

Evaluating one of the code samples, provided in C/C++, I decided to try to 
translate it into Delphi - you all probably understand why ;) 

This article is based upon the sample provided by the following link: Hidden 
Registry Keyshttp://www.sysinternals.com/ntw2k/info/tips.shtml#RegistryHidden?. 

Accessing the Windows Registry through the TRegistry object, or using the 
documented WinAPI routines, you are restricted in the choice of characters used for 
the Registry key names und value names. 

Direct quote from the Website: In the Win32 API strings are interpreted as 
NULL-terminated ANSI (8-bit) or wide character (16-bit) strings. In the Native API 
names are counted Unicode (16-bit) strings. While this distinction is usually not 
important, it leaves open an interesting situation: there is a class of names that 
can be referenced using the Native API, but that cannot be described using the 
Win32 API. 

So, I started playing around with the code some and want to provide you with the 
solution I found for Delphi. I would never have made (or tried) it without this 
great site. 

There are two units to this project. The unit uRegHide.pas defines the type 
structures and imports the Native API routines, the project file HiddenRegistry.dpr 
does the actual work. Go on and try it :) 
1   
2   ////////////////////////////////////////////////////////////
3   /////////////////////// uRegHide.pas ///////////////////////
4   ////////////////////////////////////////////////////////////
5   
6   {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
7   *
8   * Unit Name : Unit1
9   * Autor     : Daniel Wischnewski
10  * Copyright : Copyright © 2001-2003 by gate(n)etwork. All Rights Reserved.
11  * Urheber   : Daniel Wischnewski
12  *
13  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
14  
15  // THIS CODE IS DERIVED FROM "Reghide.c" PUBLISHED BY SYSTEM INTERNALS
16  
17  //
18  // Reghide.c
19  //
20  // by Mark Russinovich
21  // http://www.sysinternals.com
22  //
23  // This program demonstrates how the Native API can be used to
24  // create object names that are inaccessible from the Win32 API. While
25  // there are many different ways to do this, the method used here it to
26  // include a terminating NULL that is explicitly made part of the key name.
27  // There is no way to describe this with the Win32 API, which treats a NULL
28  // as the end of the name string and will therefore chop it. Thus, Regedit
29  // and Regedt32 won't be able to access this key, though it will be visible.
30  //
31  
32  unit uRegHide;
33  
34  interface
35  
36  uses
37    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
38    Dialogs, StdCtrls;
39  
40  type
41    TForm1 = class(TForm)
42      btnDemo: TButton;
43      procedure btnDemoClick(Sender: TObject);
44    private
45      { Private declarations }
46    public
47      { Public declarations }
48    end;
49  
50  var
51    Form1: TForm1;
52  
53  implementation
54  
55  // DEFINE MISSING CONSTANTS
56  
57  const
58    ntdll = 'ntdll.dll';
59    OBJ_CASE_INSENSITIVE = $00000040;
60  
61    // DEFINE MISSING TYPE DECLARATIONS
62  
63  type
64    USHORT = WORD;
65    NTSTATUS = ULONG;
66    PVOID = Pointer;
67  
68    // TRANSLATE MACRO
69  
70  function NT_SUCCESS(Status: Integer): WordBool;
71  begin
72    Result := Status >= 0;
73  end;
74  
75  // DEFINE Native API UNICODE STRING
76  
77  type
78    TUnicodeString = packed record
79      Length: USHORT;
80      MaximumLength: USHORT;
81      Buffer: PWideChar;
82    end;
83    UNICODE_STRING = TUnicodeString;
84    PUNICODE_STRING = ^UNICODE_STRING;
85  
86    // DEFINE Native API OBJECT ATTRIBUTES
87  
88    TObjectAttributes = packed record
89      Length: ULONG;
90      RootDirectory: THandle;
91      ObjectName: PUNICODE_STRING;
92      Attributes: ULONG;
93      SecurityDescriptor: PVOID; // Points to type SECURITY_DESCRIPTOR
94      SecurityQualityOfService: PVOID; // Points to type SECURITY_QUALITY_OF_SERVICE
95    end;
96    OBJECT_ATTRIBUTES = TObjectAttributes;
97    POBJECT_ATTRIBUTES = ^OBJECT_ATTRIBUTES;
98  
99    // TRANSLATE MACRO
100 
101 procedure InitializeObjectAttributes(var p: TObjectAttributes; n:
102   PUNICODE_STRING; a: ULONG; r: THandle; s: PVOID);
103 begin
104   p.Length := SizeOf(OBJECT_ATTRIBUTES);
105   p.RootDirectory := r;
106   p.Attributes := a;
107   p.ObjectName := n;
108   p.SecurityDescriptor := s;
109   p.SecurityQualityOfService := nil;
110 end;
111 
112 // IMPORT NTDLL FUNCTIONS
113 
114 function NtCreateKey(var KeyHandle: THandle; DesiredAccess: ULONG; var
115   ObjectAttributes: OBJECT_ATTRIBUTES; TitleIndex: ULONG; Class_:
116   PUNICODE_STRING; CreateOptions: ULONG; var Disposition: ULONG): NTSTATUS;
117   stdcall; external ntdll name 'NtCreateKey';
118 
119 function NtSetValueKey(KeyHandle: THandle; ValueName: PUNICODE_STRING;
120   TitleIndex: ULONG; Type_: ULONG; Data: PVOID; DataSize: ULONG): NTSTATUS;
121   stdcall; external ntdll name 'NtSetValueKey';
122 
123 function NtDeleteKey(KeyHandle: THandle): NTSTATUS; stdcall; external ntdll
124   name 'NtDeleteKey';
125 
126 {$R *.dfm}
127 
128 // DEFINE OUR REGISTY STRINGS
129 
130 const
131   KeyNameBuffer: AnsiString = '\Registry\Machine\SOFTWARE';
132   NewKeyNameBuffer: AnsiString = 'Systems Internals';
133   HiddenKeyNameBuffer: AnsiString = 'Can''t touch me!'#0;
134   HiddenValueNameBuffer: AnsiString = 'Hidden Value';
135 
136   // DEMONSTRATE
137 
138 procedure TForm1.btnDemoClick(Sender: TObject);
139 var
140   KeyName, ValueName: UNICODE_STRING;
141   SoftwareKeyHandle, SysKeyHandle, HiddenKeyHandle: THandle;
142   Status: ULONG;
143   ObjectAttributes: OBJECT_ATTRIBUTES;
144   Disposition: ULONG;
145   Buffer: array of WideChar;
146 begin
147   ShowMessage('Reghide'#13#10 + 'Creates a Registry key that cannot be ' +
148     'opened with Regedit/Regedt32'#13#10#13#10'original by Mark Russinovich' +
149     #13#10'Delphi-Version by Daniel Wischnewski'#13#10'http://www.' +
150     'sysinternals.com'#13#10'http://www.gatenetwork.com');
151 
152   //
153   // Open the Software key
154   //
155   SetLength(Buffer, Length(KeyNameBuffer));
156   MultiByteToWideChar(CP_UTF8, 0, @KeyNameBuffer[1], Length(KeyNameBuffer),
157     PWideChar(Buffer), Length(Buffer));
158   KeyName.Buffer := @Buffer[0];
159   KeyName.Length := Length(KeyNameBuffer) * SizeOf(WideChar);
160   InitializeObjectAttributes(ObjectAttributes, @KeyName, OBJ_CASE_INSENSITIVE,
161     0, nil);
162   Status := NtCreateKey(SoftwareKeyHandle, KEY_ALL_ACCESS, ObjectAttributes, 0,
163     nil, REG_OPTION_NON_VOLATILE, Disposition);
164   if not NT_SUCCESS(Status) then
165     raise Exception.Create('Error: Couldn''t open HKLM\Software');
166 
167   //
168   // Create the "Systems Internals" key
169   //
170   SetLength(Buffer, Length(NewKeyNameBuffer));
171   MultiByteToWideChar(CP_THREAD_ACP, 0, @NewKeyNameBuffer[1], Length(
172     NewKeyNameBuffer), PWideChar(Buffer), Length(Buffer));
173   KeyName.Buffer := @Buffer[0];
174   KeyName.Length := Length(NewKeyNameBuffer) * SizeOf(WideChar);
175   InitializeObjectAttributes(ObjectAttributes, @KeyName, OBJ_CASE_INSENSITIVE,
176     SoftwareKeyHandle, nil);
177   Status := NtCreateKey(SysKeyHandle, KEY_ALL_ACCESS, ObjectAttributes, 0,
178     nil, REG_OPTION_NON_VOLATILE, Disposition);
179   if not NT_SUCCESS(Status) then
180     raise Exception.Create(
181       'Error: Couldn''t create HKLM\Software\Systems Internals');
182 
183   //
184   // Create the Hidden key
185   //
186   SetLength(Buffer, Length(HiddenKeyNameBuffer));
187   MultiByteToWideChar(CP_UTF8, 0, @HiddenKeyNameBuffer[1], Length(
188     HiddenKeyNameBuffer), PWideChar(Buffer), Length(Buffer));
189   KeyName.Buffer := @Buffer[0];
190   KeyName.Length := Length(HiddenKeyNameBuffer) * SizeOf(WideChar);
191   InitializeObjectAttributes(ObjectAttributes, @KeyName, OBJ_CASE_INSENSITIVE,
192     SysKeyHandle, nil);
193   Status := NtCreateKey(HiddenKeyHandle, KEY_ALL_ACCESS, ObjectAttributes, 0,
194     nil, REG_OPTION_NON_VOLATILE, Disposition);
195   if not NT_SUCCESS(Status) then
196     raise Exception.Create(
197       'Error: Couldn''t create HKLM\Software\Systems Internals\RegHide');
198 
199   //
200   // Create the hidden value
201   //
202   SetLength(Buffer, Length(HiddenValueNameBuffer));
203   MultiByteToWideChar(CP_UTF8, 0, @HiddenValueNameBuffer[1], Length(
204     HiddenValueNameBuffer), PWideChar(Buffer), Length(Buffer));
205   ValueName.Buffer := @Buffer[0];
206   ValueName.Length := Length(HiddenValueNameBuffer) * SizeOf(WideChar);
207   Status := NtSetValueKey(HiddenKeyHandle, @ValueName, 0, REG_SZ,
208     @HiddenValueNameBuffer[1], Length(HiddenValueNameBuffer) * SizeOf(WideChar));
209   if not NT_SUCCESS(Status) then
210   begin
211     NtDeleteKey(HiddenKeyHandle);
212     raise Exception.Create('Error: Couldn''t create our hidden value');
213   end;
214 
215   //
216   // Let the user try and open our key!
217   //
218   ShowMessage('Try and open the key "HKLM\SOFTWARE\Systems Internals\Can''t ' +
219     'touch me!"'#13#10'with Regedit or Regedt32 (or any other Registry ' +
220     'editor). There is a value'#13#10'in the key called "Hidden Value".' +
221     #13#10#13#10'When done trying, press any key to have the key deleted ' +
222     'and exit.');
223 
224   //
225   // Cleanup the key
226   //
227   NtDeleteKey(HiddenKeyHandle);
228 end;
229 
230 end.
231 
232 ////////////////////////////////////////////////////////////
233 //////////////////// HiddenRegistry.dpr ////////////////////
234 ////////////////////////////////////////////////////////////
235 
236 {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
237 *
238 * Unit Name : Not available
239 * Autor     : Daniel Wischnewski
240 * Copyright : Copyright © 2001-2003 by gate(n)etwork. All Rights Reserved.
241 * Urheber   : Daniel Wischnewski
242 *
243 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
244 
245 program HiddenRegistry;
246 
247 uses
248   Windows,
249   uRegHeaders in 'uRegHeaders.pas';
250 
251 // DEFINE OUR REGISTY STRINGS
252 const
253   KeyNameBuffer: AnsiString = '\Registry\Machine\SOFTWARE';
254   NewKeyNameBuffer: AnsiString = 'Systems Internals';
255   HiddenKeyNameBuffer: AnsiString = 'Can''t touch me!'#0;
256   HiddenValueNameBuffer: AnsiString = 'Hidden Value';
257 
258 var
259   KeyName, ValueName: UNICODE_STRING;
260   SoftwareKeyHandle, SysKeyHandle, HiddenKeyHandle: THandle;
261   Status: ULONG;
262   ObjectAttributes: OBJECT_ATTRIBUTES;
263   Disposition: ULONG;
264   Buffer: array of WideChar;
265 
266 begin
267   MessageBox(0, 'Reghide'#13#10'Creates a Registry key that cannot be ' +
268     'opened with Regedit/Regedt32'#13#10#13#10'original by Mark Russinovich' +
269     #13#10'Delphi-Version by Daniel Wischnewski'#13#10'http://www.' +
270     'sysinternals.com'#13#10'http://www.gatenetwork.com', 'Native API Demo',
271     MB_OK);
272 
273   //
274   // Open the Software key
275   //
276   SetLength(Buffer, Length(KeyNameBuffer));
277   MultiByteToWideChar(CP_UTF8, 0, @KeyNameBuffer[1], Length(KeyNameBuffer),
278     PWideChar(Buffer), Length(Buffer));
279   KeyName.Buffer := @Buffer[0];
280   KeyName.Length := Length(KeyNameBuffer) * SizeOf(WideChar);
281   InitializeObjectAttributes(ObjectAttributes, @KeyName, OBJ_CASE_INSENSITIVE,
282     0, nil);
283   Status := NtCreateKey(SoftwareKeyHandle, KEY_ALL_ACCESS, ObjectAttributes, 0,
284     nil, REG_OPTION_NON_VOLATILE, Disposition);
285   if not NT_SUCCESS(Status) then
286   begin
287     MessageBox(0, 'Error: Couldn''t open HKLM\Software', 'Native API Demo',
288       MB_OK);
289     Exit;
290   end;
291 
292   //
293   // Create the "Systems Internals" key
294   //
295   SetLength(Buffer, Length(NewKeyNameBuffer));
296   MultiByteToWideChar(CP_THREAD_ACP, 0, @NewKeyNameBuffer[1], Length(
297     NewKeyNameBuffer), PWideChar(Buffer), Length(Buffer));
298   KeyName.Buffer := @Buffer[0];
299   KeyName.Length := Length(NewKeyNameBuffer) * SizeOf(WideChar);
300   InitializeObjectAttributes(ObjectAttributes, @KeyName, OBJ_CASE_INSENSITIVE,
301     SoftwareKeyHandle, nil);
302   Status := NtCreateKey(SysKeyHandle, KEY_ALL_ACCESS, ObjectAttributes, 0,
303     nil, REG_OPTION_NON_VOLATILE, Disposition);
304   if not NT_SUCCESS(Status) then
305   begin
306     MessageBox(0, 'Error: Couldn''t create HKLM\Software\Systems Internals',
307       'Native API Demo', MB_OK);
308     Exit;
309   end;
310 
311   //
312   // Create the Hidden key
313   //
314   SetLength(Buffer, Length(HiddenKeyNameBuffer));
315   MultiByteToWideChar(CP_UTF8, 0, @HiddenKeyNameBuffer[1], Length(
316     HiddenKeyNameBuffer), PWideChar(Buffer), Length(Buffer));
317   KeyName.Buffer := @Buffer[0];
318   KeyName.Length := Length(HiddenKeyNameBuffer) * SizeOf(WideChar);
319   InitializeObjectAttributes(ObjectAttributes, @KeyName, OBJ_CASE_INSENSITIVE,
320     SysKeyHandle, nil);
321   Status := NtCreateKey(HiddenKeyHandle, KEY_ALL_ACCESS, ObjectAttributes, 0,
322     nil, REG_OPTION_NON_VOLATILE, Disposition);
323   if not NT_SUCCESS(Status) then
324   begin
325     MessageBox(0, 'Error: Couldn''t create HKLM\Software\Systems Internals\' +
326       'RegHide', 'Native API Demo', MB_OK);
327     Exit;
328   end;
329 
330   //
331   // Create the hidden value
332   //
333   SetLength(Buffer, Length(HiddenValueNameBuffer));
334   MultiByteToWideChar(CP_UTF8, 0, @HiddenValueNameBuffer[1], Length(
335     HiddenValueNameBuffer), PWideChar(Buffer), Length(Buffer));
336   ValueName.Buffer := @Buffer[0];
337   ValueName.Length := Length(HiddenValueNameBuffer) * SizeOf(WideChar);
338   Status := NtSetValueKey(HiddenKeyHandle, @ValueName, 0, REG_SZ,
339     @HiddenValueNameBuffer[1], Length(HiddenValueNameBuffer) * SizeOf(WideChar));
340   if not NT_SUCCESS(Status) then
341   begin
342     MessageBox(0, 'Error: Couldn''t create our hidden value', 'Native API Demo',
343       MB_OK);
344     NtDeleteKey(HiddenKeyHandle);
345     Exit;
346   end;
347 
348   //
349   // Let the user try and open our key!
350   //
351   MessageBox(0, 'Try and open the key "HKLM\SOFTWARE\Systems Internals\' +
352     'Can''t touch me!"'#13#10'with Regedit or Regedt32 (or any other ' +
353     'Registry editor). There is a value'#13#10'in the key called "Hidden ' +
354     'Value".'#13#10#13#10'When done trying, press any key to have the key ' +
355     'deleted and exit.', 'Native API Demo', MB_OK);
356 
357   //
358   // Cleanup the key
359   //
360   NtDeleteKey(HiddenKeyHandle);
361 end.


			
Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10

 

Advertisement
Share this page
Advertisement
Download from Google

Copyright © Mendozi Enterprises LLC