📄 hookprocess.cpp
字号:
#include "HookProcess.h"
/////////////////////////////////////////////////////////////////////////////////////////
extern "C"
{
typedef NTSTATUS (*NtQuerySystemInfo)(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
NtQuerySystemInfo TrueNtQuerySystemInfo;
NTSTATUS NewNtQuerySystemInfo(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
NTSTATUS CompleteIrp( PIRP Irp, NTSTATUS status, ULONG info);
}
/*NTSTATUS HookProcessIrpRoutine(PIRP pIrp);
NTSTATUS AddProcessName(WCHAR* pBuf,ULONG buf_size,ULONG out_buf_size,PULONG BytesTxd);
NTSTATUS DelProcessName(WCHAR* pBuf,ULONG buf_size,ULONG out_buf_size,PULONG BytesTxd);
NTSTATUS ClearProcessNames(WCHAR* pBuf,ULONG buf_size,ULONG out_buf_size,PULONG BytesTxd);
NTSTATUS QueryProcessNames(WCHAR* pBuf,ULONG buf_size,ULONG out_buf_size,PULONG BytesTxd);
bool CheckProcessName(PUNICODE_STRING pString);
*/
// Synchronization object
static wrSync sProcessWRSync;
// Process names to hide
typedef std::vector<UNICODE_STRING> ProcNames;
static ProcNames sProcNames;
/////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS AddProcessName(WCHAR* pBuf,ULONG buf_size,ULONG out_buf_size,PULONG BytesTxd)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
DbgPrint("-HideDriver- Add Process Name - Input string: %ws\n",pBuf);
UNICODE_STRING myUStr;
WCHAR* pBuf_temp = new WCHAR[buf_size/2];
memcpy(pBuf_temp,pBuf,buf_size);
RtlInitUnicodeString(&myUStr,pBuf_temp);
sProcessWRSync.WaitToWrite();
sProcNames.push_back(myUStr);
sProcessWRSync.Done();
*pBuf=HOOK_SUCCESS; // SUCCESS
*BytesTxd = 1;
return STATUS_SUCCESS;
}
NTSTATUS DelProcessName(WCHAR* pBuf,ULONG buf_size,ULONG out_buf_size,PULONG BytesTxd)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
DbgPrint("-HideDriver- Del Process Name - Input string: %ws\n",pBuf);
UNICODE_STRING myUStr;
RtlInitUnicodeString(&myUStr,pBuf);
sProcessWRSync.WaitToWrite();
ProcNames::iterator it = sProcNames.begin();
while(sProcNames.end() != it)
{
if(RtlCompareUnicodeString(&myUStr,&(*it),FALSE) == 0)
{
// Cleanup buffer
delete[] (*it).Buffer;
// Delete from array
sProcNames.erase(it);
sProcessWRSync.Done();
*pBuf=HOOK_SUCCESS;
*BytesTxd = 1;
return STATUS_SUCCESS;
}
++it;
}
sProcessWRSync.Done();
return STATUS_INVALID_DEVICE_REQUEST;
}
NTSTATUS ClearProcessNames(WCHAR* pBuf,ULONG buf_size,ULONG out_buf_size,PULONG BytesTxd)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
DbgPrint("-HideDriver- Clear Process Names\n");
sProcessWRSync.WaitToWrite();
ProcNames::iterator it = sProcNames.begin();
while(sProcNames.end() != it)
{
delete[] (*it).Buffer;
++it;
}
sProcNames.clear();
sProcessWRSync.Done();
*pBuf=HOOK_SUCCESS;
*BytesTxd = 1;
return STATUS_SUCCESS;
}
NTSTATUS QueryProcessNames(WCHAR* pBuf,ULONG buf_size,ULONG out_buf_size,PULONG BytesTxd)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
DbgPrint("-HideDriver- Query Process Names\n");
sProcessWRSync.WaitToRead();
ULONG nIndex=0;
ProcNames::iterator it = sProcNames.begin();
while(sProcNames.end() != it)
{
size_t str_size = (*it).Length;
if((str_size + nIndex) > out_buf_size)
{
sProcessWRSync.Done();
return STATUS_INVALID_PARAMETER;
}
memcpy((char*)pBuf + nIndex,(*it).Buffer,str_size);
nIndex+=str_size;
memcpy((char*)pBuf + nIndex,L"\n",2);
nIndex+=2;
++it;
}
sProcessWRSync.Done();
memcpy((char*)pBuf + nIndex,L"\0",2);
nIndex+=2;
*BytesTxd = nIndex;
return STATUS_SUCCESS;
}
NTSTATUS HookProcessIrpRoutine(PIRP pIrp)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
NTSTATUS status = STATUS_SUCCESS;
ULONG BytesTxd =0; // Number of transmitted,received bytes
PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(pIrp);
// Getting the IOCTL code
ULONG ControlCode =
IrpStack->Parameters.DeviceIoControl.IoControlCode;
// Getting the exchange method
ULONG method = ControlCode & 0x03;
if(method!=METHOD_BUFFERED)
return CompleteIrp(pIrp,STATUS_INVALID_PARAMETER,BytesTxd);
// input buffer size
ULONG InputLength =
IrpStack->Parameters.DeviceIoControl.InputBufferLength;
// output buffer size
ULONG OutputLength =
IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
// if there is no buffer generate the error
if( OutputLength < 1 || InputLength < 1)
return CompleteIrp(pIrp,STATUS_INVALID_PARAMETER,BytesTxd);
WCHAR *buff;
buff = (PWCHAR)pIrp->AssociatedIrp.SystemBuffer;
switch( ControlCode)
{
case IOCTL_ADD_PROCESS_NAME:
status = AddProcessName(buff,InputLength,OutputLength,&BytesTxd); break;
case IOCTL_DEL_PROCESS_NAME:
status = DelProcessName(buff,InputLength,OutputLength,&BytesTxd); break;
case IOCTL_CLEAR_PROCESS_NAME:
status = ClearProcessNames(buff,InputLength,OutputLength,&BytesTxd); break;
case IOCTL_QUERY_PROCESS_NAME:
status = QueryProcessNames(buff,InputLength,OutputLength,&BytesTxd); break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
}
return CompleteIrp(pIrp,status,BytesTxd);
}
void HookProcessInit(HookMng& refHookMng,QueryMng& refQueryMng)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
UNICODE_STRING funcUnicodeStr_process;
RtlInitUnicodeString(&funcUnicodeStr_process,L"ZwQuerySystemInformation");
//
std::auto_ptr<Hook> pNewHook(
CreateHook( NewNtQuerySystemInfo,
&funcUnicodeStr_process));
TrueNtQuerySystemInfo = (NtQuerySystemInfo)pNewHook->mpTrueFuncPtr;
if(!refHookMng.QueueHook(*pNewHook))
DbgPrint("Hook installing error2\n");
//
refQueryMng.AddRoutine(IOCTL_ADD_PROCESS_NAME,&HookProcessIrpRoutine);
refQueryMng.AddRoutine(IOCTL_DEL_PROCESS_NAME,&HookProcessIrpRoutine);
refQueryMng.AddRoutine(IOCTL_CLEAR_PROCESS_NAME,&HookProcessIrpRoutine);
refQueryMng.AddRoutine(IOCTL_QUERY_PROCESS_NAME,&HookProcessIrpRoutine);
}
void HookProcessExit()
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
sProcessWRSync.WaitToWrite();
ProcNames::iterator it = sProcNames.begin();
while(sProcNames.end() != it)
{
delete[] (*it).Buffer;
++it;
}
sProcNames.clear();
sProcessWRSync.Done();
}
bool CheckProcessName(UNICODE_STRING* pString1)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
sProcessWRSync.WaitToRead();
ProcNames::iterator it = sProcNames.begin();
while(sProcNames.end() != it)
{
if(RtlCompareUnicodeString(pString1,&(*it),FALSE) == 0)
{
sProcessWRSync.Done();
return true;
}
++it;
}
sProcessWRSync.Done();
return false;
}
NTSTATUS NewNtQuerySystemInfo(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
)
/*++
Routine Description:
Function call everytime 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( CheckProcessName(&(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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -