Custom use cases: Providing API patterns: Function mode - projectbtle/argXtract GitHub Wiki
In function analysis mode, the goal is for argXtract
to determine the location of a particular function of interest. It will do this by comparing a given pattern for the function against the set of functions that it has estimated for the binary. This section describes how to define the pattern file. To be able to do this, we assume that you know the exact operation of the function of interest and are able to generate an unstripped sample binary to test against.
Pattern files are simply JSON files containing sample input and output values for registers and memory. Create a file named ExampleAPICall.json
within <root>/argxtract/resources/vendor/ExampleVendor/fpfs/
with the following skeleton structure:
{
"test_sets": {
"0": {
"input": {
"mem": {},
"reg": {}
},
"output": {
"mem": {},
"reg": {}
}
}
Let's assume ExampleAPICall
takes 2 arguments, the first being a value to be stored and the second a pointer to an address where the value is to be stored.
ExampleAPICall(uint16 val, const *address);
Let's say ExampleAPICall
returns an error 0x64
if val
is 0
. If val
is a positive integer, the value is written to the memory location pointed to by address
.
We can use this information to generate two separate test sets: one for when an error is thrown and one for when it is not.
Remember that with ARM Cortex-M, input arguments are normally passed to a function via registers r0-r3 and the output may be returned in r0 (but you will need to verify this).
{
"test_sets": {
"0": {
"input": {
"mem": {},
"reg": {
"r0": "0",
"r1": "30000000"
}
},
"output": {
"mem": {},
"reg": {
"r0": "00000064"
}
}
},
"1": {
"input": {
"mem": {},
"reg": {
"r0": "aaaaaaaa",
"r1": "30000000"
}
},
"output": {
"mem": {
"30000000": "aa",
"30000001": "aa",
"30000002": "aa",
"30000003": "aa"
},
"reg": {}
}
}
If a function has a very high call depth (i.e., it calls many other functions iteratively), then the chances increase of the pattern matching failing. To handle this, analyse intermediate values that are generated and provide these within the test cases instead.