Closed kotee4ko closed 2 years ago
Yeah, as I see it working.
def add_function(cu, func, file_index):
die = dwarf_new_die(dbg, DW_TAG_subprogram, cu, None, None, None)
loc_expr = dwarf_new_expr(dbg)
dwarf_add_expr_gen(loc_expr, DW_OP_call_frame_cfa, 0, 0)
dwarf_add_AT_location_expr(dbg, die, DW_AT_frame_base, loc_expr)
f_name = func.name
dwarf_add_AT_name(die, f_name)
dwarf_add_AT_string(dbg, die, DW_AT_linkage_name, f_name)
# TODO: Check for multiple ranges
f_start, f_end = get_function_range(func)
t = func.returnType
ret_type_die = add_type(cu, func.returnType)
dwarf_add_AT_reference(dbg, die, DW_AT_type, ret_type_die)
dwarf_add_AT_targ_address(dbg, die, DW_AT_low_pc, f_start, 0)
dwarf_add_AT_targ_address(dbg, die, DW_AT_high_pc, f_end - 1, 0)
func_line = len(decomp_lines) + 1
res = get_decompiled_function(func)
if res.decompileCompleted():
try:
d = res.decompiledFunction.c
except:
d = res.decompiledFunction.getC
else:
return
decomp_lines.extend(d.split("\n"))
dwarf_add_AT_unsigned_const(dbg, die, DW_AT_decl_file, file_index)
dwarf_add_AT_unsigned_const(dbg, die, DW_AT_decl_line, func_line)
dwarf_add_line_entry(dbg, file_index, f_start, func_line, 0, True, False)
add_decompiler_func_info(cu, die, func, file_index, func_line)
return die
Thank you for opening the issue!
It looks like sometimes ghidra isn't able to decompile a function, so we shouldn't assume that the decompiled code exists.
We never encountered this error in our tests. Would you be able to share the executable?
Btw .c
and .getC()
are the same thing in Jython. It basically converts all the methods that starts with get and have 0 parameters into python properties.
Btw .c and .getC() are the same thing in Jython. It basically converts all the methods that starts with get and have 0 parameters into python properties.
Thanks, will be know. I'm more familiar with C programming :)
It looks like sometimes ghidra isn't able to decompile a function, so we shouldn't assume that the decompiled code exists.
It happens when Ghidra could-not de-compile a function, yes. This is quite often case for large binaries.
I think I can share binary, but I wish to do it privately. May I?
UPD:
I found a new bug on my own fix - offsets are gone.
I think we need to place check of successfully decomp. to the beginning of the add_function()
, or to feel d
with dumb output.
Like, //sorry can't decompile
.
I try second variant, now I got:
Traceback (most recent call last):
File "/root/ghidra_scripts/ghidra2dwarf/ghidra2dwarf.py", line 508, in <module>
add_debug_info()
File "/root/ghidra_scripts/ghidra2dwarf/ghidra2dwarf.py", line 138, in add_debug_info
add_function(cu, f, file_index)
File "/root/ghidra_scripts/ghidra2dwarf/ghidra2dwarf.py", line 333, in add_function
add_decompiler_func_info(cu, die, func, file_index, func_line)
File "/root/ghidra_scripts/ghidra2dwarf/ghidra2dwarf.py", line 190, in add_decompiler_func_info
for name, datatype, addr, storage in get_decompiled_variables(decomp):
File "/root/ghidra_scripts/ghidra2dwarf/ghidra2dwarf.py", line 182, in get_decompiled_variables
for s in hf.localSymbolMap.symbols:
AttributeError: 'NoneType' object has no attribute 'localSymbolMap'
btw, the same thing happens when just press cancel
while plug-in running:
Traceback (most recent call last):
File "/root/ghidra_scripts/ghidra2dwarf/ghidra2dwarf.py", line 509, in <module>
add_debug_info()
File "/root/ghidra_scripts/ghidra2dwarf/ghidra2dwarf.py", line 138, in add_debug_info
add_function(cu, f, file_index)
File "/root/ghidra_scripts/ghidra2dwarf/ghidra2dwarf.py", line 319, in add_function
if res.decompileCompleted():
AttributeError: 'NoneType' object has no attribute 'decompileCompleted'
ghidra2dwarf.py> User cancelled script.
Offsets are completely gone away :(
in generated name_dbg.c:
216767 undefined4 FUN_005735a0(long *param_1,byte **param_2,uint *param_3)
216768
216769 {
216770 long *plVar1;
216771 char cVar2;
216772 byte bVar3;
216773 char extraout_AL;
216774 undefined4 uVar4;
216775 uint uVar5;
216776 undefined **ppuVar6;
216777 undefined **ppuVar7;
216778 undefined8 uVar8;
216779 uint local_3c [3];
...snipped...
in pwndbg:
pwndbg> list *FUN_005735a0
0x5735a0 is in FUN_005735a0 (./Serv-U_dbg.c:3851).
3846 piVar1 = (int *)(param_1 + 0x60);
3847 uVar3 = (uint)(*(char *)(param_1 + 0x55) == '\0');
3848 FUN_007c3980(uVar3,param_5,8,piVar1,piVar1);
3849 FUN_007c3980(uVar3,param_4,*(int *)(param_1 + 0x38),piVar1,piVar1);
3850 uVar3 = param_5[4];
3851 if ((*(uint *)(param_1 + 0x60) ==
3852 (uVar3 >> 0x18 | (uVar3 & 0xff0000) >> 8 | (uVar3 & 0xff00) << 8 | uVar3 << 0x18)) &&
3853 (uVar3 = param_5[5],
3854 *(uint *)(param_1 + 100) ==
3855 (uVar3 >> 0x18 | (uVar3 & 0xff0000) >> 8 | (uVar3 & 0xff00) << 8 | uVar3 << 0x18))) {
I think I can share binary, but I wish to do it privately. May I?
Feel free to send it via email at 33e3393c59bed4a77cb2d2ec2cd80e13 AT protonmail.com
.
Done.
I was unable to reproduce your first issue using the binary you sent us.
Are you using the latest version of ghidra2drawf?
What version of Ghidra are you using?
Did you change something (like names or types) in Ghidra before running the script?
Are you using the latest version of ghidra2drawf?
Yes.
What version of Ghidra are you using?
I check it with builded from scratch ghidra_9.3_DEV_20210406_linux64 on openjdk 13.0.4 2020-07-14 and on the server machine with openjdk 16 2021-03-16.
Did you change something (like names or types) in Ghidra before running the script?
nope.
Just test it with latest prebuilded ghidra.
It generate reverse-unstripped binary and source file.
But, all functions prototypes are undefined (void))
For ex. In ghidra: https://i.ibb.co/K6qStqG/image.png
In generated *.c file: https://i.ibb.co/3vt30HW/image.png
Under GDB: https://i.ibb.co/N7fMdFP/image.png
So, idk, but it's seems that main symptomatic of bug still present.
I can provide more details if needed.
P.S. I try to import data types and names from IDA, via xml file. And generate dwarf.
Ghidra crashed with sigsegv.
just notice, that results of 9.3 with some decompile-code check fixes in plugin is the same as for 9.2 with stock plugin. haha, am I made adaptation for feature versions of ghidra? :)
I actually ran in to this issue today, in my case it probably didn't generate sources for all functions so the c source is indeed not available. I can probably add a try/catch to ignore that but I wonder how the dressing and dwarf format will react to that.
This should have been fixed by #10.
Feel free to re-open this issue if this is not the case.
I'm new to Ghidra, so idk if my solution is right, but I found in docs that api got
getC
method.and try to fix:
But, no luck:
I found this in api docs: