-
Notifications
You must be signed in to change notification settings - Fork 402
Expand file tree
/
Copy pathNodeDissector.cs
More file actions
160 lines (141 loc) · 3.97 KB
/
Copy pathNodeDissector.cs
File metadata and controls
160 lines (141 loc) · 3.97 KB
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using ReClassNET.Nodes;
using ReClassNET.Util;
namespace ReClassNET.Memory
{
public class NodeDissector
{
public static void DissectNodes(IEnumerable<BaseHexNode> nodes, MemoryBuffer memory)
{
Contract.Requires(nodes != null);
Contract.Requires(memory != null);
foreach (var node in nodes)
{
var type = GuessType(node, memory);
if (type != null)
{
node.ParentNode.ReplaceChildNode(node, type);
}
}
}
public static Type GuessType(BaseHexNode node, MemoryBuffer memory)
{
Contract.Requires(node != null);
Contract.Requires(memory != null);
var offset = node.Offset.ToInt32();
var is4ByteAligned = offset % 4 == 0;
var is8ByteAligned = offset % 8 == 0;
// The node is not aligned, skip it.
if (!is4ByteAligned)
{
return null;
}
var data64 = memory.ReadObject<UInt64FloatDoubleData>(offset);
var data32 = memory.ReadObject<UInt32FloatData>(offset);
var raw = memory.ReadBytes(offset, node.MemorySize);
if (raw.InterpretAsUTF8().IsLikelyPrintableData() >= 0.5f)
{
return typeof(UTF8TextNode);
}
else if (raw.InterpretAsUTF16().IsLikelyPrintableData() >= 0.5f)
{
return typeof(UTF16TextNode);
}
if (is8ByteAligned)
{
#if WIN64
var pointerType = GuessPointerType(data64.IntPtr, memory);
if (pointerType != null)
{
return pointerType;
}
#endif
}
if (is4ByteAligned)
{
#if WIN32
var pointerType = GuessPointerType(data32.IntPtr, memory);
if (pointerType != null)
{
return pointerType;
}
#endif
// 0 could be anything.
if (data32.IntValue != 0)
{
// If the data represents a reasonable range, it could be a float.
if (-99999.0f <= data32.FloatValue && data32.FloatValue <= 99999.0f && !data32.FloatValue.IsNearlyEqual(0.0f, 0.001f))
{
return typeof(FloatNode);
}
if (-99999 <= data32.IntValue && data32.IntValue <= 99999)
{
return typeof(Int32Node);
}
}
}
if (is8ByteAligned)
{
if (data64.LongValue != 0)
{
// If the data represents a reasonable range, it could be a double.
if (-99999.0 <= data64.DoubleValue && data64.DoubleValue <= 99999.0 && !data64.DoubleValue.IsNearlyEqual(0.0, 0.001))
{
return typeof(DoubleNode);
}
}
}
return null;
}
private static Type GuessPointerType(IntPtr address, MemoryBuffer memory)
{
Contract.Requires(memory != null);
if (address.IsNull())
{
return null;
}
var section = memory.Process.GetSectionToPointer(address);
if (section != null) // If the address points to a section it's valid memory.
{
if (section.Category == RemoteProcess.SectionCategory.Code) // If the section contains code, it should be a function pointer.
{
return typeof(FunctionPtrNode);
}
else if (section.Category == RemoteProcess.SectionCategory.Data) // If the section contains data, it is at least a pointer to a class or something.
{
// Check if it is a vtable. Check if the first 3 values are pointers to a code section.
bool valid = true;
for (var i = 0; i < 3; ++i)
{
var pointee = memory.Process.ReadRemoteObject<IntPtr>(address);
if (memory.Process.GetSectionToPointer(pointee)?.Category != RemoteProcess.SectionCategory.Code)
{
valid = false;
break;
}
}
if (valid)
{
return typeof(VTableNode);
}
// Check if it is a string.
var data = memory.Process.ReadRemoteMemory(address, IntPtr.Size * 2);
if (data.Take(IntPtr.Size).InterpretAsUTF8().IsLikelyPrintableData() >= 0.5f)
{
return typeof(UTF8TextPtrNode);
}
else if (data.InterpretAsUTF16().IsLikelyPrintableData() >= 0.5f)
{
return typeof(UTF16TextPtrNode);
}
// Now it could be a pointer to something else but we can't tell. :(
//return typeof(ClassPtrNode);
}
}
return null;
}
}
}