@@ -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