@@ -73,6 +73,8 @@ def __init__(
7373 self .dotnetpe = dnPE (data = self .data , clr_lazy_load = True )
7474 else :
7575 self .dotnetpe = dnPE (self .file_path , clr_lazy_load = True )
76+ if not self .dotnetpe .net or not self .dotnetpe .net .mdtables :
77+ raise ConfigParserException ("Failed to load project as dotnet executable (missing Metadata)" )
7678 except Exception :
7779 raise ConfigParserException ("Failed to load project as dotnet executable" )
7880
@@ -88,17 +90,19 @@ def __init__(
8890 self ._tokens = [m .token for m in self ._methods_by_token ]
8991
9092 # Pre-compute FieldRva mapping for O(1) lookups
91- self ._field_rva_map = {
92- row .struct .Field_Index : row .struct .Rva
93- for row in self .dotnetpe .net .mdtables .FieldRva
94- }
93+ self ._field_rva_map = {}
94+ if getattr (self .dotnetpe .net .mdtables , "FieldRva" , None ):
95+ self ._field_rva_map = {
96+ row .struct .Field_Index : row .struct .Rva
97+ for row in self .dotnetpe .net .mdtables .FieldRva
98+ }
9599
96100 # Given a byte array's size and RVA, translates the RVA to the offset of
97101 # the byte array and returns the bytes of the array as a byte string
98102 def byte_array_from_size_and_rva (self , arr_size : int , arr_rva : int ) -> bytes :
99103 arr_field_rva = self .fieldrva_from_rva (arr_rva )
100104 arr_offset = self .offset_from_rva (arr_field_rva )
101- return self .data [arr_offset : arr_offset + arr_size ]
105+ return self .data [arr_offset : arr_offset + arr_size ]
102106
103107 # Given an offset, and either a terminating offset or delimiter, extracts
104108 # the byte string
@@ -122,7 +126,10 @@ def byte_string_from_offset(
122126 # Given an RVA, derives the corresponding Field name
123127 def field_name_from_rva (self , rva : int ) -> str :
124128 try :
125- return self .dotnetpe .net .mdtables .Field .rows [
129+ field_table = getattr (self .dotnetpe .net .mdtables , "Field" , None )
130+ if not field_table :
131+ raise ConfigParserException (f"Could not find Field table for RVA { rva } " )
132+ return field_table .rows [
126133 (rva ^ MDT_FIELD_DEF ) - 1
127134 ].Name .value
128135 except Exception :
@@ -141,8 +148,11 @@ def _generate_method_list(
141148 self ,
142149 ) -> list [DotNetPEMethod ]:
143150 method_objs = []
151+ method_def_table = getattr (self .dotnetpe .net .mdtables , "MethodDef" , None )
152+ if not method_def_table :
153+ return method_objs
144154
145- for idx , method in enumerate (self . dotnetpe . net . mdtables . MethodDef .rows ):
155+ for idx , method in enumerate (method_def_table .rows ):
146156 method_offset = self .offset_from_rva (method .Rva )
147157
148158 # Parse size from flags
@@ -152,7 +162,7 @@ def _generate_method_list(
152162 method_size = flags >> 2
153163 elif flags & 3 == 3 : # Fat format (add 12-byte header)
154164 method_size = 12 + bytes_to_int (
155- self .data [method_offset + 4 : method_offset + 8 ]
165+ self .data [method_offset + 4 : method_offset + 8 ]
156166 )
157167
158168 method_objs .append (
@@ -252,21 +262,28 @@ def custom_attribute_from_type(self, typespacename: str, typename: str) -> dict:
252262 config = {}
253263 try :
254264 ca_map = {}
255- for ca in self .dotnetpe .net .mdtables .CustomAttribute .rows :
256- idx = ca .Parent .row_index
257- if idx not in ca_map :
258- ca_map [idx ] = []
259- ca_map [idx ].append (ca )
265+ ca_table = getattr (self .dotnetpe .net .mdtables , "CustomAttribute" , None )
266+ if ca_table :
267+ for ca in ca_table .rows :
268+ idx = ca .Parent .row_index
269+ if idx not in ca_map :
270+ ca_map [idx ] = []
271+ ca_map [idx ].append (ca )
260272
261- for td in self .dotnetpe .net .mdtables .TypeDef .rows :
273+ td_table = getattr (self .dotnetpe .net .mdtables , "TypeDef" , None )
274+ if not td_table :
275+ return config
276+
277+ for td in td_table .rows :
262278 if (
263279 td .TypeNamespace .value != typespacename
264280 and td .TypeName .value != typename
265281 ):
266282 continue
267- for pd_row_index , pd in enumerate (
268- self .dotnetpe .net .mdtables .Property .rows
269- ):
283+ prop_table = getattr (self .dotnetpe .net .mdtables , "Property" , None )
284+ if not prop_table :
285+ continue
286+ for pd_row_index , pd in enumerate (prop_table .rows ):
270287 if pd .Name .value .startswith ((
271288 "Boolean_" ,
272289 "BorderStyle_" ,
0 commit comments