Added 'state' command

This commit is contained in:
JKornev 2016-12-12 23:40:35 +03:00
parent 146af98691
commit 5d611535e7
19 changed files with 259 additions and 62 deletions

View File

@ -3,6 +3,7 @@
#include "PsMonitor.h"
#include "Device.h"
#include "DeviceAPI.h"
#include "Driver.h"
BOOLEAN g_deviceInited = FALSE;
PDEVICE_OBJECT g_deviceObject = NULL;
@ -319,6 +320,26 @@ NTSTATUS RemoveAllPsObjects(PHid_RemoveAllPsObjectsPacket Packet, USHORT Size)
return status;
}
NTSTATUS SetDriverStateObject(PHid_DriverStatus Packet, USHORT Size)
{
if (Size != sizeof(Hid_DriverStatus))
return STATUS_INVALID_PARAMETER;
EnableDisableDriver(Packet->state ? TRUE : FALSE);
return STATUS_SUCCESS;
}
NTSTATUS GetDriverStateObject(PHid_DriverStatus Packet, USHORT Size, PULONG state)
{
UNREFERENCED_PARAMETER(Packet);
if (Size != sizeof(Hid_DriverStatus))
return STATUS_INVALID_PARAMETER;
*state = IsDriverEnabled();
return STATUS_SUCCESS;
}
NTSTATUS IrpDeviceControlHandler(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION irpStack;
@ -363,6 +384,13 @@ NTSTATUS IrpDeviceControlHandler(PDEVICE_OBJECT DeviceObject, PIRP Irp)
// data in the same time you should make the copy of input data and work with it.
switch (ioctl)
{
// Driver
case HID_IOCTL_SET_DRIVER_STATE:
result.status = SetDriverStateObject((PHid_DriverStatus)inputBuffer, (USHORT)inputBufferSize);
break;
case HID_IOCTL_GET_DRIVER_STATE:
result.status = GetDriverStateObject((PHid_DriverStatus)inputBuffer, (USHORT)inputBufferSize, &result.info.state);
break;
// Reg/Fs
case HID_IOCTL_ADD_HIDDEN_OBJECT:
result.status = AddHiddenObject((PHid_HideObjectPacket)inputBuffer, (USHORT)inputBufferSize, &result.info.id);

View File

@ -38,6 +38,11 @@ enum Hid_ObjectTypes {
// Fs/Reg packets
typedef struct _Hid_DriverStatusPacket {
unsigned short state;
unsigned short reserved;
} Hid_DriverStatus, *PHid_DriverStatus;
typedef struct _Hid_HideObjectPacket {
unsigned short objType;
unsigned short dataSize;

View File

@ -11,18 +11,18 @@
PDRIVER_OBJECT g_driverObject = NULL;
BOOLEAN g_driverActive = FALSE;
volatile LONG g_driverActive = FALSE;
// =========================================================================================
VOID SetDriverActivityState(BOOLEAN state)
VOID EnableDisableDriver(BOOLEAN enabled)
{
g_driverActive = state;
InterlockedExchange(&g_driverActive, (LONG)enabled);
}
BOOLEAN GetDriverActiviteState()
BOOLEAN IsDriverEnabled()
{
return g_driverActive;
return (g_driverActive ? TRUE : FALSE);
}
// =========================================================================================
@ -43,7 +43,7 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
UNREFERENCED_PARAMETER(RegistryPath);
g_driverActive = TRUE;
EnableDisableDriver(TRUE);
status = InitializePsMonitor(DriverObject);
if (!NT_SUCCESS(status))

View File

@ -1,4 +1,4 @@
#pragma once
VOID SetDriverActivityState(BOOLEAN state);
BOOLEAN GetDriverActiviteState();
VOID EnableDisableDriver(BOOLEAN enabled);
BOOLEAN IsDriverEnabled();

View File

@ -170,7 +170,7 @@ NTSTATUS AddExcludeListEntry(ExcludeContext Context, PUNICODE_STRING FilePath, U
NTSTATUS RemoveExcludeListEntry(ExcludeContext Context, ExcludeEntryId EntryId)
{
NTSTATUS status = STATUS_SUCCESS;
NTSTATUS status = STATUS_NOT_FOUND;
PEXCLUDE_FILE_CONTEXT cntx = (PEXCLUDE_FILE_CONTEXT)Context;
KLOCK_QUEUE_HANDLE lockHandle;
PEXCLUDE_FILE_LIST_ENTRY entry;

View File

@ -7,6 +7,7 @@
#include "FsFilter.h"
#include "Helper.h"
#include "PsMonitor.h"
#include "Driver.h"
NTSTATUS FilterSetup(PCFLT_RELATED_OBJECTS FltObjects, FLT_INSTANCE_SETUP_FLAGS Flags, DEVICE_TYPE VolumeDeviceType, FLT_FILESYSTEM_TYPE VolumeFilesystemType);
@ -101,6 +102,9 @@ FLT_PREOP_CALLBACK_STATUS FltCreatePreOperation(
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext);
if (!IsDriverEnabled())
return FLT_PREOP_SUCCESS_NO_CALLBACK;
//DbgPrint("!!!!! " __FUNCTION__ ": Entered %d\n", (ULONG)KeGetCurrentIrql());
//DbgPrint("%wZ %x\n", &Data->Iopb->TargetFileObject->FileName, Data->Iopb->Parameters.Create.Options);
@ -147,10 +151,13 @@ FLT_PREOP_CALLBACK_STATUS FltCreatePreOperation(
FLT_PREOP_CALLBACK_STATUS FltDirCtrlPreOperation(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID *CompletionContext)
{
PAGED_CODE();
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext);
PAGED_CODE();
if (!IsDriverEnabled())
return FLT_POSTOP_FINISHED_PROCESSING;
//DbgPrint("!!!!! " __FUNCTION__ ": Entered\n");
//DbgPrint("%wZ\n", &Data->Iopb->TargetFileObject->FileName);
@ -186,6 +193,9 @@ FLT_POSTOP_CALLBACK_STATUS FltDirCtrlPostOperation(PFLT_CALLBACK_DATA Data, PCFL
PAGED_CODE();
if (!IsDriverEnabled())
return FLT_POSTOP_FINISHED_PROCESSING;
if (!NT_SUCCESS(Data->IoStatus.Status))
return FLT_POSTOP_FINISHED_PROCESSING;

View File

@ -3,6 +3,7 @@
#include "Helper.h"
#include "PsTable.h"
#include "PsRules.h"
#include "Driver.h"
#define PROCESS_QUERY_LIMITED_INFORMATION 0x1000
#define SYSTEM_PROCESS_ID (HANDLE)4
@ -112,6 +113,9 @@ OB_PREOP_CALLBACK_STATUS ProcessPreCallback(PVOID RegistrationContext, POB_PRE_O
{
UNREFERENCED_PARAMETER(RegistrationContext);
if (!IsDriverEnabled())
return OB_PREOP_SUCCESS;
if (OperationInformation->KernelHandle)
return OB_PREOP_SUCCESS;
@ -141,6 +145,9 @@ OB_PREOP_CALLBACK_STATUS ThreadPreCallback(PVOID RegistrationContext, POB_PRE_OP
{
UNREFERENCED_PARAMETER(RegistrationContext);
if (!IsDriverEnabled())
return OB_PREOP_SUCCESS;
if (OperationInformation->KernelHandle)
return OB_PREOP_SUCCESS;

View File

@ -43,16 +43,17 @@
+ Слинковать с IOCTL API lib
+ Добавить поддержку флага автоприсвоение состояния существующим процессам для Hid_AddExcludedImage\Hid_AddProtectedImage
+ Проверить как ведёт себя файловый фильтр с файлами открытыми по ID или по короткому пути
- Реализовать HiddenCLI
+ Реализовать HiddenCLI
+ ignore
+ unignore
+ protect
+ unprotect
+ query
- Протестировать все комманды
- При выполнении /unhide с любым ID возвращается статус ок
- Проверить чтобы все ObjId генерировались начиная с 1
+ Протестировать все комманды
+ При выполнении /unhide с любым ID возвращается статус ок
+ Проверить чтобы все ObjId генерировались начиная с 1
- Реализовать функционал вкл\выкл драйвера через IOCTL
- Написать тест для данного функционала
- Написать тест HiddenCLITests
+ Портировать драйвер под архитектуру x64
+ Портировать под версии Windows 8, 8.1, 10

View File

@ -3,6 +3,7 @@
#include "Ignore.h"
#include "Protect.h"
#include "Query.h"
#include "State.h"
using namespace std;
@ -52,6 +53,7 @@ void Commands::LoadCommandsStack()
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()));
}
void Commands::Perform(Connection& connection)

View File

@ -148,3 +148,20 @@ bool LoadApplyOption(Arguments& args, bool applyByDefault)
return applyByDefault;
}
const wchar_t* ConvertInheritTypeToUnicode(HidPsInheritTypes type)
{
switch (type)
{
case HidPsInheritTypes::WithoutInherit:
return L"none";
break;
case HidPsInheritTypes::InheritOnce:
return L"once";
break;
case HidPsInheritTypes::InheritAlways:
return L"always";
break;
}
return L"unknown";
}

View File

@ -69,3 +69,5 @@ HidRegRootTypes GetRegType(std::wstring& path);
HidPsInheritTypes LoadInheritOption(Arguments& args, HidPsInheritTypes default);
bool LoadApplyOption(Arguments& args, bool applyByDefault);
const wchar_t* ConvertInheritTypeToUnicode(HidPsInheritTypes type);

View File

@ -159,6 +159,7 @@
<ClCompile Include="Ignore.cpp" />
<ClCompile Include="Protect.cpp" />
<ClCompile Include="Query.cpp" />
<ClCompile Include="State.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Commands.h" />
@ -168,6 +169,7 @@
<ClInclude Include="Ignore.h" />
<ClInclude Include="Protect.h" />
<ClInclude Include="Query.h" />
<ClInclude Include="State.h" />
</ItemGroup>
<ItemGroup>
<Text Include="cli.txt" />

View File

@ -17,6 +17,9 @@
<ClCompile Include="Query.cpp">
<Filter>Commands</Filter>
</ClCompile>
<ClCompile Include="State.cpp">
<Filter>Commands</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="cli.txt" />
@ -37,6 +40,9 @@
<ClInclude Include="Query.h">
<Filter>Commands</Filter>
</ClInclude>
<ClInclude Include="State.h">
<Filter>Commands</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Commands">

View File

@ -23,53 +23,62 @@ void CommandQuery::LoadArgs(Arguments& args)
if (!args.GetNext(object))
throw WException(-2, L"Error, mismatched argument #1 for command 'query'");
if (object != L"process")
throw WException(-2, L"Error, invalid object type for command 'query'");
if (!args.GetNext(target))
throw WException(-2, L"Error, mismatched argument #2 for command 'query'");
m_targetProcId = _wtol(target.c_str());
if (!m_targetProcId)
throw WException(-2, L"Error, invalid target pid for command 'query'");
}
const wchar_t* ConvertInheritTypeToUnicode(HidPsInheritTypes type)
{
switch (type)
if (object == L"process")
{
case HidPsInheritTypes::WithoutInherit:
return L"none";
break;
case HidPsInheritTypes::InheritOnce:
return L"once";
break;
case HidPsInheritTypes::InheritAlways:
return L"always";
break;
m_queryType = EQueryType::QueryProcess;
if (!args.GetNext(target))
throw WException(-2, L"Error, mismatched argument #2 for command 'query'");
m_targetProcId = _wtol(target.c_str());
if (!m_targetProcId)
throw WException(-2, L"Error, invalid target pid for command 'query'");
}
else if (object == L"state")
{
m_queryType = EQueryType::QueryState;
}
else
{
throw WException(-2, L"Error, invalid object type for command 'query'");
}
return L"unknown";
}
void CommandQuery::PerformCommand(Connection& connection)
{
HidStatus status;
HidActiveState excludeState, protectedState;
HidPsInheritTypes excludedInherit, protectedInherit;
status = Hid_GetExcludedState(connection.GetContext(), m_targetProcId, &excludeState, &excludedInherit);
if (!HID_STATUS_SUCCESSFUL(status))
throw WException(HID_STATUS_CODE(status), L"Error, query ignored state rejected");
if (m_queryType == EQueryType::QueryState)
{
HidActiveState state;
status = Hid_GetProtectedState(connection.GetContext(), m_targetProcId, &protectedState, &protectedInherit);
if (!HID_STATUS_SUCCESSFUL(status))
throw WException(HID_STATUS_CODE(status), L"Error, query protected state rejected");
status = Hid_GetState(connection.GetContext(), &state);
if (!HID_STATUS_SUCCESSFUL(status))
throw WException(HID_STATUS_CODE(status), L"Error, query state rejected");
wcerr << L"Ignored state:" << (excludeState == HidActiveState::StateEnabled ? L"true" : L"false")
<< L", inherit:" << ConvertInheritTypeToUnicode(excludedInherit) << endl;
wcerr << L"Protected state:" << (protectedState == HidActiveState::StateEnabled ? L"true" : L"false")
<< L", inherit:" << ConvertInheritTypeToUnicode(protectedInherit) << endl;
wcerr << L"Driver state:" << (state == HidActiveState::StateEnabled ? L"enabled" : L"disabled") << endl;
wcout << L"status:ok;state:" << (state == HidActiveState::StateEnabled ? 1 : 0) << endl;
}
else if (m_queryType == EQueryType::QueryProcess)
{
HidActiveState excludeState, protectedState;
HidPsInheritTypes excludedInherit, protectedInherit;
wcout << L"status:ok;ignored:" << excludeState << L"," << excludedInherit
<< L";protected:" << protectedState << L"," << protectedInherit << endl;
status = Hid_GetExcludedState(connection.GetContext(), m_targetProcId, &excludeState, &excludedInherit);
if (!HID_STATUS_SUCCESSFUL(status))
throw WException(HID_STATUS_CODE(status), L"Error, query ignored state rejected");
status = Hid_GetProtectedState(connection.GetContext(), m_targetProcId, &protectedState, &protectedInherit);
if (!HID_STATUS_SUCCESSFUL(status))
throw WException(HID_STATUS_CODE(status), L"Error, query protected state rejected");
wcerr << L"Ignored state:" << (excludeState == HidActiveState::StateEnabled ? L"true" : L"false")
<< L", inherit:" << ConvertInheritTypeToUnicode(excludedInherit) << endl;
wcerr << L"Protected state:" << (protectedState == HidActiveState::StateEnabled ? L"true" : L"false")
<< L", inherit:" << ConvertInheritTypeToUnicode(protectedInherit) << endl;
wcout << L"status:ok;ignored:" << excludeState << L"," << excludedInherit
<< L";protected:" << protectedState << L"," << protectedInherit << endl;
}
}

View File

@ -4,9 +4,15 @@
class CommandQuery : public ICommand
{
enum EQueryType {
QueryProcess,
QueryState,
};
const wchar_t* m_command = nullptr;
HidProcId m_targetProcId;
EQueryType m_queryType;
HidProcId m_targetProcId;
public:

44
HiddenCLI/State.cpp Normal file
View File

@ -0,0 +1,44 @@
#include "State.h"
#include <iostream>
using namespace std;
CommandState::CommandState() : m_command(L"/state")
{
}
CommandState::~CommandState()
{
}
bool CommandState::CompareCommand(std::wstring& command)
{
return (command == m_command);
}
void CommandState::LoadArgs(Arguments& args)
{
wstring state, enable;
if (!args.GetNext(state))
throw WException(-2, L"Error, mismatched argument #1 for command 'state'");
if (state == L"on")
m_state = true;
else if (state == L"off")
m_state = false;
else
throw WException(-2, L"Error, mismatched argument #2 for command 'state'");
}
void CommandState::PerformCommand(Connection& connection)
{
HidStatus status;
status = Hid_SetState(connection.GetContext(), (m_state ? HidActiveState::StateEnabled : HidActiveState::StateDisabled));
if (!HID_STATUS_SUCCESSFUL(status))
throw WException(HID_STATUS_CODE(status), L"Error, command 'state' rejected");
wcerr << L"Command 'state' successful" << endl;
wcout << L"status:ok" << endl;
}

19
HiddenCLI/State.h Normal file
View File

@ -0,0 +1,19 @@
#pragma once
#include "Commands.h"
class CommandState : public ICommand
{
const wchar_t* m_command = nullptr;
bool m_state;
public:
CommandState();
virtual ~CommandState();
virtual bool CompareCommand(std::wstring& command);
virtual void LoadArgs(Arguments& args);
virtual void PerformCommand(Connection& connection);
};

View File

@ -10,7 +10,10 @@ connection:
commands:
state <on|off>
Enable or disable hidden
Enable or disable enforcement (hiding, protecting, ignoring etc)
query state
Get enforcement state
hide <file|dir|regval|regkey> <%path%>
Hide filesystem or registry object by path
@ -21,7 +24,6 @@ commands:
unhide <file|dir|regval|regkey> <%ruleid%>
Unhide all filesystem or registry object by selected type and rule ID
ignore image [inherit:<none|always|once>] [apply:<fornew|forall>] <%path%>
Set rule that allows to see hidden filesystem and registry objects for processes with specific image path
@ -37,7 +39,6 @@ commands:
unignore pid <%pid%>
Turn off abillity to see hidden filesystem and registry objects for specific process by PID
protect image [inherit:<none|always|once>] [apply:<fornew|forall>] <%path%>
Set rule that allows to enable process protection for processes with specific image path
@ -54,4 +55,4 @@ commands:
Turn off protection for specific process by PID
query process <%pid%>
Query information about state of the process by PID
Query information about state of the process by PID

View File

@ -249,6 +249,46 @@ void FreeNormalizedPath(wchar_t* normalized)
free(normalized);
}
HidStatus SendIoctl_QueryDriverStatusPacket(PHidContextInternal context, HidActiveState* state)
{
Hid_DriverStatus packet = { 0 };
Hid_StatusPacket result;
DWORD returned;
if (!DeviceIoControl(context->hdevice, HID_IOCTL_GET_DRIVER_STATE, &packet, sizeof(packet), &result, sizeof(result), &returned, NULL))
return HID_SET_STATUS(FALSE, GetLastError());
if (returned != sizeof(result))
return HID_SET_STATUS(FALSE, ERROR_INVALID_PARAMETER);
if (!NT_SUCCESS(result.status))
return HID_SET_STATUS(FALSE, result.status);
*state = (result.info.state ? HidActiveState::StateEnabled : HidActiveState::StateDisabled);
return HID_SET_STATUS(TRUE, 0);
}
HidStatus SendIoctl_SetDriverStatusPacket(PHidContextInternal context, HidActiveState state)
{
Hid_DriverStatus packet;
Hid_StatusPacket result;
DWORD returned;
packet.state = (state == HidActiveState::StateEnabled ? 1 : 0);
packet.reserved = 0;
if (!DeviceIoControl(context->hdevice, HID_IOCTL_SET_DRIVER_STATE, &packet, sizeof(packet), &result, sizeof(result), &returned, NULL))
return HID_SET_STATUS(FALSE, GetLastError());
if (returned != sizeof(result))
return HID_SET_STATUS(FALSE, ERROR_INVALID_PARAMETER);
if (!NT_SUCCESS(result.status))
return HID_SET_STATUS(FALSE, result.status);
return HID_SET_STATUS(TRUE, 0);
}
HidStatus SendIoctl_HideObjectPacket(PHidContextInternal context, const wchar_t* path, unsigned short type, HidObjId* objId)
{
PHid_HideObjectPacket hide;
@ -498,14 +538,12 @@ HidStatus SendIoctl_SetPsStatePacket(PHidContextInternal context, HidProcId proc
HidStatus _API Hid_SetState(HidContext context, HidActiveState state)
{
PHidContextInternal cntx = (PHidContextInternal)context;
return HID_SET_STATUS(FALSE, ERROR_CALL_NOT_IMPLEMENTED);
return SendIoctl_SetDriverStatusPacket((PHidContextInternal)context, state);
}
HidStatus _API Hid_GetState(HidContext context, HidActiveState* pstate)
{
PHidContextInternal cntx = (PHidContextInternal)context;
return HID_SET_STATUS(FALSE, ERROR_CALL_NOT_IMPLEMENTED);
return SendIoctl_QueryDriverStatusPacket((PHidContextInternal)context, pstate);
}
// Registry hiding interface