yuke
驱动牛犊
驱动牛犊
  • 注册日期2001-09-02
  • 最后登录2009-04-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
阅读:2759回复:9

SOS,请指教一下

楼主#
更多 发布于:2002-05-05 15:22
为什么下面这段程序不能完成目录隐藏呢?请指点一下!谢谢!
目标 - 隐藏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_flyfly_fl...
[color=blue]
zdhe
驱动太牛
驱动太牛
  • 注册日期2001-12-26
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分72362分
  • 威望362260点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于: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]
yuke
驱动牛犊
驱动牛犊
  • 注册日期2001-09-02
  • 最后登录2009-04-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-05-05 15:48
谢谢,你的帮忙,如果有需要,找我,qq-33244209
[color=blue]
yuke
驱动牛犊
驱动牛犊
  • 注册日期2001-09-02
  • 最后登录2009-04-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
地板#
发布于: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;
}

这样做的错误更严重啊,请问如何处理?
谢谢了!
[color=blue]
zdhe
驱动太牛
驱动太牛
  • 注册日期2001-12-26
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分72362分
  • 威望362260点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
地下室#
发布于: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


晚上我抽点时间调调看. 假期就完了, 能帮大家多少忙我也不知.

好运吧.
yuke
驱动牛犊
驱动牛犊
  • 注册日期2001-09-02
  • 最后登录2009-04-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-05-05 20:35
谢谢!我就是做的第二个方案,我也很清楚,但是好象我做了以后并不能成功,谢谢你帮忙,如果有可能,请针对源码,给我一些指导和建议!
[color=blue]
zdhe
驱动太牛
驱动太牛
  • 注册日期2001-12-26
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分72362分
  • 威望362260点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
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)&currentIrpStack->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.
yuke
驱动牛犊
驱动牛犊
  • 注册日期2001-09-02
  • 最后登录2009-04-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-05-06 01:47
谢谢,非常感谢,真的,我的主页-http://110i.8u8.com
qq-33244209 以后多联系,byebye
[color=blue]
zdhe
驱动太牛
驱动太牛
  • 注册日期2001-12-26
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分72362分
  • 威望362260点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
8楼#
发布于:2002-05-07 10:40
上面的程序没有经得起第二轮简单测试. 修改过的放在
http://61.193.161.104:10080
自个取吧.
yuke
驱动牛犊
驱动牛犊
  • 注册日期2001-09-02
  • 最后登录2009-04-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-05-08 12:59
谢谢了,我已经搞定了,谢谢
[color=blue]
游客

返回顶部