Skip to content

Commit 5ae0961

Browse files
committed
Refactored NodeDissector.
1 parent c0e472d commit 5ae0961

1 file changed

Lines changed: 63 additions & 46 deletions

File tree

ReClass.NET/Memory/NodeDissector.cs

Lines changed: 63 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,28 @@ public static void DissectNodes(IEnumerable<BaseHexNode> nodes, MemoryBuffer mem
1717

1818
foreach (var node in nodes)
1919
{
20-
var type = GuessExplicitNode(node, memory);
21-
if (type != null)
20+
if (GuessNode(node, memory, out var guessedNode))
2221
{
23-
node.GetParentContainer()?.ReplaceChildNode(node, type);
22+
node.GetParentContainer()?.ReplaceChildNode(node, guessedNode);
2423
}
2524
}
2625
}
2726

28-
public static BaseNode GuessExplicitNode(BaseHexNode node, MemoryBuffer memory)
27+
public static bool GuessNode(BaseHexNode node, MemoryBuffer memory, out BaseNode guessedNode)
2928
{
3029
Contract.Requires(node != null);
3130
Contract.Requires(memory != null);
3231

32+
guessedNode = null;
33+
3334
var offset = node.Offset;
3435
var is4ByteAligned = offset % 4 == 0;
3536
var is8ByteAligned = offset % 8 == 0;
3637

3738
// The node is not aligned, skip it.
3839
if (!is4ByteAligned)
3940
{
40-
return null;
41+
return false;
4142
}
4243

4344
var data64 = memory.ReadObject<UInt64FloatDoubleData>(offset);
@@ -46,46 +47,48 @@ public static BaseNode GuessExplicitNode(BaseHexNode node, MemoryBuffer memory)
4647
var raw = memory.ReadBytes(offset, node.MemorySize);
4748
if (raw.InterpretAsUtf8().IsLikelyPrintableData() >= 0.75f)
4849
{
49-
return new Utf8TextNode();
50+
guessedNode = new Utf8TextNode();
51+
52+
return true;
5053
}
5154
if (raw.InterpretAsUtf16().IsLikelyPrintableData() >= 0.75f)
5255
{
53-
return new Utf16TextNode();
56+
guessedNode = new Utf16TextNode();
57+
58+
return true;
5459
}
5560

61+
#if RECLASSNET64
5662
if (is8ByteAligned)
5763
{
58-
#if RECLASSNET64
59-
var pointerType = GuessPointerNode(data64.IntPtr, memory);
60-
if (pointerType != null)
64+
if (GuessPointerNode(data64.IntPtr, memory.Process, out guessedNode))
6165
{
62-
return pointerType;
66+
return true;
6367
}
64-
#endif
6568
}
69+
#else
70+
if (GuessPointerNode(data32.IntPtr, memory.Process, out guessedNode))
71+
{
72+
return true;
73+
}
74+
#endif
6675

76+
// 0 could be anything.
77+
if (data32.IntValue != 0)
6778
{
68-
#if RECLASSNET32
69-
var pointerNode = GuessPointerNode(data32.IntPtr, memory);
70-
if (pointerNode != null)
79+
// If the data represents a reasonable range, it could be a float.
80+
if (-999999.0f <= data32.FloatValue && data32.FloatValue <= 999999.0f && !data32.FloatValue.IsNearlyEqual(0.0f, 0.001f))
7181
{
72-
return pointerNode;
82+
guessedNode = new FloatNode();
83+
84+
return true;
7385
}
74-
#endif
7586

76-
// 0 could be anything.
77-
if (data32.IntValue != 0)
87+
if (-999999 <= data32.IntValue && data32.IntValue <= 999999)
7888
{
79-
// If the data represents a reasonable range, it could be a float.
80-
if (-999999.0f <= data32.FloatValue && data32.FloatValue <= 999999.0f && !data32.FloatValue.IsNearlyEqual(0.0f, 0.001f))
81-
{
82-
return new FloatNode();
83-
}
89+
guessedNode = new Int32Node();
8490

85-
if (-999999 <= data32.IntValue && data32.IntValue <= 999999)
86-
{
87-
return new Int32Node();
88-
}
91+
return true;
8992
}
9093
}
9194

@@ -96,60 +99,74 @@ public static BaseNode GuessExplicitNode(BaseHexNode node, MemoryBuffer memory)
9699
// If the data represents a reasonable range, it could be a double.
97100
if (-999999.0 <= data64.DoubleValue && data64.DoubleValue <= 999999.0 && !data64.DoubleValue.IsNearlyEqual(0.0, 0.001))
98101
{
99-
return new DoubleNode();
102+
guessedNode = new DoubleNode();
103+
104+
return true;
100105
}
101106
}
102107
}
103108

104-
return null;
109+
return false;
105110
}
106111

107-
private static BaseNode GuessPointerNode(IntPtr address, MemoryBuffer memory)
112+
private static bool GuessPointerNode(IntPtr address, IProcessReader process, out BaseNode node)
108113
{
109-
Contract.Requires(memory != null);
114+
Contract.Requires(process != null);
115+
116+
node = null;
110117

111118
if (address.IsNull())
112119
{
113-
return null;
120+
return false;
114121
}
115122

116-
var section = memory.Process.GetSectionToPointer(address);
123+
var section = process.GetSectionToPointer(address);
117124
if (section == null)
118125
{
119-
return null;
126+
return false;
120127
}
121128

122129
if (section.Category == SectionCategory.CODE) // If the section contains code, it should be a function pointer.
123130
{
124-
return new FunctionPtrNode();
131+
node = new FunctionPtrNode();
132+
133+
return true;
125134
}
126135
if (section.Category == SectionCategory.DATA || section.Category == SectionCategory.HEAP) // If the section contains data, it is at least a pointer to a class or something.
127136
{
128137
// Check if it is a vtable. Check if the first 3 values are pointers to a code section.
129-
var possibleVmt = memory.Process.ReadRemoteObject<ThreePointersData>(address);
130-
if (memory.Process.GetSectionToPointer(possibleVmt.Pointer1)?.Category == SectionCategory.CODE
131-
&& memory.Process.GetSectionToPointer(possibleVmt.Pointer2)?.Category == SectionCategory.CODE
132-
&& memory.Process.GetSectionToPointer(possibleVmt.Pointer3)?.Category == SectionCategory.CODE)
138+
var possibleVmt = process.ReadRemoteObject<ThreePointersData>(address);
139+
if (process.GetSectionToPointer(possibleVmt.Pointer1)?.Category == SectionCategory.CODE
140+
&& process.GetSectionToPointer(possibleVmt.Pointer2)?.Category == SectionCategory.CODE
141+
&& process.GetSectionToPointer(possibleVmt.Pointer3)?.Category == SectionCategory.CODE)
133142
{
134-
return new VirtualMethodTableNode();
143+
node = new VirtualMethodTableNode();
144+
145+
return true;
135146
}
136147

137148
// Check if it is a string.
138-
var data = memory.Process.ReadRemoteMemory(address, IntPtr.Size * 2);
149+
var data = process.ReadRemoteMemory(address, IntPtr.Size * 2);
139150
if (data.Take(IntPtr.Size).InterpretAsUtf8().IsLikelyPrintableData() >= 07.5f)
140151
{
141-
return new Utf8TextPtrNode();
152+
node = new Utf8TextPtrNode();
153+
154+
return true;
142155
}
143156
if (data.InterpretAsUtf16().IsLikelyPrintableData() >= 0.75f)
144157
{
145-
return new Utf16TextPtrNode();
158+
node = new Utf16TextPtrNode();
159+
160+
return true;
146161
}
147162

148163
// Now it could be a pointer to something else but we can't tell. :(
149-
return new PointerNode();
164+
node = new PointerNode();
165+
166+
return true;
150167
}
151168

152-
return null;
169+
return false;
153170
}
154171
}
155172
}

0 commit comments

Comments
 (0)