Functions (analysis.fns)

analysis.fns: malcat.Functions

The analysis.fns object is a malcat.Functions instance that gives you access to all the functions identified by the Functions recovery algorithm.

Note that in addition to this documentation, you can find usage examples in the sample script which is loaded when you hit F8.

Functions and prototypes

The function object

A function is a Function instance offering the following python methods and properties:

class malcat.Function
__iter__()

Iterate over the function’s basic blocks. Shortcut for analysis.cfg[fn.start:fn.end].

first_function = analysis.fns.find_forward(0)
for bb in first_function:
    print("Basic block found at {}".format(analysis.ppa(bb.address)))
rtype:

iterator over BasicBlock

Base

address: int (effective address)

the start of the function

start: int (effective address)

same as address

end: int (effective address)

last effective address inside the function + 1

size: int

size in bytes of the function: end - start

__len__()

return the size in bytes of the function: end - start

Return type:

int

__contains__(ea)

return True iff the effective address ea is within the function boundaries

Parameters:

ea (int) – address to query

Return type:

bool

disasm(use_hexadecimal=True, only_valid_code=True, use_smart_labels=True, resolve_symbols=True, resolve_functions=True, resolve_strings=True, resolve_structures=True)

Disassemble this function following the given formatting

Parameters:
  • use_hexadecimal (bool) – display immediates in hexadecimal base

  • only_valid_code (bool) – ignore/don’t disasm basic blocks not recognized as valid code

  • use_smart_labels (bool) – replace in-function jump targets with .1, .2 .. .N labels

  • resolve_symbols (bool) – known symbol addresses will be replaced by their symbol names

  • resolve_functions (bool) – known function start addresses will be replaced by their function name

  • resolve_strings (bool) – known string addresses will be replaced by the string content

  • resolve_structures (bool) – known structure/fields addresses will be replaced by their structure/field name

Return type:

str

hex(exclude_off=False, exclude_disp=False, exclude_reg=False, exclude_imm=False)

Get the masked out function hex bytes, e.g. 558BEC68????????8374??45..

Parameters:
  • exclude_off (bool) – exclude absolute offsets in valid instructions, e.g. mov eax, off_15bf34

  • exclude_disp (bool) – exclude displacements in valid instructions, e.g. mov eax, [ecx+128]

  • exclude_reg (bool) – exclude registers in valid instructions, e.g. push eax

  • exclude_imm (bool) – exclude immediates in valid instructions, e.g. mov eax, 0x1223

Return type:

str

callers: List[malcat.Function]

return the list of functions calling this function

fn = analysis.fns[analysis.v2a(0x18000127c)]
for caller in fn.callers:
    print(f"function {caller} is calling {fn}")
callees: List[malcat.Function]

return the list of functions called by some code in this function

fn = analysis.fns[analysis.v2a(0x18000127c)]
for callee in fn.callees:
    print(f"function {callee} is called by {fn}")
inrefs: List[malcat.Reference]

list of all data and code (a list of malcat.Reference objects) that references the start of this function

fn = analysis.fns[analysis.v2a(0x18000127c)]
for inref in fn.inrefs:
    print(f"function {fn} is referenced by {analysis.ppa(inref.address)} ({inref.type})")
>> "function sub_18000127c is referenced by 0x1800015f3 (sub_1800014c4+12f) (Type.CODE)"
outrefs: List[malcat.Reference]

list of all data and code (a list of malcat.Reference objects) referenced by any code instruction of this basic block

fn = analysis.fns[analysis.v2a(0x18000127c)]
for outref in fn.outrefs:
    print(f"An instruction of {fn} references {analysis.ppa(outref.address)} (r={outref.r}, x={outref.x})")

Prototype

fullname: str

fully qualified function name, e.g X1.X2.Y<Z1, Z2>(A1, A2)

module: str

module part of name:, X1.X2.Y<Z1, Z2>(A1, A2) -> X1.X2

name: str

identifier part of name: X1.X2.Y<Z1, Z2>(A1, A2) -> Y

template_args: List[str]

list of template parameters (strings): X1.X2.Y<Z1, Z2>(A1, A2) -> [Z1, Z2]

args: List[FunctionParameter]

list of arguments (see below): X1.X2.Y<Z1, Z2>(A1, A2) -> [A1, A2]

is_library: bool

true iff the function is part of a known library (e.g. was recognized by a FLIRT signature)

Statistics

Malcat computes some statistics for every functions. These are used in anomalies, but can be used in scripts too.

num_bb: int

number of basic blocks inside the function (both code and data blocks)

num_bb_code: int

number of code basic blocks inside the function

num_bb_data: int

number of data basic blocks inside the function (e.g. a switch pointer array)

size_code: int

size in bytes of all code blocks inside the functions

size_data: int

size in bytes of all data blocks inside the functions

num_intra_jumps: int

number of jumps whose target lies within the function

num_dynamic_jumps: int

number of jump/call <register>

num_unique_immediate_bytes: int

number of unique bytes defined across all immediate operands in the function (range between 0 and 256)

num_highvalue_immediates: int

number of immediate operands how have at least 2 non-zero non-ff bytes defined

Instruction statistics

num_xor: int

number of xor-like opcodes inside the function

num_instructions: int

number of assembly instructions found inside all block codes within the function

num_add: int

number of add-like opcodes inside the function

num_and: int

number of and-like opcodes inside the function

num_assign: int

number of mov-like opcodes inside the function

num_call: int

number of calls inside the function

num_cast: int

number of cast-like opcodes inside the function

num_cjump: int

number of conditional jumps opcodes inside the function

num_cmp: int

number of comparison opcodes inside the function

num_div: int

number of div-like opcodes inside the function

num_faulty: int

number of faulty opcodes inside the function (i.e very likely to raise an error when executed, like int3)

num_fpu: int

number of fpu opcodes inside the function

num_invalid: int

number of invalid opcodes inside the function (could not be decoded)

num_jump: int

number of non-conditional jumps inside the function

num_lshift: int

number of lelft shift opcodes inside the function

num_mmx: int

number of mmx opcodes inside the function

num_mul: int

number of mul-like opcodes inside the function

num_nop: int

number of nop-like opcodes inside the function

num_or: int

number of or-like opcodes inside the function

num_pop: int

number of pop-like opcodes inside the function

num_push: int

number of push-like opcodes inside the function

num_return: int

number of return-like opcodes inside the function

num_rshift: int

number of right shift-like opcodes inside the function

num_stack: int

number of stack-like opcodes inside the function (like dup or stack frame setup)

num_sub: int

number of sub-like opcodes inside the function

num_other: int

number of opcodes which don’t fit in any other category inside the function

Function arguments

Function arguments are represented in Malcat using FunctionParameter instances. Note that debug information parsing in Malcat is work in progress, and that there is currently no stack analysis to automatically deduce the functions arguments. So the argument list is empty most of the time, except when FLIRT signatures have matched or for .NET functions.

Also note that there is no calling convention information yet, since it will be added in another analysis object.

class malcat.FunctionParameter
name: str

name of the argument

type: str

string representing the type (e.g “unsigned int”) of the argument

size: int

size in byte of the argument