iniwf

风是温柔的,雨是伤心的,云是快乐的,月是多情的,爱是迷失的,恋是醉人的,情是难忘的,天是长久的,地是永恒的

Driver to Hide Processes and Files

转自http://www.codeproject.com/KB/system/hide-driver.aspx

Introduction

We are glad to introduce our project "The Hide Driver project".

The main idea of this work is to create a driver for hiding selected processes and files.

The processes selected by the user should be invisible for such applications as the Task Manager, Process Explorer, and others. In addition, they should not be available for such Windows API functions as EnumProcesses(), OpenProcess(), EnumProcessModules(), and other Process APIs. The files selected by the user should be invisible for such file managers as Windows Explorer, Far, Total Commander, etc. In addition, they should not be available for such Windows API functions as FindFile(), OpenFile(), and other File API functions.

Basic knowledge

We recommend the article "Driver Development" by Toby Opferman:

It would also be useful to look through the other articles in the series (parts 2, 3, 4, 5, 6).

Also, a lot of knowledge that helped us develop this project was obtained here:

For Russian speaking readers, we recommend these sources:

Project structure

Collapse Copy Code
.\bin - folder with binary files
.\obj - folder with intermediate files
.\src - folder with sources
|
|-> drvCppLib  - Kernel library to develop driver in C++
|-> Gui        - Win32 Application used to communicate with driver
|-> HideDriver - Kernel driver installed by Gui App. Performs main
work.
|-> TestDriver - Kernel library to run test code

How to build this solution

  1. Install the Windows Driver Developer Kit 2003: http://www.microsoft.com/whdc/devtools/ddk/default.mspx.
  2. Set the global environment variable "BASEDIR" to the path of the installed DDK.

    Computer Properties -> Advanced -> Environment Variables ->System Variables -> New.

    Like this: BASEDIR -> c:\winddk\3790. (You have to restart your computer after this.)

VS2003

If you choose Visual Studio 2003, then you can simply open HideDriver_vs7.sln and Build All.

VS2005 & VS2008

If you choose Visual Studio 2005 or 2008, you need to copy the contents of the folder C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\crt\src\intel\st_lib\ (the path depends on the Visual Studio install path) to the project folder HideDriver_source\src\drvCppLib\lib_copy\. After this, you can use HideDriver_vs8.sln in Visual Studio 2005 and HideDriver_vs9.sln Visual Studio 2008.

Project implementation

The task described in the Introduction was resolved by using one of the general ways - Hooking SSDT. A lot of information about this technology can be found in the articles mentioned in the Basic knowledge section.

Process hiding

To hide processes, we need to cut them from the list returned by NtQuerySystemInformation().

[Code from HookProcess.cpp] From Line # 451 to 512

Collapse Copy Code
NTSTATUS NewNtQuerySystemInfo(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
)
/*++
Routine Description:
Function call every time when NtQuerySystemInformation function call in the system.
For hiding process we need to change SystemInformation structure.
Arguments:
SystemInformationClass - One of the values enumerated in SYSTEM_INFORMATION_CLASS,
which indicate the kind of system information to be retrieved.
SystemInformation - A pointer to a buffer that receives the requested information.
SystemInformationLength - The size of the buffer pointed
to by the SystemInformation parameter, in bytes.
Return Value:
NT status code.
--*/
{
NTSTATUS status=TrueNtQuerySystemInfo(SystemInformationClass,
SystemInformation, SystemInformationLength, ReturnLength);
if(!NT_SUCCESS(status))return status;
if( SystemInformationClass == SystemProcessesAndThreadsInformation )
{
// convert buffer to  SYSTEM_PROCESSES_INFORMATION
SYSTEM_PROCESSES_INFORMATION*
pSystemInfo=static_cast<system_processes_information*>(SystemInformation);
ULONG PreviousDelta=0;
// The loop for enumerating process
while( pSystemInfo->NextEntryDelta != 0 )
{
// go to the next process ( idle is always the first process )
PreviousDelta = pSystemInfo->NextEntryDelta;
pSystemInfo = (SYSTEM_PROCESSES_INFORMATION*)
(((PUCHAR)pSystemInfo)+PreviousDelta);
// check if the current process need to hide
if( CheckProcess(&(pSystemInfo->ProcessName)) )
{
// go to the previous process
ULONG curentDelta=pSystemInfo->NextEntryDelta;
pSystemInfo =
(SYSTEM_PROCESSES_INFORMATION*)(((PUCHAR)pSystemInfo)-PreviousDelta);
// if the process is last:
if(curentDelta == 0 )
PreviousDelta=0;
pSystemInfo->NextEntryDelta = PreviousDelta + curentDelta;
} // if(CheckProcessName(pSystemInfo->ProcessName))
}//while(pSystemInfo->NextEntryDelta != 0)
}//    if(SystemInformationClass == SystemProcessesAndThreadsInformation)
return status;
}

File hiding

To hide a file, we need to cut it from the list returned by NtQueryDirectoryFile().

First, we choose what type of information is requested.

[Code from HookFile.cpp] From Line # 672 to 719

Collapse Copy Code
NTSTATUS NewNtQueryDirectoryFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG FileInformationLength,
IN FILE_INFORMATION_CLASS FileInformationClass,
IN BOOLEAN ReturnSingleEntry,
IN PUNICODE_STRING FileName OPTIONAL,
IN BOOLEAN RestartScan
)
/*++
Routine Description:
Function call every time when NtQueryDirectoryFile function call in the system.
For hiding files we need to change one of supported FileInformation structure.
Arguments:
Return Value:
--*/
{
NTSTATUS status=TrueNtQueryDirectoryFile(FileHandle,Event,
ApcRoutine,ApcContext,IoStatusBlock,
FileInformation,FileInformationLength,FileInformationClass,
ReturnSingleEntry, FileName , RestartScan);
if(!NT_SUCCESS(status))return status;
switch(FileInformationClass)
{
case FileDirectoryInformation:
return HideFile<pfile_directory_information>(FileHandle,FileInformation);
case FileFullDirectoryInformation:
return HideFile<pfile_full_directory_information>(FileHandle,FileInformation);
case FileBothDirectoryInformation:
return HideFile<pfile_both_directory_information>(FileHandle,FileInformation);
case FileNamesInformation:
return HideFile<pfile_names_information>(FileHandle,FileInformation);
case FileIdBothDirectoryInformation: // Used by Vista explorer
return HideFile<pfile_id_both_dir_information>(FileHandle,FileInformation);
case FileIdFullDirectoryInformation: // Used by Vista explorer
return HideFile<pfile_id_full_dir_information>(FileHandle,FileInformation);
default:return status;
}
}

When we know what type of information is requested, we can cut the process from the list.

[Code from HookFile.cpp] From Line # 572 - 719

Collapse Copy Code
template<class>
NTSTATUS HideFile(HANDLE FileHandle,PVOID FileInformation)
/*++
Routine Description:
Hides selected files
Arguments:
Return Value:
--*/
{
ULONG PreviousDelta=0;
UNICODE_STRING UnicodeFileName;
RtlInitUnicodeString(&UnicodeFileName,NULL);
T pFileInfo=reinterpret_cast<t>(FileInformation);
// The loop for finding and remounting files, 
// which should be hided, from the array
bool pass_me_once=true;
while( (pFileInfo->NextEntryOffset != 0) || pass_me_once)
{
if(pass_me_once)
pass_me_once=false;
else
{
// move to the next file in the array
PreviousDelta = pFileInfo->NextEntryOffset;
pFileInfo = (T)(((PUCHAR)pFileInfo)+pFileInfo->NextEntryOffset);
}
UnicodeFileName.Buffer = pFileInfo->FileName;
UnicodeFileName.Length = pFileInfo->FileNameLength;
UnicodeFileName.MaximumLength = pFileInfo->FileNameLength;
if(!CheckFile(&UnicodeFileName,FileHandle))
continue;
// if the file is first
if(PreviousDelta == 0)
{
// if there are no any file
if( pFileInfo->NextEntryOffset == 0 )
return STATUS_NO_MORE_FILES;
//if other files exist, erasing current file 
//by moving the remain array`s elements to the beginning
ULONG shift = pFileInfo->NextEntryOffset;
//Calculate the buffer size
ULONG totalSize=0;
T ptempFileInfo=(T)pFileInfo;
while(ptempFileInfo->NextEntryOffset != 0)
{
// calculate size
totalSize+=ptempFileInfo->NextEntryOffset;
// shift to the next file in the array
ptempFileInfo = (T)(((PUCHAR)ptempFileInfo)+
ptempFileInfo->NextEntryOffset);
}
// subtract the size of the first element in the array
size_t MoveSize = (size_t)(totalSize-shift);
// add the size of the last element
MoveSize += sizeof(*ptempFileInfo);
// add the Filename`s length of the last element
MoveSize += ptempFileInfo->FileNameLength;
//we already have definition WCHAR FileName[1](2 bytes)
//so we need delete it from general sum
MoveSize -= 2;
// shift array to one element
memcpy((PVOID)pFileInfo,(PUCHAR)pFileInfo+(size_t)(shift),MoveSize);
//start the loop from the beginning
pass_me_once=true;
PreviousDelta = 0;
continue;
}
// if the file isn`t the first,
// save the current offset
ULONG curentDelta=pFileInfo->NextEntryOffset;
// go to one file back
pFileInfo = (T)(((PUCHAR)pFileInfo)-PreviousDelta);
// if the file is the last
if(curentDelta == 0 )
{
// set the offset in 0
// as the last file in array
pFileInfo->NextEntryOffset = 0;
break;
}
//if the file isn`t the last, hide file and set additional offset
pFileInfo->NextEntryOffset = PreviousDelta + curentDelta;
}//while(pFileInfo->NextEntryDelta != 0)
return STATUS_SUCCESS;
}

GUI application

The GUI application enables a user to choose processes or/and files for hiding in an easy way. In the attached file, you can find a sample of such an application. It was developed using MFC.

But, it should be mentioned here that you can create your own GUI application. IOCTLs and the DeviceIoCotrol() routine should be used for communication between the user-mode application and the driver.

You can find additional information about such communication implementations in the article: Driver Development Part 2: Introduction to Implementing IOCTLs.

In the code below, all IOCTLs which can be used have been mentioned:

Collapse Copy Code
#define IOCTL_ADD_PROCESS_NAME CTL_CODE( \
FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
Format of input string must be ¬process_name_to_hide;user_name;process_name
or ¬process_name_to_hide;*;*
where:
process_name_to_hide – process name to hide; can be for ex. *.*
user_name           - user' name, which mustn’t see process
process_name       - process' name, which mustn’t see process
#define IOCTL_DEL_PROCESS_NAME CTL_CODE( \
FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
Format of input string must be process_name
where:
process_name         - process' name, which should be deleted from the list
#define IOCTL_CLEAR_PROCESS_NAME CTL_CODE( \
FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
Input string should be empty.
#define IOCTL_QUERY_PROCESS_NAME CTL_CODE( \
FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)
Format of output string is process prosess_name\nprocess_name\n…\0
// File hooks IOCTLs
#define IOCTL_ADD_FILE_NAME CTL_CODE( \
FILE_DEVICE_UNKNOWN, 0x901, METHOD_BUFFERED, FILE_ANY_ACCESS)
Format of input string must be file_name_to_hide;user_name;process_name
or file_name_to_hide;*;*
where:
file_name_to_hide    – file name to hide; can be for ex. *.*
user_name           - user' name, which mustn’t see process
process_name       - process' name, which mustn’t see process
#define IOCTL_DEL_FILE_NAME CTL_CODE( \
FILE_DEVICE_UNKNOWN, 0x902, METHOD_BUFFERED, FILE_ANY_ACCESS)
Format of input string must be file_name
where:
file_name            - file' name, which should be deleted from the list
#define IOCTL_CLEAR_FILE_NAME CTL_CODE( \
FILE_DEVICE_UNKNOWN, 0x903, METHOD_BUFFERED, FILE_ANY_ACCESS)
Input string should be empty.
#define IOCTL_QUERY_FILE_NAME CTL_CODE( \
FILE_DEVICE_UNKNOWN, 0x904, METHOD_BUFFERED, FILE_ANY_ACCESS)
Format of output string is process file_name\nfile_name\n…\0

Documentation and additional info

Documentation for the project as well as additional information can be found at the Apriorit Education page.

History

21/01/2009

  • Initial version of this article.

12/02/2009

  • Added possibility to build the solution in VS2003, VS2005, and VS2008.
  • Added the topic "How to build this solution".

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

posted on 2009-04-11 23:52 iniwf 阅读(1274) 评论(0)  编辑 收藏 引用 所属分类: 驱动


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

统计

常用链接

留言簿(2)

随笔分类

随笔档案

收藏夹

IT技术

积分与排名

最新评论

阅读排行榜

评论排行榜