2020using NtApiDotNet . Utilities . Memory ;
2121using NtApiDotNet . Win32 ;
2222using NtApiDotNet . Win32 . Debugger ;
23+ using NtApiDotNet . Win32 . Rpc ;
2324using System ;
2425using System . Collections . Generic ;
2526using System . ComponentModel ;
@@ -130,6 +131,10 @@ public enum NdrParserFlags
130131 /// Ignore processing any complex user marshal types.
131132 /// </summary>
132133 IgnoreUserMarshal = 1 ,
134+ /// <summary>
135+ /// Resolve structure names, required private symbols.
136+ /// </summary>
137+ ResolveStructureNames = 2 ,
133138 }
134139
135140 /// <summary>
@@ -153,6 +158,136 @@ private static NdrRpcServerInterface ReadRpcServerInterface(IMemoryReader reader
153158 server_interface . GetProtSeq ( reader ) . Select ( s => new NdrProtocolSequenceEndpoint ( s , reader ) ) ) ;
154159 }
155160
161+ private static UserDefinedTypeInformation GetUDTType ( TypeInformation type_info )
162+ {
163+ if ( type_info is PointerTypeInformation pointer_type )
164+ {
165+ return GetUDTType ( pointer_type . PointerType ) ;
166+ }
167+
168+ if ( type_info is ArrayTypeInformation array_type )
169+ {
170+ return GetUDTType ( array_type . ArrayType ) ;
171+ }
172+
173+ return type_info as UserDefinedTypeInformation ;
174+ }
175+
176+ private static NdrComplexTypeReference GetComplexType ( NdrBaseTypeReference type_reference )
177+ {
178+ if ( type_reference is NdrPointerTypeReference pointer_type )
179+ {
180+ return GetComplexType ( pointer_type . Type ) ;
181+ }
182+
183+ if ( type_reference is NdrBaseArrayTypeReference array_type )
184+ {
185+ return GetComplexType ( array_type . ElementType ) ;
186+ }
187+
188+ return type_reference as NdrComplexTypeReference ;
189+ }
190+
191+ private static void UpdateComplexTypes ( Dictionary < NdrComplexTypeReference , UserDefinedTypeInformation > complex_types ,
192+ TypeInformation type_info , NdrBaseTypeReference type_reference )
193+ {
194+ var udt = GetUDTType ( type_info ) ;
195+ var complex = GetComplexType ( type_reference ) ;
196+ if ( udt != null && complex != null && ! complex_types . ContainsKey ( complex ) )
197+ {
198+ complex_types [ complex ] = udt ;
199+ }
200+ }
201+
202+ private static void FixupStructureType ( HashSet < NdrComplexTypeReference > fixup_set , NdrBaseStructureTypeReference complex_type , UserDefinedTypeInformation udt )
203+ {
204+ var members = complex_type . Members . ToList ( ) ;
205+ if ( members . Count != udt . Members . Count )
206+ return ;
207+ for ( int i = 0 ; i < members . Count ; ++ i )
208+ {
209+ members [ i ] . Name = udt . Members [ i ] . Name ;
210+ var member_udt = GetUDTType ( udt . Members [ i ] . Type ) ;
211+ var member_complex = GetComplexType ( members [ i ] . MemberType ) ;
212+ if ( member_udt != null && member_complex != null )
213+ {
214+ FixupComplexType ( fixup_set , member_complex , member_udt ) ;
215+ }
216+ }
217+ }
218+
219+ private static void FixupUnionType ( HashSet < NdrComplexTypeReference > fixup_set , NdrUnionTypeReference union_type , UserDefinedTypeInformation udt )
220+ {
221+ var members = union_type . Arms . Arms . ToList ( ) ;
222+ if ( members . Count != udt . Members . Count )
223+ return ;
224+ for ( int i = 0 ; i < members . Count ; ++ i )
225+ {
226+ members [ i ] . Name = udt . Members [ i ] . Name ;
227+ var member_udt = GetUDTType ( udt . Members [ i ] . Type ) ;
228+ var member_complex = GetComplexType ( members [ i ] . ArmType ) ;
229+ if ( member_udt != null && member_complex != null )
230+ {
231+ FixupComplexType ( fixup_set , member_complex , member_udt ) ;
232+ }
233+ }
234+ }
235+
236+ private static void FixupComplexType ( HashSet < NdrComplexTypeReference > fixup_set , NdrComplexTypeReference complex_type , UserDefinedTypeInformation udt )
237+ {
238+ if ( ! fixup_set . Add ( complex_type ) )
239+ return ;
240+
241+ // Fixup the name to remove compiler generated characters.
242+ complex_type . Name = CodeGenUtils . MakeIdentifier ( udt . Name ) ;
243+ if ( udt . Union )
244+ {
245+ if ( complex_type is NdrUnionTypeReference union )
246+ {
247+ FixupUnionType ( fixup_set , union , udt ) ;
248+ }
249+ }
250+ else
251+ {
252+ if ( complex_type is NdrBaseStructureTypeReference str )
253+ {
254+ FixupStructureType ( fixup_set , str , udt ) ;
255+ }
256+ }
257+ }
258+
259+ private static void FixupStructureNames ( List < NdrProcedureDefinition > procs ,
260+ ISymbolResolver symbol_resolver , NdrParserFlags parser_flags )
261+ {
262+ if ( ! parser_flags . HasFlagSet ( NdrParserFlags . ResolveStructureNames ) || ! ( symbol_resolver is ISymbolTypeResolver type_resolver ) )
263+ return ;
264+
265+ var complex_types = new Dictionary < NdrComplexTypeReference , UserDefinedTypeInformation > ( ) ;
266+
267+ foreach ( var proc in procs )
268+ {
269+ if ( ! ( type_resolver . GetTypeForSymbolByAddress ( proc . DispatchFunction ) is FunctionTypeInformation func_type ) )
270+ continue ;
271+
272+ if ( func_type . Parameters . Count != proc . Params . Count )
273+ continue ;
274+
275+ for ( int i = 0 ; i < func_type . Parameters . Count ; ++ i )
276+ {
277+ proc . Params [ i ] . Name = func_type . Parameters [ i ] . Name ;
278+ UpdateComplexTypes ( complex_types , func_type . Parameters [ i ] . ParameterType , proc . Params [ i ] . Type ) ;
279+ }
280+
281+ UpdateComplexTypes ( complex_types , func_type . ReturnType , proc . ReturnValue . Type ) ;
282+ }
283+
284+ HashSet < NdrComplexTypeReference > fixup_set = new HashSet < NdrComplexTypeReference > ( ) ;
285+ foreach ( var pair in complex_types )
286+ {
287+ FixupComplexType ( fixup_set , pair . Key , pair . Value ) ;
288+ }
289+ }
290+
156291 private static IEnumerable < NdrProcedureDefinition > ReadProcs ( IMemoryReader reader , MIDL_SERVER_INFO server_info , int start_offset ,
157292 int dispatch_count , NdrTypeCache type_cache , ISymbolResolver symbol_resolver , IList < string > names , NdrParserFlags parser_flags )
158293 {
@@ -200,6 +335,9 @@ private static IEnumerable<NdrProcedureDefinition> ReadProcs(IMemoryReader reade
200335 }
201336 }
202337 }
338+
339+ FixupStructureNames ( procs , symbol_resolver , parser_flags ) ;
340+
203341 return procs . AsReadOnly ( ) ;
204342 }
205343
0 commit comments