@@ -137,7 +137,9 @@ def add_debug_info():
137137 file_index = dwarf_add_file_decl (dbg , c_file_name , dir_index , 0 , 0 )
138138 dwarf_add_AT_comp_dir (cu , "." )
139139
140- for f in get_functions ():
140+ funcs = get_functions ()
141+ for i , f in enumerate (funcs ):
142+ print "Decompiling function %d: %s" % (i , f )
141143 add_function (cu , f , file_index )
142144
143145 dwarf_add_die_to_debug_a (dbg , cu )
@@ -182,16 +184,17 @@ def get_decompiled_function(func):
182184
183185def get_decompiled_variables (decomp ):
184186 hf = decomp .highFunction
185- for s in hf .localSymbolMap .symbols :
186- yield s .name , s .dataType , s .PCAddress , s .storage
187+ symbolMap = hf .localSymbolMap
188+ params = [symbolMap .getParam (i ).symbol for i in range (symbolMap .numParams ) if symbolMap .getParam (i )]
189+ for s in symbolMap .symbols :
190+ yield s .name , s .dataType , s .PCAddress , s .storage , s in params
187191
188192
189- def add_decompiler_func_info (cu , func_die , func , file_index , func_line ):
193+ def add_decompiler_func_info (cu , func_die , func , decomp , file_index , func_line ):
190194 # https://ghidra.re/ghidra_docs/api/ghidra/app/decompiler/DecompileResults.html
191195 # print func.allVariables
192- decomp = get_decompiled_function (func )
193- for name , datatype , addr , storage in get_decompiled_variables (decomp ):
194- add_variable (cu , func_die , name , datatype , addr , storage )
196+ for name , datatype , addr , storage , is_param in get_decompiled_variables (decomp ):
197+ add_variable (cu , func_die , name , datatype , addr , storage , is_parameter = is_param )
195198
196199 cmarkup = decomp .CCodeMarkup
197200 # TODO: implement our own pretty printer?
@@ -251,7 +254,7 @@ def add_structures(cu):
251254 add_type (cu , s )
252255
253256
254- def add_variable (cu , func_die , name , datatype , addr , storage ):
257+ def add_variable (cu , func_die , name , datatype , addr , storage , is_parameter = False ):
255258 # TODO: there could be more than one varnode, what does it even mean?
256259 varnode = storage .firstVarnode
257260 # It looks like sometimes ghidra creates a fake/temp variable without any varnodes, it should be ok to ignore it
@@ -260,7 +263,10 @@ def add_variable(cu, func_die, name, datatype, addr, storage):
260263 varnode_addr = varnode .getAddress ()
261264
262265 # TODO: add varaible starting from addr
263- var_die = dwarf_new_die (dbg , DW_TAG_variable , func_die , None , None , None )
266+ tag = DW_TAG_variable
267+ if is_parameter :
268+ tag = DW_TAG_formal_parameter
269+ var_die = dwarf_new_die (dbg , tag , func_die , None , None , None )
264270 type_die = add_type (cu , datatype )
265271
266272 dwarf_add_AT_reference (dbg , var_die , DW_AT_type , type_die )
@@ -308,7 +314,6 @@ def add_function(cu, func, file_index):
308314 # TODO: Check for multiple ranges
309315 f_start , f_end = get_function_range (func )
310316
311- t = func .returnType
312317 ret_type_die = add_type (cu , func .returnType )
313318 dwarf_add_AT_reference (dbg , die , DW_AT_type , ret_type_die )
314319
@@ -318,13 +323,17 @@ def add_function(cu, func, file_index):
318323 func_line = len (decomp_lines ) + 1
319324
320325 res = get_decompiled_function (func )
321- d = res .decompiledFunction .c
326+ if res .decompiledFunction is None :
327+ d = "/* Error decompiling %s: %s */" % (func .getName (True ), res .errorMessage )
328+ else :
329+ d = res .decompiledFunction .c
322330 decomp_lines .extend (d .split ("\n " ))
323331
324332 dwarf_add_AT_unsigned_const (dbg , die , DW_AT_decl_file , file_index )
325333 dwarf_add_AT_unsigned_const (dbg , die , DW_AT_decl_line , func_line )
326334 dwarf_add_line_entry (dbg , file_index , f_start , func_line , 0 , True , False )
327- add_decompiler_func_info (cu , die , func , file_index , func_line )
335+ if res .decompiledFunction is not None :
336+ add_decompiler_func_info (cu , die , func , res , file_index , func_line )
328337
329338 return die
330339
@@ -425,7 +434,7 @@ def add_struct_type(cu, struct):
425434 member_die = dwarf_new_die (dbg , DW_TAG_member , die , None , None , None )
426435 member_type_die = add_type (cu , c .dataType )
427436 dwarf_add_AT_reference (dbg , member_die , DW_AT_type , member_type_die )
428- dwarf_add_AT_name (member_die , c .fieldName )
437+ dwarf_add_AT_name (member_die , c .fieldName or c . defaultFieldName )
429438
430439 loc_expr = dwarf_new_expr (dbg )
431440 dwarf_add_expr_gen (loc_expr , DW_OP_plus_uconst , c .offset , 0 )
@@ -504,3 +513,6 @@ def generate_dwarf_sections():
504513 sections = generate_dwarf_sections ()
505514 dwarf_producer_finish_a (dbg )
506515 add_sections_to_elf (exe_path , out_path , sections )
516+ print "Done."
517+ print "ELF saved to" , out_path
518+ print "C source saved to" , decompiled_c_path
0 commit comments