-
-
Notifications
You must be signed in to change notification settings - Fork 55
Writing Extns
By definition, extensions are meant for extending the tool's capabilities from just a mere patcher to much more by adding features to it.
At present there are 2 extensions available inbuilt and they cannot be modified.
We would be focusing on the extensions that are defined externally and implemented via QJS functions.
A general use case would be to generate a specific file based on information extracted from the loaded Exe.
We can make use of TextFile and/or BinFile classes for this purpose.
Extensions are intended to be an addition to the Main GUI.
Each new extension defined gets added to the Extension drawer on the right side.
We can test extensions against multiple apps just like patches in the Test Bench.
Here they get added to a seperate list inside Extensions tab instead.
The appearance is similar to the entries in the Patch list.
Extensions are defined by means of it's name along with title
, author
, icon
& tooltip
keys.
Only the name
is the mandatory information required.
The tool reads extension definitions from a specific YAML file called 'Extensions.yml' . It has the following format:
- ExtName1:
title : <Brief title to be displayed in the drawer>
author : <Name of the author(s)>
tooltip : <Proper description of the extension. While it can be longer than the title. Keep it of reasonable length.>
icon : <Path to image serving as the icon. Relative paths will be wrt the repo folder.>
- ExtName2:
title : <Brief title>
author : <Author name(s)>
tooltip : <Proper description of the extension.>
icon : <Path to image serving as the icon.>
# etc.
Couple of points to consider:
-
The name of the extension also serves as the name of the Extension function which is invoked when the extension is clicked.
-
In the case of Test Bench the function is called while running tests.
-
The
title
,author
,icon
&tooltip
are all used for creating the extension's Action item and Delegate. -
As mentioned earlier, aside from the
name
all other members of an extension are optional.If not specified, they pick up the following default values:
Extension Member Default value title
extension name itself author
'Unknown' tooltip
will be empty icon
will be empty
As stated before, every extension has an associated QJS function and it shares the name
with the extension.
For an extension to be added to the Extension drawer, this function should have already been defined.
For this reason, the tool auto-loads scripts first if not done atleast once.
The function can be implemented as either a regular function or an arrow function. A general syntax is shown below:
ExtnName = function()
{
<bunch of code>
return true;
};
The function takes no arguments.
The return values are similar to a Patch function but with slight differences.
There are 3 scenarios in which an Extension function stops further execution and return control back to the tool.
-
Error occured:
The QJS engine will automatically detect known errors like syntax issues, unknown variable access etc.
In addition to this, it is also possible to report an error from the script by means of the
throw
keyword and anError
object.throw Error("Something failed");
This message will get displayed in an Error MessageBox.
-
Normal exit
If you end the function returning anything other than a
false
it is considered to be a normal exit.If the returned value is not
true
then it is displayed in an Info MessageBox.- no message
return true;
- with message
return "File has been generated";
Please note: a QJS function always returns something.
If you do not have an explicitreturn
orthrow
statement, then the returned value isundefined
and it will be displayed as such in the MessageBox -
Abnormal exit
When you return a
false
, the tool shows a Warning MessageBox saying it received afalse
value.This can be useful to check for unexpected inputs or invalid switch cases for e.g.
Every extension function is different and therefore difficult to generalize the steps.
However, these are some of the usual steps involved in an extension function:
-
Gathering information
-
Find the reference location (usually a
PUSH
) of a string using combination of the Exe.Find functions. -
Find the address(es) where a known code pattern occurs using Exe.FindHex & Exe.FindHexN functions.
-
Use the reference address to discover a second pattern in it's vicinity.
-
Extract some data from the addresses found with one of the Exe.Get functions.
-
Retrieve inputs from user with the Exe.GetUserInput function.
-
Sometimes, the inputs are YAML files which need to be loaded using Warp.LoadYaml function to get an array or hashmap.
-
Use TextFile & BinFile classes for loading custom input files.
-
-
Processing information
-
Finally either
return true
orreturn "message to be shown"
While the last step is not mandatory, it is a best practice to have atleast return true
to avoid a message box saying undefined
.