nt!MiDispatchFault函数分析之nt!MiCompleteProtoPteFault函数的作用

news2025/6/4 2:31:59

nt!MiDispatchFault函数分析之nt!MiCompleteProtoPteFault函数的作用


第一部分:

       //
        // PTE is still in transition state, same protection, etc.
        //

        ASSERT (Pfn1->u4.InPageError == 0);

        if (Pfn1->u2.ShareCount == 0) {
            MI_REMOVE_LOCKED_PAGE_CHARGE (Pfn1, 9);
        }

        Pfn1->u2.ShareCount += 1;
        Pfn1->u3.e1.PageLocation = ActiveAndValid;
        Pfn1->u3.e1.CacheAttribute = MiCached;

        MI_MAKE_TRANSITION_PTE_VALID (TempPte, ReadPte);
        if (StoreInstruction && TempPte.u.Hard.Write) {
            MI_SET_PTE_DIRTY (TempPte);
        }
        MI_WRITE_VALID_PTE (ReadPte, TempPte);

        if (PointerProtoPte != NULL) {

            //
            // The prototype PTE has been made valid, now make the
            // original PTE valid.  The original PTE must still be invalid
            // otherwise MiWaitForInPageComplete would have returned
            // a collision status.
            //

            ASSERT (PointerPte->u.Hard.Valid == 0);

            //
            // PTE is not valid, continue with operation.
            //

            status = MiCompleteProtoPteFault (StoreInstruction,
                                              VirtualAddress,
                                              PointerPte,
                                              PointerProtoPte,
                                              OldIrql,
                                              &LockedProtoPfn);


第二部分:

        //
        // This is the thread which owns the event, clear the event field
        // in the PFN database.
        //

        Pfn1 = ReadBlock->Pfn;
        Page = &ReadBlock->Page[0];
        NumberOfBytes = (LONG)ReadBlock->Mdl.ByteCount;
        CheckPte = ReadBlock->BasePte;

dv
             ReadPte = 0xe1009c00
           ReadBlock = 0x8962de10

1: kd> dx -r1 ((ntkrnlmp!_MMINPAGE_SUPPORT *)0x8962de10)
((ntkrnlmp!_MMINPAGE_SUPPORT *)0x8962de10)                 : 0x8962de10 [Type: _MMINPAGE_SUPPORT *]
    [+0x000] Event            [Type: _KEVENT]
    [+0x010] IoStatus         [Type: _IO_STATUS_BLOCK]
    [+0x018] ReadOffset       : {0} [Type: _LARGE_INTEGER]
    [+0x020] WaitCount        : 1 [Type: long]
    [+0x024] Thread           : 0x8999d020 [Type: _ETHREAD *]
    [+0x028] FilePointer      : 0x899abb00 [Type: _FILE_OBJECT *]
    [+0x02c] BasePte          : 0xe1009c00 [Type: _MMPTE *]
    [+0x030] Pfn              : 0x810f1650 [Type: _MMPFN *]
    [+0x034] u1               [Type: __unnamed]
    [+0x038] Mdl              [Type: _MDL]
    [+0x054] Page             [Type: unsigned long [16]]
    [+0x094] ListEntry        [Type: _SINGLE_LIST_ENTRY]
1: kd> dx -r1 (*((ntkrnlmp!_MDL *)0x8962de48))
(*((ntkrnlmp!_MDL *)0x8962de48))                 [Type: _MDL]
    [+0x000] Next             : 0x0 [Type: _MDL *]
    [+0x004] Size             : 32 [Type: short]
    [+0x006] MdlFlags         : 66 [Type: short]
    [+0x008] Process          : 0x20202020 [Type: _EPROCESS *]
    [+0x00c] MappedSystemVa   : 0x80402020 [Type: void *]
    [+0x010] StartVa          : 0x2700000 [Type: void *]
    [+0x014] ByteCount        : 0x1000 [Type: unsigned long]
    [+0x018] ByteOffset       : 0x0 [Type: unsigned long]
1: kd> dx -r1 (*((ntkrnlmp!unsigned long (*)[16])0x8962de64))
(*((ntkrnlmp!unsigned long (*)[16])0x8962de64))                 [Type: unsigned long [16]]
    [0]              : 0xa0ee [Type: unsigned long]


dv

             ReadPte = 0xe1009c00
      IoCompleteTime = {0}
        ProtoProtect = struct _MMWSLE
             PfnHeld = 0
    StoreInstruction = 0
               Flags = 0xc1080000
             OldIrql = 0x01 ''
            CheckPte = 0xe1009c00

                Page = 0x8962de64
1: kd> dx -r1 ((ntkrnlmp!unsigned long *)0x8962de64)
((ntkrnlmp!unsigned long *)0x8962de64)                 : 0x8962de64 : 0xa0ee [Type: unsigned long *]
    0xa0ee [Type: unsigned long]


1: kd>  dd 0xe1009c00
e1009c00  0a0ee8c0 fcf194c6 fcf194c6 fcf194c6
e1009c10  fcf194c6 fcf194c6 fcf194c6 fcf194c6
e1009c20  fcf194c6 fcf194c6 fcf194c6 fcf194c6

            else {
                PageFrameIndex = *Page;
                MI_SNAP_DATA (MI_PFN_ELEMENT (PageFrameIndex),
                              MI_PFN_ELEMENT (PageFrameIndex)->PteAddress,
                              0xC);
            }


#define MI_SNAP_DATA(_Pfn, _Pte, _CallerId) MiSnapData(_Pfn, _Pte, _CallerId)

            CheckPte += 1;
            Page += 1;
            NumberOfBytes -= PAGE_SIZE;


第三部分:

        //
        // PTE is still in transition state, same protection, etc.
        //

        ASSERT (Pfn1->u4.InPageError == 0);

        if (Pfn1->u2.ShareCount == 0) {
            MI_REMOVE_LOCKED_PAGE_CHARGE (Pfn1, 9);
        }

        Pfn1->u2.ShareCount += 1;
        Pfn1->u3.e1.PageLocation = ActiveAndValid;
        Pfn1->u3.e1.CacheAttribute = MiCached;

        MI_MAKE_TRANSITION_PTE_VALID (TempPte, ReadPte);


dv
                Pfn1 = 0x810f1650

第四部分:

1: kd> dd 810f1650
810f1650  00000000 e1009c00 00000000 00011008
810f1660  fcf194c6 2000a1cd

        Pfn1->u2.ShareCount += 1;
        Pfn1->u3.e1.PageLocation = ActiveAndValid;
        Pfn1->u3.e1.CacheAttribute = MiCached;

1: kd> dd 810f1650
810f1650  00000000 e1009c00 00000001 00011608
810f1660  fcf194c6 0000a1cd


第五部分:修改 e1009c00 ,先构造一个TempPte


        MI_MAKE_TRANSITION_PTE_VALID (TempPte, ReadPte);    //关键代码1:构造TempPte=0a0ee921


#define MI_MAKE_TRANSITION_PTE_VALID(OUTPTE,PPTE)                             \
        ASSERT (((PPTE)->u.Hard.Valid == 0) &&                                \
                ((PPTE)->u.Trans.Prototype == 0) &&                           \
                ((PPTE)->u.Trans.Transition == 1));                           \
               (OUTPTE).u.Long = (((PPTE)->u.Long & ~0xFFF) |                 \
                         (MmProtectToPteMask[(PPTE)->u.Trans.Protection]) |   \
                          MiDetermineUserGlobalPteMask ((PMMPTE)PPTE));


1: kd> p
nt!MiDispatchFault+0x29fa:
80a93016 e88fc30300      call    nt!MiDetermineUserGlobalPteMask (80acf3aa)
1: kd> p
nt!MiDispatchFault+0x29ff:
80a9301b 8bd8            mov     ebx,eax
1: kd> r
eax=00000121


1: kd> p
nt!MiDispatchFault+0x2a19:
80a93035 0bd8            or      ebx,eax
1: kd> r
eax=0a0ee000 ebx=00000921

第六部分:修改 e1009c00 ,使用TempPte

        MI_WRITE_VALID_PTE (ReadPte, TempPte);        0a0ee921        //关键代码2:赋值给ReadPte


1: kd> p
nt!MiDispatchFault+0x2b32:
80a9314e 8918            mov     dword ptr [eax],ebx
1: kd> r
eax=e1009c00 ebx=0a0ee921


1: kd> dd e1009c00
e1009c00  0a0ee921 fcf194c6 fcf194c6 fcf194c6
e1009c10  fcf194c6 fcf194c6 fcf194c6 fcf194c6
e1009c20  fcf194c6 fcf194c6 fcf194c6 fcf194c6
e1009c30  fcf194c6 fcf194c6 fcf194c6 fcf194c6


第七部分:现在还是无效的not valid,需要修改C0304200


1: kd> !pte c1080000
                 VA c1080000
PDE at C0300C10         PTE at C0304200
contains 0A03F963       contains 00027400
pfn a03f  -G-DA--KWEV   not valid
                         Proto: E1009C00

1: kd> dd 0xc0304200
c0304200  00027400 00027402 00027404 00027406
c0304210  00027408 0002740a 0002740c 0002740e
c0304220  00027410 00027412 00027414 00027416
c0304230  00027418 0002741a 0002741c 0002741e


//关键代码3:改变    00027400

            //
            // PTE is not valid, continue with operation.
            //

            status = MiCompleteProtoPteFault (StoreInstruction,
                                              VirtualAddress,
                                              PointerPte,
                                              PointerProtoPte,
                                              OldIrql,
                                              &LockedProtoPfn);

第八部分:

1: kd> p
nt!MiDispatchFault+0x2b64:
80a93180 e8df4fffff      call    nt!MiCompleteProtoPteFault (80a88164)
1: kd> t
nt!MiCompleteProtoPteFault:
80a88164 55              push    ebp
1: kd> kc
 #
00 nt!MiCompleteProtoPteFault
01 nt!MiDispatchFault
02 nt!MmAccessFault
03 nt!_KiTrap0E
04 nt!CcMapData
05 Ntfs!NtfsMapStream
06 Ntfs!NtfsReadBootSector
07 Ntfs!NtfsMountVolume
08 Ntfs!NtfsCommonFileSystemControl
09 Ntfs!NtfsFspDispatch
0a nt!ExpWorkerThread
0b nt!PspSystemThreadStartup
0c nt!KiThreadStartup
1: kd> dv
StoreInstruction = 0
 FaultingAddress = 0xc1080000
      PointerPte = 0xc0304200
 PointerProtoPte = 0xe1009c00
         OldIrql = 0x01 ''
  LockedProtoPfn = 0xf78d68e0
      FileOffset = 0n48
     OriginalPte = struct _MMPTE
    ProtoProtect = struct _MMWSLE
          Status = 0n1
   MarkPageDirty = 0xa0ee921
            Pfn1 = 0x80a88164


第九部分:

NTSTATUS
MiCompleteProtoPteFault (
    IN ULONG_PTR StoreInstruction,
    IN PVOID FaultingAddress,
    IN PMMPTE PointerPte,
    IN PMMPTE PointerProtoPte,
    IN KIRQL OldIrql,
    IN OUT PMMPFN *LockedProtoPfn
    )

/*++

Routine Description:

    This routine completes a prototype PTE fault.  It is invoked
    after a read operation has completed bringing the data into
    memory.

第十部分:

    ProtoPteContents.u.Long = PointerProtoPte->u.Long;


1: kd> p
nt!MiCompleteProtoPteFault+0x50:
80a881b4 8b3f            mov     edi,dword ptr [edi]
1: kd> r
eax=00000002 ebx=0a0ee921 ecx=f78d6910 edx=e80e369c esi=c0304200 edi=e1009c00

    PageFrameIndex = MI_GET_PAGE_FRAME_FROM_PTE (&ProtoPteContents);
    Pfn1 = MI_PFN_ELEMENT (PageFrameIndex);
    Pfn1->u3.e1.PrototypePte = 1;

1: kd> p
nt!MiCompleteProtoPteFault+0x52:
80a881b6 8b0dd805bf80    mov     ecx,dword ptr [nt!MmPfnDatabase (80bf05d8)]
1: kd> p
nt!MiCompleteProtoPteFault+0x58:
80a881bc c1ef0c          shr     edi,0Ch
1: kd> p
nt!MiCompleteProtoPteFault+0x5b:
80a881bf 8d047f          lea     eax,[edi+edi*2]
1: kd> r
eax=00000002 ebx=0a0ee921 ecx=81000000 edx=e80e369c esi=c0304200 edi=0000a0ee
eip=80a881bf esp=f78d682c ebp=f78d6858 iopl=0         nv up ei pl nz na pe cy
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000207
nt!MiCompleteProtoPteFault+0x5b:
80a881bf 8d047f          lea     eax,[edi+edi*2]

1: kd> dd 810f1650
810f1650  00000000 e1009c00 00000001 00011608
810f1660  fcf194c6 0000a1cd


   +0x00c u3               : __unnamed
      +0x000 e1               : _MMPFNENTRY
         +0x000 Modified         : Pos 0, 1 Bit
         +0x000 ReadInProgress   : Pos 1, 1 Bit
         +0x000 WriteInProgress  : Pos 2, 1 Bit
         +0x000 PrototypePte     : Pos 3, 1 Bit        1

    //
    // Capture prefetch fault information.
    //

    OriginalPte = Pfn1->OriginalPte;        


第十一部分:

    ContainingPageTablePointer = MiGetPteAddress (PointerPte);        C0300C10

      PointerPte = 0xc0304200
#define MiGetPteAddress(va) ((PMMPTE)(((((ULONG)(va)) >> 12) << 2) + PTE_BASE))


1: kd> !pte 0xc0304200
                 VA c1080000
PDE at C0300C10         PTE at C0304200
contains 0A03F963       contains 00027400
pfn a03f  -G-DA--KWEV   not valid
                         Proto: E1009C00

C0304200


1100 0000 0011 0000 0100 0010 0000 0000

11    00 00    00 00    11 00    00 01    00 00

300c10

第十二部分:

eax=0a03f963

0a03f


    Pfn2 = MI_PFN_ELEMENT (ContainingPageTablePointer->u.Hard.PageFrameNumber);    81000000+0a03f*18


1: kd> dd 81000000+0a03f*18
810f05e8  00000000 c0300c10 00000025 00011601
810f05f8  00000080 00000039

1: kd> p
nt!MiCompleteProtoPteFault+0x87:
80a881eb 8d04c2          lea     eax,[edx+eax*8]
1: kd> p
nt!MiCompleteProtoPteFault+0x8a:
80a881ee ff4008          inc     dword ptr [eax+8]
1: kd> r
eax=810f05e8


dv
    ProtoProtect = struct _MMWSLE
    
1: kd> dx -r1 (*((ntkrnlmp!_MMWSLE *)0xf78d6854))
(*((ntkrnlmp!_MMWSLE *)0xf78d6854))                 [Type: _MMWSLE]
    [+0x000] u1               [Type: __unnamed]


1: kd> dd 0xf78d6854
f78d6854  00000346

    ProtoProtect.u1.Long = 0;


        ProtoProtect.u1.e1.Protection = MI_GET_PROTECTION_FROM_SOFT_PTE(&OriginalPte);
        ProtoProtect.u1.e1.SameProtectAsProto = 1;


#define MI_GET_PROTECTION_FROM_SOFT_PTE(PTE) ((PTE)->u.Soft.Protection)

fcf194c6


    +0x000 Soft             : _MMPTE_SOFTWARE
         +0x000 Valid            : Pos 0, 1 Bit
         +0x000 PageFileLow      : Pos 1, 4 Bits
         +0x000 Protection       : Pos 5, 5 Bits    00 110=0x6


0100 1100 0110

第十三部分:

    MI_MAKE_VALID_PTE (TempPte,
                       PageFrameIndex,
                       ProtoProtect.u1.e1.Protection,
                       PointerPte);            //TempPte=ebx=0a0ee921

#define MI_MAKE_VALID_PTE(OUTPTE,FRAME,PMASK,PPTE)                            \
       (OUTPTE).u.Long = ((FRAME << 12) |                                     \
                         (MmProtectToPteMask[PMASK]) |                        \
                          MiDetermineUserGlobalPteMask ((PMMPTE)PPTE));


1: kd> p
nt!MiCompleteProtoPteFault+0x4e2:
80a88646 e85f6d0400      call    nt!MiDetermineUserGlobalPteMask (80acf3aa)
1: kd> p
nt!MiCompleteProtoPteFault+0x4e7:
80a8864b 8bd8            mov     ebx,eax
1: kd> r
eax=00000121

1: kd> p
nt!MiCompleteProtoPteFault+0x4f0:
80a88654 c1e70c          shl     edi,0Ch
1: kd> p
nt!MiCompleteProtoPteFault+0x4f3:
80a88657 0bdf            or      ebx,edi
1: kd> p
nt!MiCompleteProtoPteFault+0x4f5:
80a88659 837dec00        cmp     dword ptr [ebp-14h],0
1: kd> r
eax=00000121 ebx=0a0ee921

   MI_WRITE_VALID_PTE (PointerPte, TempPte);


1: kd> dd 0xc0304200
c0304200  00027400 00027402 00027404 00027406
c0304210  00027408 0002740a 0002740c 0002740e
c0304220  00027410 00027412 00027414 00027416

改为

1: kd> dd 0xc0304200
c0304200  0a0ee921 00027402 00027404 00027406
c0304210  00027408 0002740a 0002740c 0002740e
c0304220  00027410 00027412 00027414 00027416

1: kd> p
nt!MiCompleteProtoPteFault+0x60f:
80a88773 8918            mov     dword ptr [eax],ebx
1: kd> r
eax=c0304200 ebx=0a0ee921


1: kd> dd 0xc0304200
c0304200  0a0ee921 00027402 00027404 00027406
c0304210  00027408 0002740a 0002740c 0002740e
c0304220  00027410 00027412 00027414 00027416


1: kd> !pte c1080000
                 VA c1080000
PDE at C0300C10         PTE at C0304200
contains 0A03F963       contains 0A0EE921
pfn a03f  -G-DA--KWEV   pfn a0ee  -G--A--KREV        

第十四部分:


    WorkingSetIndex = MiAddValidPageToWorkingSet (FaultingAddress,
                                                  PointerPte,
                                                  Pfn1,
                                                  (ULONG) ProtoProtect.u1.Long);

1: kd> x nt!MmSystemCacheWs
80bf03c0          nt!MmSystemCacheWs = struct _MMSUPPORT
1: kd> dx -r1 (*((ntkrnlmp!_MMSUPPORT *)0x80bf03c0))
(*((ntkrnlmp!_MMSUPPORT *)0x80bf03c0))                 [Type: _MMSUPPORT]
    [+0x000] WorkingSetExpansionLinks [Type: _LIST_ENTRY]
    [+0x008] LastTrimTime     : {0} [Type: _LARGE_INTEGER]
    [+0x010] Flags            [Type: _MMSUPPORT_FLAGS]
    [+0x014] PageFaultCount   : 0x378 [Type: unsigned long]
    [+0x018] PeakWorkingSetSize : 0x342 [Type: unsigned long]
    [+0x01c] GrowthSinceLastEstimate : 0x378 [Type: unsigned long]
    [+0x020] MinimumWorkingSetSize : 0x3f1 [Type: unsigned long]
    [+0x024] MaximumWorkingSetSize : 0x20000 [Type: unsigned long]
    [+0x028] VmWorkingSetList : 0xc0c00000 [Type: _MMWSL *]
    [+0x02c] Claim            : 0x0 [Type: unsigned long]
    [+0x030] NextEstimationSlot : 0x0 [Type: unsigned long]
    [+0x034] NextAgingSlot    : 0x0 [Type: unsigned long]
    [+0x038] EstimatedAvailable : 0x0 [Type: unsigned long]
    [+0x03c] WorkingSetSize   : 0x342 [Type: unsigned long]
    [+0x040] WorkingSetMutex  [Type: _KGUARDED_MUTEX]


1: kd> dx -r1 ((ntkrnlmp!_MMWSL *)0xc0c00000)
((ntkrnlmp!_MMWSL *)0xc0c00000)                 : 0xc0c00000 [Type: _MMWSL *]
    [+0x000] FirstFree        : 0x343 [Type: unsigned long]
    [+0x004] FirstDynamic     : 0x1 [Type: unsigned long]
    [+0x008] LastEntry        : 0x3f1 [Type: unsigned long]
    [+0x00c] NextSlot         : 0x1 [Type: unsigned long]
    [+0x010] Wsle             : 0xc0c00038 [Type: _MMWSLE *]
    [+0x014] LastInitializedWsle : 0x3f1 [Type: unsigned long]
    [+0x018] NonDirectCount   : 0x1d [Type: unsigned long]
    [+0x01c] HashTable        : 0x0 [Type: _MMWSLE_HASH *]
    [+0x020] HashTableSize    : 0x0 [Type: unsigned long]
    [+0x024] NumberOfCommittedPageTables : 0x0 [Type: unsigned long]
    [+0x028] HashTableStart   : 0xc0df1000 [Type: void *]
    [+0x02c] HighestPermittedHashAddress : 0xc1000000 [Type: void *]
    [+0x030] NumberOfImageWaiters : 0x0 [Type: unsigned long]
    [+0x034] VadBitMapHint    : 0x0 [Type: unsigned long]
    [+0x038] UsedPageTableEntries [Type: unsigned short [768]]
    [+0x638] CommittedPageTables [Type: unsigned long [24]]


结果:


    Wsle[WorkingSetIndex] = WsleContents;

1: kd> dd 0xc0c00038+343*4
c0c00d44  c1080201 00003450 00003460 00003470
c0c00d54  00003480 00003490 000034a0 000034b0

    if (WsleMask != 0) {
        Wsle[WorkingSetIndex].u1.Long |= WsleMask;
    }


1: kd> dd 0xc0c00038+343*4
c0c00d44  c1080331 00003450 00003460 00003470
c0c00d54  00003480 00003490 000034a0 000034b0
c0c00d64  000034c0 000034d0 000034e0 000034f0
c0c00d74  00003500 00003510 00003520 00003530


第十五部分:最终结果0xc0304200和e1009c00地址处的内容都修改为0a0ee921


1: kd> dd 0xc0304200
c0304200  0a0ee921 00027402 00027404 00027406
c0304210  00027408 0002740a 0002740c 0002740e
c0304220  00027410 00027412 00027414 00027416
c0304230  00027418 0002741a 0002741c 0002741e
c0304240  00027420 00027422 00027424 00027426
c0304250  00027428 0002742a 0002742c 0002742e
c0304260  00027430 00027432 00027434 00027436
c0304270  00027438 0002743a 0002743c 0002743e
1: kd> dd e1009c00
e1009c00  0a0ee921 fcf194c6 fcf194c6 fcf194c6
e1009c10  fcf194c6 fcf194c6 fcf194c6 fcf194c6

原来是:

1: kd> dd 0xc0304200
c0304200  00027400 00027402 00027404 00027406
c0304210  00027408 0002740a 0002740c 0002740e
c0304220  00027410 00027412 00027414 00027416
c0304230  00027418 0002741a 0002741c 0002741e

1: kd> dd e1009c00
e1009c00  0a0ee8c0 fcf194c6 fcf194c6 fcf194c6
e1009c10  fcf194c6 fcf194c6 fcf194c6 fcf194c6
e1009c20  fcf194c6 fcf194c6 fcf194c6 fcf194c6

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2396116.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

YOLOX 的动态标签分类(如 SimOTA)与 Anchor-free 机制解析2025.5.29

YOLOX 的动态标签分类&#xff08;如 SimOTA&#xff09;与 Anchor-free 机制是其核心改进中的两个关键部分&#xff0c;它们在目标检测中的作用和实现方式存在显著差异。以下从原理、实现细节及效果三个方面进行详细对比&#xff1a; 一、核心原理与目标 1. Anchor-free 机制…

724.寻找数组的中心下标前缀和

题目链接&#xff1a; https://leetcode.cn/problems/find-pivot-index/ 这道题目我们可以使用暴力解法&#xff0c;就一个下标前数组之和&#xff0c;再求一个下标后数组之和&#xff0c;时间复杂度达到n方&#xff0c;我们来写一下&#xff1a; int pivotIndex(vector<in…

软考-系统架构设计师-第十六章 层次式架构设计理论与实践

层次式架构设计理论与实践 16.2 表现层框架设计16.3 中间层框架设计16.4 数据访问层设计16.5 数据架构规划与设计16.6 物联网层次架构设计 软件体系结构为软件系统提供了结构、行为和属性的高级抽象&#xff0c;由构成系统的元素描述这些元素的相互作用、指导元素集成的模式以及…

Docker学习笔记:基础知识

本文是自己的学习笔记 1、什么是Docker2、Docker的架构设计2.1、镜像&#xff08;Image&#xff09;2.2、容器&#xff08;Container&#xff09;2.3、仓库&#xff08;Repository)2.4、Docker使用场景案例 1、什么是Docker Docker是基于Go语言实现的云开源项目。它的角色是作…

5.2 初识Spark Streaming

在本节实战中&#xff0c;我们初步探索了Spark Streaming&#xff0c;它是Spark的流式数据处理子框架&#xff0c;具备高吞吐量、可伸缩性和强容错能力。我们了解了Spark Streaming的基本概念和运行原理&#xff0c;并通过两个案例演示了如何利用Spark Streaming实现词频统计。…

Python趣学篇:交互式词云生成器(jieba + Tkinter + WordCloud等)

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。—— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、为什么要做词云&#xff1f;让文字"活"起来&#xff01;二、核心…

理解解释器架构:原理、组成与运行机制全解析

目录 前言1. 什么是解释器架构2. 解释器的基本组成2.1 被解释执行的程序2.2 解释器引擎2.3 解释器内部状态2.4 程序执行的当前状态2.5 存储器模型 3. 解释器的工作原理3.1 解析源代码3.2 初始化运行环境3.3 逐条执行语法结构3.4 维护程序状态3.5 内存管理与变量作用域 4. 举例&…

2025华为OD机试真题+全流程解析+备考攻略+经验分享+Java/python/JavaScript/C++/C/GO六种语言最佳实现

华为OD全流程解析&#xff0c;备考攻略 快捷目录 华为OD全流程解析&#xff0c;备考攻略一、什么是华为OD&#xff1f;二、什么是华为OD机试&#xff1f;三、华为OD面试流程四、华为OD薪资待遇及职级体系五、ABCDE卷类型及特点六、题型与考点七、机试备考策略八、薪资与转正九、…

设计模式——桥接设计模式(结构型)

摘要 桥接设计模式是一种结构型设计模式&#xff0c;用于将抽象与实现解耦&#xff0c;使二者可以独立变化。它通过将一个类拆分为“抽象”和“实现”两部分&#xff0c;并通过桥接关系组合&#xff0c;避免了类继承层次结构过于庞大。桥接模式包含抽象类、扩充抽象类、实现类…

LLaDa——基于 Diffusion 的大语言模型 打平 LLama 3

这里分享一篇文章《Large Language Diffusion Models》&#xff0c;来自人民大学高领人工智能学院&#xff0c;一篇尝试改变传统自回归范&#xff08;预测下一个token&#xff09; LLM 架构&#xff0c;探索扩散模型在 LLM 上的作用&#xff0c;通过随机掩码-预测逆向思维&…

2. 数据结构基本概念 (2)

本文部分ppt、视频截图来自&#xff1a;[青岛大学-王卓老师的个人空间-王卓老师个人主页-哔哩哔哩视频] 1. 数据结构基本概念 1.1 数据类型和抽象数据类型 (1) 数据类型(Data Type) 概念 数据类型是一组性质相同的值的集合以及定义于这个值集合上的一组操作的总称。 在使用…

STM32F407寄存器操作(多通道单ADC+DMA)

1.前言 又是半年没更新了&#xff0c;趁着端午放假有点时间&#xff0c;并且最近项目要用这块知识&#xff0c;我就顺带研究一下ADC吧。 一般来说ADC主要用法包含了1.单通道软件触发&#xff08;这是最简单和最常用的用法&#xff09;2.单通道多次采集&#xff08;需要快速采…

基于React和TypeScript的金融市场模拟器开发与模式分析

基于React和TypeScript的金融市场模拟器开发与模式分析 项目概述 本项目开发了一个基于React和TypeScript的金融市场模拟器&#xff0c;通过模拟订单流和价格发现机制&#xff0c;重现了真实市场的动态特性。该模拟器不仅提供了实时价格图表、订单簿和交易功能&#xff0c;还…

reverse_ssh 建立反向 SSH 连接指南 混淆AV [好东西哟]

目录 &#x1f310; 工具简介 ⚙️ 前提条件 攻击主机 (Linux) 目标主机 (Windows) &#x1f4cb; 详细步骤 步骤 1&#xff1a;安装 Go 环境 步骤 2&#xff1a;安装必要依赖 步骤 3&#xff1a;下载并编译 reverse_ssh 步骤 4&#xff1a;配置密钥 步骤 5&#xff…

lvs-keepalived高可用群集

目录 1.Keepalived 概述及安装 1.1 Keepalived 的热备方式 1.2 keepalived的安装与服务控制 &#xff08;1&#xff09;安装keep alived (2)控制 Keepalived 服务DNF 安装 keepalived 后,执行以下命令将keepalived 服务设置为开机启动。 2.使用 Keepalived 实现双机热备 …

高速收发器

一、高速收发器 1.FPGA高速收发器&#xff1a;GTP,GTX,GTH,GTZ 2.每个Quad有4对高速收发器GT(4个TX和4个RX)和一个COmmon 3.走差分&#xff0c;提高抗干扰性 4.CPLL是每个lane私有的&#xff0c;QPLL是整个Quad的所有通道共享的 5.每个MGT的bank有两对差分参考时钟 6.CPLL的时钟…

webpack的安装及其后序部分

npm install原理 这个其实就是npm从registry下载项目到本地&#xff0c;没有什么好说的 值得一提的是npm的缓存机制&#xff0c;如果多个项目都需要同一个版本的axios&#xff0c;每一次重新从registry中拉取的成本过大&#xff0c;所以会有缓存&#xff0c;如果缓存里有这个…

如何利用自动生成文档工具打造出色的技术文档

文章目录 每日一句正能量前言一、自动生成文档工具的优势&#xff08;一&#xff09;提高效率&#xff08;二&#xff09;保持一致性&#xff08;三&#xff09;实时更新 二、常见的自动生成文档工具&#xff08;一&#xff09;Sphinx&#xff08;二&#xff09;Javadoc&#x…

实验设计与分析(第6版,Montgomery)第5章析因设计引导5.7节思考题5.7 R语言解题

本文是实验设计与分析&#xff08;第6版&#xff0c;Montgomery著&#xff0c;傅珏生译) 第5章析因设计引导5.7节思考题5.7 R语言解题。主要涉及方差分析&#xff0c;正态假设检验&#xff0c;残差分析&#xff0c;交互作用图&#xff0c;等值线图。 dataframe <-data.frame…

OpenCv高阶(二十)——dlib脸部轮廓绘制

文章目录 一、人脸面部轮廓绘制代码实现1、定义绘制直线段的函数2、定义绘制凸包轮廓的函数3、读取输入图像4、初始化dlib的人脸检测器5、使用检测器在图像中检测人脸&#xff08;参数0表示不进行图像缩放&#xff09;6、加载dlib的68点人脸关键点预测模型7、遍历检测到的每个人…