Skip to content

Commit

Permalink
Fix rebase bug in IDA; Add better local var resolving (#53)
Browse files Browse the repository at this point in the history
* fix rebase bug
* update version
* remove debug
  • Loading branch information
mahaloz authored Jan 27, 2023
1 parent a238b4e commit 17ddea9
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 11 deletions.
2 changes: 1 addition & 1 deletion decomp2dbg/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "3.2.0"
__version__ = "3.2.1"

try:
from .clients.client import DecompilerClient
Expand Down
37 changes: 33 additions & 4 deletions decomp2dbg/clients/gdb/gdb_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def __init__(self, gdb_client, name="decompiler", host="127.0.0.1", port=3662):
self.gdb_client: "GDBClient" = gdb_client
self.symbol_mapper = SymbolMapper()
self._is_pie = None
self._lvar_bptr = None

@property
@lru_cache()
Expand Down Expand Up @@ -103,10 +104,32 @@ def _clean_type_str(self, type_str):

return type_str

def _find_local_var_base_ptr(self):
if self._lvar_bptr is not None:
return self._lvar_bptr

candidates = ["$rbp", "$ebp", "$bp", "$fp"]
for candidate in candidates:
# the register must exist
try:
val = gdb.parse_and_eval(candidate)
except Exception:
continue

# the register must have a real value
try:
int(str(val), 16)
except Exception:
continue

self._lvar_bptr = candidate
return self._lvar_bptr


def update_function_data(self, addr):
func_data = self.function_data(addr)
reg_vars = func_data["reg_vars"]
stack_vars = func_data["stack_vars"]
reg_vars = func_data.get("reg_vars", {})
stack_vars = func_data.get("stack_vars", {})

for name, var in reg_vars.items():
type_str = self._clean_type_str(var['type'])
Expand All @@ -127,9 +150,15 @@ def update_function_data(self, addr):
continue

for offset, stack_var in stack_vars.items():
offset = int(offset, 0)
offset = abs(int(offset, 0))
type_str = self._clean_type_str(stack_var['type'])
expr = f"""({type_str}*) ($fp - {offset})"""
lvar_bptr = self._find_local_var_base_ptr()
if lvar_bptr == "$rbp":
offset -= 8
elif lvar_bptr == "$ebp":
offset -= 4

expr = f"""({type_str}*) ({lvar_bptr} - {offset})"""
var_name = stack_var['name']

try:
Expand Down
10 changes: 6 additions & 4 deletions decomp2dbg/clients/gdb/symbol_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,13 @@ def add_native_symbols(self, sym_info_list):
queued_sym_sizes[i % max_commit_size] = size

# absolute addressing
if addr >= self.text_base_addr:
addr_str = "{:#x}".format(addr)
#if addr >= self.text_base_addr:
# addr_str = "{:#x}".format(addr)
# relative addressing
else:
addr_str = ".text:{:#x}".format(addr)
#else:

# you always want relative adressing
addr_str = ".text:{:#x}".format(addr)

# create a symbol command for the symbol
objcopy_cmds.append(
Expand Down
20 changes: 18 additions & 2 deletions decompilers/d2d_ida/d2d_ida/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,28 @@ def __init__(self, host=None, port=None):
"global_vars": None,
"function_headers": None
}
self._base_addr = None

# make the server init cache data once
self.function_headers()
self.global_vars()

def rebase_addr(self, addr, down=False):
if self._base_addr is None:
self._base_addr = idaapi.get_imagebase()

rebased = addr
if down:
rebased -= self._base_addr
elif addr < self._base_addr:
rebased += self._base_addr

return rebased


@execute_read
def decompile(self, addr):
addr = self.rebase_addr(addr)
resp = {
"decompilation": None,
"curr_line": None,
Expand Down Expand Up @@ -141,6 +156,7 @@ def decompile(self, addr):

@execute_read
def function_data(self, addr):
addr = self.rebase_addr(addr)
resp = {
"stack_vars": None,
"reg_vars": None
Expand Down Expand Up @@ -211,7 +227,7 @@ def function_headers(self):
continue

func_size = ida_funcs.get_func(f_addr).size()
resp[str(f_addr)] = {
resp[str(self.rebase_addr(f_addr, down=True))] = {
"name": func_name,
"size": func_size
}
Expand Down Expand Up @@ -244,7 +260,7 @@ def global_vars(self):
if not name:
continue

resp[str(seg_ea)] = {
resp[str(self.rebase_addr(seg_ea, down=True))] = {
"name": name
}

Expand Down

0 comments on commit 17ddea9

Please sign in to comment.