解析 IRtlFile
要使用对象,需要创建实例,即 NewInstance.Allocate(),大体有三步:
1、分配空间
2、构造对象
3、初始化
一、实例化
//----- (0000000180067820) ----------------------------------------------------
__int64 __fastcall Windows::Rtl::CRtlRefCountedObjectBase<
Windows::Rtl::SystemImplementation::CFile,
Windows::Rtl::IRtlFile,
Windows::Rtl::IRtlSystemObject,
Windows::Rtl::Detail::CRtlRefCountedObjectBaseNoInterface,
Windows::Rtl::Detail::CRtlRefCountedObjectBaseNoInterface>::CreateInstance<
Windows::Rtl::SystemImplementation::CreateFileSource,
Windows::Rtl::IRtlFile>(
struct Windows::Rtl::SystemImplementation::CreateFileSource *a1,
Windows::Rtl::SystemImplementation::CFile **a2)
{
v2 = a1
v3 = a2
// 1、分配空间
LODWORD(v4) = operator new(96i64)
// 2、构造对象
if ( v4 )
v5 = Windows::Rtl::SystemImplementation::CFile::CFile(v4)
else
v5 = 0i64
// 3、初始化
v6 = Windows::Rtl::SystemImplementation::CFile::Initialize(v5, v2)
*v3 = v5
return 0i64
}
二、构造对象,即 CFile::CFile
1、+0 为 Windows::Rtl::SystemImplementation::CFile::`vftable 地址
Windows::Rtl::CRtlRefCountedObjectBase
2、+2 为 Windows::Rtl::SystemImplementation::CFile::`vftable 地址
Windows::Rtl::SystemImplementation::CSystemObject
3、+1 为标志位,1
4、+3 4 5 6 8 9 10 11 清零
5、如果设置了全局变量 g_pTrackTypeDescription,进行记录。
//----- (0000000180067EE8) ----------------------------------------------------
Windows::Rtl::SystemImplementation::CFile *__fastcall Windows::Rtl::SystemImplementation::CFile::CFile(
Windows::Rtl::SystemImplementation::CFile *this)
{
v1 = Windows::Rtl::g_pTrackTypeDescription
v2 = this
// 这两种写法,有什么不一样?
// 如果一样,为什么要写两次;如果不一样,在同一个字段同写两次,后面的肯定会覆盖前面的。
*(_QWORD *)this = Windows::Rtl::CRtlRefCountedObjectBase<
Windows::Rtl::SystemImplementation::CFile,
Windows::Rtl::IRtlFile,
Windows::Rtl::IRtlSystemObject,
Windows::Rtl::Detail::CRtlRefCountedObjectBaseNoInterface,
Windows::Rtl::Detail::CRtlRefCountedObjectBaseNoInterface>::`vftable'
*(_QWORD *)this = Windows::Rtl::SystemImplementation::CFile::`vftable'{for `Windows::Rtl::CRtlRefCountedObjectBase<
Windows::Rtl::SystemImplementation::CFile,
Windows::Rtl::IRtlFile,
Windows::Rtl::IRtlSystemObject,
Windows::Rtl::Detail::CRtlRefCountedObjectBaseNoInterface,
Windows::Rtl::Detail::CRtlRefCountedObjectBaseNoInterface>'}
*((_QWORD *)this + 2) = &Windows::Rtl::SystemImplementation::CSystemObject::`vftable'
*((_QWORD *)this + 2) = &Windows::Rtl::SystemImplementation::CFile::`vftable'{for `Windows::Rtl::SystemImplementation::CSystemObject'}
*((_DWORD *)this + 2) = 1
*((_QWORD *)this + 3) = 0i64
*((_QWORD *)this + 4) = 0i64
*((_QWORD *)this + 5) = 0i64
*((_QWORD *)this + 6) = 0i64
*((_QWORD *)v2 + 8) = 0i64
*((_QWORD *)v2 + 9) = 0i64
*((_QWORD *)v2 + 10) = 0i64
*((_QWORD *)v2 + 11) = 0i64
// 根据全局变量 g_pTrackTypeDescription,记录对象构造过程。
if ( v1 )
{
v3 = *(void (__fastcall **)(struct Windows::Rtl::CRtlTrackTypeDescription *, const char *, signed __int64))(*(_QWORD *)v1 + 16i64)
_guard_check_icall_fptr(*(_QWORD *)(*(_QWORD *)v1 + 16i64))
v3(v1, "CFile", 13i64)
}
result = v2
return result
}
三、初始化
初始化时使用结构:Windows::Rtl::SystemImplementation::CreateFileSource
CFile 对象是继承自 CSystemObject,因此,初始化也分成两步,第一步先初始化 CFile,第二步再初始化 CSystemObject。
另外,前面在构造对象时,一部分别用了 this,另一部分使用了 v2,是否也是因为两个对象所造成的?
//----- (101098B8) --------------------------------------------------------
int __thiscall Windows::Rtl::SystemImplementation::CFile::Initialize(
Windows::Rtl::SystemImplementation::CFile *this,
const struct Windows::Rtl::SystemImplementation::CreateFileSource *a2)
{
Windows::Rtl::SystemImplementation::CFile *v2
v2 = this
// +8 是 IRtlFileSystemProvider 的地址
v3 = Windows::Rtl::IRtlObject::CreateRequiredInterface<
Windows::Rtl::SystemImplementation::IRtlFileSystemProvider>(
*(void **)a2,
(int *)this + 8)
// +3 是 IRtlObjectProvider 的地址
v3 = Windows::Rtl::IRtlObject::CreateRequiredInterface<
Windows::Rtl::SystemImplementation::IRtlObjectProvider>(
*(void **)a2,
(int *)v2 + 3)
// 把 CreateFileSource 中的 Name 复制到来
// +5 ==> +9
v4 = RtlDuplicateLUnicodeString((int)a2 + 20, (int)v2 + 36)
v3 = v4
// 初始化 CSystemObject
// +2 是 CSystemObject 的地址
v3 = Windows::Rtl::SystemImplementation::CSystemObject::Initialize(
(Windows::Rtl::SystemImplementation::CFile *)((char *)v2 + 8),
a2)
if ( v3 < 0 )
return v3
return 0
}
int __thiscall Windows::WCP::Implementation::CAllocationPool::Allocate<
Windows::Auto<Windows::Rtl::IRtlFile >>(
Windows::WCP::Implementation::CAllocationPool *this,
int a2)
{
_DWORD *v2
*(_DWORD *)a2 = 0
v2 = Windows::WCP::Implementation::CAllocationPool::Allocate(
this,
4u,
Windows::Auto<Windows::Rtl::IRtlSystemIsolationLayer *>::~Auto<Windows::Rtl::IRtlSystemIsolationLayer *>)
if ( v2 )
{
*v2 = 0
*(_DWORD *)a2 = v2
}
return *(_DWORD *)a2
}
void *__thiscall Windows::WCP::Implementation::CAllocationPool::Allocate(
Windows::WCP::Implementation::CAllocationPool *this,
unsigned __int32 a2, void (__fastcall *a3)(void *))
{
BUCL::CDequeBase *v3
v3 = this
if ( a2 < 0xFFFFFFEF )
{
v5 = RtlAllocateHeap(*(HANDLE *)(__readfsdword(48) + 24), 0, a2 + 16)
// 前面的 IRtlFile,这里是 4,说明 IRtlFile 有 5 个字段
v7 = v5
if ( v5 )
{ // 把前 3 个字段清空
v5[2] = 0
*v5 = 0
v5[1] = 0
}
else
{
v7 = 0
}
if ( v7 )
{ // 这里也是清空的动作,v3 即 this,可以是不同的类型,比如 IRtlFile
v7[3] = a3
BUCL::CDequeBase::InsertBefore(v3, v3, (struct BUCL::CDequeLinkage *)v7, v6)
result = v7 + 4
}
else
{
result = 0
}
}
else
{
result = 0
}
return result
}
创建接口
//----- (000000018006B3E0) ----------------------------------------------------
__int64 __fastcall Windows::Rtl::CRtlRefCountedObjectBase<
Windows::Rtl::SystemImplementation::CFile,
Windows::Rtl::IRtlFile,
Windows::Rtl::IRtlSystemObject,
Windows::Rtl::Detail::CRtlRefCountedObjectBaseNoInterface,
Windows::Rtl::Detail::CRtlRefCountedObjectBaseNoInterface>::
CreateInterface(
__int64 a1,
__int64 a2,
int (__fastcall ****a3)(_QWORD))
{
v3 = 0
v12 = C00000E5
v4 = a3
v5 = a2
v6 = a1
// a2 - IID
// 38218435_079f_49e9_bb3f_149cb22b88cd - 所有的接口都有这个 IID,可能是 System
// 144aa3c6_22ad_4666_91ee_064d0aa0179e - 这个接口和 CIniFile 有
// e42c887e_3ed6_4087_a172_d346ab63a13a - 有四个
// a3 - pObject
if ( a3 )
{
Windows::AutoPointerBase<Windows::Cdf::Rtl::IRtlCdfUlongTableEnumerator *,Windows::Auto<Windows::Cdf::Rtl::IRtlCdfUlongTableEnumerator *>>::Close(a3)
if ( *(_QWORD *)v5 == *(_QWORD *)&GUID_38218435_079f_49e9_bb3f_149cb22b88cd.Data1
&& *(_QWORD *)(v5 + 8) == *(_QWORD *)&GUID_38218435_079f_49e9_bb3f_149cb22b88cd.Data4[0]
|| *(_QWORD *)v5 == *(_QWORD *)&GUID_144aa3c6_22ad_4666_91ee_064d0aa0179e.Data1
&& *(_QWORD *)(v5 + 8) == *(_QWORD *)&GUID_144aa3c6_22ad_4666_91ee_064d0aa0179e.Data4[0]
|| *(_QWORD *)v5 == *(_QWORD *)&GUID_e42c887e_3ed6_4087_a172_d346ab63a13a.Data1
&& *(_QWORD *)(v5 + 8) == *(_QWORD *)&GUID_e42c887e_3ed6_4087_a172_d346ab63a13a.Data4[0] )
{
_InterlockedIncrement((volatile signed __int32 *)(v6 + 8))
*v4 = v6
}
}
// 出错
return (unsigned int)v3
// 32 位的更直观
if ( a3 )
{
Windows::AutoPointerBase<Windows::Cdf::Rtl::IRtlCdfStringTableEnumerator *,Windows::Auto<Windows::Cdf::Rtl::IRtlCdfStringTableEnumerator *>>::Close(a3)
if ( IsEqualGUID(a2, (int)&_GUID_38218435_079f_49e9_bb3f_149cb22b88cd)
|| IsEqualGUID(v6, (int)&_GUID_144aa3c6_22ad_4666_91ee_064d0aa0179e)
|| IsEqualGUID(v7, (int)&_GUID_e42c887e_3ed6_4087_a172_d346ab63a13a) )
{
_InterlockedIncrement((volatile signed __int32 *)v3 + 1)
*(_DWORD *)a3 = v3
}
result = 0
}
}
析构函数
//----- (0000000180068C40) ----------------------------------------------------
void *__fastcall Windows::Rtl::CRtlRefCountedObjectBase<
Windows::Rtl::SystemImplementation::CFile,
Windows::Rtl::IRtlFile,
Windows::Rtl::IRtlSystemObject,
Windows::Rtl::Detail::CRtlRefCountedObjectBaseNoInterface,
Windows::Rtl::Detail::CRtlRefCountedObjectBaseNoInterface>::
`vector deleting destructor'(void *a1, char a2)
{
void *v2
v2 = a1
*(_QWORD *)a1 = Windows::Rtl::IRtlObject::`vftable'
if ( a2 & 1 )
operator delete(a1)
return v2
}
示例 GetName
//----- (10109770) --------------------------------------------------------
Windows::Rtl::SystemImplementation::CFile::GetName(unsigned long,class Windows::Auto<struct _LUNICODE_STRING> *)
int __userpurge Windows::Rtl::SystemImplementation::CFile::GetName@<eax>(
struct Windows::WCP::Rtl::_RTL_TRACING_FACILITY *a1@<edx>,
int a2@<ecx>,
char *a3@<edi>,
char a4, // 0 - error
int a5)
{
v20 = 0
v5 = a2
v17 = C00000E5
v21 = 0
v19 = 1
if ( (unsigned __int8)Windows::WCP::Rtl::CEnterExitTracer<Windows::ErrorHandling::COM::CSimpleHResultCarryingFrame,6>::ShouldArm(
(Windows::WCP::Rtl *)&Facility_SIL,
a1) )
Windows::WCP::Rtl::CEnterExitTracer<Windows::ErrorHandling::Rtl::CSimpleNtStatusCarryingFrame,7>::Arm(
&v18,
(int)&v17,
v6,
v5,
(int)"Windows::Rtl::SystemImplementation::CFile::GetName",
v6)
if ( a4 & 2 )
{
v7 = RtlDuplicateLUnicodeString(v5 + 36, a5)
if ( v7 >= 0 )
{
v8 = *(_DWORD *)a5
if ( *(_DWORD *)a5 > 2u && *(_WORD *)(*(_DWORD *)(a5 + 8) + 2 * (v8 >> 1) - 2) == 92 )
*(_DWORD *)a5 = v8 - 2
LABEL_8:
v21 = 1
Windows::ErrorHandling::Rtl::CBaseFrame<Windows::ErrorHandling::Rtl::CVoidRaiseFrame>::SetCanonicalSuccess(&v17)
v9 = v17
Windows::WCP::Rtl::CEnterExitTracer<Windows::ErrorHandling::Rtl::CSimpleNtStatusCarryingFrame,7>::~CEnterExitTracer<Windows::ErrorHandling::Rtl::CSimpleNtStatusCarryingFrame,7>(
(int)&v18,
(int)a3)
return v9
}
}
else
{
if ( !(a4 & 1) )
goto LABEL_8
v11 = v5 + 36
v12 = *(_DWORD *)v11
v11 += 4
v13 = *(_DWORD *)v11
v14 = *(_DWORD *)(v11 + 4)
a3 = &v15
if ( v12 > 2 && *(_WORD *)(v14 + 2 * (v12 >> 1) - 2) == 92 )
v12 -= 2
v7 = RtlSplitLUnicodeString(2, (int)&v12, 0, 0, 0x5Cu, (int)&v16, (int)&v15)
if ( v7 >= 0 )
{
v7 = RtlDuplicateLUnicodeString((int)&v15, a5)
if ( v7 >= 0 )
goto LABEL_8
}
}
v17 = v7
Windows::WCP::Rtl::CEnterExitTracer<Windows::ErrorHandling::Rtl::CSimpleNtStatusCarryingFrame,7>::~CEnterExitTracer<Windows::ErrorHandling::Rtl::CSimpleNtStatusCarryingFrame,7>(
(int)&v18,
(int)a3)
return v17
}
示例
//----- (0000000180202DB0) ----------------------------------------------------
__int64 __fastcall Windows::Rtl::DeltaDecompressFile(
Windows::Rtl *this,
struct Windows::Rtl::IRtlFile *a2,
__int64 a3,
struct Windows::Rtl::IRtlFile *a4,
struct Windows::Rtl::IRtlFile *a5)
{
// 总觉得这里的顺序不是太对,应该是两个输入文件,一个输出文件
// 即,a2 a3 是输入,a4 是输出
v5 = a4
v6 = a3
v7 = a2
v8 = this
v9 = `anonymous namespace'::ValidateDeltaBufferCompressorInitialized()
if ( v9 < 0 )
return (unsigned int)v9
v15 = 0i64
*(_QWORD *)v14 = 0i64
v16 = 0i64
v18 = 0i64
v17 = 0i64
v19 = 0i64
if ( v8
&& (v10 = *(int (__fastcall **)(Windows::Rtl *, _QWORD, unsigned __int32 *, _QWORD))(*(_QWORD *)v8 + 48i64),
_guard_check_icall_fptr(*(_QWORD *)(*(_QWORD *)v8 + 48i64)),
v9 = v10(v8, 0i64, v14, 0i64),
v9 < 0)
// 读 a2 到 v14,
// +6 是读操作
|| (v11 = *(int (__fastcall **)(__int64, _QWORD, struct _LBLOB **, _QWORD))(*(_QWORD *)v6 + 48i64),
_guard_check_icall_fptr(*(_QWORD *)(*(_QWORD *)v6 + 48i64)),
v9 = v11(v6, 0i64, &v17, 0i64),
v9 < 0) )
// 读 a3 到 v17
{
LABEL_8:
Windows::Rtl::AutoBlob<Windows::Auto<_LBLOB>>::Close((__int64)&v17)
Windows::Rtl::AutoBlob<Windows::Auto<_LBLOB>>::Close((__int64)v14)
return (unsigned int)v9
}
v21 = 0i64
v20 = 0i64
v22 = 0i64
v9 = Windows::Rtl::DeltaDecompressBuffer(
(Windows::Rtl *)3,
(__int64)v14,
v7,
(__int64)&v17,
(struct _LBLOB *)&v20,
v18)
if ( v9 < 0
|| (v12 = *(int (__fastcall **)(struct Windows::Rtl::IRtlFile *, _QWORD, __int64 *))(*(_QWORD *)v5 + 56i64),
// a4,目标文件,这里是写文件,把 v20 写到 a4
// +7 是写操作
_guard_check_icall_fptr(*(_QWORD *)(*(_QWORD *)v5 + 56i64)),
v9 = v12(v5, 0i64, &v20),
v9 < 0) )
{
Windows::Rtl::AutoDeltaBlob::Close((Windows::Rtl::AutoDeltaBlob *)&v20)
goto LABEL_8
}
Windows::Rtl::AutoDeltaBlob::Close((Windows::Rtl::AutoDeltaBlob *)&v20)
Windows::Rtl::AutoBlob<Windows::Auto<_LBLOB>>::Close((__int64)&v17)
Windows::Rtl::AutoBlob<Windows::Auto<_LBLOB>>::Close((__int64)v14)
return 0i64
}
示例 OpenFilesystemFile
//----- (0000000180086758) ----------------------------------------------------
__int64 __usercall Windows::Rtl::SystemImplementation::CSystemIsolationLayer::
OpenFilesystemFile@<rax>(
char a1@<dl>,
__int64 a2@<rcx>,
_DWORD *a3@<rbx>,
unsigned int a4@<r8d>,
const struct _LUNICODE_STRING *a5@<r9>)
{
v5 = a3
v6 = a5
v7 = a1
v20 = a4
v8 = a2
v37 = C00000E5
if ( a3 )
*a3 = 0
v25 = -1i64
v33 = 0i64
v34 = &v40
_mm_store_si128((__m128i *)&v23, 0i64)
_mm_store_si128((__m128i *)&v24, 0i64)
_mm_storeu_si128((__m128i *)&v38, 0i64)
v32 = 48
_mm_storeu_si128((__m128i *)&v36, 0i64)
v35 = 64
v9 = RtlInitUnicodeStringFromLUnicodeStringSafely(a5, &v40)
if ( v9 < 0 )
goto LABEL_24
v10 = *(_QWORD *)(v8 + 56)
v11 = *(int (__fastcall **)(__int64, __int64 *))(*(_QWORD *)v10 + 24i64)
_guard_check_icall_fptr(*(_QWORD *)(*(_QWORD *)v10 + 24i64))
v9 = v11(v10, &v21)
if ( v9 < 0 )
goto LABEL_24
v12 = 0
if ( v7 & 1 )
v12 = 2
if ( v7 & 2 )
v12 |= 4u
if ( v7 & 8 )
v12 |= 0x80u
if ( v7 & 0x10 )
v12 |= 0x200u
if ( v7 & 0x20 )
v12 |= 0x400u
v13 = v7 & 4
if ( v13 && vars30 & 2 )
{
Windows::ErrorHandling::Rtl::CBaseFrame<Windows::ErrorHandling::Rtl::CVoidRaiseFrame>::SetInvalidParameter(&v37)
Windows::Rtl::SystemImplementation::CSilHandle::~CSilHandle((Windows::Rtl::SystemImplementation::CSilHandle *)&v38)
v30 = 622
v28 = "base\\wcp\\sil\\systemisolationlayer.cpp"
v29 = "Windows::Rtl::SystemImplementation::CSystemIsolationLayer::OpenFilesystemFile"
v31 = "(ShareAccess & 0x00000002) == 0"
Windows::ErrorHandling::Rtl::CBaseFrame<Windows::ErrorHandling::Rtl::CVoidRaiseFrame>::ReportErrorOrigination(
&v37,
(__int64)&v28)
return v37
}
v14 = *(_QWORD *)(v8 + 32)
v15 = *(int (__fastcall **)(__int64, _QWORD, __int128 *, _QWORD))(*(_QWORD *)v14 + 72i64)
_guard_check_icall_fptr(*(_QWORD *)(*(_QWORD *)v14 + 72i64))
*(_QWORD *)&v23 = &v39
v22 = v21
LODWORD(v21) = 0
v9 = v15(v14, (unsigned int)v12, &v38, v20)
if ( v9 < 0 )
{
LABEL_24:
Windows::Rtl::SystemImplementation::CSilHandle::~CSilHandle((Windows::Rtl::SystemImplementation::CSilHandle *)&v38)
return (unsigned int)v9
}
if ( v39 == 1 )
{
v17 = *((_QWORD *)v6 + 2)
v25 = *((_QWORD *)&v38 + 1)
*(_QWORD *)&v23 = *(_QWORD *)(v8 + 32)
*((_QWORD *)&v23 + 1) = *(_QWORD *)(v8 + 40)
*(_QWORD *)&v24 = *(_QWORD *)(v8 + 48)
*((_QWORD *)&v24 + 1) = *(_QWORD *)(v8 + 56)
v27 = v17
v26 = *(_OWORD *)v6
if ( v13 )
v18 = Windows::Rtl::CRtlOneShotTypeDescriptionInit<Windows::Rtl::SystemImplementation::CIniFile>::CreateInstance<Windows::Rtl::SystemImplementation::CIniFile_IRtlIniFileTearoff,Windows::Rtl::SystemImplementation::CreateFileSource,Windows::Rtl::IRtlFile>(
v16,
(struct Windows::Rtl::OneShotTypeDescriptionRecord *)&v23,
0i64)
else
v18 = Windows::Rtl::CRtlRefCountedObjectBase<Windows::Rtl::SystemImplementation::CFile,Windows::Rtl::IRtlFile,Windows::Rtl::IRtlSystemObject,Windows::Rtl::Detail::CRtlRefCountedObjectBaseNoInterface,Windows::Rtl::Detail::CRtlRefCountedObjectBaseNoInterface>::CreateInstance<Windows::Rtl::SystemImplementation::CreateFileSource,Windows::Rtl::IRtlFile>(
(struct Windows::Rtl::SystemImplementation::CreateFileSource *)&v23,
0i64)
v9 = v18
if ( v18 < 0 )
goto LABEL_24
if ( v5 )
*v5 = 1
}
else if ( v5 )
{
switch ( v39 )
{
case 3:
*v5 = 2
break
case 4:
*v5 = 3
break
case 9:
*v5 = 4
break
case 11:
*v5 = 5
break
case 12:
*v5 = 6
break
}
}
Windows::Rtl::SystemImplementation::CSilHandle::~CSilHandle((Windows::Rtl::SystemImplementation::CSilHandle *)&v38)
return 0i64
}