Closed harmansmithandsons closed 2 weeks ago
There's not a direct way to call these actions through a script. Note that the BSim results do not contain the signature and types of the matching function. However, applying the signature and types can be done easily with a static method in the FunctionUtility
class, provided you have a Function
object for the matching function.
To get that object, you will have to open the program containing the matching function and then get the Function
at the appropriate address. The ghidra URL and the address are contained in the BSim results. To open the program you can use the constructor of the OpenProgramTask
class that takes a ghidra URL.
We should probably add a utility method to handle all of this for you, or at least provide an example script.
The method you just described that goes through FunctionUtility
sounds like it has the implicit requirement of the user having access to whatever project contains the executable of the matching function. So in order to apply a search result, you would need both a database to perform the search as well as the project containing the executable of the matching function.
Does BSim as used through the listing view also require both the original project and a database? My understanding was that it was possible to use the application functionality of BSim with just a database without requiring the original project. I quickly leafed through the tutorial docs (.../docs/GhidraClass/BSim
) just now again, and didn't find a mention of this requirement.
Edit: After taking a look through FunctionUtility
, it looks like updateFunction()
is definitely part of the behavior I was after, and is responsible for updating a function name and signature. I was having some trouble finding something in FunctionUtility
that handles modifying function bodies. If you have any pointers to that behavior, I'd appreciate it.
In order to use the apply actions or the side-by-side comparison view you need to access the original program. The BSim database doesn't store the needed information.
The BSim server does return the name of the matching function (but not the namespace), so if that's all you care about you could write a script to rename a function using the BSim results alone.
What kind of modifications to a function body are you trying to do? Are you manually fixing switch statements?
In order to use the apply actions or the side-by-side comparison view you need to access the original program. The BSim database doesn't store the needed information.
Thanks for clarifying this, it seems I had a misunderstanding.
What kind of modifications to a function body are you trying to do?
The body modifications I'm interested in are just the ones BSim already does, importing any user-defined structs/data types from a matched function and retyping any parameters/locals in the base function accordingly.
I'm having some difficulty working with the OpenProgramTask
class @ghidracadabra pointed me towards. I'm getting a little tripped up on what URL I should be passing into this constructor. Right now, I am creating a new OpenProgramTask
with the following code:
FunctionDescription matchedFn = ...; // came from BSim SimilarityNote
String matchedFnRepoPath = matchedFn.getExecutableRecord().getRepository();
String matchedFnExeRelativePath = matchedFn.getExecutableRecord().getPath();
String fullPath = matchedFnRepoPath + matchedFnExeRelativePath;
OpenProgramTask opt = new OpenProgramTask(new URL(fullPath), new Object());
I then get a return value of null
when I try opt.getOpenProgram()
. One source of error that comes to my mind is that the URL I am passing into the OpenProgramTask
constructor isn't what it expects. The source code for OpenProgramTask doesn't have much guidance to this end, so I'd appreciate a pointer to what the constructor is expecting.
Use the getURLString()
method on the ExecutableResult
to get the URL - I don't think the string you are using contains the program name. Also, make sure you call TaskLauncher.launch(opt)
before you call opt.getOpenProgram()
.
Thank you for those pointers! With those changes, my script is working as intended and I'm able to populate symbols across projects. I greatly appreciated your help! The below code snippet is what ended up working for me; I'll leave it below in case any others have similar questions.
FunctionDescription matchedFn = ...; // from BSim results
OpenProgramTask opt = new OpenProgramTask(new URL(matchedFn.getExecutableRecord().getURLString), new Object());
TaskLauncher.launch(opt);
Program matchedProgram = opt.getOpenProgram.getProgram();
Function replacementSource = matchedProgram.getFunctionManager().getFunctionAt(addressOfMatchedFn);
FunctionUtility.applyNameAndNamespace(queriedFunction, replacementSource);
Forgot to mention, but it's probably a good idea to pass this
as the consumer in the OpenProgramTask
constructor. When you are done with matchedProgram
, call matchedProgram.release(this)
. If you are iterating through a list of matches and applying them it might be worth organizing the code so that you open a program, apply all of the matches from it, and then release it.
I am interested in performing the "apply function signature and types of search result" functionality of BSim through programmatic means as part of a script I am working on.
I've reviewed the available example scripts that ship with Ghidra 11, namely QueryFunction.java and ExampleOverviewQueryScript,java, and while those show how to perform a search against BSim databases they don't show how the application is performed. I then tracked down the code responsible for populating functions in the Listing view, and came across
AbstractBSimApplyTask::applyResults()
and related functions in<ghidra_install_dir>\Ghidra\Features\BSim\lib\BSim-src.zip\ghidra\features\bsim\gui\search\results\apply\
.The relevant functions I've found do not appear to play nicely with the BSim scripting API exposed in the example scripts. As an example of this, a query made through
QueryFunction.java
provides aSimilarityResult
object, but to instantiate anAbstractBSimApplyTask
aBSimMatchResult
object is needed, which has a lot of member overlap yet is distinguished from aSimilarityResult
.I'd like to know two things: first, is there a manageable way to perform search result application that is compatible with the kinds of objects the example scripts works with; second, if that is not the case, I'd appreciate confirmation/redirection to what parts of Ghidra code is responsible for application, so I could start adapting my current code to hook into that. Thanks for your time.