From 8bb7ed968db64e9b12a6447e2eec3586ef9e935c Mon Sep 17 00:00:00 2001 From: Dirk Date: Tue, 10 Jun 2014 14:19:40 +0200 Subject: Windows system name changer during bootup. --- windows/bootpgm/win32/Handle.cpp | 293 +++++++++++++++++ windows/bootpgm/win32/Handle.h | 90 +++++ windows/bootpgm/win32/IO.cpp | 136 ++++++++ windows/bootpgm/win32/IO.h | 102 ++++++ windows/bootpgm/win32/MAKEFILE | 7 + windows/bootpgm/win32/Main.cpp | 220 +++++++++++++ windows/bootpgm/win32/Main.h | 90 +++++ windows/bootpgm/win32/RegistryBrowser.cpp | 71 ++++ windows/bootpgm/win32/RegistryBrowser.h | 19 ++ windows/bootpgm/win32/SOURCES | 25 ++ windows/bootpgm/win32/account.cpp | 60 ++++ windows/bootpgm/win32/account.h | 27 ++ windows/bootpgm/win32/computername.cpp | 435 +++++++++++++++++++++++++ windows/bootpgm/win32/experimental.cpp | 275 ++++++++++++++++ windows/bootpgm/win32/stdafx.cpp | 26 ++ windows/bootpgm/win32/stdafx.h | 50 +++ windows/bootpgm/win32/usermode-registry.sln | 23 ++ windows/bootpgm/win32/usermode-registry.vcproj | 365 +++++++++++++++++++++ windows/bootpgm/win32/win32.cpp | 92 ++++++ 19 files changed, 2406 insertions(+) create mode 100644 windows/bootpgm/win32/Handle.cpp create mode 100644 windows/bootpgm/win32/Handle.h create mode 100644 windows/bootpgm/win32/IO.cpp create mode 100644 windows/bootpgm/win32/IO.h create mode 100644 windows/bootpgm/win32/MAKEFILE create mode 100644 windows/bootpgm/win32/Main.cpp create mode 100644 windows/bootpgm/win32/Main.h create mode 100644 windows/bootpgm/win32/RegistryBrowser.cpp create mode 100644 windows/bootpgm/win32/RegistryBrowser.h create mode 100644 windows/bootpgm/win32/SOURCES create mode 100644 windows/bootpgm/win32/account.cpp create mode 100644 windows/bootpgm/win32/account.h create mode 100644 windows/bootpgm/win32/computername.cpp create mode 100644 windows/bootpgm/win32/experimental.cpp create mode 100644 windows/bootpgm/win32/stdafx.cpp create mode 100644 windows/bootpgm/win32/stdafx.h create mode 100644 windows/bootpgm/win32/usermode-registry.sln create mode 100644 windows/bootpgm/win32/usermode-registry.vcproj create mode 100644 windows/bootpgm/win32/win32.cpp (limited to 'windows/bootpgm/win32') diff --git a/windows/bootpgm/win32/Handle.cpp b/windows/bootpgm/win32/Handle.cpp new file mode 100644 index 00000000..f55f3316 --- /dev/null +++ b/windows/bootpgm/win32/Handle.cpp @@ -0,0 +1,293 @@ +#include "StdAfx.h" +#include "Handle.h" +#include "main.h" + +void debug(char *msg) +{ + mainSingleton->get_io().debugout(msg); +} + +void handle(ULONG status,char *file,char *line) +{ + if (status!=STATUS_SUCCESS) + { + char *buffer = new char[5000]; + sprintf(buffer,"Fehler in %s Zeile %s: 0x%X",file,line,status); + mainSingleton->get_io().println(buffer); + mainSingleton->get_io().readln(buffer,sizeof(buffer)); + } +} + +WinObject::~WinObject() +{ + if (valid()) + { + char buffer[500]; + debug((L"Closing Handle to '" + get_name() + L"'" ).chars(buffer,500)); + ULONG status = ZwClose(handle); + CHECKER(status) + } +} + +UnicodeString WinObject::get_name() +{ + OBJECT_BASIC_INFORMATION info; + ULONG status = NtQueryObject( + handle + ,ObjectBasicInformation + ,&info + ,sizeof(info) + ,0); + + CHECKER(status); + + int len=info.NameInformationLength; + + len = len==0? 500 : len; + + if (len>0) + { + OBJECT_NAME_INFORMATION *poni=reinterpret_cast(_alloca(len)); + status = NtQueryObject( + handle + ,ObjectNameInformation + ,poni + ,len + ,0); + + CHECKER(status); + + return UnicodeString::from_unicode(poni->Name); + } + else + return UnicodeString(L""); +} + +UnicodeString::UnicodeString(const wchar_t *chars) +{ + unsigned short len = (unsigned short)wcslen(chars); + wchar_t *buffer=new wchar_t[len]; + string.Length= len * sizeof(wchar_t); + string.Buffer=buffer; + string.MaximumLength=string.Length; + memcpy(buffer,chars,len*2); + + /*debug("UnicodeString created:"); + char buffer2[500]; + debug(this->chars(buffer2,500));*/ +} +UnicodeString::UnicodeString(const wchar_t *chars,unsigned int length) +{ + string.Length = (USHORT)length; + string.MaximumLength = (USHORT)length; + string.Buffer = new wchar_t[length/2]; + memcpy(string.Buffer,chars,length); +} +UnicodeString::UnicodeString(const char *chars) +{ + unsigned short l=(unsigned short)strlen(chars); + wchar_t *wcs=new wchar_t[l]; + mbstowcs(wcs,chars,l); + string.Length = l*2; + string.MaximumLength = l*2; + string.Buffer = wcs; +} +/*UnicodeString &UnicodeString::operator=(wchar_t *chars) +{ + char buffer[1000]; + _snprintf(buffer,1000,"UnicodeString = called old = %S, new = %S",string.Buffer,chars); + debug(buffer); + + unsigned short len= (unsigned short)wcslen(chars) * 2; + + if (len > string.MaximumLength) + { + delete string.Buffer; + string.Buffer = new wchar_t[len/2]; + string.MaximumLength = len; + } + + memcpy(string.Buffer,chars,len); + string.Length = len; + + return *this; +}*/ +UnicodeString::~UnicodeString() +{ + debug("UnicodeString deleted:"); + char buffer[500]; + debug(this->chars(buffer,500)); + + delete string.Buffer; +} +UnicodeString UnicodeString::operator+(UnicodeString&str2) +{ + UNICODE_STRING str; + + str.Length = 0; + str.MaximumLength = string.Length + str2.string.Length; + str.Buffer = new wchar_t[str.MaximumLength/2]; + + NT::RtlAppendUnicodeStringToString(&str,&string); + NT::RtlAppendUnicodeStringToString(&str,&str2.string); + + return UnicodeString(str); +} + +int RegKey::get_value(UnicodeString *path,PULONG type,void *buffer,int length) +{ + int len=length + sizeof(KEY_VALUE_PARTIAL_INFORMATION); + void *temp=_alloca(len); + ULONG read; + KEY_VALUE_PARTIAL_INFORMATION *pinfo = reinterpret_cast(temp); + ULONG status=ZwQueryValueKey( + handle + ,&path->unicode_string() + ,KeyValuePartialInformation + ,pinfo + ,len + ,&read); + + CHECKER(status) + + if (status!=STATUS_SUCCESS) + return 0; + + memcpy(buffer,pinfo->Data,pinfo->DataLength); + *type = pinfo->Type; + return pinfo->DataLength; +} + +void RegKey::set_value(UnicodeString *path,ULONG type,void *data,ULONG size) +{ + ULONG status = ZwSetValueKey( + handle + ,&path->unicode_string() + ,0 + ,type + ,data + ,size); + CHECKER(status) +} + +UnicodeString RegKey::get_string_value(UnicodeString *name) +{ + char buffer[500]; + ULONG type; + ULONG len=get_value(name,&type,buffer,sizeof(buffer)); + + if (type!=REG_SZ){ + debug("Only REG_SZ allowed in get_string_value"); + return (wchar_t*)0; + } + + wchar_t *value= reinterpret_cast(buffer); + value[min(sizeof(buffer)-1,len)] = 0; + return value; +} + +HANDLE RegKey::open_key(HANDLE parent,UnicodeString &path) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + + UnicodeString fullPath = UnicodeString(L"\\Registry\\") + path; + UnicodeString *pp = parent ? &path : &fullPath; + + InitializeObjectAttributes( + &ObjectAttributes, + const_cast(&pp->unicode_string()), + OBJ_CASE_INSENSITIVE, + parent, + NULL); + + HANDLE h; + ULONG Disposition; + ULONG status = ZwOpenKey( + &h, + KEY_ALL_ACCESS, + &ObjectAttributes); + + if (status == 0xC000034){ + IO &io=mainSingleton->get_io(); + io.print("Not found: "); + char buffer[1000]; + io.println(path.chars(buffer,sizeof(buffer))); + } + + return status == STATUS_SUCCESS? h : 0; +} + +void RegKey::flush() +{ + ULONG status=NtFlushKey(handle); + CHECKER(status); +} + +void RegKey::save_to(HANDLE fileHandle) +{ + ULONG status = NtSaveKey(handle,fileHandle); + CHECKER(status); +} + +void RegKey::print_subkeys(IO &io) +{ + ULONG status = STATUS_SUCCESS; + int i=0; + char buffer[1000]; + do + { + ULONG res; + KEY_BASIC_INFORMATION *info = reinterpret_cast(buffer); + status = ZwEnumerateKey( + handle + ,i + ,KeyBasicInformation + ,buffer + ,sizeof(buffer) + ,&res); + + if (status == STATUS_SUCCESS) + { + UnicodeString name(info->Name,info->NameLength); + io.println(name.chars(buffer,sizeof(buffer))); + } + + i++; + } while (status == STATUS_SUCCESS); +} +void RegKey::print_values(IO &io) +{ + ULONG status = STATUS_SUCCESS; + int i=0; + char buffer[1000]; + do + { + ULONG len; + status = ZwEnumerateValueKey( + handle + ,i + ,KeyValueBasicInformation + ,buffer + ,sizeof(buffer)-2 + ,&len); + + if (status==STATUS_SUCCESS) + { + KEY_VALUE_BASIC_INFORMATION *info = reinterpret_cast(buffer); + info->Name[info->NameLength/2] = 0; + char buf[100]; + _snprintf(buf,sizeof(buf),"%-30S | %-15s",info->Name,type_to_name(info->Type)); + io.println(buf); + } + + i++; + } while(status == STATUS_SUCCESS); +} +RegKey *RegKey::subkey(UnicodeString&name) +{ + HANDLE h = open_key(handle,name); + if (h) + return new RegKey(h); + else + return 0; +} diff --git a/windows/bootpgm/win32/Handle.h b/windows/bootpgm/win32/Handle.h new file mode 100644 index 00000000..14f65e57 --- /dev/null +++ b/windows/bootpgm/win32/Handle.h @@ -0,0 +1,90 @@ +#pragma once + +class IO; + +class UnicodeString +{ + NT::UNICODE_STRING string; + UnicodeString(UNICODE_STRING str):string(str){} +public: + UnicodeString(const wchar_t *chars); + UnicodeString(const wchar_t *chars,unsigned int length); + UnicodeString(const char *chars); + UNICODE_STRING& unicode_string(){return string;} + virtual ~UnicodeString(); + static UnicodeString& from_unicode(UNICODE_STRING str) + { + UNICODE_STRING str2 = str; + str2.Buffer = new wchar_t[str.Length/2]; + memcpy(str2.Buffer,str.Buffer,str.Length); + return *new UnicodeString(str2); + } + //UnicodeString& operator=(wchar_t *new_data); + //UnicodeString& operator=(UnicodeString &other); + char *chars(char *buffer,size_t len) + { + wcstombs(buffer,string.Buffer,min(len,(unsigned int)string.Length/2)); + buffer[min(len-1,(unsigned int)string.Length/2)]=0; + return buffer; + } + UnicodeString operator+(UnicodeString&str2); + UnicodeString operator+(wchar_t *ch) + { + return *this + UnicodeString(ch); + } + + friend UnicodeString operator+(wchar_t* ch,UnicodeString str) + { + return UnicodeString(ch) + str; + } +}; + +class WinObject +{ +protected: + const HANDLE handle; +public: + WinObject(HANDLE h):handle(h){} +public: + ~WinObject(); + UnicodeString get_name(); + HANDLE get_handle(){return handle;} + bool valid(){return handle != 0;} +}; + +class RegKey:public WinObject +{ +private: + static HANDLE open_key(HANDLE parent,UnicodeString &path); + RegKey(HANDLE h):WinObject(h){} +public: + RegKey(UnicodeString &path):WinObject(open_key(0,path)){} + RegKey(const wchar_t *path):WinObject(open_key(0,UnicodeString(path))){} + + int get_value(UnicodeString *path,PULONG type,void *buffer,int length); + UnicodeString get_string_value(UnicodeString *name); + void set_value(UnicodeString *path,ULONG type,void *data,ULONG size); + void flush(); + void save_to(HANDLE fileHandle); + + RegKey *subkey(UnicodeString&name); + + void print_subkeys(IO &io); + void print_values(IO &io); + static const char *type_to_name(ULONG type) + { + switch(type) + { + case REG_SZ: + return "String"; + case REG_EXPAND_SZ: + return "Expandable String"; + case REG_MULTI_SZ: + return "Multiline String"; + case REG_DWORD: + return "DWORD"; + default: + return "Unknown"; + } + } +}; diff --git a/windows/bootpgm/win32/IO.cpp b/windows/bootpgm/win32/IO.cpp new file mode 100644 index 00000000..9b31832b --- /dev/null +++ b/windows/bootpgm/win32/IO.cpp @@ -0,0 +1,136 @@ +/* The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + * License for the specific language governing rights and limitations + * under the License. + * + * The Initial Developer of the Original Code is Johannes Rudolph. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Johannes Rudolph + */ + +#include "StdAfx.h" +#include "IO.h" + +IO::IO(void):indent(0),current(0) +{ +} + +IO::~IO(void) +{ +} +void IO::print(char *buffer) +{ + if (current==0) + { + for (int i=0;i0) + { + curlength--; + handleCharEcho(curChar[0],buffer,curlength); + } + } + } + buffer[curlength-1]=0; + + debugout("readln beendet"); + //NT::DbgPrint("readln beendet\n"); +} +wchar_t *IO::char2wchar(char *buffer) +{ + unsigned int size=strlen(buffer)+1; + wchar_t *buffer2=(wchar_t*)malloc(sizeof(wchar_t)*size); + mbstowcs(buffer2,(char*)buffer,size); + buffer2[size-1]=0; + + return buffer2; +} +NT::UNICODE_STRING IO::getUnicodeString(char *buffer) +{ + wchar_t *buffer2=char2wchar(buffer); + + NT::UNICODE_STRING UnicodeFilespec; + RtlInitUnicodeString(&UnicodeFilespec, buffer2); + + return UnicodeFilespec; +} + +void IO::handleStatus(NT::NTSTATUS status,char *place,char *file,char *line,bool onlyWhenDebugging){ +#ifndef DEBUGGING + if (!onlyWhenDebugging) +#endif + if (status!=STATUS_SUCCESS) + { + print("[error]"); + print(file); + print("("); + print(line); + println("):"); + print("[error] Fehler: "); + println(place); + NT::DbgPrint("Fehler (Datei: %s \tZeile: %s): %s, %d\n",file,line,place,status); + } + else + { + print("[success] Erfolg: "); + println(place); + NT::DbgPrint("Erfolg: %s\n",place); + } +} +inline void IO::debugout(char *string) +{ +//#ifdef DEBUGGING + //print("[debug] "); + //println(string); + NT::DbgPrint("[bootpgm] %s\n",string); +//#endif +} + +void IO::setIndent(unsigned char indent) +{ + this->indent=indent; +} +unsigned char IO::getIndent() +{ + return indent; +} \ No newline at end of file diff --git a/windows/bootpgm/win32/IO.h b/windows/bootpgm/win32/IO.h new file mode 100644 index 00000000..575aef06 --- /dev/null +++ b/windows/bootpgm/win32/IO.h @@ -0,0 +1,102 @@ +/* The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + * License for the specific language governing rights and limitations + * under the License. + * + * The Initial Developer of the Original Code is Johannes Rudolph. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Johannes Rudolph + */ + +/* +File: IO.h +Declaration of IO and Indenter classes +*/ + +#pragma once + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) +#define CHECK_STATUS(status,name) io.handleStatus(status, #name,__FILE__ ,TOSTRING(__LINE__),true); +#define CHECK_STATUSA(status,name) io.handleStatus(status, #name,__FILE__ ,TOSTRING(__LINE__),false); + +#define CHECKER(status) ::handle(status, __FILE__ ,TOSTRING(__LINE__)); +void handle(ULONG status,char *file,char *line); + +/* +Class: IO +Interface for the main input/output functions, contains some helper functions +*/ +class IO +{ + unsigned char indent; + unsigned char current; +public: + /* + Method: getChar + has to be implemented by concrete controllers + + Returns: + one char per call from input device (keyboard) + */ + virtual char getChar()=0; + /* + Method: internalPrint + prints buffer to screen, must be implemented by concrete controllers + + Parameters: + buffer - null-terminated string to be printed to screen + */ + virtual void internalPrint(char *buffer)=0; + /* + Method: malloc + allocates memory of specified size, must be implemented by concrete controllers + + Parameters: + length - length of buffer to allocate + + Returns: + pointer to allocated memory + */ + virtual void*malloc(unsigned int length)=0; + virtual void free(void *buffer)=0; + virtual char *getVersion()=0; + virtual void handleCharEcho(char ch,char *buffer,unsigned int length)=0; + + IO(void); + ~IO(void); + + void print(char *buffer); + void println(char *buffer); + void readln(char *buffer,unsigned int length); + wchar_t *char2wchar(char *buffer); + NT::UNICODE_STRING getUnicodeString(char *buffer); + void handleStatus(NTSTATUS status, char *function, char *file, char *line,bool onlyWhenDebugging); + void debugout(char *string); + void setIndent(unsigned char indent); + unsigned char getIndent(); +}; + +class Indenter +{ + unsigned char original; + IO &io; +public: + Indenter(IO &pio):io(pio) + { + original=io.getIndent(); + io.setIndent(original+2); + } + ~Indenter() + { + io.setIndent(original); + } +}; \ No newline at end of file diff --git a/windows/bootpgm/win32/MAKEFILE b/windows/bootpgm/win32/MAKEFILE new file mode 100644 index 00000000..9c985f57 --- /dev/null +++ b/windows/bootpgm/win32/MAKEFILE @@ -0,0 +1,7 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the driver components of the Windows NT DDK +# + +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/windows/bootpgm/win32/Main.cpp b/windows/bootpgm/win32/Main.cpp new file mode 100644 index 00000000..f23a70ec --- /dev/null +++ b/windows/bootpgm/win32/Main.cpp @@ -0,0 +1,220 @@ +/* The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + * License for the specific language governing rights and limitations + * under the License. + * + * The Initial Developer of the Original Code is Johannes Rudolph. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Johannes Rudolph + */ + +#include "StdAfx.h" +#include "Main.h" + +Main *mainSingleton=NULL; + +char **split_args(IO &io,wchar_t* cmdLine,int length,int *pargc) +{ + int argCount=0; + for (int i=0;i(&func); + (p->*f)(io,args); + } + else + func(io,args); +} + + +void Main::showCmds(IO &io,char *args) +{ + io.println("Available commands:"); + Indenter i(io); + for (int i=0;ihelp ? cmd->help : "No help entry available"); +} + +command *Main::findCommand(char *name) +{ + for(int i=0;i\nShow help entries for command if available"); + + if (mainSingleton!=NULL) + { + io.println("Error: Main may be instantiated only once"); + return; + } + else + { + mainSingleton=this; + } +} + +Main::~Main(void) +{ + mainSingleton=NULL; +} + +void Main::run() +{ + showSplashScreen(); + rpl(); +} +void Main::rpl() +{ + io.println("Starting RPL (Read-Print-Loop) Type \"exit\" to stop."); + + char buffer[100]; + buffer[0]=0; + + while (strcmp(buffer,"exit")!=0) + { + io.print("rpl> "); + io.readln(buffer,100); + + command *cmd=findCommand(buffer); + if (cmd) + cmd->invoke(io,buffer + strlen(cmd->name)); + else + io.println("Command not found"); + } + + io.println("Exiting RPL"); +} +void Main::showSplashScreen() +{ + io.println("Boot-time Computername Changer by Johannes Rudolph"); + io.println("v0.1"); + io.print("IO: "); + io.println(io.getVersion()); +} + +void Main::addCommand(char *name,invokeFunc func,char *desc,char *help,void*pObject) +{ + if (funcc>=maxFuncs) + { + io.println("Es kann kein neues Kommando hinzugefügt werden"); + return; + } + + command c; + c.func=func; + c.name=name; + c.description=desc; + c.help=help; + c.pObject=pObject; + + commands[funcc]=c; + + funcc++; +} + +void Main::addCommand(char *name,deleg dg,char *desc,char *help) +{ + addCommand(name,(invokeFunc)dg.func,desc,help,dg.object); +} + + +void* __cdecl operator new(size_t sz) { + IO& io=mainSingleton->get_io(); + void* m = io.malloc((unsigned int)sz); + + if(!m) + io.println("out of memory"); + + return m; +} + +void __cdecl operator delete(void* m) { + mainSingleton->get_io().free(m); +} diff --git a/windows/bootpgm/win32/Main.h b/windows/bootpgm/win32/Main.h new file mode 100644 index 00000000..bd0e1bab --- /dev/null +++ b/windows/bootpgm/win32/Main.h @@ -0,0 +1,90 @@ +/* The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + * License for the specific language governing rights and limitations + * under the License. + * + * The Initial Developer of the Original Code is Johannes Rudolph. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Johannes Rudolph + */ + +#pragma once +#include "io.h" + +typedef void (*invokeFunc)(IO &io,char *args); + +struct command{ + invokeFunc func; + void *pObject; + char *name; + char *description; + char *help; + void invoke(IO &io,char *args); +}; + +struct deleg +{ + void *func; + void *object; +}; + +// template to create a command delegate +template deleg make_dg(T *t,void(T::*func)(IO&,char*)) +{ + deleg dg; + dg.func = *(void**)&func; + dg.object = t; + return dg; +} + +class Main +{ + IO &io; + + int funcc; + static const int maxFuncs=50; + command commands[maxFuncs]; + + char** argv; + int argc; + + void help(IO &io,char *args); + void showCmds(IO &io,char *args); + void showArgs(IO &io,char *args); + + command *findCommand(char *name); +public: + Main(IO &io,int argc,char** argv); + void run(); + ~Main(void); + void rpl(); + void addCommand(char *name,invokeFunc func,char *desc=0,char *help=0,void *pObject=0); + void addCommand(char *name,deleg d,char *desc=0,char *help=0); + + void showSplashScreen(); + IO &get_io(){return io;} +private: + friend void showCmds(IO &io,char *args); + friend void showArgs(IO &io,char *args); + +public: + int getArgc() + { + return argc; + } + char **getArgs() + { + return argv; + } +}; + +extern Main *mainSingleton; +char **split_args(IO &io,wchar_t* cmdLine,int length,int *pargc); \ No newline at end of file diff --git a/windows/bootpgm/win32/RegistryBrowser.cpp b/windows/bootpgm/win32/RegistryBrowser.cpp new file mode 100644 index 00000000..9254f8e8 --- /dev/null +++ b/windows/bootpgm/win32/RegistryBrowser.cpp @@ -0,0 +1,71 @@ +#include "StdAfx.h" +#include "RegistryBrowser.h" +#include "io.h" +#include "main.h" +#include "handle.h" + +RegKey *RegistryBrowser::get_current_key() +{ + if (!current) + current = new RegKey(L""); + + return current; +} + +void RegistryBrowser::lk(IO &io,char *args) +{ + get_current_key()->print_subkeys(io); +} +void RegistryBrowser::lv(IO &io,char *args) +{ + get_current_key()->print_values(io); +} + +void RegistryBrowser::tk(IO &io,char *args) +{ + char buffer[1000]; + io.println(get_current_key()->get_name().chars(buffer,sizeof(buffer))); +} + +void RegistryBrowser::ck(IO &io,char *args) +{ + if (*args==0) + { + if (current) delete current; + current = 0; + return; + } + + UnicodeString name(&args[1]); + RegKey *key=get_current_key()->subkey(name); + if (key) + { + if (current) delete current; + current = key; + } + else + io.println("Key not found"); +} + +RegistryBrowser::RegistryBrowser(Main &main) : current(0) +{ + main.addCommand("lk",make_dg(this,&RegistryBrowser::lk) + ,"List subkeys" + ,"Usage: lk\nList all subkeys of the current key"); + main.addCommand("lv",make_dg(this,&RegistryBrowser::lv) + ,"List values" + ,"Usage: lv\nList the names of all values of the current key with their types"); + main.addCommand("ck",make_dg(this,&RegistryBrowser::ck) + ,"Change current registry key" + ,"Usage: ck []\nGo into the subkey if specified or else to the root of the registry"); + main.addCommand("tk",make_dg(this,&RegistryBrowser::tk) + ,"Show information about current key" + ,"Usage: tk\nShow information about the current key (*t*his *k*ey)"); +} + +RegistryBrowser::~RegistryBrowser(void) +{ + if (current) + delete current; + current = 0; +} diff --git a/windows/bootpgm/win32/RegistryBrowser.h b/windows/bootpgm/win32/RegistryBrowser.h new file mode 100644 index 00000000..57424320 --- /dev/null +++ b/windows/bootpgm/win32/RegistryBrowser.h @@ -0,0 +1,19 @@ +#pragma once + +class RegKey; +class IO; +class Main; + +class RegistryBrowser +{ + RegKey *current; + RegKey *get_current_key(); +public: + RegistryBrowser(Main &m); + ~RegistryBrowser(void); + + void lk(IO &io,char *args); + void lv(IO &io,char *args); + void ck(IO &io,char *args); + void tk(IO &io,char *args); +}; diff --git a/windows/bootpgm/win32/SOURCES b/windows/bootpgm/win32/SOURCES new file mode 100644 index 00000000..8bf55002 --- /dev/null +++ b/windows/bootpgm/win32/SOURCES @@ -0,0 +1,25 @@ +TARGETNAME=common +TARGETPATH=../obj +TARGETTYPE=LIBRARY +#USE_NATIVE_EH= +#USE_RTTI= +#TARGETTYPE=PROGRAM + +TARGETLIBS=$(DDK_LIB_PATH)\ntdll.lib +# $(DDK_LIB_PATH)\libc.lib +# $(DDK_LIB_PATH)\msvcrt.lib + + +INCLUDES=$(SDK_INC_PATH);$(DDK_INC_PATH); +SOURCES=io.cpp \ + main.cpp \ + stdafx.cpp \ + computername.cpp \ + tests.cpp \ + registrybrowser.cpp \ + experimental.cpp \ + account.cpp \ + handle.cpp + +#UMTYPE=console +#UMBASE=0x400000 diff --git a/windows/bootpgm/win32/account.cpp b/windows/bootpgm/win32/account.cpp new file mode 100644 index 00000000..24a3c32e --- /dev/null +++ b/windows/bootpgm/win32/account.cpp @@ -0,0 +1,60 @@ +#include "stdafx.h" + +#include "account.h" + +void *get_entry(char *data,unsigned int cEntries,unsigned int index,unsigned int *length) +{ + data_entry *entries = reinterpret_cast(data); + if (length != 0) + *length = entries[index].length; + + return data + sizeof(data_entry) * cEntries + entries[index].position; +} + +void *get_V_entry(char *data,unsigned int index, unsigned int *length) +{ + return get_entry(data,17,index,length); +} + +entry *read_entries(char *data,unsigned int cEntries) +{ + data_entry *entries = reinterpret_cast(data); + entry *fixed = new entry[cEntries]; + for(unsigned int i=0;i(buffer); + + int pos = 0; + + for(unsigned int i=0;i + */ + +/* +File: computername.cpp +functions to change the computer name in the Windows registry +*/ + +#include "stdafx.h" +#include "io.h" +#include "main.h" + +WCHAR KeyNameBuffer[] = L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName"; +WCHAR KeyNameBuffer2[] = L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName"; +WCHAR Tcpip[] = L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"; +WCHAR ComputerNameBuffer[] = L"ComputerName"; + +/* +Function: setRegistryValue + +Parameters: +io: reference to -Controller +*/ +void setRegistryValue(IO &io,WCHAR *keyName,WCHAR *valueName,WCHAR *value) +{ + Indenter i(io); + UNICODE_STRING KeyName, ValueName; + HANDLE SoftwareKeyHandle; + ULONG Status; + OBJECT_ATTRIBUTES ObjectAttributes; + ULONG Disposition; + + //io.print("Schreibe Registry-Key "); + + //DbgBreakPoint(); + // + // Open the Software key + // + NT::RtlInitUnicodeString(&KeyName,keyName); + InitializeObjectAttributes( + &ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = ZwCreateKey( + &SoftwareKeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + &Disposition); + + CHECK_STATUS(Status,Öffnen des Schlüssels) + + NT::RtlInitUnicodeString(&ValueName,valueName); + + Status = ZwSetValueKey( + SoftwareKeyHandle, + &ValueName, + 0, + REG_SZ, + value, + (wcslen( value )+1) * sizeof(WCHAR)); + + CHECK_STATUSA(Status,Setzen des Schlüssels); + + Status = ZwClose(SoftwareKeyHandle); + + CHECK_STATUS(Status,Schließen des Schlüssels); +} + +/* +Function: setComputerName +sets the computer name in the registry to the specified one + +Parameters: +io - reference to the -Controller +computerName - the designated computer name as UNICODE string +*/ +void setComputerName(IO &io,WCHAR *computerName) +{ + Indenter i(io); + io.println("Setze Computernamen "); + setRegistryValue(io,KeyNameBuffer,ComputerNameBuffer,computerName); + setRegistryValue(io,KeyNameBuffer2,ComputerNameBuffer,computerName); + setRegistryValue(io,Tcpip,L"Hostname",computerName); + setRegistryValue(io,Tcpip,L"NV Hostname",computerName); +} +/* +Function: setComputerNameCmd +command line command for setting the computer name manually + +Parameters: +io - -Controller +args - command line argument string +*/ +void setComputerNameCmd(IO &io,char *args) +{ + Indenter i(io); + if (strlen(args)<2) + { + io.println("Syntax: setComputerName "); + return; + } + io.print("Setting Computer Name to: "); + io.println(args+1); + setComputerName(io,io.char2wchar(args+1)); +} + +#define RETURN_NULL_IF_STATUS_UNSUCCESSFULL if (Status!=STATUS_SUCCESS) return 0; + +/* +Constant: whitespaces +defines whitespace character group, each char of this array +designates one white space character +*/ +const char whitespaces[]=" \t\n\x0B\f\r"; + +/* +Function: isWhitespace +Helper function for regexp parser. Tests if c is white space. + +Parameters: +c - character to test + +Returns: +true if character is white space as defined in +*/ +bool isWhitespace(char c) +{ + for (int i=0;i='A'&&c<='Z'; +} +bool isDigit(char c) +{ + return c>='0'&&c<='9'; +} +bool isSmallLetter(char c) +{ + return c>='a'&&c<='z'; +} + +bool isWordCharacter(char c) +{ + return isDigit(c)||isCapitalLetter(c)||isSmallLetter(c)||c=='-'; +} +bool char_matcher(char c,char d) +{ + return c==d; +} +//const char pattern[]="Computername:\\s+(\\w+)"; +/* +Constant: pattern +regular expression pattern which defines the place in a file +to read the computer name from. + +The computer name will be the match for the first bracketed expression. + +Example: +: * +*/ +const char pattern[]=" to find a match in the buffer + +Parameters: +io - -Controller +buffer - source buffer +length - length of source buffer + +Returns: +a string containing the match or 0 otherwise +*/ +char *parseComputerNameFile(IO &io,char *buffer,unsigned int length) +{ + int patternpos=0; + int capture_start=-1; + int capture_end=-1; + void *matcher=0; + char lastData=0; + for (unsigned int i=0;i0) + i--; + patternpos++; + continue; + default: + lastData=pattern[patternpos]; + matcher=char_matcher; + break; + } + + matched=false; + if (lastData!=0) + matched=((bool(*)(char,char))matcher)(buffer[i],lastData); + else + matched=((bool(*)(char))matcher)(buffer[i]); + + if (matched) + patternpos++; + else + patternpos=0; + } + if (pattern[patternpos]==')') + capture_end=length; + + if (capture_start!=-1&&capture_end!=-1) + { + int matchlength=capture_end-capture_start; + char *returnBuffer=(char*)io.malloc(matchlength+1); + memcpy(returnBuffer,buffer+capture_start,matchlength); + returnBuffer[matchlength]=0; + return returnBuffer; + } + else + return 0; +} + +void testMatcher(IO &io,char *args) +{ + char string[]="Computername: "; + char *return0=parseComputerNameFile(io,string,sizeof(string)); +} + +/* +Function: readComputerNameFromFile +reads the computer name from the specified file, uses to +find computer name in it + +Parameters: +io - -Controller +fileName - reads computer name from this file + +Returns: +UNICODE string containing the new computer name, 0 in case of error or if +the name couldn't be found +*/ +wchar_t *readComputerNameFromFile(IO &io,wchar_t *fileName) +{ + Indenter i(io); + NTSTATUS Status; + UNICODE_STRING UnicodeFilespec; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE FileHandle; + IO_STATUS_BLOCK Iosb; + char *buffer; + PWCHAR buffer2; + ULONG converted; + + RtlInitUnicodeString(&UnicodeFilespec,fileName); + + InitializeObjectAttributes( + &ObjectAttributes, // ptr to structure + &UnicodeFilespec, // ptr to file spec + OBJ_CASE_INSENSITIVE, // attributes + NULL, // root directory handle + NULL ); // ptr to security descriptor + + Status = ZwCreateFile( + &FileHandle, // returned file handle + (GENERIC_READ | SYNCHRONIZE), // desired access + &ObjectAttributes, // ptr to object attributes + &Iosb, // ptr to I/O status block + 0, // allocation size + FILE_ATTRIBUTE_NORMAL, // file attributes + 0, // share access + FILE_OPEN, // create disposition + FILE_SYNCHRONOUS_IO_NONALERT, // create options + NULL, // ptr to extended attributes + 0); // length of ea buffer + + CHECK_STATUSA(Status,Öffnen der Computernamensdatei) + RETURN_NULL_IF_STATUS_UNSUCCESSFULL + + buffer = (char*)io.malloc(256);//RtlAllocateHeap( Heap, 0, 256 ); + Status = ZwReadFile(FileHandle,0,NULL,NULL,&Iosb,buffer,256,0,NULL); + ((char*)buffer)[Iosb.Information]=0; + + CHECK_STATUSA(Status,Lesen des Computernamens); + RETURN_NULL_IF_STATUS_UNSUCCESSFULL + + io.print("Trying to parse file ... "); + char *parsed=parseComputerNameFile(io,buffer,Iosb.Information); + + if (parsed!=0) + { + io.print("successful: "); + io.println(parsed); + } + else + { + io.println("failed."); + io.free(buffer); + io.free(parsed); + return 0; + } + + buffer2 = (PWCHAR)io.malloc(500); + + mbstowcs(buffer2,(char*)parsed,strlen(parsed)); + + Status = ZwClose(FileHandle); + + CHECK_STATUS(Status,Schließen der Datei); + + io.free(buffer); + io.free(parsed); + + return buffer2; +} + +/* +Function: setCompnameFromFile +command line command to set computer name from file. + +Uses a list of files to find computer name. List consists of +command line parameters and hard coded *\\device\\floppy0\\compname.txt*. + +Tries to read each file and extract the computer name in the list till a +valid one is found. This is set as computer name afterwards. + +Parameters: +io - -Controller +args - command line +*/ +void setCompnameFromFile(IO &io,char *args) +{ + Indenter i(io); + int numFiles=mainSingleton->getArgc(); + char **valueNames=(char**)io.malloc(4*numFiles); + char **cmdargs=mainSingleton->getArgs(); + + io.print("Computername file pipe: "); + + for (int i=1;i + */ + +// stdafx.cpp : source file that includes just the standard includes +// usermode-registry.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/windows/bootpgm/win32/stdafx.h b/windows/bootpgm/win32/stdafx.h new file mode 100644 index 00000000..4450335a --- /dev/null +++ b/windows/bootpgm/win32/stdafx.h @@ -0,0 +1,50 @@ +/* The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + * License for the specific language governing rights and limitations + * under the License. + * + * The Initial Developer of the Original Code is Johannes Rudolph. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Johannes Rudolph + */ + +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#endif +#include +#include +#include +#include +#include + +namespace NT { + extern "C" { +#ifndef _X86_ + #define _X86_ +#endif +#pragma warning(disable: 4005) +#include +#include +#pragma warning(default: 4005) + } +} + +using namespace NT; +#include "../native/newnative.h" + +// TODO: reference additional headers your program requires here diff --git a/windows/bootpgm/win32/usermode-registry.sln b/windows/bootpgm/win32/usermode-registry.sln new file mode 100644 index 00000000..a732e479 --- /dev/null +++ b/windows/bootpgm/win32/usermode-registry.sln @@ -0,0 +1,23 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C++ Express 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "usermode-registry", "usermode-registry.vcproj", "{63B64315-1D50-4C6B-8A9D-69E44436FBF6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Library|Win32 = Library|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {63B64315-1D50-4C6B-8A9D-69E44436FBF6}.Debug|Win32.ActiveCfg = Debug|Win32 + {63B64315-1D50-4C6B-8A9D-69E44436FBF6}.Debug|Win32.Build.0 = Debug|Win32 + {63B64315-1D50-4C6B-8A9D-69E44436FBF6}.Library|Win32.ActiveCfg = Library|Win32 + {63B64315-1D50-4C6B-8A9D-69E44436FBF6}.Library|Win32.Build.0 = Library|Win32 + {63B64315-1D50-4C6B-8A9D-69E44436FBF6}.Release|Win32.ActiveCfg = Release|Win32 + {63B64315-1D50-4C6B-8A9D-69E44436FBF6}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/windows/bootpgm/win32/usermode-registry.vcproj b/windows/bootpgm/win32/usermode-registry.vcproj new file mode 100644 index 00000000..57a2e4e9 --- /dev/null +++ b/windows/bootpgm/win32/usermode-registry.vcproj @@ -0,0 +1,365 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/windows/bootpgm/win32/win32.cpp b/windows/bootpgm/win32/win32.cpp new file mode 100644 index 00000000..cc3999fe --- /dev/null +++ b/windows/bootpgm/win32/win32.cpp @@ -0,0 +1,92 @@ +/* The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + * License for the specific language governing rights and limitations + * under the License. + * + * The Initial Developer of the Original Code is Johannes Rudolph. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Johannes Rudolph + */ + +#include "stdafx.h" +#include "io.h" +#include "main.h" +#include "registrybrowser.h" + +class UsermodeIO:public IO{ +public: + char getChar() + { + return getchar(); + } + void internalPrint(char *buffer) + { + printf(buffer); + } + char *getVersion() + { + return "Usermode IO"; + } + void *malloc(unsigned int length) + { + return ::malloc(length); + } + void free(void *buffer) + { + ::free(buffer); + } + void handleCharEcho(char ch,char *buffer,unsigned int length) + { + // no echo necessary because getchar() echos + } +}; + +void splitArgs(IO &io,char *args){ + if (strlen(args)==0) + return; + + int argc; + UNICODE_STRING str; + wchar_t *wstr; + char buffer[100]; + wstr=(wchar_t*)buffer; + mbstowcs(wstr,args,50); + NT::RtlInitUnicodeString(&str,wstr); + str.Length-=2; + char **argv=split_args(io,str.Buffer,str.Length/2,&argc); + for (int i=0;i