вторник, 3 декабря 2024 г.

Как понять, что файл находится внутри транзакции?

 Пусть у нас есть хендл файла, например 0xa4

По хендлу находим file object:

1: kd> !handle 00000000000000a4

PROCESS ffffa805650c2080
    SessionId: 1  Cid: 1f28    Peb: 245c58000  ParentCid: 1e18
    DirBase: 1f62ad002  ObjectTable: ffffb80f1473ae40  HandleCount:  42.
    Image: PipeClient.exe

Handle table at ffffb80f1473ae40 with 42 entries in use

00a4: Object: ffffa80566027850  GrantedAccess: 00120196 (Inherit) Entry: ffffb80f0b4d1290
Object: ffffa80566027850  Type: (ffffa8055e0940c0) File
    ObjectHeader: ffffa80566027820 (new version)
        HandleCount: 1  PointerCount: 1
        Directory Object: 00000000  Name: \test\testfile.txt {HarddiskVolume4}

Далее, смотрим структуру данного FILE_OBJECT:

1: kd> dt nt!_FILE_OBJECT ffffa80566027850
   +0x000 Type             : 0n5
   +0x002 Size             : 0n216
   +0x008 DeviceObject     : 0xffffa805`5ebc2060 _DEVICE_OBJECT
   +0x010 Vpb              : 0xffffa805`602ac5e0 _VPB
   +0x018 FsContext        : 0xffffb80f`14c33b80 Void
   +0x020 FsContext2       : 0xffffb80f`14c33df0 Void
   +0x028 SectionObjectPointer : 0xffffa805`6682a918 _SECTION_OBJECT_POINTERS
   +0x030 PrivateCacheMap  : (null)
   +0x038 FinalStatus      : 0n0
   +0x040 RelatedFileObject : (null)
   +0x048 LockOperation    : 0 ''
   +0x049 DeletePending    : 0 ''
   +0x04a ReadAccess       : 0 ''
   +0x04b WriteAccess      : 0x1 ''
   +0x04c DeleteAccess     : 0 ''
   +0x04d SharedRead       : 0 ''
   +0x04e SharedWrite      : 0 ''
   +0x04f SharedDelete     : 0 ''
   +0x050 Flags            : 0x40042
   +0x058 FileName         : _UNICODE_STRING "\test\testfile.txt"
   +0x068 CurrentByteOffset : _LARGE_INTEGER 0x0
   +0x070 Waiters          : 0
   +0x074 Busy             : 0
   +0x078 LastLock         : (null)
   +0x080 Lock             : _KEVENT
   +0x098 Event            : _KEVENT
   +0x0b0 CompletionContext : (null)
   +0x0b8 IrpListLock      : 0
   +0x0c0 IrpList          : _LIST_ENTRY [ 0xffffa805`66027910 - 0xffffa805`66027910 ]
   +0x0d0 FileObjectExtension : 0xffffa805`642a8f30 Void
У файла, не находящегося в транзакции поле FileObjectExtension равно нулю, а у транзакционного файла там лежит структура:

1: kd> dqs 0xffffa805`642a8f30
ffffa805`642a8f30  00000000`00000000
ffffa805`642a8f38  ffffa805`644f5e50
ffffa805`642a8f40  00000000`00000000
ffffa805`642a8f48  00000000`00000000
Я её не реверсил, но по смещению 0x8 там лежит TXN_PARAMETER_BLOCK и уже в ней лежит транзакция, к которой принадлежит исходный файл:
1: kd> dt nt!_TXN_PARAMETER_BLOCK ffffa805`644f5e50
   +0x000 Length           : 0x10
   +0x002 TxFsContext      : 0xfffe
   +0x008 TransactionObject : 0xffffa805`650ec060 Void
   
1: kd> !object 0xffffa805`650ec060
Object: ffffa805650ec060  Type: (ffffa8055e095140) TmTx
    ObjectHeader: ffffa805650ec030 (new version)
    HandleCount: 1  PointerCount: 32776

dt nt!_KTRANSACTION ffffa805650ec060
   +0x000 OutcomeEvent     : _KEVENT
   +0x018 cookie           : 0xb00b0001
   +0x020 Mutex            : _KMUTANT
   +0x058 TreeTx           : 0xffffa805`650ec060 _KTRANSACTION
   +0x060 GlobalNamespaceLink : _KTMOBJECT_NAMESPACE_LINK
   +0x088 TmNamespaceLink  : _KTMOBJECT_NAMESPACE_LINK
   +0x0b0 UOW              : _GUID {d9403709-b1b3-11ef-988c-000c29bfd957}
   +0x0c0 State            : 1 ( KTransactionActive )
   +0x0c4 Flags            : 0x100
   +0x0c8 EnlistmentHead   : _LIST_ENTRY [ 0xffffa805`6306b578 - 0xffffa805`6306b328 ]
   +0x0d8 EnlistmentCount  : 2
   +0x0dc RecoverableEnlistmentCount : 1
   +0x0e0 PrePrepareRequiredEnlistmentCount : 1
   +0x0e4 PrepareRequiredEnlistmentCount : 2
   +0x0e8 OutcomeRequiredEnlistmentCount : 2
   +0x0ec PendingResponses : 0
   +0x0f0 SuperiorEnlistment : (null)
   +0x0f8 LastLsn          : _CLS_LSN
   +0x100 PromotedEntry    : _LIST_ENTRY [ 0xffffa805`650ec160 - 0xffffa805`650ec160 ]
   +0x110 PromoterTransaction : (null)
   +0x118 PromotePropagation : (null)
   +0x120 IsolationLevel   : 0
   +0x124 IsolationFlags   : 0
   +0x128 Timeout          : _LARGE_INTEGER 0x0
   +0x130 Description      : _UNICODE_STRING ""
   +0x140 RollbackThread   : (null)
   +0x148 RollbackWorkItem : _WORK_QUEUE_ITEM
   +0x168 RollbackDpc      : _KDPC
   +0x1a8 RollbackTimer    : _KTIMER
   +0x1e8 LsnOrderedEntry  : _LIST_ENTRY [ 0xffffa805`650ec248 - 0xffffa805`650ec248 ]
   +0x1f8 Outcome          : 1 ( KTxOutcomeUndetermined )
   +0x200 Tm               : 0xffffa805`60321b30 _KTM
   +0x208 CommitReservation : 0n0
   +0x210 TransactionHistory : [10] _KTRANSACTION_HISTORY
   +0x260 TransactionHistoryCount : 0
   +0x268 DTCPrivateInformation : (null)
   +0x270 DTCPrivateInformationLength : 0
   +0x278 DTCPrivateInformationMutex : _KMUTANT
   +0x2b0 PromotedTxSelfHandle : (null)
   +0x2b8 PendingPromotionCount : 0
   +0x2c0 PromotionCompletedEvent : _KEVENT
Видно, что у нее State == KTransactionActive, т.е. она не закоммичена и не откачена.

Также можно получить enlistment и ktm(transaction manager) и resource manager:

1: kd> dt nt!_KENLISTMENT 0xffffa805`6306b578-78
   +0x000 cookie           : 0xb00b0003
   +0x008 NamespaceLink    : _KTMOBJECT_NAMESPACE_LINK
   +0x030 EnlistmentId     : _GUID {d940370c-b1b3-11ef-988c-000c29bfd957}
   +0x040 Mutex            : _KMUTANT
   +0x078 NextSameTx       : _LIST_ENTRY [ 0xffffa805`6306b328 - 0xffffa805`650ec128 ]
   +0x088 NextSameRm       : _LIST_ENTRY [ 0xffffa805`60336ca0 - 0xffffa805`60336ca0 ]
   +0x098 ResourceManager  : 0xffffa805`60336b90 _KRESOURCEMANAGER
   +0x0a0 Transaction      : 0xffffa805`650ec060 _KTRANSACTION
   +0x0a8 State            : 100 ( KEnlistmentActive )
   +0x0ac Flags            : 0x30
   +0x0b0 NotificationMask : 0x20f
   +0x0b8 Key              : (null)
   +0x0c0 KeyRefCount      : 1
   +0x0c8 RecoveryInformation : (null)
   +0x0d0 RecoveryInformationLength : 0
   +0x0d8 DynamicNameInformation : (null)
   +0x0e0 DynamicNameInformationLength : 0
   +0x0e8 FinalNotification : 0xffffa805`6637cd90 _KTMNOTIFICATION_PACKET
   +0x0f0 SupSubEnlistment : 0xffffa805`6306b750 _KENLISTMENT
   +0x0f8 SupSubEnlHandle  : 0xffffffff`80002b78 Void
   +0x100 SubordinateTxHandle : (null)
   +0x108 CrmEnlistmentEnId : _GUID {d940370d-b1b3-11ef-988c-000c29bfd957}
   +0x118 CrmEnlistmentTmId : _GUID {d9403259-b1b3-11ef-988c-806e6f6e6963}
   +0x128 CrmEnlistmentRmId : _GUID {d9403259-b1b3-11ef-988c-806e6f6e6963}
   +0x138 NextHistory      : 0
   +0x13c History          : [20] _KENLISTMENT_HISTORY
1: kd> dt _KRESOURCEMANAGER 0xffffa805`60336b90
nt!_KRESOURCEMANAGER
   +0x000 NotificationAvailable : _KEVENT
   +0x018 cookie           : 0xb00b0002
   +0x01c State            : 2 ( KResourceManagerOnline )
   +0x020 Flags            : 0
   +0x028 Mutex            : _KMUTANT
   +0x060 NamespaceLink    : _KTMOBJECT_NAMESPACE_LINK
   +0x088 RmId             : _GUID {aac01acf-dcfb-11ed-a446-b2fd1f82aa81}
   +0x098 NotificationQueue : _KQUEUE
   +0x0d8 NotificationMutex : _KMUTANT
   +0x110 EnlistmentHead   : _LIST_ENTRY [ 0xffffa805`6306b588 - 0xffffa805`6306b588 ]
   +0x120 EnlistmentCount  : 1
   +0x128 NotificationRoutine : 0xfffff805`0d48c3c0     long  tm!TmpInternalCrmNotification+0
   +0x130 Key              : 0xffffffff`800002d0 Void
   +0x138 ProtocolListHead : _LIST_ENTRY [ 0xffffa805`60336cc8 - 0xffffa805`60336cc8 ]
   +0x148 PendingPropReqListHead : _LIST_ENTRY [ 0xffffa805`60336cd8 - 0xffffa805`60336cd8 ]
   +0x158 CRMListEntry     : _LIST_ENTRY [ 0x00000000`00000000 - 0x00000000`00000000 ]
   +0x168 Tm               : 0xffffa805`60321b30 _KTM
   +0x170 Description      : _UNICODE_STRING ""
   +0x180 Enlistments      : _KTMOBJECT_NAMESPACE
   +0x228 CompletionBinding : _KRESOURCEMANAGER_COMPLETION_BINDING
1: kd> dt nt!_KTM 0xffffa805`60321b30
   +0x000 cookie           : 0xb00b0004
   +0x008 Mutex            : _KMUTANT
   +0x040 State            : 3 ( KKtmOnline )
   +0x048 NamespaceLink    : _KTMOBJECT_NAMESPACE_LINK
   +0x070 TmIdentity       : _GUID {aac01acf-dcfb-11ed-a446-b2fd1f82aa81}
   +0x080 Flags            : 0xc0
   +0x084 VolatileFlags    : 0
   +0x088 LogFileName      : _UNICODE_STRING "\Device\HarddiskVolume4\$Extend\$RmMetadata\$TxfLog\$TxfLog::KtmLog"
   +0x098 LogFileObject    : 0xffffa805`6035d0b0 _FILE_OBJECT
   +0x0a0 MarshallingContext : 0xffffb80f`07d513a0 Void
   +0x0a8 LogManagementContext : 0xffffa805`5ecb0b90 Void
   +0x0b0 Transactions     : _KTMOBJECT_NAMESPACE
   +0x158 ResourceManagers : _KTMOBJECT_NAMESPACE
   +0x200 LsnOrderedMutex  : _KMUTANT
   +0x238 LsnOrderedList   : _LIST_ENTRY [ 0xffffa805`60321d68 - 0xffffa805`60321d68 ]
   +0x248 CommitVirtualClock : _LARGE_INTEGER 0xe3
   +0x250 CommitVirtualClockMutex : _FAST_MUTEX
   +0x288 BaseLsn          : _CLS_LSN
   +0x290 CurrentReadLsn   : _CLS_LSN
   +0x298 LastRecoveredLsn : _CLS_LSN
   +0x2a0 TmRmHandle       : 0xffffffff`800002d0 Void
   +0x2a8 TmRm             : 0xffffa805`60336b90 _KRESOURCEMANAGER
   +0x2b0 LogFullNotifyEvent : _KEVENT
   +0x2c8 CheckpointWorkItem : _WORK_QUEUE_ITEM
   +0x2e8 CheckpointTargetLsn : _CLS_LSN
   +0x2f0 LogFullCompletedWorkItem : _WORK_QUEUE_ITEM
   +0x310 LogWriteResource : _ERESOURCE
   +0x378 LogFlags         : 2
   +0x37c LogFullStatus    : 0n0
   +0x380 RecoveryStatus   : 0n0
   +0x388 LastCheckBaseLsn : _CLS_LSN
   +0x390 RestartOrderedList : _LIST_ENTRY [ 0xffffb80f`07cc7b48 - 0xffffb80f`07cc7b48 ]
   +0x3a0 OfflineWorkItem  : _WORK_QUEUE_ITEM


Если стоит цель программно по файловому объекту получить транзакцию, то это делается вызовом ф-ции IoGetTransactionParameterBlock, которая вернет все тот же PTXN_PARAMETER_BLOCK с объектом транзакции внутри.

Комментариев нет:

Отправить комментарий