mirror of
https://github.com/isledecomp/isle.git
synced 2026-01-26 17:51:16 +00:00
feature: Import stub functions but don't overwrite their argument list
Ghidra might have auto-detected some arguments, so we don't want to overwrite that if the stub's argument list has not been verified Closes #1009
This commit is contained in:
parent
91dd9fed0d
commit
bead9d1010
@ -88,7 +88,10 @@ def matches_ghidra_function(self, ghidra_function: Function) -> bool:
|
|||||||
self.signature.call_type == ghidra_function.getCallingConventionName()
|
self.signature.call_type == ghidra_function.getCallingConventionName()
|
||||||
)
|
)
|
||||||
|
|
||||||
if thiscall_matches:
|
if self.is_stub:
|
||||||
|
# We do not import the argument list for stubs, so it should be excluded in matches
|
||||||
|
args_match = True
|
||||||
|
elif thiscall_matches:
|
||||||
if self.signature.call_type == "__thiscall":
|
if self.signature.call_type == "__thiscall":
|
||||||
args_match = self._matches_thiscall_parameters(ghidra_function)
|
args_match = self._matches_thiscall_parameters(ghidra_function)
|
||||||
else:
|
else:
|
||||||
@ -102,7 +105,7 @@ def matches_ghidra_function(self, ghidra_function: Function) -> bool:
|
|||||||
name_match,
|
name_match,
|
||||||
return_type_match,
|
return_type_match,
|
||||||
thiscall_matches,
|
thiscall_matches,
|
||||||
args_match,
|
"ignored" if self.is_stub else args_match,
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -163,16 +166,25 @@ def overwrite_ghidra_function(self, ghidra_function: Function):
|
|||||||
ghidra_function.setReturnType(self.return_type, SourceType.USER_DEFINED)
|
ghidra_function.setReturnType(self.return_type, SourceType.USER_DEFINED)
|
||||||
ghidra_function.setCallingConvention(self.call_type)
|
ghidra_function.setCallingConvention(self.call_type)
|
||||||
|
|
||||||
|
if self.is_stub:
|
||||||
|
logger.debug(
|
||||||
|
"%s is a stub, skipping parameter import", self.get_full_name()
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
ghidra_function.replaceParameters(
|
ghidra_function.replaceParameters(
|
||||||
Function.FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,
|
Function.FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,
|
||||||
True,
|
True, # force
|
||||||
SourceType.USER_DEFINED,
|
SourceType.USER_DEFINED,
|
||||||
self.arguments,
|
self.arguments,
|
||||||
)
|
)
|
||||||
|
|
||||||
# When we set the parameters, Ghidra will generate the layout.
|
self._import_parameter_names(ghidra_function)
|
||||||
# Now we read them again and match them against the stack layout in the PDB,
|
|
||||||
# both to verify and to set the parameter names.
|
def _import_parameter_names(self, ghidra_function: Function):
|
||||||
|
# When we call `ghidra_function.replaceParameters`, Ghidra will generate the layout.
|
||||||
|
# Now we read the parameters again and match them against the stack layout in the PDB,
|
||||||
|
# both to verify the layout and to set the parameter names.
|
||||||
ghidra_parameters: list[Parameter] = ghidra_function.getParameters()
|
ghidra_parameters: list[Parameter] = ghidra_function.getParameters()
|
||||||
|
|
||||||
# Try to add Ghidra function names
|
# Try to add Ghidra function names
|
||||||
@ -186,7 +198,9 @@ def overwrite_ghidra_function(self, ghidra_function: Function):
|
|||||||
|
|
||||||
# Appears to never happen - could in theory be relevant to __fastcall__ functions,
|
# Appears to never happen - could in theory be relevant to __fastcall__ functions,
|
||||||
# which we haven't seen yet
|
# which we haven't seen yet
|
||||||
logger.warning("Unhandled register variable in %s", self.get_full_name)
|
logger.warning(
|
||||||
|
"Unhandled register variable in %s", self.get_full_name()
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
def _rename_stack_parameter(self, index: int, param: Parameter):
|
def _rename_stack_parameter(self, index: int, param: Parameter):
|
||||||
|
|||||||
@ -135,9 +135,7 @@ def get_function_list(self) -> list[PdbFunction]:
|
|||||||
)
|
)
|
||||||
return [signature for signature in handled if signature is not None]
|
return [signature for signature in handled if signature is not None]
|
||||||
|
|
||||||
def handle_matched_function(
|
def handle_matched_function(self, match_info: MatchInfo) -> Optional[PdbFunction]:
|
||||||
self, match_info: MatchInfo
|
|
||||||
) -> Optional[PdbFunction]:
|
|
||||||
assert match_info.orig_addr is not None
|
assert match_info.orig_addr is not None
|
||||||
match_options = self.compare.get_match_options(match_info.orig_addr)
|
match_options = self.compare.get_match_options(match_info.orig_addr)
|
||||||
assert match_options is not None
|
assert match_options is not None
|
||||||
@ -172,8 +170,4 @@ def handle_matched_function(
|
|||||||
|
|
||||||
is_stub = match_options.get("stub", False)
|
is_stub = match_options.get("stub", False)
|
||||||
|
|
||||||
# TODO: Remove when implementing stubs
|
|
||||||
if is_stub:
|
|
||||||
return None
|
|
||||||
|
|
||||||
return PdbFunction(match_info, function_signature, is_stub)
|
return PdbFunction(match_info, function_signature, is_stub)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user