Ntfs!NtfsGetHighestVcn函数分析--NTFS源代码分析

第一部分:

;   Attribute Form Codes

RESIDENT_FORM       EQU 0
NONRESIDENT_FORM    EQU 1


        if (Attribute->FormCode == NONRESIDENT_FORM) {

            ListEntry->LowestVcn = Attribute->Form.Nonresident.LowestVcn;
        }

第二部分:

1: kd> dt Attribute_RECORD_HEADER -r
Ntfs!ATTRIBUTE_RECORD_HEADER
   +0x000 TypeCode         : Uint4B
   +0x004 RecordLength     : Uint4B
   +0x008 FormCode         : UChar
   +0x009 NameLength       : UChar
   +0x00a NameOffset       : Uint2B
   +0x00c Flags            : Uint2B
   +0x00e Instance         : Uint2B
   +0x010 Form             : __unnamed
      +0x000 Resident         : __unnamed
         +0x000 ValueLength      : Uint4B
         +0x004 ValueOffset      : Uint2B
         +0x006 ResidentFlags    : UChar
         +0x007 Reserved         : UChar
      +0x000 Nonresident      : __unnamed
         +0x000 LowestVcn        : Int8B
         +0x008 HighestVcn       : Int8B
         +0x010 MappingPairsOffset : Uint2B
         +0x012 CompressionUnit  : UChar
         +0x013 Reserved         : [5] UChar
         +0x018 AllocatedLength  : Int8B
         +0x020 FileSize         : Int8B
         +0x028 ValidDataLength  : Int8B
         +0x030 TotalAllocated   : Int8B


第三部分:例子:

1: kd>  dx -id 0,0,899a2278 -r1 ((Ntfs!_FILE_RECORD_SEGMENT_HEADER *)0xc4313400)
((Ntfs!_FILE_RECORD_SEGMENT_HEADER *)0xc4313400)                 : 0xc4313400 [Type: _FILE_RECORD_SEGMENT_HEADER *]
    [+0x000] MultiSectorHeader [Type: _MULTI_SECTOR_HEADER]
    [+0x008] Lsn              : {123755220} [Type: _LARGE_INTEGER]
    [+0x010] SequenceNumber   : 0x1 [Type: unsigned short]
    [+0x012] ReferenceCount   : 0x2 [Type: unsigned short]
    [+0x014] FirstAttributeOffset : 0x38 [Type: unsigned short]
    [+0x016] Flags            : 0x1 [Type: unsigned short]
    [+0x018] FirstFreeByte    : 0x1e0 [Type: unsigned long]
    [+0x01c] BytesAvailable   : 0x400 [Type: unsigned long]
    [+0x020] BaseFileRecordSegment [Type: _MFT_SEGMENT_REFERENCE]
    [+0x028] NextAttributeInstance : 0x7 [Type: unsigned short]
    [+0x02a] SegmentNumberHighPart : 0x0 [Type: unsigned short]
    [+0x02c] SegmentNumberLowPart : 0x274d [Type: unsigned long]
    [+0x030] UpdateArrayForCreateOnly [Type: unsigned short [1]]
1: kd> dt Attribute_RECORD_HEADER 0xc4313000+0x38
Ntfs!ATTRIBUTE_RECORD_HEADER
   +0x000 TypeCode         : 0x10
   +0x004 RecordLength     : 0x60
   +0x008 FormCode         : 0 ''
   +0x009 NameLength       : 0 ''
   +0x00a NameOffset       : 0
   +0x00c Flags            : 0
   +0x00e Instance         : 0
   +0x010 Form             : __unnamed
1: kd> dt Attribute_RECORD_HEADER 0xc4313400+0x38+60
Ntfs!ATTRIBUTE_RECORD_HEADER
   +0x000 TypeCode         : 0x30
   +0x004 RecordLength     : 0x78
   +0x008 FormCode         : 0 ''
   +0x009 NameLength       : 0 ''
   +0x00a NameOffset       : 0
   +0x00c Flags            : 0
   +0x00e Instance         : 6
   +0x010 Form             : __unnamed
1: kd> dt Attribute_RECORD_HEADER 0xc4313400+0x38+60+78
Ntfs!ATTRIBUTE_RECORD_HEADER
   +0x000 TypeCode         : 0x30
   +0x004 RecordLength     : 0x80
   +0x008 FormCode         : 0 ''
   +0x009 NameLength       : 0 ''
   +0x00a NameOffset       : 0
   +0x00c Flags            : 0
   +0x00e Instance         : 5
   +0x010 Form             : __unnamed


第四部分:

1: kd> dt Attribute_RECORD_HEADER 0xc4313400+0x38+60+78+80
Ntfs!ATTRIBUTE_RECORD_HEADER
   +0x000 TypeCode         : 0x80
   +0x004 RecordLength     : 0x48
   +0x008 FormCode         : 0x1 ''                //+0x008 FormCode         : 0x1 ''
   +0x009 NameLength       : 0 ''
   +0x00a NameOffset       : 0
   +0x00c Flags            : 0
   +0x00e Instance         : 4
   +0x010 Form             : __unnamed
1: kd> dd 0xc4313400+0x38+60+78+80
c4313590  00000080 00000048 00000001 00040000
c43135a0  00000000 00000000 00000000 00000000
c43135b0  00000040 00000000 00001000 00000000
c43135c0  00000603 00000000 00000603 00000000
c43135d0  902d0131 00010050

      +0x000 Nonresident      : __unnamed
         +0x000 LowestVcn        : Int8B        00000000 00000000
         +0x008 HighestVcn       : Int8B        00000000 00000000
         +0x010 MappingPairsOffset : Uint2B    0040
         +0x012 CompressionUnit  : UChar
         +0x013 Reserved         : [5] UChar
         +0x018 AllocatedLength  : Int8B        00001000 00000000
         +0x020 FileSize         : Int8B        00000603 00000000
         +0x028 ValidDataLength  : Int8B        00000603 00000000
         +0x030 TotalAllocated   : Int8B        902d0131 00010050

    31    01    2d    90    50    00    01    00


        VcnBytes = *ch & 0xF;                        1
        LcnBytes = (*ch++ >> 4) & 0xF;  // avoid sign extended case        3
    0x1        是VCN号
    0x50902d        是LCN号

第五部分:

    MappingPairs = (PCHAR)Attribute + (ULONG)Attribute->Form.Nonresident.MappingPairsOffset;
    HighestVcn = NtfsGetHighestVcn( IrpContext,
                                    Attribute->Form.Nonresident.LowestVcn,
                                    (PCHAR)Attribute + (ULONG)Attribute->RecordLength,
                                    MappingPairs );
第六部分:

VCN
NtfsGetHighestVcn (
    IN PIRP_CONTEXT IrpContext,
    IN VCN LowestVcn,
    IN PCHAR EndOfMappingPairs,
    IN PCHAR MappingPairs
    )
{
    VCN CurrentVcn, NextVcn;
    ULONG VcnBytes, LcnBytes;
    LONGLONG Change;
    PCHAR ch = MappingPairs;
    PCHAR VcnStart;

    PAGED_CODE();

    //
    //  Implement the decompression algorithm, as defined in ntfs.h.
    //

    NextVcn = LowestVcn;
    ch = MappingPairs;

    //
    //  Loop to process mapping pairs.
    //

    while ((ch < EndOfMappingPairs) && !IsCharZero(*ch)) {

        //
        // Set Current Vcn from initial value or last pass through loop.
        //

        CurrentVcn = NextVcn;

        //
        //  Extract the counts from the two nibbles of this byte.
        //

        VcnBytes = *ch & 0xF;
        LcnBytes = (*ch++ >> 4) & 0xF;  // avoid sign extended case

        VcnStart = ch;

        //
        //  Calculate next mapping pair location first and check for buffer overrun
        //

        ch += VcnBytes + LcnBytes;

        //
        //  Extract the Vcn change (use of RtlCopyMemory works for little-Endian)
        //  and update NextVcn.
        //

        Change = 0;

        if ((ch > EndOfMappingPairs) ||
            VcnBytes > 8 ||
            LcnBytes > 8 ||
            IsCharLtrZero(*(VcnStart + VcnBytes - 1))) {

            NtfsRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR, NULL, NULL );
        }

        RtlCopyMemory( &Change, VcnStart, VcnBytes );
        NextVcn = NextVcn + Change;
    }

    Change = NextVcn - 1;
    return *(PVCN)&Change;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值