1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
EObjectFlags ObjectFlags;
/
*
*
Index into GObjectArray...very private.
*
/
int32 InternalIndex;
/
*
*
Class the
object
belongs to.
*
/
UClass
*
ClassPrivate;
/
*
*
Name of this
object
*
/
FName NamePrivate;
/
*
*
Object
this
object
resides
in
.
*
/
UObject
*
OuterPrivate;
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
/
*
补充一下FName的结构,想要更详细了解请参阅引擎源码中
"NameTypes.h"
这里要特别注意,不同引擎版本这三个的顺序不一样哦,有的版本(
5.x
),会把Number放在最后,但其实这三个影响不大,管他究竟是哪个,试三次总能对.(其实用到的永远是第一个,第一个位置不变)
*
/
private:
FNameEntryId ComparisonIndex;
#if !UE_FNAME_OUTLINE_NUMBER
uint32 Number;
#endif// ! //UE_FNAME_OUTLINE_NUMBER
#if WITH_CASE_PRESERVING_NAME
FNameEntryId DisplayIndex;
#endif // WITH_CASE_PRESERVING_NAME
/
/
记住啦,一会还要用到它!
|
1
2
3
4
5
6
7
8
9
10
11
|
FORCEINLINE FString GetName() const
{
if
(this !
=
nullptr)
{
return
NamePrivate.ToString();
}
else
{
return
TEXT(
"None"
);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
String FName::ToString() const
{
/
/
With UE_FNAME_OUTLINE_NUMBER reading number isn't free so skip this check
#if !UE_FNAME_OUTLINE_NUMBER
if
(GetNumber()
=
=
NAME_NO_NUMBER_INTERNAL)
{
/
/
Avoids some extra allocations
in
non
-
number case
return
GetDisplayNameEntry()
-
>GetPlainNameString();
}
#endif // !UE_FNAME_OUTLINE_NUMBER
FString Out;
ToString(Out);
return
Out;
}
|
1
|
GetDisplayNameEntry()
-
>GetPlainNameString();
|
1
2
3
4
|
const FNameEntry
*
FName::GetDisplayNameEntry() const
{
return
ResolveEntryRecursive(GetDisplayIndexInternal());
}
|
1
2
3
4
5
6
7
8
|
FORCEINLINE FNameEntryId GetDisplayIndexInternal() const
{
#if WITH_CASE_PRESERVING_NAME
return
DisplayIndex;
#else // WITH_CASE_PRESERVING_NAME
return
ComparisonIndex;
#endif // WITH_CASE_PRESERVING_NAME
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
/
/
"UnrealNames.cpp"
const FNameEntry
*
FName::ResolveEntryRecursive(FNameEntryId LookupId)
{
const FNameEntry
*
Entry
=
ResolveEntry(LookupId);
/
/
下面都是错误处理,主要看上边这一行.
#if UE_FNAME_OUTLINE_NUMBER
if
(Entry
-
>Header.
Len
=
=
0
)
{
return
ResolveEntry(Entry
-
>NumberedName.
Id
);
}
else
#endif
{
return
Entry;
}
}
|
1
2
3
4
|
const FNameEntry
*
FName::ResolveEntry(FNameEntryId LookupId)
{
return
&GetNamePool().Resolve(LookupId);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
/
/
再次分析之前需要看一下这个频繁出现的FNameEntryId究竟是什么
struct FNameEntryId{
private:
uint32 Value;
}
/
/
他真的只是存了一个
ID
(
4bits
uint32),那么FNameEntry呢
struct FNameEntry
{
private:
#if WITH_CASE_PRESERVING_NAME
FNameEntryId ComparisonId;
#endif
FNameEntryHeader Header;
union
{
ANSICHAR AnsiName[NAME_SIZE];
WIDECHAR WideName[NAME_SIZE];
#if UE_FNAME_OUTLINE_NUMBER
struct
{
FNameEntryId
Id
;
uint32 Number;
} NumberedName;
#endif // UE_FNAME_OUTLINE_NUMBER
};
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
static
bool
bNamePoolInitialized;
alignas(FNamePool) static uint8 NamePoolData[sizeof(FNamePool)];
static FNamePool& GetNamePool()
{
if
(bNamePoolInitialized)
{
return
*
(FNamePool
*
)NamePoolData;
}
FNamePool
*
Singleton
=
new (NamePoolData) FNamePool;
bNamePoolInitialized
=
true;
return
*
Singleton;
}
|
1
2
3
4
5
6
|
return
&GetNamePool().Resolve(LookupId);
/
/
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
FNameEntry& Resolve(FNameEntryHandle Handle) const
{
return
Entries.Resolve(Handle);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
struct FNameEntryHandle
{
uint32 Block
=
0
;
uint32 Offset
=
0
;
FNameEntryHandle(uint32 InBlock, uint32 InOffset)
: Block(InBlock)
, Offset(InOffset)
{
checkName(Block < FNameMaxBlocks);
checkName(Offset < FNameBlockOffsets);
}
FNameEntryHandle(FNameEntryId
Id
)
: Block(
Id
.ToUnstableInt() >> FNameBlockOffsetBits)
, Offset(
Id
.ToUnstableInt() & (FNameBlockOffsets
-
1
))
{
}
operator FNameEntryId() const
{
return
FNameEntryId::FromUnstableInt(Block << FNameBlockOffsetBits | Offset);
}
explicit operator
bool
() const {
return
Block | Offset; }
};
|
1
2
3
4
5
|
FNameEntryHandle(FNameEntryId
Id
)
: Block(
Id
.ToUnstableInt() >> FNameBlockOffsetBits)
, Offset(
Id
.ToUnstableInt() & (FNameBlockOffsets
-
1
))
{
}
|
1
|
uint32 ToUnstableInt() const {
return
Value; }
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
/
/
可以轻松的在
"UnrealName.cpp"
找到这些,他们都放在一起哦
static constexpr uint32 FNameMaxBlockBits
=
13
;
static constexpr uint32 FNameBlockOffsetBits
=
16
;
static constexpr uint32 FNameMaxBlocks
=
1
<< FNameMaxBlockBits;
static constexpr uint32 FNameBlockOffsets
=
1
<< FNameBlockOffsetBits;
static constexpr uint32 FNameEntryIdBits
=
FNameBlockOffsetBits
+
FNameMaxBlockBits;
static constexpr uint32 FNameEntryIdMask
=
(
1
<< FNameEntryIdBits )
-
1
;
我把他丢给了Claude:
好的,已知:
static constexpr uint32 FNameMaxBlockBits
=
13
;
static constexpr uint32 FNameBlockOffsetBits
=
16
;
根据这两个已知值,可以计算出剩余值:
static constexpr uint32 FNameMaxBlocks
=
1
<< FNameMaxBlockBits;
这里FNameMaxBlockBits是
13
,
1
左移
13
位结果是:
8192
所以:
static constexpr uint32 FNameMaxBlocks
=
8192
;
static constexpr uint32 FNameBlockOffsets
=
1
<< FNameBlockOffsetBits;
这里FNameBlockOffsetBits是
16
,
1
左移
16
位结果是:
65536
所以:
static constexpr uint32 FNameBlockOffsets
=
65536
;
static constexpr uint32 FNameEntryIdBits
=
FNameBlockOffsetBits
+
FNameMaxBlockBits;
FNameBlockOffsetBits
+
FNameMaxBlockBits
=
16
+
13
=
29
所以:
static constexpr uint32 FNameEntryIdBits
=
29
;
static constexpr uint32 FNameEntryIdMask
=
(
1
<< FNameEntryIdBits)
-
1
;
1
左移
29
位结果是:
536870912
,减
1
则是:
536870911
所以:
static constexpr uint32 FNameEntryIdMask
=
536870911
;
请确认我的计算结果是否正确,如果有任何问题,请随时提出来讨论!
姑且就认为他的计算正确吧.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
auto
Id
=
ComparisonIndex;
Handle.Block
=
(
Id
.Value >>
16
);
Handle.Offset
=
(
Id
.Value &
65535
);
/
/
再加上一开始的
FNameEntry& Resolve(FNameEntryHandle Handle) const
{
return
*
reinterpret_cast<FNameEntry
*
>(
Blocks[Handle.Block]
+
Stride
*
Handle.Offset
);
}
/
/
Stride
=
4
因为 enum { Stride
=
alignof(FNameEntry) };
/
/
(手动奸笑)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
class
FNameEntryAllocator
{
mutable FRWLock Lock;
uint32 CurrentBlock
=
0
;
uint32 CurrentByteCursor
=
0
;
uint8
*
Blocks[FNameMaxBlocks]
=
{};
}
class
FNamePool
{
private:
enum { MaxENames
=
512
};
FNameEntryAllocator Entries;
};
alignas(FNamePool) static uint8 NamePoolData[sizeof(FNamePool)];
const FNameEntry
*
FName::ResolveEntry(FNameEntryId LookupId)
{
return
&GetNamePool().Resolve(LookupId);
}
|
1
2
3
4
5
6
7
8
9
10
|
/
/
FRWLock占用
8Bits
原因是:
mutable FRWLock Lock;
↓
typedef FHoloLensRWLock FRWLock;
↓
class
FPThreadsRWLock
{
private:
pthread_rwlock_t Mutex;
/
/
指针类型
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
struct FNameEntry
{
private:
#if WITH_CASE_PRESERVING_NAME
FNameEntryId Compariso nId;
#endif
FNameEntryHeader Header;
union
{
ANSICHAR AnsiName[NAME_SIZE];
WIDECHAR WideName[NAME_SIZE];
#if UE_FNAME_OUTLINE_NUMBER
struct
{
FNameEntryId
Id
;
uint32 Number;
} NumberedName;
#endif // UE_FNAME_OUTLINE_NUMBER
};
/
/
好熟悉的
#if WITH_CASE_PRESERVING_NAME
|
更多【UnrealEngine 5 逆向之类名算法的分析】相关视频教程:www.yxfzedu.com