diff --git a/Hidden/todo.txt b/Hidden/todo.txt index ec1f010..166eb29 100644 --- a/Hidden/todo.txt +++ b/Hidden/todo.txt @@ -52,8 +52,8 @@ + Протестировать все комманды + При выполнении /unhide с любым ID возвращается статус ок + Проверить чтобы все ObjId генерировались начиная с 1 -- Реализовать функционал вкл\выкл драйвера через IOCTL - - Написать тест для данного функционала ++ Реализовать функционал вкл\выкл драйвера через IOCTL +- Написать тест для вкл\выкл драйвера через IOCTL - Написать тест HiddenCLITests + Портировать драйвер под архитектуру x64 + Портировать под версии Windows 8, 8.1, 10 diff --git a/HiddenCLI/Commands.cpp b/HiddenCLI/Commands.cpp index 03267b5..22bc352 100644 --- a/HiddenCLI/Commands.cpp +++ b/HiddenCLI/Commands.cpp @@ -9,15 +9,68 @@ using namespace std; // ================= -Commands::Commands(Arguments& args) +void LoadCommandsStack(vector& stack) +{ + stack.push_back(CommandPtr(new CommandHide())); + stack.push_back(CommandPtr(new CommandUnhide())); + stack.push_back(CommandPtr(new CommandIgnore())); + stack.push_back(CommandPtr(new CommandUnignore())); + stack.push_back(CommandPtr(new CommandProtect())); + stack.push_back(CommandPtr(new CommandUnprotect())); + stack.push_back(CommandPtr(new CommandQuery())); + stack.push_back(CommandPtr(new CommandState())); +} + +// ================= + +SingleCommand::SingleCommand(Arguments& args) +{ + wstring arg; + bool found = false; + + if (!args.GetNext(arg)) + throw WException(-2, L"Error, no command, please use 'hiddencli /help'"); + + LoadCommandsStack(m_commandsStack); + + for (auto it = m_commandsStack.begin(); it != m_commandsStack.end(); it++) + { + if ((*it)->CompareCommand(arg)) + { + (*it)->LoadArgs(args); + m_current = *it; + found = true; + break; + } + } + + if (!found) + throw WException(-2, L"Error, unknown command, please use 'hiddencli /help'"); + + if (args.GetNext(arg)) + throw WException(-2, L"Error, too many arguments"); +} + +SingleCommand::~SingleCommand() +{ +} + +void SingleCommand::Perform(Connection& connection) +{ + m_current->PerformCommand(connection); +} + +// ================= + +MultipleCommands::MultipleCommands(Arguments& args) { wstring arg; if (!args.GetNext(arg)) - throw WException(-2, L"Error, no command, please use 'hiddencli help'"); + throw WException(-2, L"Error, no command, please use 'hiddencli /help'"); + + LoadCommandsStack(m_commandsStack); - LoadCommandsStack(); - do { bool found = false; @@ -26,37 +79,42 @@ Commands::Commands(Arguments& args) { if ((*it)->CompareCommand(arg)) { - (*it)->LoadArgs(args); - m_current = *it; + CommandPtr command = (*it)->CreateInstance(); + command->LoadArgs(args); + m_currentStack.push_back(command); found = true; break; } } if (!found) - throw WException(-2, L"Error, unknown command, please use 'hiddencli help'"); - } + throw WException(-2, L"Error, unknown command, please use 'hiddencli /help'"); + } while (args.GetNext(arg)); - } -Commands::~Commands() +MultipleCommands::~MultipleCommands() { } -void Commands::LoadCommandsStack() +void MultipleCommands::Perform(Connection& connection) { - m_commandsStack.push_back(CommandPtr(new CommandHide())); - m_commandsStack.push_back(CommandPtr(new CommandUnhide())); - m_commandsStack.push_back(CommandPtr(new CommandIgnore())); - m_commandsStack.push_back(CommandPtr(new CommandUnignore())); - m_commandsStack.push_back(CommandPtr(new CommandProtect())); - m_commandsStack.push_back(CommandPtr(new CommandUnprotect())); - m_commandsStack.push_back(CommandPtr(new CommandQuery())); - m_commandsStack.push_back(CommandPtr(new CommandState())); + for (auto it = m_currentStack.begin(); it != m_currentStack.end(); it++) + (*it)->PerformCommand(connection); } -void Commands::Perform(Connection& connection) +// ================= + +MultipleCommandsFromFile::MultipleCommandsFromFile(Arguments& args) { - m_current->PerformCommand(connection); + throw WException(-2, L"Error, /config isn't implemented yet"); } + +MultipleCommandsFromFile::~MultipleCommandsFromFile() +{ +} + +void MultipleCommandsFromFile::Perform(Connection& connection) +{ +} + diff --git a/HiddenCLI/Commands.h b/HiddenCLI/Commands.h index a6f66cd..759dc4b 100644 --- a/HiddenCLI/Commands.h +++ b/HiddenCLI/Commands.h @@ -7,27 +7,63 @@ class ICommand { public: + typedef std::shared_ptr CommandPtrInternal; virtual ~ICommand() {}; virtual bool CompareCommand(std::wstring& command) = 0; virtual void LoadArgs(Arguments& args) = 0; virtual void PerformCommand(Connection& connection) = 0; + + virtual CommandPtrInternal CreateInstance() = 0; }; -class Commands -{ - typedef std::shared_ptr CommandPtr; +typedef ICommand::CommandPtrInternal CommandPtr; +class ICommandMode +{ +public: + virtual ~ICommandMode() {} + virtual void Perform(Connection& connection) = 0; +}; + +typedef std::shared_ptr CommandModePtr; + +class SingleCommand : public ICommandMode +{ std::vector m_commandsStack; CommandPtr m_current; - void LoadCommandsStack(); +public: + + SingleCommand(Arguments& args); + virtual ~SingleCommand(); + + virtual void Perform(Connection& connection); +}; + +class MultipleCommands : public ICommandMode +{ + std::vector m_commandsStack; + std::vector m_currentStack; public: - Commands(Arguments& args); - ~Commands(); + MultipleCommands(Arguments& args); + virtual ~MultipleCommands(); - void Perform(Connection& connection); + virtual void Perform(Connection& connection); +}; + +class MultipleCommandsFromFile : public ICommandMode +{ + std::vector m_commandsStack; + std::vector m_currentStack; + +public: + + MultipleCommandsFromFile(Arguments& args); + virtual ~MultipleCommandsFromFile(); + + virtual void Perform(Connection& connection); }; diff --git a/HiddenCLI/HiddenCLI.cpp b/HiddenCLI/HiddenCLI.cpp index 38a8695..3003b9f 100644 --- a/HiddenCLI/HiddenCLI.cpp +++ b/HiddenCLI/HiddenCLI.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include "Helper.h" #include "Connection.h" @@ -18,72 +19,122 @@ bool PrintUsage(Arguments& args) return false; wchar_t message[] = - L"hiddencli [connection] \n" + L"hiddencli [mode] [connection] [perform] \n" L"hiddencli /help\n" L"\n" + L"mode:\n" + L"\n" + L" By default perform current commands\n" + L"\n" + L" /install [%driver%]\n" + L" Install commands to registry without execution, driver will load them on\n" + L" start. If this flag is set connection parameters shouldn't be set. Optional\n" + L" parameter is used for set valid registry path if driver name is changed, by\n" + L" default \"hidden\"\n" + L"\n" L"connection:\n" L"\n" - L" gate <%name%>\n" - L" Set specific connection gate name (driver device name)\n" + L" /gate <%name%>\n" + L" Set specific connection gate name. By default \"HiddenGate\" is used\n" + L"\n" + L"perform:\n" + L"\n" + L" By default perform one command by one execution\n" + L"\n" + L" /multi\n" + L" Enable multiple commands per execution, just type commands one by one\n" + L" without any separator\n" + L"\n" + L" /config\n" + L" Loads multiple commands from file, each command should be on separate line\n" L"\n" L"commands:\n" L"\n" - L" state \n" - //L" Enable or disable hidden\n" - L" Doesn't implemented yet\n" + L" /state \n" + L" Enable or disable hidden\n" L"\n" - L" hide <%path%>\n" + L" /query state\n" + L" Get enforcement state\n" + L"\n" + L" /hide <%path%>\n" L" Hide filesystem or registry object by path\n" L"\n" - L" unhide all\n" + L" /unhide all\n" L" Unhide all filesystem or registry object by selected type\n" L"\n" - L" unhide <%ruleid%>\n" + L" /unhide <%ruleid%>\n" L" Unhide all filesystem or registry object by selected type and rule ID\n" L"\n" - L" ignore image [inherit:] [apply:] <%path%>\n" - L" Set rule that allows to see hidden filesystem and registry objects for processes with specific image path\n" + L" /ignore image [inherit:] [apply:] <%path%>\n" + L" Set rule that allows to see hidden filesystem and registry objects for\n" + L" processes with specific image path\n" L"\n" - L" unignore <%ruleid%>\n" - L" Remove rule that allows to see hidden filesystem and registry objects by rule ID\n" + L" /unignore <%ruleid%>\n" + L" Remove rule that allows to see hidden filesystem and registry objects by\n" + L" rule ID\n" L"\n" - L" unignore all\n" + L" /unignore all\n" L" Remove all rules that allow to see hidden filesystem and registry objects\n" L"\n" - L" ignore pid [inherit:] <%pid%>\n" - L" Turn on abillity to see hidden filesystem and registry objects for specific process by PID\n" + L" /ignore pid [inherit:] <%pid%>\n" + L" Turn on abillity to see hidden filesystem and registry objects for\n" + L" specific process by PID\n" L"\n" - L" unignore pid <%pid%>\n" - L" Turn off abillity to see hidden filesystem and registry objects for specific process by PID\n" + L" /unignore pid <%pid%>\n" + L" Turn off abillity to see hidden filesystem and registry objects for\n" + L" specific process by PID\n" L"\n" - L" protect image [inherit:] [apply:] <%path%>\n" - L" Set rule that allows to enable process protection for processes with specific image path\n" + L" /protect image [inherit:] [apply:] <%path%>\n" + L" Set rule that allows to enable process protection for processes with\n" + L" specific image path\n" L"\n" - L" unprotect <%ruleid%>\n" + L" /unprotect <%ruleid%>\n" L" Remove rule that enables process protection by rule ID\n" L"\n" - L" unprotect all\n" + L" /unprotect all\n" L" Remove all rules that enable process protection\n" L"\n" - L" protect pid [inherit:] <%pid%>\n" + L" /protect pid [inherit:] <%pid%>\n" L" Turn on protection for specific process by PID\n" L"\n" - L" unprotect pid <%pid%>\n" + L" /unprotect pid <%pid%>\n" L" Turn off protection for specific process by PID\n" L"\n" - L" query process <%pid%>\n" + L" /query process <%pid%>\n" L" Query information about state of the process by PID\n"; wcout << message << endl; return true; } +CommandModePtr LoadCommands(Arguments& args) +{ + wstring command; + + if (!args.Probe(command)) + throw WException(-2, L"Error, unknown mode, please use 'hiddencli /help'"); + + if (command == L"/multi") + { + args.SwitchToNext(); + return CommandModePtr(new MultipleCommands(args)); + } + else if (command == L"/config") + { + args.SwitchToNext(); + return CommandModePtr(new MultipleCommandsFromFile(args)); + } + + return CommandModePtr(new SingleCommand(args)); +} + int wmain(int argc, wchar_t* argv[]) { try { Arguments arguments(argc, argv); Connection connection(arguments); + wstring mode; if (!arguments.ArgsCount()) throw WException( @@ -91,12 +142,13 @@ int wmain(int argc, wchar_t* argv[]) L"Welcome to HiddenCLI, please use 'hiddencli /help'" ); - if (!PrintUsage(arguments)) - { - Commands commands(arguments); + if (PrintUsage(arguments)) + return 0; + { + CommandModePtr commands = LoadCommands(arguments); connection.Open(); - commands.Perform(connection); + commands->Perform(connection); } } catch (WException& exception) diff --git a/HiddenCLI/HiddenCLI.vcxproj b/HiddenCLI/HiddenCLI.vcxproj index be2f8a0..3ea314a 100644 --- a/HiddenCLI/HiddenCLI.vcxproj +++ b/HiddenCLI/HiddenCLI.vcxproj @@ -174,6 +174,9 @@ + + + diff --git a/HiddenCLI/HiddenCLI.vcxproj.filters b/HiddenCLI/HiddenCLI.vcxproj.filters index ef84ed1..9131fc4 100644 --- a/HiddenCLI/HiddenCLI.vcxproj.filters +++ b/HiddenCLI/HiddenCLI.vcxproj.filters @@ -49,4 +49,7 @@ {680a2e80-be0d-4ac2-8a4a-d59b67e55c61} + + + \ No newline at end of file diff --git a/HiddenCLI/Hide.cpp b/HiddenCLI/Hide.cpp index 9273d5b..5f43f9a 100644 --- a/HiddenCLI/Hide.cpp +++ b/HiddenCLI/Hide.cpp @@ -82,6 +82,11 @@ void CommandHide::PerformCommand(Connection& connection) wcout << L"status:ok;ruleid:" << objId << endl; } +CommandPtr CommandHide::CreateInstance() +{ + return CommandPtr(new CommandHide()); +} + // ================= CommandUnhide::CommandUnhide() : m_command(L"/unhide") @@ -189,3 +194,8 @@ void CommandUnhide::PerformCommand(Connection& connection) wcerr << L"Command 'unhide' successful" << endl; wcout << L"status:ok" << endl; } + +CommandPtr CommandUnhide::CreateInstance() +{ + return CommandPtr(new CommandUnhide()); +} diff --git a/HiddenCLI/Hide.h b/HiddenCLI/Hide.h index 21a2cf5..048e3b0 100644 --- a/HiddenCLI/Hide.h +++ b/HiddenCLI/Hide.h @@ -18,6 +18,8 @@ public: virtual bool CompareCommand(std::wstring& command); virtual void LoadArgs(Arguments& args); virtual void PerformCommand(Connection& connection); + + virtual CommandPtr CreateInstance(); }; class CommandUnhide : public ICommand @@ -36,4 +38,6 @@ public: virtual bool CompareCommand(std::wstring& command); virtual void LoadArgs(Arguments& args); virtual void PerformCommand(Connection& connection); + + virtual CommandPtr CreateInstance(); }; diff --git a/HiddenCLI/Ignore.cpp b/HiddenCLI/Ignore.cpp index 0510e6c..7733e9d 100644 --- a/HiddenCLI/Ignore.cpp +++ b/HiddenCLI/Ignore.cpp @@ -86,6 +86,11 @@ void CommandIgnore::PerformCommand(Connection& connection) wcout << L"status:ok;ruleid:" << objId << endl; } +CommandPtr CommandIgnore::CreateInstance() +{ + return CommandPtr(new CommandIgnore()); +} + // ================= CommandUnignore::CommandUnignore() : m_command(L"/unignore") @@ -158,3 +163,8 @@ void CommandUnignore::PerformCommand(Connection& connection) wcerr << L"Command 'unignore' successful" << endl; wcout << L"status:ok" << endl; } + +CommandPtr CommandUnignore::CreateInstance() +{ + return CommandPtr(new CommandUnignore()); +} diff --git a/HiddenCLI/Ignore.h b/HiddenCLI/Ignore.h index bb04748..92a60c0 100644 --- a/HiddenCLI/Ignore.h +++ b/HiddenCLI/Ignore.h @@ -20,6 +20,8 @@ public: virtual bool CompareCommand(std::wstring& command); virtual void LoadArgs(Arguments& args); virtual void PerformCommand(Connection& connection); + + virtual CommandPtr CreateInstance(); }; class CommandUnignore : public ICommand @@ -44,4 +46,6 @@ public: virtual bool CompareCommand(std::wstring& command); virtual void LoadArgs(Arguments& args); virtual void PerformCommand(Connection& connection); + + virtual CommandPtr CreateInstance(); }; diff --git a/HiddenCLI/Protect.cpp b/HiddenCLI/Protect.cpp index e49aa4a..2acae5a 100644 --- a/HiddenCLI/Protect.cpp +++ b/HiddenCLI/Protect.cpp @@ -86,6 +86,11 @@ void CommandProtect::PerformCommand(Connection& connection) wcout << L"status:ok;ruleid:" << objId << endl; } +CommandPtr CommandProtect::CreateInstance() +{ + return CommandPtr(new CommandProtect()); +} + // ================= CommandUnprotect::CommandUnprotect() : m_command(L"/unprotect") @@ -158,3 +163,8 @@ void CommandUnprotect::PerformCommand(Connection& connection) wcerr << L"Command 'unprotect' successful" << endl; wcout << L"status:ok" << endl; } + +CommandPtr CommandUnprotect::CreateInstance() +{ + return CommandPtr(new CommandUnprotect()); +} diff --git a/HiddenCLI/Protect.h b/HiddenCLI/Protect.h index 23be0a3..ff14538 100644 --- a/HiddenCLI/Protect.h +++ b/HiddenCLI/Protect.h @@ -20,6 +20,8 @@ public: virtual bool CompareCommand(std::wstring& command); virtual void LoadArgs(Arguments& args); virtual void PerformCommand(Connection& connection); + + virtual CommandPtr CreateInstance(); }; class CommandUnprotect : public ICommand @@ -44,4 +46,6 @@ public: virtual bool CompareCommand(std::wstring& command); virtual void LoadArgs(Arguments& args); virtual void PerformCommand(Connection& connection); + + virtual CommandPtr CreateInstance(); }; diff --git a/HiddenCLI/Query.cpp b/HiddenCLI/Query.cpp index 4ec84bb..7fe4d75 100644 --- a/HiddenCLI/Query.cpp +++ b/HiddenCLI/Query.cpp @@ -82,3 +82,8 @@ void CommandQuery::PerformCommand(Connection& connection) << L";protected:" << protectedState << L"," << protectedInherit << endl; } } + +CommandPtr CommandQuery::CreateInstance() +{ + return CommandPtr(new CommandQuery()); +} diff --git a/HiddenCLI/Query.h b/HiddenCLI/Query.h index c13c3bd..ccc8171 100644 --- a/HiddenCLI/Query.h +++ b/HiddenCLI/Query.h @@ -22,5 +22,7 @@ public: virtual bool CompareCommand(std::wstring& command); virtual void LoadArgs(Arguments& args); virtual void PerformCommand(Connection& connection); + + virtual CommandPtr CreateInstance(); }; diff --git a/HiddenCLI/State.cpp b/HiddenCLI/State.cpp index 378b770..7346363 100644 --- a/HiddenCLI/State.cpp +++ b/HiddenCLI/State.cpp @@ -42,3 +42,8 @@ void CommandState::PerformCommand(Connection& connection) wcerr << L"Command 'state' successful" << endl; wcout << L"status:ok" << endl; } + +CommandPtr CommandState::CreateInstance() +{ + return CommandPtr(new CommandState()); +} diff --git a/HiddenCLI/State.h b/HiddenCLI/State.h index e944d1e..6cdf09b 100644 --- a/HiddenCLI/State.h +++ b/HiddenCLI/State.h @@ -16,4 +16,6 @@ public: virtual bool CompareCommand(std::wstring& command); virtual void LoadArgs(Arguments& args); virtual void PerformCommand(Connection& connection); + + virtual CommandPtr CreateInstance(); }; diff --git a/HiddenCLI/cli.txt b/HiddenCLI/cli.txt index 2a895ca..aa75eb6 100644 --- a/HiddenCLI/cli.txt +++ b/HiddenCLI/cli.txt @@ -1,58 +1,77 @@ -hiddencli [connection] +hiddencli [mode] [connection] [perform] hiddencli /help +mode: + + By default perform current commands + + /install [%driver%] + Install commands to registry without execution, driver will load them on start. If this flag is set + connection parameters shouldn't be set. Optional parameter is used for set valid registry path if + driver name is changed, by default "hidden" + connection: - gate <%name%> + /gate <%name%> Set specific connection gate name (driver device name) +perform: + + By default perform one command by one execution + + /multi + Enable multiple commands per execution, just type commands one by one without any separator + + /config + Loads multiple commands from file, each command should be on separate line + commands: - state + /state Enable or disable enforcement (hiding, protecting, ignoring etc) - query state + /query state Get enforcement state - hide <%path%> + /hide <%path%> Hide filesystem or registry object by path - unhide all + /unhide all Unhide all filesystem or registry object by selected type - unhide <%ruleid%> + /unhide <%ruleid%> Unhide all filesystem or registry object by selected type and rule ID - ignore image [inherit:] [apply:] <%path%> + /ignore image [inherit:] [apply:] <%path%> Set rule that allows to see hidden filesystem and registry objects for processes with specific image path - unignore <%ruleid%> + /unignore <%ruleid%> Remove rule that allows to see hidden filesystem and registry objects by rule ID - unignore all + /unignore all Remove all rules that allow to see hidden filesystem and registry objects - ignore pid [inherit:] <%pid%> + /ignore pid [inherit:] <%pid%> Turn on abillity to see hidden filesystem and registry objects for specific process by PID - unignore pid <%pid%> + /unignore pid <%pid%> Turn off abillity to see hidden filesystem and registry objects for specific process by PID - protect image [inherit:] [apply:] <%path%> + /protect image [inherit:] [apply:] <%path%> Set rule that allows to enable process protection for processes with specific image path - unprotect <%ruleid%> + /unprotect <%ruleid%> Remove rule that enables process protection by rule ID - unprotect all + /unprotect all Remove all rules that enable process protection - protect pid [inherit:] <%pid%> + /protect pid [inherit:] <%pid%> Turn on protection for specific process by PID - unprotect pid <%pid%> + /unprotect pid <%pid%> Turn off protection for specific process by PID - query process <%pid%> + /query process <%pid%> Query information about state of the process by PID diff --git a/HiddenCLI/vmware.conf b/HiddenCLI/vmware.conf new file mode 100644 index 0000000..3023e59 --- /dev/null +++ b/HiddenCLI/vmware.conf @@ -0,0 +1,35 @@ + +/state on + +/hide dir "c:\Program Files\VMware" +/hide dir "c:\ProgramData\VMware" +/hide dir "c:\Windows\Temp\vmware-SYSTEM" +/hide dir "c:\Program Files\Common Files\VMware" + +/hide regkey "HKLM\Software\VMware, Inc." +/hide regkey "HKLM\ControlSet001\Control\Print\Monitors\ThinPrint Print Port Monitor for VMWare" +/hide regkey "HKLM\ControlSet002\Control\Print\Monitors\ThinPrint Print Port Monitor for VMWare" +/hide regkey "HKLM\CurrentControlSet\Control\Print\Monitors\ThinPrint Print Port Monitor for VMWare" +/hide regkey "HKCU\VMware, Inc." + +/hide regval "HKLM\Hardware\Description\System\BIOS\SystemManufacturer" +/hide regval "HKLM\Hardware\Description\System\BIOS\SystemProductName" + +/ignore image inherit:none apply:forall "C:\Windows\System32\services.exe" +/ignore image inherit:none apply:forall "C:\Windows\System32\csrss.exe" +/ignore image inherit:none apply:forall "C:\Windows\System32\vssvc.exe" +/ignore image inherit:none apply:forall "C:\Windows\System32\spoolsv.exe" +/ignore image inherit:none apply:forall "C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" +/ignore image inherit:none apply:forall "C:\Program Files\VMware\VMware Tools\TPAutoConnSvc.exe" +/ignore image inherit:none apply:forall "C:\Program Files\VMware\VMware Tools\rpctool.exe" +/ignore image inherit:none apply:forall "C:\Program Files\VMware\VMware Tools\rvmSetup.exe" +/ignore image inherit:none apply:forall "C:\Program Files\VMware\VMware Tools\TPAutoConnect.exe" +/ignore image inherit:none apply:forall "C:\Program Files\VMware\VMware Tools\TPVCGateway.exe" +/ignore image inherit:none apply:forall "C:\Program Files\VMware\VMware Tools\VMwareHgfsClient.exe" +/ignore image inherit:none apply:forall "C:\Program Files\VMware\VMware Tools\VMwareHostOpen.exe" +/ignore image inherit:none apply:forall "C:\Program Files\VMware\VMware Tools\VMwareResolutionSet.exe" +/ignore image inherit:none apply:forall "C:\Program Files\VMware\VMware Tools\VMwareToolboxCmd.exe" +/ignore image inherit:none apply:forall "C:\Program Files\VMware\VMware Tools\VMwareXferlogs.exe" +/ignore image inherit:none apply:forall "C:\Program Files\VMware\VMware Tools\zip.exe" + +/stealth on "my_stealth_gate"