SDKtoGhidra: apply the XML's calling convention when importing functions - #116
Closed
jatassi wants to merge 1 commit into
Closed
SDKtoGhidra: apply the XML's calling convention when importing functions#116jatassi wants to merge 1 commit into
jatassi wants to merge 1 commit into
Conversation
ImportSporeSDK.java read each function's calling convention from the
function's existing convention, which is always "unknown" after Ghidra's
auto-analysis, and ignored the CONVENTION attribute the XML carries on
3,662 thiscall and 203 stdcall definitions. The this-in-ECX branch in
createParameters therefore never ran: "this" landed at stack offset 4
and every stack argument of a __thiscall function was shifted by four
bytes. Editors::EditorModel::SetColor labelled its real "index" argument
as "this", and the decompiler read the real "this" as in_ECX.
Two changes:
- processFunctionDef stores the convention through
FunctionDefinition.setCallingConvention with Ghidra's own names
(__thiscall, __stdcall, ...). The deprecated
setGenericCallingConvention stored the bare enum name ("thiscall"),
which no compiler spec recognises, so every definition read as an
unknown convention. This also fixes calls through vftable slots, which
the decompiler resolves from the definition's convention.
- setSignature passes the definition's convention into updateFunction
when the compiler spec knows it, and keeps the existing one otherwise.
Custom storage is kept, because the functions live in Ghidra's global
namespace with "::" in their names and dynamic storage would lose the
typed "this".
Tested against Ghidra 12.1.3 with SporeGhidra_march2017.xml: SetColor
decompiles to "this->mColors[index].r = color.r", App::Property::
GetValueInt32 reads "this->", and float-returning functions still return
in st0.
Member
That link doesn't work but I presume it's also mostly LLM generated? |
Member
|
After some internal discussion with the other maintainers, we've decided we will not accept LLM generated patches. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
ImportSporeSDK.javaresolves each function's calling convention from the function's existing convention (getCallingConvention(Function, FunctionSignature, CompilerSpec)returnsfunction.getCallingConventionName()). After Ghidra's auto-analysis that is alwaysunknown, so theCONVENTIONattribute the XML carries on 3,662thiscalland 203stdcalldefinitions is never used. Thethis-in-ECX branch increateParameterstherefore never runs:thisis placed at stack offset 4 and every stack argument of a__thiscallfunction is shifted by four bytes.Example,
Editors::EditorModel::SetColorbefore the fix:The real
thisisin_ECX, the parameter namedthisis the realindex, andindexis the first word ofcolor.A second, related problem:
processFunctionDefstores the convention through the deprecatedFunctionDefinition.setGenericCallingConvention, which in Ghidra 11+ stores the bare enum name (thiscall). No compiler spec recognises that name, so every definition reportshasUnknownCallingConventionName() == true, and the decompiler treats calls through__vftableslots (whose members are pointers to these definitions) as unknown-convention calls.Fix
getCallingConvention(String)now maps the XML'scdecl/fastcall/stdcall/thiscall/vectorcall/unknownto theCompilerSpec.CALLING_CONVENTION_*names, andprocessFunctionDefstores that name withFunctionDefinition.setCallingConvention.getCallingConvention(Function, FunctionSignature, CompilerSpec)returns the definition's convention when the program's compiler spec knows it, and the function's existing convention otherwise.thisis lost, because the functions live in Ghidra's global namespace with::in their names and Ghidra only derives an auto-thisinside a class namespace.CONVENTIONvalue now prints the offending text instead ofnull.Tested
Ghidra 12.1.3, JDK 21,
SporeGhidra_march2017.xmlagainst the GOGSporeApp.exe:Editors::EditorModel::SetColordecompiles tothis->mColors[index].r = color.r; ....App::Property::GetValueInt32readsthis->in its body.Math::RandomNumberGenerator::RandomFloat(returnsfloat) still returns inst0.__thiscallor__stdcallinstead ofunknown.Found while building an annotated project for the OpenSpore effort (https://github.com/jatassi/OpenSpore).