66import csv
77import hashlib
88
9- guid_regex = re .compile ("[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" )
9+ guid_regex = re .compile (b "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" )
1010
1111
1212def format_guid_from_hex (hex_string ):
@@ -19,7 +19,7 @@ def format_guid_from_hex(hex_string):
1919def read_blob (blob ):
2020 if len (blob ) == 0 :
2121 return ""
22- first_byte = ord ( blob [0 ])
22+ first_byte = blob [0 ]
2323 if first_byte & 0x80 == 0 :
2424 # easy one
2525 raw_string = blob [1 :][:first_byte ]
@@ -43,7 +43,7 @@ def get_assembly_guids(assembly_path):
4343 txt_start = None
4444 txt_end = None
4545 for section in pe .sections :
46- if section .Name .startswith (".text\x00 " ):
46+ if section .Name .startswith (b ".text\x00 " ):
4747 txt_start = section .PointerToRawData
4848 txt_end = txt_start + section .SizeOfRawData
4949 except pefile .PEFormatError :
@@ -71,18 +71,18 @@ def get_assembly_guids(assembly_path):
7171 else :
7272 offsets_to_test = [mdo - txt_start ]
7373
74- offsets_to_test .extend ([l .start () for l in re .finditer ("\x42 \x53 \x4a \x42 " , text_section )][::- 1 ])
74+ offsets_to_test .extend ([l .start () for l in re .finditer (b "\x42 \x53 \x4a \x42 " , text_section )][::- 1 ])
7575
7676 del file_data
7777
7878 for i_offset in offsets_to_test :
7979 i = text_section [i_offset :]
8080 try :
81- if "\x42 \x53 \x4a \x42 " not in i :
81+ if b "\x42 \x53 \x4a \x42 " not in i :
8282 continue
83- if not i .startswith ("\x42 \x53 \x4a \x42 " ):
83+ if not i .startswith (b "\x42 \x53 \x4a \x42 " ):
8484 continue
85- meta_data_offset = i .find ("\x42 \x53 \x4a \x42 " )
85+ meta_data_offset = i .find (b "\x42 \x53 \x4a \x42 " )
8686 clr_version_length = struct .unpack ("<I" , i [meta_data_offset + 12 :meta_data_offset + 16 ])[0 ]
8787 try :
8888 stream_count = struct .unpack ("<H" , i [meta_data_offset + clr_version_length +
@@ -91,26 +91,26 @@ def get_assembly_guids(assembly_path):
9191 continue
9292 current_offset = meta_data_offset + clr_version_length + 20
9393 heaps = {}
94- for c in xrange (stream_count ):
94+ for c in range (stream_count ):
9595 offset = struct .unpack ("<I" , i [current_offset :current_offset + 4 ])[0 ]
9696 size = struct .unpack ("<I" , i [current_offset + 4 :current_offset + 8 ])[0 ]
9797 current_offset += 8
98- name = ""
99- while "\x00 " not in name :
98+ name = b ""
99+ while b "\x00 " not in name :
100100 name += i [current_offset :current_offset + 4 ]
101101 current_offset += 4
102- name = name .strip ("\x00 " )
102+ name = name .strip (b "\x00 " )
103103 # print "{0} at {1}, {2} bytes".format(name, offset, size)
104104 heaps [name ] = i [meta_data_offset + offset :meta_data_offset + offset + size ]
105105 # if len(heaps[name]) != size:
106106 # raise
107107
108108 try :
109- extracted_mvid = format_guid_from_hex (heaps ["#GUID" ][:16 ]. encode ( "hex" ) )
110- except KeyError :
109+ extracted_mvid = format_guid_from_hex (heaps [b "#GUID" ][:16 ])
110+ except :
111111 return {}
112112
113- tilde = heaps ["#~" ]
113+ tilde = heaps [b "#~" ]
114114
115115 if tilde is not None :
116116 # print "Reserved: {0}".format([tilde[0:4]])
@@ -133,7 +133,7 @@ def get_assembly_guids(assembly_path):
133133
134134 row_counts = [0 ] * 64
135135 t_offset = 24
136- for index in xrange (len (tables_present )):
136+ for index in range (len (tables_present )):
137137 if index < len (tables_present ) and tables_present [index ]:
138138 row_counts [index ] = struct .unpack ("<I" , tilde [t_offset :t_offset + 4 ])[0 ]
139139 t_offset += 4
@@ -189,10 +189,10 @@ def get_assembly_guids(assembly_path):
189189 # Don't care about the rest
190190 ]
191191
192- for index in xrange (0x0c ):
192+ for index in range (0x0c ):
193193 t_offset += row_type_widths [index ] * row_counts [index ]
194194
195- for index in xrange (row_counts [0x0c ]):
195+ for index in range (row_counts [0x0c ]):
196196 # In the most strict interpretation, a typelib id is expressed as a
197197 # GuidAttribute on the current assembly.
198198 # To check that it's actually a GuidAttribute we'd have to support parsing
@@ -230,7 +230,7 @@ def get_assembly_guids(assembly_path):
230230 blob_index = struct .unpack ("<I" , tilde [row_offset :row_offset + 4 ])[0 ]
231231 row_offset += 4
232232
233- data_value = read_blob (heaps ["#Blob" ][blob_index :])
233+ data_value = read_blob (heaps [b "#Blob" ][blob_index :])
234234 if guid_regex .match (data_value ):
235235 return {"mvid" : extracted_mvid .lower (), "typelib_id" : data_value .lower (), "compiled" : compiled }
236236 t_offset += row_type_widths [0x0c ]
@@ -253,8 +253,7 @@ def get_assembly_guids(assembly_path):
253253
254254 parser = ArgumentParser (
255255 prog = __file__ ,
256- description = "Extracts Typelib IDs and MVIDs from .NET assemblies." ,
257- version = "%(prog)s v" + version + " by Brian Wallace (@botnet_hunter)" ,
256+ description = "Extracts Typelib IDs and MVIDs from .NET assemblies.\n %(prog)s v" + version + " by Brian Wallace (@botnet_hunter)" ,
258257 epilog = "%(prog)s v" + version + " by Brian Wallace (@botnet_hunter)"
259258 )
260259 parser .add_argument ('path' , metavar = 'path' , type = str , nargs = '*' , default = [],
@@ -267,9 +266,8 @@ def get_assembly_guids(assembly_path):
267266 args = parser .parse_args ()
268267
269268 if args .path is None or len (args .path ) == 0 :
270- if not args .stdin :
271- parser .print_help ()
272- exit ()
269+ parser .print_help ()
270+ exit ()
273271
274272 from os .path import isfile , isdir , join , abspath
275273 from glob import iglob
@@ -295,7 +293,7 @@ def get_compiletime(pe):
295293 writer = csv .writer (theCSV )
296294 writer .writerow (('TYPELIB' , 'MVID' , 'HASH' , 'COMPILED' , 'PATH' ))
297295 else :
298- print "{0}\t \t \t \t \t {1}\t \t \t \t \t {2}\t \t \t \t \t {3}\t \t {4}" .format ('TYPELIB' , 'MVID' , 'HASH' , 'COMPILED' , 'PATH' )
296+ print ( "{0}\t \t \t \t \t {1}\t \t \t \t \t {2}\t \t \t \t \t {3}\t \t {4}" .format ('TYPELIB' , 'MVID' , 'HASH' , 'COMPILED' , 'PATH' ) )
299297
300298 for file_path , result in scan_paths (args .path , args .recursive ):
301299 if result is None :
@@ -320,7 +318,7 @@ def get_compiletime(pe):
320318 if args .csv :
321319 writer .writerow ((typelib_id , mvid , s , compiled , file_path ))
322320 else :
323- print "{0}\t {1}\t {2}\t {3}\t {4}" .format (typelib_id , mvid , s , compiled , file_path )
321+ print ( "{0}\t {1}\t {2}\t {3}\t {4}" .format (typelib_id , mvid , s , compiled , file_path ) )
324322
325323 if args .csv :
326324 theCSV .close ()
0 commit comments