Skip to content

Instantly share code, notes, and snippets.

@williballenthin
Created May 18, 2022 17:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save williballenthin/635329b7bc4dc73805f6cbfb1bef468b to your computer and use it in GitHub Desktop.
Save williballenthin/635329b7bc4dc73805f6cbfb1bef468b to your computer and use it in GitHub Desktop.
use FLOSS as a library to identify potential decoding routines
# decoding_routines.py
#
# An example of using FLOSS as a library to identify potential decoding routines.
# It will print an ordered list of function addresses and their "score",
# ranked from most likely to least likely to be a decoding routine.
#
# Usage:
#
# $ python decoding_routines.py /path/to/input.exe
# 0x401000: 0.99
# 0x40100A: 0.95
# 0x401020: 0.93
# 0x401048: 0.93
# 0x402000: 0.91
# ...
#
# Installation:
#
# This script relies on the upcoming version of FLOSS that targets python 3.
# That version is scheduled to be tagged and release on May 25, 2022.
# At that point, you'll be able to do: `pip install flare-floss` and then invoke this script.
#
# Until then, you should check out the source from git:
#
# $ git clone https://github.com/mandiant/flare-floss.git
# $ cd flare-floss
# $ git checkout f881867ad7b72fe5eaaaede3d2210bc50a296aaa
# $ pip install -e .
#
# Author: Willi Ballenthin <william.ballenthin@mandiant.com>
# License: Apache 2.0
import sys
# temporary hack around https://github.com/mandiant/flare-floss/issues/542 (sorry)
import tqdm.contrib.logging
import viv_utils.flirt
# temporary hack around https://github.com/mandiant/flare-floss/issues/541 (sorry)
import floss.utils
import viv_utils
import floss.identify
vw = viv_utils.getWorkspace(sys.argv[1])
functions = vw.getFunctions()
# dict from function VA to metadata/features about the function,
# like:
#
# 4304352: {'features': [BlockCount = 17 (score: 0.40, weighted: 0.10),
# InstructionCount = 70 (score: 0.80, weighted: 0.20),
# Arguments = 4 (score: 1.00, weighted: 0.25),
# CallsTo = 2 (score: 0.01, weighted: 0.00),
# Shift = 0x41ae47 shr ebx,1 (score: 1.00, weighted: 0.75),
# Shift = 0x41ae49 rcr ecx,1 (score: 1.00, weighted: 0.75),
# Shift = 0x41ae4b shr edx,1 (score: 1.00, weighted: 0.75),
# Shift = 0x41ae4d rcr eax,1 (score: 1.00, weighted: 0.75)],
# 'meta': {'api': {'arguments': [('int', 'arg0'),
# ('int', 'arg1'),
# ('int', 'arg2'),
# ('int', 'arg3')],
# 'call_conv': 'stdcall',
# 'func_name': None,
# 'ret_name': None,
# 'ret_type': 'int'},
# 'block_count': 17,
# 'instruction_count': 70,
# 'size': 170},
# 'score': 0.8364363221016562
func_features, lib_funcs = floss.identify.find_decoding_function_features(vw, functions)
# dict from function VA (int) to score (float)
func_scores = {
fva: features["score"]
for fva, features in func_features.items()
}
# list of tuples (score (float), function VA (int)) sorted descending
func_scores = sorted([
(score, fva)
for fva, score in func_scores.items()
], reverse=True)
for score, fva in func_scores:
print(f"0x{fva:x}: {score:0.2f}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment