阅读:2759回复:9
SOS,请指教一下
为什么下面这段程序不能完成目录隐藏呢?请指点一下!谢谢!
目标 - 隐藏C:\\Apc\\TestH case IRP_MJ_DIRECTORY_CONTROL: if( currentIrpStack->MinorFunction == IRP_MN_QUERY_DIRECTORY ) { if( strncmp( fullPathName, \"C:\\\\Apc\\0\", 6 ) == 0 ) { ApcHookHideFile( Irp, currentIrpStack ); } } break; VOID ApcHookHideFile( PIRP Irp, PIO_STACK_LOCATION currentIrpStack ) { PFILE_BOTH_DIR_INFORMATION QueryBuffer = NULL; ULONG offset = 0; ULONG currentPosition = 0; ULONG bufferLength = currentIrpStack->Parameters.QueryFile.Length; ULONG NewLength = 0; WCHAR fileNameToRemove[] = L\"TestH\"; PUCHAR startEntryToRemove = NULL; PUCHAR startNextEntry = NULL; NewLength = bufferLength; QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer; if( QueryBuffer->NextEntryOffset > bufferLength ) return; do { offset = QueryBuffer->NextEntryOffset; DebugPrint( ( \"HookRoutine : QUERY_DIR : TestH - %ws 0x%d\\n\", QueryBuffer->FileName, QueryBuffer->NextEntryOffset ) ); if( wcsncmp(QueryBuffer->FileName, fileNameToRemove, 5 ) == 0 ) { startEntryToRemove = (PUCHAR) QueryBuffer; startNextEntry = (PUCHAR) QueryBuffer + offset; RtlMoveMemory( startEntryToRemove, startNextEntry, bufferLength - currentPosition - offset ); NewLength -= offset; break; } currentPosition += offset; QueryBuffer= (PFILE_BOTH_DIR_INFORMATION) ( (PUCHAR) QueryBuffer + offset ); } while( offset != 0 ); Irp->IoStatus.Information = NewLength; } |
|
最新喜欢:fly_fl...
|
沙发#
发布于:2002-05-05 15:46
从FILEMON改起的吧.
如果没有猜错, 你的处理完了之后, 估计没有自己IOCOMPLETE REQUEST , 而使用正常流程IOCALLDRIVER(PHOOKEXT->FILESYSTEM,IRP)了, 那时系统会执行正常的处理把你辛辛苦苦做的结果全部冲掉. 还有就是你跟过程序吗?应该不太难就能确认的. 除此只外, if( strncmp( fullPathName, \"C:\\\\Apc\\0\", 6 ) == 0 ) { 也不太好, 建议你用 #define HIDE_DIR_PARENT \"C:\\\\Apc\" if( _strnicmp( fullPathName, HIDE_DIR_PARENT, strlen(HIDE_DIR_PARENT))==0 ) 除非POSIX系统, 不应该区分大小写的. [编辑 - 5/5/02 作者: zdhe] [编辑 - 5/5/02 作者: zdhe] [编辑 - 5/5/02 作者: zdhe] |
|
板凳#
发布于:2002-05-05 15:48
谢谢,你的帮忙,如果有需要,找我,qq-33244209
|
|
|
地板#
发布于:2002-05-05 18:00
if( _strnicmp( fullPathName, \"C:\\\\Apc\\0\", strlen(\"C:\\\\Apc\\0\") ) == 0 ) {
ApcHookHideFile( Irp, currentIrpStack ); IoCompleteRequest( Irp, IO_NO_INCREMENT ); return STATUS_SUCCESS; } 这样做的错误更严重啊,请问如何处理? 谢谢了! |
|
|
地下室#
发布于:2002-05-05 19:04
当然严重.
应该是先IOCALLDRIVER (LOWERDRIVER), 然后在COMPLETE ROUTINE里进行分析修改呀. 否则你要修改的BUFFER谁来填呢? 在DDK的体系里, return STATUS_SUCCESS不能代表什么. 而且IRP的IO_STATUS_BLOCK也要添好.否则CALLER没法判断你的执行结果的. 你可以这样考虑. 1.如果你处理的目的是可以显示C:\\Apc\\TestH ,而不想在CMD, EXPLOERE下列出下面的子目录和文件列表, 按照现在的做法做下去可以. 2.如果你是想当BROWSER父目录C:\\Apc时, 不想列出TestH和他下面所有的东西, 得先按照正常的流程IOCALLDRIVER (LOWERDRIVER), 然后在修改取得后的东西. 还有就是 你的目的和选择的方法是什么? 具体代码正确与否, 只是看除非明显的CODING错误一般不会有什么结果的, 调上面要下工夫. 看你的做法,似乎是按照2来做. 那么先让下层文件系统取得结果是必要的. 然后, 你在返回之前, 把TestH 删除掉也就是了. 除此之外, 只考虑考虑QueryFile似乎有问题, 应该也考虑QUERY_DIRECTORY吧. dir *.txt 时, 用的好象不是QueryFile. 使用QUERY_DIRECTORY才对. FileInformationClass没有分析,不能简单的用 QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer 晚上我抽点时间调调看. 假期就完了, 能帮大家多少忙我也不知. 好运吧. |
|
5楼#
发布于:2002-05-05 20:35
谢谢!我就是做的第二个方案,我也很清楚,但是好象我做了以后并不能成功,谢谢你帮忙,如果有可能,请针对源码,给我一些指导和建议!
|
|
|
6楼#
发布于:2002-05-06 01:41
搞定了, 我只在FAT上简单的测试了一下.不错, 写的很乱, 凑和着看吧.
其它的情况你自己测试,如果有问题, 自己解决吧. #include \"ntddk.h\" #include \"stdarg.h\" #include \"stdio.h\" #include \"stdlib.h\" #include \"..\\exe\\ioctlcmd.h\" #include \"filemon.h\" NTSTATUS FilemonHookDirCtrlRoutine( PDEVICE_OBJECT HookDevice, IN PIRP Irp ) { PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp); PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp); PMOVE_FILE_DATA moveFile; PQUERY_DIRECTORY queryDirectory; PFILE_OBJECT FileObject; PHOOK_EXTENSION hookExt; LARGE_INTEGER dateTime; LARGE_INTEGER perfTime; PCHAR fullPathName = NULL; BOOLEAN hookCompletion=FALSE; //, createPath; CHAR controlCodeBuffer[ERRORLEN]; CHAR attributeString[ERRORLEN]; CHAR optionString[ERRORLEN]; CHAR name[PROCNAMELEN]; ULONG i; ANSI_STRING directoryFilter; PCHAR queryFilter; ULONG seqNum; KIRQL oldirql; BOOLEAN bDirObject=TRUE; FileObject = currentIrpStack->FileObject; hookExt = HookDevice->DeviceExtension; // Allocate a buffer and get the name only if we have to // if( FilterOn && hookExt->Hooked ) { //see comment in IRP_MJ_CREATE !!! GETPATHNAME( FALSE ); } // // Only log it if it passes the filter // if( hookExt->Hooked && fullPathName ) { // // If measuring absolute time go and get the timestamp. // KeQuerySystemTime( &dateTime ); perfTime = KeQueryPerformanceCounter( NULL ); // // We want to watch this IRP complete // seqNum = (ULONG) -1; // // Determine what function we\'re dealing with // FilemonGetProcess( name ); switch( currentIrpStack->MajorFunction ) { case IRP_MJ_DIRECTORY_CONTROL: { switch( currentIrpStack->MinorFunction ) { case IRP_MN_NOTIFY_CHANGE_DIRECTORY: //hookCompletion = LogRecord( TRUE, &seqNum, &dateTime, NULL, \"%s\\tIRP_MJ_DIRECTORY_CONTROL\\t%s\\tChange Notify\", name, fullPathName ); /* if ( _stricmp(fullPathName, HIDE_DIR_PARENT) ==0 || _stricmp(fullPathName, HIDE_DIR_PARENT_) ==0 ) { //it\'s querying our directory... hookCompletion = TRUE; } */ break; case IRP_MN_QUERY_DIRECTORY: queryDirectory = (PQUERY_DIRECTORY)¤tIrpStack->Parameters; queryFilter = NULL; if( queryDirectory->FileName ) { if( NT_SUCCESS( RtlUnicodeStringToAnsiString( &directoryFilter, queryDirectory->FileName, TRUE ))) { queryFilter = ExAllocatePool( PagedPool, directoryFilter.Length + 1 ); if( queryFilter ) { memcpy( queryFilter, directoryFilter.Buffer, directoryFilter.Length ); queryFilter[ directoryFilter.Length ] = 0; // // Massage DOS-internal wildcards // for( i = 0; i < strlen( queryFilter ); i++ ) { if( queryFilter == \'<\' ) queryFilter = \'*\'; else if( queryFilter == \'>\' ) queryFilter = \'?\'; } } RtlFreeAnsiString( &directoryFilter ); } } if( queryFilter ) { //hookCompletion = LogRecord( TRUE, &seqNum, &dateTime, NULL, \"%s\\tIRP_MJ_DIRECTORY_CONTROL\\t%s\\t%s: Query Filter: [%s]\", name, fullPathName, FileInformation[queryDirectory->FileInformationClass], queryFilter ); ExFreePool( queryFilter ); } else { //hookCompletion = LogRecord( TRUE, &seqNum, &dateTime, NULL, \"%s\\tIRP_MJ_DIRECTORY_CONTROL\\t%s\\t%s\", name, fullPathName, FileInformation[queryDirectory->FileInformationClass] ); } //added by zdhe... if ( _stricmp(fullPathName, HIDE_DIR_PARENT) ==0 || _stricmp(fullPathName, HIDE_DIR_PARENT_) ==0 ) { //it\'s querying our directory... hookCompletion = TRUE; } break; default: //hookCompletion = LogRecord( TRUE, &seqNum, &dateTime, NULL, \"%s\\tIRP_MJ_DIRECTORY_CONTROL\\t%s\\t\", name, fullPathName ); break; } } break; default: ASSERT(FALSE); //hookCompletion = LogRecord( TRUE, &seqNum, &dateTime, NULL, \"%s\\t*UNKNOWN* 0x%X\\t\\t\", name, currentIrpStack->MajorFunction ); break; } } else { hookCompletion = FALSE; } // // Free the buffer if we have one // if( fullPathName && fullPathName != InsufficientResources ) { ExFreeToNPagedLookasideList( &FullPathLookaside, fullPathName ); } if( !UnloadInProgress && hookCompletion ) { PCHAR pBuffer = NULL;//,pUserBuf =NULL; PFILE_BOTH_DIRECTORY_INFORMATION pDirInfo = NULL; KEVENT event; NTSTATUS ntLocalStatus; *nextIrpStack = *currentIrpStack; /* it seems there is no use of complete routine. it seems it\'s always be a syn io //event set, FilemonDirCtlHookDone will never be called... maybe lower driver // has not complete irp , just FreeIrp and return a magic value -> STATUS_MORE_PROCESSING_REQUIRED //because of this, we can modify Irp->UserBuffer directory. haha. maybe unsafe.but it really work. IoSetCompletionRoutine( Irp, FilemonDirCtlHookDone, (PVOID) &event, FALSE, FALSE, FALSE ); */ if (1 || currentIrpStack->MinorFunction == IRP_MN_QUERY_DIRECTORY ) { ntLocalStatus = IoCallDriver( hookExt->FileSystem, Irp ); }else { ntLocalStatus = Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; if (Irp->Flags & IRP_INPUT_OPERATION ) { Irp->IoStatus.Information =0; } IoCompleteRequest(Irp, IO_DISK_INCREMENT ); return ntLocalStatus ; } //ASSERT(currentIrpStack->MinorFunction == IRP_MN_QUERY_DIRECTORY ); ASSERT(NT_SUCCESS(ntLocalStatus) || ntLocalStatus == STATUS_NO_MORE_FILES); ASSERT(NT_SUCCESS(Irp->IoStatus.Status ) || Irp->IoStatus.Status == STATUS_NO_MORE_FILES); //ASSERT(Irp->IoStatus.Information >= sizeof(FILE_BOTH_DIRECTORY_INFORMATION)); //It\'s funny that lower device change our currentIrpStack->MinorFunction ->>>??? if (//currentIrpStack->MinorFunction == IRP_MN_QUERY_DIRECTORY && (NT_SUCCESS(ntLocalStatus) || ntLocalStatus == STATUS_NO_MORE_FILES) && (NT_SUCCESS(Irp->IoStatus.Status ) || Irp->IoStatus.Status == STATUS_NO_MORE_FILES) && Irp->IoStatus.Information >= sizeof(FILE_BOTH_DIRECTORY_INFORMATION)) { pBuffer /*= pUserBuf */= Irp->UserBuffer; try { DbgPrint((\"\\n -----begin dump output ...\")); pDirInfo = (PFILE_BOTH_DIRECTORY_INFORMATION )pBuffer ; while ( pDirInfo ) { char szLogBuffer[100]={0x00,}; memcpy(szLogBuffer, pDirInfo->FileName , min(pDirInfo->FileNameLength,sizeof(szLogBuffer) - 4 )); DbgPrint((\"[%S]\\n\",szLogBuffer)); if ( pDirInfo->NextEntryOffset) { pBuffer = (PCHAR )pDirInfo; pBuffer+=pDirInfo->NextEntryOffset; pDirInfo = (PFILE_BOTH_DIRECTORY_INFORMATION )pBuffer ; }else { pDirInfo =NULL; } } DbgPrint((\"-----end dump output ...\\n\")); //Begin Change Work... pDirInfo = (PFILE_BOTH_DIRECTORY_INFORMATION )Irp->UserBuffer; //if pDirInfo->NextEntryOffset ==0 , then we need not do this work.it\'s the buffer size query //first data will always be \'.\' if pDirInfo->NextEntryOffset !=0 if (pDirInfo->NextEntryOffset ) { while (pDirInfo) { //now, pDirInfo ->FileName will never be hide directory name. PFILE_BOTH_DIRECTORY_INFORMATION pNextInfo = NULL; //make sure , PCHAR pBuffer is always same with pDirInfo pBuffer = (PCHAR ) pDirInfo ; if ( pDirInfo->NextEntryOffset ) //there are following dir info { //remember pDirInfo ->FileName is Hide dir... //check next dir is our hide dir or not. pNextInfo = (PFILE_BOTH_DIRECTORY_INFORMATION) (pBuffer +pDirInfo->NextEntryOffset); DbgPrint((\"(%d, %d)\\n\", pNextInfo->FileNameLength , sizeof(WANT_HIDE_DIR_NAME) -2)); DbgPrint((\"(%s)\\n\", _wcsnicmp(WANT_HIDE_DIR_NAME, pNextInfo->FileName, pNextInfo->FileNameLength ) == 0? \"String Same\":\"String Different\")); if (pNextInfo->FileNameLength == sizeof(WANT_HIDE_DIR_NAME) -2 && _wcsnicmp(WANT_HIDE_DIR_NAME, pNextInfo->FileName, pNextInfo->FileNameLength ) == 0 ) { //pNextInfo->FileName Hit Our Hide Dir -> WANT_HIDE_DIR_NAME if ( pNextInfo->NextEntryOffset) { //pNextInfo data block should be skip so, modify it. ULONG dwBytesMove =0; PCHAR pNextNextInfo= (PCHAR) pNextInfo; pNextNextInfo += pNextInfo->NextEntryOffset; dwBytesMove = ((PCHAR) Irp->UserBuffer) + Irp->IoStatus.Information - pNextNextInfo; Irp->IoStatus.Information -= pNextInfo->NextEntryOffset; //modify output buffer size. memmove(pNextInfo, pNextNextInfo, dwBytesMove ); //Now, WANT_HIDE_DIR_NAME has been skipped. break; /* pBuffer = (PCHAR )pDirInfo; pBuffer+=pDirInfo->NextEntryOffset; pDirInfo = (PFILE_BOTH_DIRECTORY_INFORMATION )pBuffer ; */ }else { //ok , because WANT_HIDE_DIR_NAME is the last dir/file in parent directory ... we need do less thing. Irp->IoStatus.Information -= pDirInfo->NextEntryOffset; //modify output buffer size. pDirInfo->NextEntryOffset =0; //clear orginal value. skip it. break; } }else { //should not hide this file or dir. pBuffer = (PCHAR )pDirInfo; pBuffer+=pDirInfo->NextEntryOffset; pDirInfo = (PFILE_BOTH_DIRECTORY_INFORMATION )pBuffer ; } }else //there is no following dir info.. { //this is the last one in HIDE_DIR_PARENT directory, so we need not do anything. break; } } } //end change work }except(1) { ASSERT(FALSE); } } /* else if ( currentIrpStack->MinorFunction == IRP_MN_NOTIFY_CHANGE_DIRECTORY && NT_SUCCESS(ntLocalStatus) && NT_SUCCESS(Irp->IoStatus.Status ) ) { pBuffer = Irp->UserBuffer; ASSERT(FALSE); } */ return ntLocalStatus; } else { *nextIrpStack = *currentIrpStack; IoSetCompletionRoutine( Irp, FilemonDirCtlHookDone, NULL, FALSE, FALSE, FALSE ); return IoCallDriver( hookExt->FileSystem, Irp ); } } 关于必要的定义. 这个程序和MACY关系的那个是同一个SOURCE. 只改一下下面的定义就可以了. //#define DECRYPT_WHEN_READ //#define ENCRYPT_WHEN_WRITE #define HIDE_CERTERN_DIR #ifdef DECRYPT_WHEN_READ #define ENCRYPT_DIR \"C:\\\\EncryptDir\\\\\" #endif #ifdef ENCRYPT_WHEN_WRITE #ifndef ENCRYPT_DIR #define ENCRYPT_DIR \"C:\\\\EncryptDir\\\\\" #endif #endif #ifdef HIDE_CERTERN_DIR #define HIDE_DIR_PARENT \"C:\\\\HideDir\" #define HIDE_DIR_PARENT_ HIDE_DIR_PARENT\"\\\\\" #define WANT_HIDE_DIR_NAME L\"MyDir\" #endif #endif 由于调试上的原因, 我把SOURCE打散了, 一眼能够看清才好. 全SOURCE 5/7号吧. 我会放在一个大家都能拿到的地方. NTSTATUS FilemonDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { // // Determine if its a request from the GUI to us, or one that is // directed at a file system driver that we\'ve hooked // if( ((PHOOK_EXTENSION) DeviceObject->DeviceExtension)->Type == GUIINTERFACE ) { return FilemonDeviceRoutine( DeviceObject, Irp ); } else { PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp); switch ( currentIrpStack->MajorFunction) { case IRP_MJ_READ: return FilemonHookReadRoutine( DeviceObject, Irp ); case IRP_MJ_WRITE: return FilemonHookWriteRoutine( DeviceObject, Irp ); case IRP_MJ_DIRECTORY_CONTROL: return FilemonHookDirCtrlRoutine(DeviceObject, Irp ); default: return FilemonHookRoutine( DeviceObject, Irp ); } } } 你这个简单些, MACY的那个真是头疼. 本来打算花一两天时间写着玩玩的, 一上手就是将近4天. 这个五一休息的比上班还累. 下周得对付自己的工作了. BYE. |
|
7楼#
发布于:2002-05-06 01:47
谢谢,非常感谢,真的,我的主页-http://110i.8u8.com
qq-33244209 以后多联系,byebye |
|
|
8楼#
发布于:2002-05-07 10:40
上面的程序没有经得起第二轮简单测试. 修改过的放在
http://61.193.161.104:10080 自个取吧. |
|
9楼#
发布于:2002-05-08 12:59
谢谢了,我已经搞定了,谢谢
|
|
|