Skip to content

Commit e5e2a24

Browse files
authored
Merge pull request #10 from nneonneo/master
macOS support, fix #9, function parameters
2 parents 6c992bb + 17d5328 commit e5e2a24

File tree

4 files changed

+26
-13
lines changed

4 files changed

+26
-13
lines changed

lib/src/main/java/libdwarf/LibdwarfLibrary.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ public Dwarf_P_Attribute() {
161161
public static final int DW_TAG_compile_unit = (int)0x11;
162162
public static final int DW_TAG_enumeration_type = (int)0x04;
163163
public static final int DW_TAG_enumerator = (int)0x28;
164+
public static final int DW_TAG_formal_parameter = (int)0x05;
164165
public static final int DW_TAG_member = (int)0x0d;
165166
public static final int DW_TAG_pointer_type = (int)0x0f;
166167
public static final int DW_TAG_structure_type = (int)0x13;
534 KB
Binary file not shown.

lib/target/libdwarf.jar

199 KB
Binary file not shown.

src/ghidra2dwarf.py

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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

183185
def 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

Comments
 (0)