fritzo
Goto Top

HowTo - Delete 0-Byte Registry Keys

Wie man nicht löschbare Regkeys aus dem System entfernt; am Beispiel eines Keys der Software O&O Defrag

Wie man nicht löschbare Regkeys aus dem System entfernt; am Beispiel eines Keys der Software O&O Defrag
O&O Defrag ist ein wohlbekanntes Windows-Tool zum Defragmentieren von Festplatten. Es funktioniert recht gut, hat aber einen entschiedenen Nachteil - es setzt einen Regkey, der sich mit herkömmlichen Mitteln nicht einsehen oder löschen lässt. Es wäre nicht weiter tragisch, wenn man sich des Problems durch eine einfache Deinstallation des Programms entledigen könnte - aber leider, leider bleibt einem der Key auch danach noch erhalten, sozusagen als kleines Andenken an die Fähigkeiten der Programmierer (worauf man bestimmt gerne verzichten könnte).

Der betreffende Key ist:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\System

Dieser lässt sich weder mit regedit.exe oder reg.exe noch mit anderen Scripts oder Tools lesen oder bearbeiten, die die Windows-API benutzen. Auch der Versuch, die Rechte zu setzen, mißlingt - sämtliche Zugriffsversuche quittiert das System mit der Fehlermeldung, daß entweder nicht zugegriffen werden kann oder der betreffende Key angeblich nicht existiert.

Der Grund dafür, daß er sich nicht lesen oder löschen lässt, ist ein unsichtbarer 0-Byte-Eintrag unterhalb des Zweigs. Eine Beschreibung dieser 0-Byte-Keys von Marc Russinovich (Sysinternals) zu finden.

Der Key wird über einen nativen Windows-API-Call generiert. Er lässt sich deshalb nicht löschen, weil alle heute verbreiteten Tools diese API nicht verwenden; sie benutzen stattdessen Aufrufe der Windows32-API. Diese interpretiert Strings als sog. null-terminiertes ANSI (8-bit) oder Wide Character (16-bit). In der nativen API-Schnittstelle hingegen werden Strings als "counted Unicode (16-bit)" definiert. (Quelle: www.sysinternals.com)

Man kann über beide Schnittstellen auf die Registry zugreifen. Native API bietet -anders als ANSI- über Unicode die Möglichkeit, Nullen (0) als Teil des Strings zu definieren. Beispiel hierfür: der String "Key\0" wird in Unicode als ein String mit 4 byte Länge definiert. (Quelle: www.sysinternals.com)

Greift man nun über die Win32-API auf die Registry zu, so wird der String nicht mit 4 byte Länge erkannt - stattdessen sieht Windows hier nur den String "Key". Der restliche Teil des Strings, also "\0" wird einfach abgeschnitten. Somit kann man auf diesen Key nicht mehr auf normalem Wege zugreifen. Es ergibt sich ein Problem, da, wie bereits erwähnt, sämtliche Registry-Werkzeuge die Win32-API verwenden. (Quelle: www.sysinternals.com)

Interessanterweise werden ähnliche Techniken zum Verschleiern von Registryeinträgen teilweise auch von Rootkits verwendet. Wie O&O dazu kommt, derlei Sachen in kommerziellen Softwareprodukten einzusetzen, bleibt ein Geheimnis der Firma und uns ein Rätsel. Der Key wird auch prompt von Rootkit-Detektoren bei einem Scan als fragwürdig gemeldet; z.B der bekannte Rootkit-Scanner "RootkitRevealer" von Sysinternals findet und listet ihn.

Genug Informationen, machen wir uns daran, den Key zu löschen. Wir wollen dies online am laufenden Rechner vornehmen, benötigt werden hierzu folgende Tools:
-regback.exe (NT Ressourcekit)
-regrest.exe (NT Ressourcekit)
-regedit.exe
-ein Hexeditor (z.B. HexWorkshop)

Schritt 1 - Sichern der Registry
Wir öffnen eine Dosbox und geben folgendes ein:
md c:\temp\reg_backup
Dies legt ein Verzeichnis an, welches wir später zum Sichern der Registrydaten benötigen.

Weiterhin geben wir folgenden Befehl ein:
regback c:\temp\reg_backup
Hiermit wird die Registry in das vorher angelegte Verzeichnis gesichert. Regback meldet sich nun idealerweise mit folgendem oder ähnlichem Output:

saving SECURITY to c:\temp\reg_backup\SECURITY
saving SOFTWARE to c:\temp\reg_backup\software
saving SYSTEM to c:\temp\reg_backup\system
saving .DEFAULT to c:\temp\reg_backup\default
saving SAM to c:\temp\reg_backup\SAM


Schritt 2 - Anpassen des gesicherten Registry-Hives
Nun starten wir den Hex Editor -ich verwende "Hex Workshop", einen gebräuchlichen und recht komfortablen Editor- und laden über Öffnen die folgende Datei in den Editor:
c:\temp\reg_backup\software

Wir rufen nun die Suchfunktion Über das Menü oder die Tastenkombination STRG-F auf und stellen in der daraufhin erscheinenden Box als Suchparameter "String" ein. Als Suchbegriff geben wir "OODEFRAG" ein und klicken auf "Suche". Der Wert wird gefunden und angezeigt.

Ewas oberhalb des gefundenen Strings befindet sich ein weiterer String namens "SYSTEM" - dieser String entspricht dem Regkey, den wir löschen wollen. Jetzt klicken wir in das Anzeigefeld und geben direkt hinter dem String "SYSTEM" folgendes ein:"X0"

Nun speichern wir die Datei ab - die Frage, ob man eine Sicherung anlegen möchte, bestätigen wir mit "Ja" und schließen den Hex Editor.


Schritt 3 - Löschen des Regkeys
Wir starten den Registry Editor (regedit.exe) und klicken in der linken Spalte auf den Hive HKEY_LOCAL_MACHINE. Daraufhin öffnen wir das Menü "Datei". Hier rufen wir den Punkt "Struktur laden" auf und öffnen dann das File c:\temp\reg_backup\software, das wir vorher mit regbackup generiert haben.

Bei der folgenden Abfrage-Box geben wir xxxOODEFRAGxxx oder etwas ähnlich sprechendes als Namen an -hier keinen existierenden Zweignamen angeben, sondern einen Wert, der noch nicht existiert- und klicken auf OK.

Nachdem die Struktur geladen ist, findet man sie unterhalb des Zweiges HKEY_LOCAL_MACHINE. Wir navigieren jetzt zum Key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\System
und sehen uns den Wert unterhalb des Keys an: OODEFRAGxxxxxxxxxx

Nachdem wir uns satt gesehen haben, markieren wir jetzt den Key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\System
ganz einfach in der linken Spalte und löschen ihn kurz und knackig.

Anschließend rufen wir das Menü "Datei" und hier den Punkt "Struktur entfernen" auf (WICHTIG!) und schließen dann den Registry Editor.


Schritt 4 - Import des geänderten Registry-Hives
Es folgt der letzte Schritt. Wir öffnen wiederum eine Dosbox, in der wir folgendes eingeben:
cd c:\temp\reg_backup

Nun kommt der wichtigste Schritt, das Zurückschreiben des geänderten Registry-Hives. Wir geben den folgenden Befehl in der Dosbox ein:
regrest C:\temp\reg_backup\software software.bku machine software

Eine Meldung erscheint:
replacing software with C:\temp\reg_backup\software You must reboot for changes to take effect.

Danach schließen wir alles und rebooten das System. Dieser Teil ist mit einem gewissen Nervenkitzel verbunden - aber keine Sorge; wenn alles wie oben angegeben durchgeführt wurde, dann sollten sich keinerlei Probleme ergeben.

Schlußendlich starten wir nach dem erfolgreichen Reboot noch einmal den Registry Editor und stellen fest, daß der Regkey nicht mehr vorhanden ist.


Ein herzliches Dankeschön an alle für die Hilfe bei der Suche und die Tipps face-smile

Weiterhin unbekannterweise ein Dank an Marc Russinovich für die sehr ausführliche Erläuterung der 0-Byte-Keys auf seinen Seiten - ich habe hier zur Erläuterung dieser Keys drei kleinere Absätze entnommen und ins Deutsche übersetzt.

Quellen:
Wie kann ich die Registry in W2K und XP offline bearbeiten ?
Regkey lässt sich nicht löschen
Verhindert Löschen von Registry-Eintrag
Registry Keys

Content-Key: 8376

Url: https://administrator.de/contentid/8376

Printed on: April 19, 2024 at 19:04 o'clock

Member: franzkat
franzkat Mar 25, 2005 at 09:44:00 (UTC)
Goto Top
Hallo fritzo !

Ein sehr schönes Tut. Ich denke, dass in Zukunft noch mehr User mit dem Problem konfrontiert sein werden. Insofern ist das, was du hier veröffentlichst, sehr nützlich.

Grüße franzkat
Member: TBO
TBO Jun 23, 2005 at 20:44:48 (UTC)
Goto Top
Moin zusammen,

der Tipp hat mir bei 2 Einträgen sehr geholfen (OODefrag und eine Testversion von Buhl-Data "On4u2").

Danke geile Seite mit TipTop Infos
Mitglied: 19596
19596 Nov 04, 2005 at 18:14:25 (UTC)
Goto Top
Hallo,

leider hat dieses Beispiel des 0-Byte-Tricks Schule gemacht. Die Firma Haenlein Software bietet eine Testversion des Programms DVR-Studio-Pro an. Nach dem Deinstallieren bleibt ein Registry-Eintrag (HKEY_LOKAL_MACHINE\Software\Haenlein) übrig, der sich nicht löschen lässt. In diesem Eintrag ist offensichtlich das Datum der Erstinstallation gespeichert, so daß man die Demoversion nicht nochmal installieren kann.

Ich würde diesen Eintrag gerne loswerden, traue mich aber nicht, auf Gutglück in der Registry herum zu experimentieren. Wäre toll, wenn sich mal jemand ranwagt, der mehr Ahnung davon hat und die Beschreibung postet.
Member: fritzo
fritzo Nov 14, 2005 at 02:03:17 (UTC)
Goto Top
Hi,

ich nehme an, daß keiner Lust hat, die Soft zu installieren und danach auch den Key in der Registry zu haben ;) Ich schon, weil das auf einer Testmaschine nix ausmacht. Das Problem ist nur, daß Du es danach dann trotzdem selbst ausführen musst, weil wir an Deine Maschine ja wahrscheinlich nicht dran kommen. face-smile

Vorschlag: Sichere wie beschrieben den Registry-Hive SOFTWARE mit regbackup und führ die Schritte wie angegeben aus. Wenn Du die Datei wie angegeben in regedit laden und den Key entfernen kannst, dann sollte eigentlich auch alles klar gehen. Wenn Du in regedit auf "Struktur entfernen" (Schritt 3) gehst, dann wird ja noch nichts geschrieben - das passiert erst, wenn Du Schritt 4 ausführst. Mach erst mal alles bis auf Schritt 4 und berichte dann hier, wie es gelaufen ist.

Alternativ kannst Du den gesicherten Hive SOFTWARE auch auf nen FTP- oder Webspace ablegen und mir den Link darauf schicken, dann mach ich Dir das fertig. Ich muß dann nur eine Möglichkeit zum Uploaden haben.

Viele Grüße,
fritzo
Member: fritzo
fritzo Nov 14, 2005 at 02:22:57 (UTC)
Goto Top
Eine weitere Software, die 0-Byte-Keys nutzt: der LicCtrl - Dienst des Lizenzdienstes eLicense von VIATech. Soweit mir bekannt, kommt dieser u.a. mit Grafikprogrammen (ich meine, es ist Maya oder 3DStudioMax, bin mir aber nicht sicher - es wird aber weitere Software geben, die diesen Lizenzschutz nutzt) auf den Rechner. Herstellerseite: http://www.elicense.com/

Der Hersteller bietet unter anderem DRM-Dienste und ähnliches an. Kunden sind u.a. EA Games, Grey Dog, Right Hemisphere, Rocket Software, Vivendi Universal Games, Puppetworks, 400 Software und Zugg Software. Ob die Produkte dieser Firmen alle die eLicence-Software und diesen Key mit installieren, kann ich nicht sagen, man sollte aber vorher evtl. zweimal prüfen.

Keyname:
HKEY_LOCAL_MACHINE\SOFTWARE\LicCtrl (noch lesbar)

HKEY_LOCAL_MACHINE\SOFTWARE\LicCtrl\LicCtrl (mit 0-Byte geschrieben und gesperrt)

zugehöriger Dienst:
LicCtrl Service

Service-Binary:
C:\WINDOWS\runservice.exe

Der Name des Keys wird genau wie oben bereits beschrieben mit einem 0-Byte beendet und lässt sich auf herkömmliche Weise nicht entfernen. Mit dem Hexeditor funktioniert es, ABER: startet man den Dienst danach neu, wird auch der Regkey neu gesetzt. Ich vermute, daß unterhalb des Keys die Lizenzdaten gespeichert sind. Es ist schön, wenn die Lizenzen nicht verloren gehen können, aber so eine Art Absicherung ist nicht mein Geschmack - das sind Methoden, wie sie auch ein sehr großer japanischer Hersteller von Hard- und Software anwendet, der jüngst dadurch in Verruf geraten ist und den selbst MS nun boykottiert, indem sie ihren Spywarescanner so aufrüsten, daß er diese Software entfernen kann. Gott sei Dank kriegt diese Firma nun so die fällige Quittung face-smile

Ich habe übrigens einen Uninstaller für den eLicense-Dienst vom Hersteller gefunden und ausprobiert - dieser hatte aber keinen Effekt. Er scheint nur die Lizenzen zu deinstallieren, der Dienst selbst und auch der Regkey bleiben auf dem System - also nicht sehr effektiv.

Man hat also die Wahl - entweder das Produkt nicht nutzen oder aber doch nutzen und sein System verunschandeln.

Grüße,
fritzo
Member: fritzo
fritzo Nov 14, 2005 at 03:12:04 (UTC)
Goto Top
Nachtrag:

hier die Lösung für das eLicence-Problem. Ein kleines Programm von jemand namens sgdt, das den 0-Byte-Regkey des eLicense-Programms schnell und sauber entfernt: ZapHidden

Infos über das Problem und das Tool auf dieser Seite

Ich wünschte nur, daß sgdt das Programm so geschrieben hätte, daß man beliebige Keys damit entfernen kann, aber vielleicht macht er oder jemand anderes das ja noch.

Grüße,
fritzo
Member: fritzo
fritzo Nov 14, 2005 at 03:25:01 (UTC)
Goto Top
Hehe - lustiger Hintergrund zu diesem Tool: es wurde anscheinend ursprünglich für eLicense geschrieben. Tjaja, so kommt alles retour face-smile
Member: fritzo
fritzo Nov 14, 2005 at 03:33:26 (UTC)
Goto Top
Wenn jemand mit ausreichenden Assembler/C++ - Kenntnissen sich der Sache annehmen will, dann sollte er mal in www.woodmann.com unter im Thread "E-license diesen Thread" reinschauen - dort findet sich mehr Info zu dem Thema. Meine bescheidenen Kenntnisse reichen nicht aus, um daraus was zu machen:

Listing 1

void *LoadEntryPoint (HMODULE hModule, char *szFunction)
     {
     void *pResult_;

     if ((pResult_ = GetProcAddress (hModule, szFunction)) == NULL)
        {
        printf ("Could not find %s entry point.\n", szFunction);  
        exit (1);
        }
     return (pResult_);
     }

//
// Loads and finds the entry points we need in NTDLL.DLL
//
VOID LocateNTDLLEntryPoints ()
     {
     HMODULE hLib_;

     if ((hLib_ = GetModuleHandle ("ntdll.dll")) != NULL)  
        {
        NtOpenKey           = LoadEntryPoint (hLib_, "NtOpenKey");  
        NtCreateKey         = LoadEntryPoint (hLib_, "NtCreateKey");  
        NtEnumerateValueKey = LoadEntryPoint (hLib_, "NtEnumerateValueKey");  
        NtEnumerateKey      = LoadEntryPoint (hLib_, "NtEnumerateKey");  
        NtSetValueKey       = LoadEntryPoint (hLib_, "NtSetValueKey");  
        NtQueryValueKey     = LoadEntryPoint (hLib_, "NtQueryValueKey");  
        NtDeleteKey         = LoadEntryPoint (hLib_, "NtDeleteKey");  
        }
     else
        {
        printf("Could not get handle for NTDLL.DLL\n");  
        exit (1);
        }
     return;
     }


Listing 2:
BOOL RecurseKey (PUNICODE_STRING pKeyName, HANDLE hPrior)
     {
     OBJECT_ATTRIBUTES ObjectAttributes_;
     UNICODE_STRING TmpKeyName_;
     NTSTATUS ntStatus_;
     KEY_NODE_INFORMATION *pknInfo_;
     char *szKey_;
     HANDLE hKey_;
     WCHAR wTmpKey_ [MaxKeySize * 2], wBuffer_ [MaxKeySize * 2];
     int ch_;
     DWORD dwSize_, dwKeyLen_, dwIndex_, dwChrIdx_;
     BOOL Result_;

     InitializeObjectAttributes (&ObjectAttributes_, pKeyName,  OBJ_CASE_INSENSITIVE, hPrior, NULL);

     ntStatus_ = NtOpenKey (&hKey_, KEY_ALL_ACCESS,  &ObjectAttributes_);

     dwIndex_ = 0;
     dwSize_ = (MaxKeySize + 1) * sizeof (WCHAR);
     ntStatus_ = NtEnumerateKey (hKey_, dwIndex_, KeyNodeInformation, (char *)wBuffer_, dwSize_, &dwSize_);

     while (ntStatus_ == 0)
        {
        pknInfo_ = (KEY_NODE_INFORMATION *) wBuffer_;
        dwKeyLen_ = WideCharToMultiByte (CP_ACP, 0, pknInfo_->Name, pknInfo_->NameLength/sizeof(WCHAR), NULL, 0, NULL, NULL);

        szKey_ = (char *) wTmpKey_;
        memcpy (szKey_, pKeyName->Buffer, pKeyName->Length);
        szKey_ += pKeyName->Length;
        *szKey_++ = '\\';  
        *szKey_++ = 0;
        memcpy (szKey_, pknInfo_->Name,   pknInfo_->NameLength);

        TmpKeyName_.Buffer = wTmpKey_;
        TmpKeyName_.Length = pKeyName->Length + 2 + pknInfo_->NameLength;

        if (RecurseKey (&TmpKeyName_, NULL) == FALSE)
           dwIndex_++;

        dwSize_ = (MaxKeySize + 1) * sizeof (WCHAR);
        ntStatus_ = NtEnumerateKey (hKey_, dwIndex_, KeyNodeInformation, (char *)wBuffer_, dwSize_, &dwSize_);
        }
     Result_ = FALSE;

     for (dwChrIdx_ = 0; dwChrIdx_ < (pKeyName->Length >> 1); dwChrIdx_++)
        {
        if (pKeyName->Buffer [dwChrIdx_] == 0)
           Result_ = TRUE;
        }
     if (Result_)
        {
        // We have a KEY with a NUL imbedded. Print it out.
        for (dwChrIdx_ = 0; dwChrIdx_ < (pKeyName->Length >> 1); dwChrIdx_++)
           {
           if (pKeyName->Buffer [dwChrIdx_] == 0)
              printf ("Û");  
           else
              printf ("%c", pKeyName->Buffer [dwChrIdx_]);  
           }
        printf ("\n");  
        PrintValues (hKey_);

        printf ("Kill this key? (y/n) ");  

        ch_ = getchar ();

        while (ch_ != 'y' && ch_ != 'n')  
           ch_ = getchar ();

        if (ch_ == 'y')  
           NtDeleteKey (hKey_);
        else
           Result_ = FALSE;
        }
     return (Result_);
     }

int main (int arg_cn, char *arg_pa )
     {
     UNICODE_STRING KeyName_;
     PWCHAR pwKeyName_;

     LocateNTDLLEntryPoints ();

     pwKeyName_ = L"\\Registry\\Machine\\SOFTWARE\\LicCtrl";  

     KeyName_.Buffer = pwKeyName_;
     KeyName_.Length = wcslen (pwKeyName_) * sizeof(WCHAR);

     RecurseKey (&KeyName_, NULL);

     return (0);
     }


Grüße,
@fritzo
Member: fritzo
fritzo Nov 14, 2005 at 03:41:28 (UTC)
Goto Top
Diese Seite könnte beim Coden auch hilfreich sein:

http://undocumented.ntinternals.net/
Member: fritzo
fritzo Nov 14, 2005 at 16:57:55 (UTC)
Goto Top
Marc Russinovich von www.sysinternals.com plant, in naher Zukunft ein Tool zu veröffentlichen, mit dem man beliebige 0-Byte-Regkeys löschen kann - "I plan on releasing such a tool in the near future."

Grüße,
fritzo
Mitglied: 19596
19596 Dec 04, 2005 at 11:34:20 (UTC)
Goto Top
Hallo,

ich habe eine gute Neuigkeit - Marc Russinovich hat es geschafft! Unter http://www.sysinternals.com könnt Ihr das Tool "regdelnull" runterladen und damit alle 0-Byte Registry Keys löschen.

Bei mir hat es funktioniert, obwohl es nicht den gewünschten Erfolg gebracht hat. Offensichtlich ist irgendwo noch auf meinem Rechner das Datum der Erstinstallation hinterlegt. Na ja, wenigstens bin ich jetzt diesen Key los. Falls jemand noch eine Idee hat, was ich machen kann, dann bitte melden.
Member: fritzo
fritzo Dec 04, 2005 at 21:49:53 (UTC)
Goto Top
Hallo,

super, dankeschön für die Info! Ich werde das Tool testen und anschließend berichten.

Grüße,
fritzo

[EDIT: ich habe mit dem Tool Reghide einen Nullbyte-Regkey erzeugt und konnte ihn mit RegDelNull in 5 Sekunden löschen. Sieht aus, als würde es gut funktionieren.]
Member: fritzo
fritzo Dec 04, 2005 at 22:21:00 (UTC)
Goto Top
Tool Reghide

// Reghide.c
//
// by Mark Russinovich
// http://www.sysinternals.com
//
// 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.                  
//
#include "windows.h" 
#include "stdio.h" 
#include "reghide.h" 

//
// The name of the key and value that we're going to create  
//
WCHAR KeyNameBuffer		= L"\\Registry\\Machine\\SOFTWARE";  
WCHAR NewKeyNameBuffer	= L"Systems Internals";  
WCHAR HiddenKeyNameBuffer = L"Can't touch me!\0";  
WCHAR HiddenValueNameBuffer= L"Hidden Value";  

//
// Convenience output routine
//
VOID Output( char *msg, DWORD Buttons )
{
	MessageBox( NULL, msg, "RegHide", Buttons );  
}


//
// Loads and finds the entry points we need in NTDLL.DLL
//
VOID LocateNTDLLEntryPoints()
{
	if( !(NtCreateKey = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),  
			"NtCreateKey" )) ) {  

		printf("Could not find NtCreateKey entry point in NTDLL.DLL\n");  
		exit(1);
	}
	if( !(NtDeleteKey = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),  
			"NtDeleteKey" )) ) {  

		printf("Could not find NtDeleteKey entry point in NTDLL.DLL\n");  
		exit(1);
	}
	if( !(NtSetValueKey = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),  
			"NtSetValueKey" )) ) {  

		printf("Could not find NtSetValueKey entry point in NTDLL.DLL\n");  
		exit(1);
	}
}


//
// Create the key and value, tell the user to try to access it, and then delete it
// after they've tried  
//
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
						LPSTR lpCmdLine, int nCmdShow )
{
	UNICODE_STRING KeyName, ValueName;
	HANDLE SoftwareKeyHandle, SysKeyHandle, HiddenKeyHandle;
	ULONG Status;
	OBJECT_ATTRIBUTES ObjectAttributes;
	ULONG Disposition;
	char input;

	//
	// Load the entry points we need
	//
	LocateNTDLLEntryPoints();

	//
	// Print banner
	//
	Output( "\n                                              Reghide\n"  
			"Creates a Registry key that cannot be opened with Regedit/Regedt32\n\n"  
			"                                 by Mark Russinovich\n"  
			"                             http://www.sysinternals.com\n", MB_OK );  

	//
	// Open the Software key
	//
	KeyName.Buffer = KeyNameBuffer;
	KeyName.Length = wcslen( KeyNameBuffer ) *sizeof(WCHAR);
	InitializeObjectAttributes( &ObjectAttributes, &KeyName, 
			OBJ_CASE_INSENSITIVE, NULL, NULL );
	Status = NtCreateKey( &SoftwareKeyHandle, KEY_ALL_ACCESS, 
					&ObjectAttributes, 0,  NULL, REG_OPTION_NON_VOLATILE,
					&Disposition );
	if( !NT_SUCCESS( Status )) {

		Output("Error: Couldn't open HKLM\\Software\n", MB_ICONERROR );  
		exit(1);
	}

	//
	// Create the Systems Internals key
	//
	KeyName.Buffer = NewKeyNameBuffer;
	KeyName.Length = wcslen( NewKeyNameBuffer ) *sizeof(WCHAR);
	InitializeObjectAttributes( &ObjectAttributes, &KeyName, 
			OBJ_CASE_INSENSITIVE, SoftwareKeyHandle, NULL );
	Status = NtCreateKey( &SysKeyHandle, KEY_ALL_ACCESS, 
					&ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE,
					&Disposition );
	if( !NT_SUCCESS( Status )) {

		Output("Error: Couldn't create HKLM\\Software\\Systems Internals\n",  
				MB_ICONERROR);
		exit(1);
	}

	//
	// Create the Hidden key
	//
	KeyName.Buffer = HiddenKeyNameBuffer;
	// length here must include terminating null
	KeyName.Length = wcslen( HiddenKeyNameBuffer ) *sizeof(WCHAR) + sizeof(WCHAR);
	InitializeObjectAttributes( &ObjectAttributes, &KeyName, 
			OBJ_CASE_INSENSITIVE, SysKeyHandle, NULL );
	Status = NtCreateKey( &HiddenKeyHandle, KEY_ALL_ACCESS, 
					&ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE,
					&Disposition );
	if( !NT_SUCCESS( Status )) {

		Output("Error: Couldn't create HKLM\\Software\\Systems Internals\\RegHide\n",  
				MB_ICONERROR);
		exit(1);
	}

	//
	// Create the hidden value
	//
	ValueName.Buffer = HiddenValueNameBuffer;
	ValueName.Length = wcslen( HiddenValueNameBuffer ) *sizeof(WCHAR);
	Status = NtSetValueKey( HiddenKeyHandle, &ValueName, 0, REG_SZ, 
						HiddenValueNameBuffer, 
						wcslen( HiddenValueNameBuffer ) * sizeof(WCHAR) );
	if( !NT_SUCCESS( Status )) {

		Output("Error: Couldn't create our hidden value\n", MB_ICONERROR);  
		NtDeleteKey( HiddenKeyHandle );
		exit(1);
	}

	//
	// Let the user try and open our key!
	//
	Output("Try and open the key \"HKLM\\SOFTWARE\\Systems Internals\\Can't touch me!\"\n"  
		"with Regedit or Regedt32 (or any other Registry editor). There is a value\n"  
		"in the key called \"Hidden Value\".\n\n"  
		"When done trying, press any key to have the key deleted and exit.\n",  
		MB_ICONINFORMATION|MB_OK );

	input = getchar();

	//
	// Cleanup the key
	//
	NtDeleteKey( HiddenKeyHandle );
	return 0;

}
Member: fritzo
fritzo Dec 04, 2005 at 22:21:28 (UTC)
Goto Top
Update:

//
// Reghide.h
//
// Various native API stuff that we need
//

#define OBJ_CASE_INSENSITIVE 0x40

typedef DWORD ULONG;
typedef WORD  USHORT;
typedef ULONG NTSTATUS;

#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;


typedef struct _OBJECT_ATTRIBUTES {
    ULONG Length;
    HANDLE RootDirectory;
    PUNICODE_STRING ObjectName;
    ULONG Attributes;
    PVOID SecurityDescriptor;        // Points to type SECURITY_DESCRIPTOR
    PVOID SecurityQualityOfService;  // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;

#define InitializeObjectAttributes( p, n, a, r, s ) { \
    (p)->Length = sizeof( OBJECT_ATTRIBUTES );          \
    (p)->RootDirectory = r;                             \
    (p)->Attributes = a;                                \
    (p)->ObjectName = n;                                \
    (p)->SecurityDescriptor = s;                        \
    (p)->SecurityQualityOfService = NULL;               \
    }

NTSTATUS (__stdcall *NtCreateKey)(
		HANDLE KeyHandle, 
		ULONG DesiredAccess, 
		POBJECT_ATTRIBUTES ObjectAttributes,
		ULONG TitleIndex, 
		PUNICODE_STRING Class, 
		ULONG CreateOptions, 
		PULONG Disposition 
		);

NTSTATUS (__stdcall *NtSetValueKey)(
		IN HANDLE  KeyHandle,
		IN PUNICODE_STRING  ValueName,
		IN ULONG  TitleIndex,			/* optional */
		IN ULONG  Type,
		IN PVOID  Data,
		IN ULONG  DataSize
		);


NTSTATUS (__stdcall *NtDeleteKey)(
		HANDLE KeyHandle
		);
Member: Biber
Biber Dec 04, 2005 at 23:01:56 (UTC)
Goto Top
Moin fritzo,

mal zwischendurch ein paar Rückmeldungen zu diesem allerbesten Sahne-Thread.
Erstmal vielen Dank für die Mühe, die Du Dir machst, hier mal ein paar Gegenmittel einzusetzen gegen die sich krebsartig ausbreitenden 0-Byte-Registry-Keys. Wie sich die auch ohne großartige Programmierkenntnisse erzeugen lassen, scheint sich ja auch schon in Scriptkiddie-Kreisen rumgesprochen zu haben..

Folgende Anmerkungen:
- in dem Reghide.c-Source sind Dir durch HTML-Tags die beiden Standard-Include-Dateien
windows.h und stdio.h verloren gegangen. Könntest Du noch mal editieren vielleicht.
- beim Link der ZipHidden.rar wird bei mir nur eine ZipHidden.exe entpackt, und die ist ist nicht sonderlich geschwätzig. Oder ist mein WinRar zu alt? Sollte da nicht Source dabei sein?
- die RegDelNull funktioniert bestens. Wurde auch bei mir gleich fündig.
- was ich in diesem Thread vermisse, ist noch mal der deutliche Hinweis, dass das ganze Elend mit diesen 0-Byte-Registry-Keys dadurch entstanden ist, dass M$ nur den unbedingt nötigen Bodensatz der native API-Calls nach außen dokumentiert hat... und ich wette eine Kiste Becks, dass die ersten 0-Byte-Registry-Keys "aus Versehen", durch falsche Parameter entstanden sind und nicht bei dem Versuch, einen "Installationsschutz" zu entwickeln. Wieder ein Fall mehr, wo wir Enduser diese M$-Selbstherrlichkeit ausbaden.

Umso schöner, da nun mal etwas Licht ins Dunkel zu bringen. Danke dafür.
Grüße Biber
Member: fritzo
fritzo Dec 05, 2005 at 02:50:45 (UTC)
Goto Top
Moin Biber,

danke, geht ja runter wie Öl face-smile Dickes Dito!

Zu den Scriptkiddies - die Sourcen sind nicht sonderlich kompliziert, daher wird wohl mehr zu erwarten sein. Schön wäre eine Schutzroutine für Virenscanner, die die Calls abfängt.

Die Includes habe ich editiert, sie werden beim Parsen wegen der Tags verschluckt - hab sie durch "" ersetzt. Im Zaphidden-Archiv sind leider keine Sourcen enthalten, da bliebe höchstens das Disassembly mit nem Symboldebugger. Auch bei RegDelNull finden sich leider keine.

Das mit MS lässt sich evtl. so begründen, daß die Registry eben ein gewachsenes Produkt ist und einfach nicht darüber nachgedacht wurde, daß sich solche Keys eben nicht auf herkömmliche Weise löschen lassen. Vielleicht gibt es aber auch noch andere versteckte, gewollt existierende Registry-Bereiche, die man gar nicht zu Gesicht bekommt, wer weiß?! *Gerüchteküche anwerf* face-smile

Grüße,
fritzo
Member: demann2003
demann2003 Jan 31, 2006 at 14:40:42 (UTC)
Goto Top
Hallo!
Zunächst Lob an diese Seite und an den Autor. Ich habe sie gefunden, nachdem ich auf meinem Rechner einen 0-Byte Schlüssel ausfindig gemacht habe.

Meine Frage an den Autor und an alle, die sie sich auskennen ist, wie gefährlich ist so ein 0-Byte Schlüssel von O&O Defrag. Ich habe dieses Programm als Testversion benutzt und es dann deinstalliert. Der Schlüssel ist natürlich geblieben. Allgemein gefragt, sind 0-Byte Schlüssel, sofern sie von normalen Programmen stammen und keine bösartigen Sachen verstecken, gefährlich ??? Muss man sie überhapt löschen??? Ist das notwendig???
Ihr siehr schon an den Fragen, ich habe absolut keine Ahnung, was die Tiefen des Betriebssystems angeht, aber die Fragen muss ich einfach stellen.
Grüsse an Alle!!!
Member: Biber
Biber Jan 31, 2006 at 19:03:38 (UTC)
Goto Top
Moin demann2003,

wie gefährlich ist so ein 0-Byte Schlüssel von O&O Defrag..
Da muss man/frau sicherlich unterscheiden zwischen diesem konkreten O&O-Defrag-Schlüssel und anderen, die diese 0-Byte-Schlüssel-Mimik nutzen.
Der O&O-Eintrag war sicherlich nur als kleiner Insiderwitz des Entwicklerteams gedacht, bestenfalls noch als Installationsschutz gegen dauerhafte Shareware-Nutzung.
Der macht eigentlich nichts kaputt, stört nur diejenigen, die sogar in der Registry auf gewisse Ästhetik achten.

Aber, was ich zumindest fahrlässig finde an diesem kleinen Gag der O&O-Truppe: Keiner von denen hat sicherlich getestet, ob alle anderen Registry-Bearbeitungs-Utilities damit umgehen können.
Stell Dir vor, Du lässt einen der üblichen Registry-Cleaner oder sogar ein original M$-Tool zum Komprimieren/Sichern/Archivieren Deiner Registry laufen... und das Programm stürzt wegen dieses nicht vorgesehenen Eintrags ab.
Oder schlimmer - Du sicherst Deine Registry OHNE Fehlermeldung und Monate später, wenn Du sie mal brauchst, lässt sie sich nicht zurücksichern wegen dieses kleinen Gags.
Genau diesen mögliche Datenverlust oder ähnliche Seiteneffekte bin ich nicht bereit zu riskieren oder zu tolerieren.
So etwas tut man/frau einfach nicht - ich würde auch nie von anderen Programmen erwarten, dass sie so robust sind wie meine eigenen face-wink
...und ein anderes Programm so auf eine Mine laufen zu lassen, ist einfach kein guter Stil. (Ich hoffe, die O&O-Entwickler haben jetzt einen hochroten Kopf).
Und dazu kommt ja noch, das vielleicht die O&O-Hansels sauber programmiert haben - aber das kann ich nicht von den 13jährigen Skript-Kiddies erwarten, die so etwas auch in ihre zusammenkloppten Erstlings-Skripte einbauen.
Ich kann es nur vergleichen mit älteren Kopierschutzmechanismen, die frecherweise und ungefragt auf der Festplatte des Benutzers Sektoren als "ungültig" markiert haben, um ihre geheimen Lizenzdaten dort hineinzuschreiben, oder an die Spielchen mit ungültigen Zeichen im Dateinamen (was bei M$-Defrag zu einem "Berichtigen" aller untergeordneten Verzeichnisse führt) oder -aktuelleres Beispiel- ein Kopierschutz bei CDs, der dazu führt, dass legal gekaufte CDs nicht gelesen werden können, weil die Verzeichnisstruktur von "guten" Programmen als ungültig interpretiert wird.

Hoffe, es beantwortet Deine Frage
Biber
Member: fritzo
fritzo Mar 08, 2006 at 02:10:15 (UTC)
Goto Top
Hi Bob,

die Info steht bereits im Thread; wahrscheinlich hast Du sie überlesen:

"Marc Russinovich von www.sysinternals.com plant, in naher Zukunft ein Tool zu veröffentlichen, mit dem man beliebige 0-Byte-Regkeys löschen kann - "I plan on releasing such a tool in the near future.""

"Hallo, ich habe eine gute Neuigkeit - Marc Russinovich hat es geschafft! Unter http://www.sysinternals.com könnt Ihr das Tool "regdelnull " runterladen und damit alle 0-Byte Registry Keys löschen."

Dass die Registry standardmäßig Keys dieser Art enthält, kann ich nach meinem jetzigen Wissensstand nicht bestätigen.

Übrigens, Teile des oben gelisteten Codes werden in diesem Tool so oder in ähnlicher Form verwendet.

Viele Grüße,
fritzo
Member: fritzo
fritzo Mar 09, 2006 at 18:52:56 (UTC)
Goto Top
Hi Gastkommentar,

sorry, hast noch was überlesen - im Artikel. ;) Zitat aus dem Tutorial:

"Interessanterweise werden ähnliche Techniken zum Verschleiern von Registryeinträgen teilweise auch von Rootkits verwendet. Wie O&O dazu kommt, derlei Sachen in kommerziellen Softwareprodukten einzusetzen, bleibt ein Geheimnis der Firma und uns ein Rätsel. Der Key wird auch prompt von Rootkit-Detektoren bei einem Scan als fragwürdig gemeldet; z.B der bekannte Rootkit-Scanner "RootkitRevealer" von Sysinternals findet und listet ihn. "

Da tauchen einige auf, die
ganz offensichtlich vom System eingetragen
wurden.

Kann ich nicht bestätigen. Nach einer Grundinstallation Scan mit RR ergibt bei mir keine Resultate; die Registry dieser Systeme ist clean. Getestet mit XP SP2 auf einer VMware-Box.

Ob hier etwas versteckt werden sollte oder es sich um Reste von Eintragungen
handelt ist nicht mehr nachvollziehbar.

Mit Sicherheit zweiteres und mit Sicherheit nicht vom System selbst, sondern von 3rdparty-Programmen, die diese Entries so schreiben, als ob es Systemeinträge seien.

Ebenso denkbar eine Notbremse der Registry - ohne diese 0-byte am Ende einer
Eintragung/Key würde die Stuktur der Registry wohl unrettbar zusammenbrechen.

Öhm.. nein. Das einzige, was hier unrettbar zusammenbricht, ist die Logik ;) Diese 0-byte-Strings werden normalerweise überhaupt nicht geschrieben - dies funktioniert nur mit speziell programmierten API-Calls, die aber vom System selbst nicht verwendet werden und ein Überbleibsel aus der 16bit-Welt sind.

Anyway - dank jedenfalls an Mark Russinovich und fritzo

Immer wieder gern. face-smile

Grüße,
fritzo
Member: grotti74
grotti74 Dec 27, 2007 at 01:58:28 (UTC)
Goto Top
sysinternals wurde 2006 LEIDER (!!) von Microsoft geschluckt (oder annektiert, wie ihr wollt) und nun findet sich regdelnull hier:

http://technet.microsoft.com/de-de/sysinternals/bb897448(en-us).aspx
Member: Mitchell
Mitchell Jul 29, 2009 at 10:50:06 (UTC)
Goto Top
Der gute Fritzo ist ja leider nicht mehr angemeldet, aber er hat es (wenn der Nick auf falsch geschrieben ist) als Verweis in ein Buch geschafft face-smile

Anti Hackerz Book 3. Auflage Seite 166

Mfg
Mitchell
Member: fritzo
fritzo Jul 26, 2013 at 20:57:51 (UTC)
Goto Top
So, bin wieder zurück. Manchmal dauert's halt ein bißchen, ist halt ein asynchrones Medium. Anti Hackerz Book - wtf..? :D
Member: Mitchell
Mitchell Jul 28, 2013 at 11:04:57 (UTC)
Goto Top
Fritzo!!!! face-smile Lass uns das mal per PN bequatschen, der Thread ist schon ein paar Jahre alt

Mfg
Mitchell
Member: scanner-x
scanner-x Jun 15, 2014 at 18:02:10 (UTC)
Goto Top
Hi,
die Anleitung ist unbrauchbar geworden; Ein übler Vorgang hat \t und \r gefressen. - Auf archive.org gibt es noch eine heile Kopie.
Member: Mitchell
Mitchell Jun 17, 2014 at 16:33:36 (UTC)
Goto Top
über Vorgang? unbrauchbar? Erklär mal face-smile
Member: scanner-x
scanner-x Jun 17, 2014 at 18:50:14 (UTC)
Goto Top
über? - nix über; übLer !
erklär mal? - pfft - lies mal die befehle. - fällt dir nix auf? - die erklärung ist mein zweiter halbsatz - merkst du was? - noch nicht? - archive.org geschaut? face-smile face-sad face-smile face-sad
Member: Mitchell
Mitchell Jun 18, 2014 at 11:09:01 (UTC)
Goto Top
hab mich vertippt...übLER hab ich schon gelesen ^^
gib mir mal nen Link, archive.org sagt mir irgendwie immer, dass keine Quelle zu finden ist. Und ja, dein zweiter Halbsatz erklärt mir, dass Umbrüche und Tabulatoren fehlen...wow face-smile
Member: scanner-x
scanner-x Jun 18, 2014 updated at 12:00:52 (UTC)
Goto Top
face-smile schon besser... und es freut mich dass du beeindruckt bist.. -- bei archive.org sind sie wohl irgendwie am arbeiten.. am sonntag gab es noch mehrere kopien der seite, jetzt nur noch eine, (und diese (wie auch schon sonntag) muss älter als 2011 sein..). -- mein hinweis war auch mehr so an den ersteller der anleitung gerichtet.. bzw an den admin der ganzen seite, denn dann ist anzunehmen dass der zeichenfrass noch andere artikel betroffen hat. -- muss wohl ein PM schreiben?
Member: Mitchell
Mitchell Jun 18, 2014 at 16:40:43 (UTC)
Goto Top
mach mal, aber häng ihm direkt den Link von archive.org mit dran, wie du es hier schon lange hättest tun können.
Member: fritzo
fritzo Nov 30, 2016 at 00:12:08 (UTC)
Goto Top
Ich vermute mal, daß ein script quergeschossen ist und die \t und \ als unerlaubte commands weggeschnitten hat. Ich habe das mal repariert. Danke für die Info. Warum kriege ich eigentlich die Info darüber zwei Jahre später? :D
Member: Mitchell
Mitchell Nov 30, 2016 at 12:18:36 (UTC)
Goto Top
gute Frage, ich sehe dich auch nur noch alle zwei Jahre hier face-smile. Aber schön zu wissen, dass du noch aktiv bist...hast mich anfangs durch viele Probleme geleitet. Aber kurz mal BTT face-big-smile:

Die Anleitung kam vor dem neuen Release, von daher ist es nicht verwunderlich, dass da /r /t und so flöten geht...oder auch die komplette Formatierung.

<<So, bin wieder zurück. Manchmal dauert's halt ein bißchen, ist halt ein asynchrones Medium. Anti Hackerz Book - wtf..? :D>>
kein Witz. Ich hab das Buch vor einigen Jahren gelesen und hier stehen. Zitat müsste ich raussuchen, aber DU bist definitiv gemeint ^^

Mit freundlichen Grüßen
Mitchell