-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from quarkslab/custom_backend_tutorial
Add custom backend loader tutorial
- Loading branch information
Showing
3 changed files
with
239 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,238 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# Custom Backend Loader\n", | ||
"\n", | ||
"If you want to load the disassembled binaries made by a tool that is not yet supported by QBinDiff you can implement your own backend loader.\n", | ||
"\n", | ||
"You have to provide an implementation for all the classes that are found in `src/qbindiff/loader/backend/abstract.py`:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 3, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import networkx\n", | ||
"from collections.abc import Iterator\n", | ||
"\n", | ||
"from qbindiff.loader.backend import (\n", | ||
" AbstractOperandBackend,\n", | ||
" AbstractInstructionBackend,\n", | ||
" AbstractBasicBlockBackend,\n", | ||
" AbstractFunctionBackend,\n", | ||
" AbstractProgramBackend\n", | ||
")\n", | ||
"from qbindiff.loader import Structure\n", | ||
"from qbindiff.loader.types import ReferenceType, ReferenceTarget, FunctionType\n", | ||
"from qbindiff.types import Addr\n", | ||
"\n", | ||
"class CustomOperandBackend(AbstractOperandBackend):\n", | ||
"\n", | ||
" def __str__(self) -> str:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def immutable_value(self) -> int | None:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def type(self) -> int:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" def is_immutable(self) -> bool:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
"class CustomInstructionBackend(AbstractInstructionBackend):\n", | ||
"\n", | ||
" @property\n", | ||
" def addr(self) -> Addr:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def mnemonic(self) -> str:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def references(self) -> dict[ReferenceType, list[ReferenceTarget]]:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def operands(self) -> Iterator[AbstractOperandBackend]:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def groups(self) -> list[int]:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def id(self) -> int:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def comment(self) -> str:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def bytes(self) -> bytes:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
"class CustomBasicBlockBackend(AbstractBasicBlockBackend):\n", | ||
"\n", | ||
" @property\n", | ||
" def addr(self) -> Addr:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def instructions(self) -> Iterator[AbstractInstructionBackend]:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
"class CustomFunctionBackend(AbstractFunctionBackend):\n", | ||
"\n", | ||
" @property\n", | ||
" def basic_blocks(self) -> Iterator[AbstractBasicBlockBackend]:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def addr(self) -> Addr:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def graph(self) -> networkx.DiGraph:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def parents(self) -> set[Addr]:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def children(self) -> set[Addr]:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def type(self) -> FunctionType:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def name(self) -> str:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
"class CustomProgramBackend(AbstractProgramBackend):\n", | ||
"\n", | ||
" @property\n", | ||
" def functions(self) -> Iterator[AbstractFunctionBackend]:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def name(self) -> str:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def structures(self) -> list[Structure]:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def callgraph(self) -> networkx.DiGraph:\n", | ||
" raise NotImplementedError()\n", | ||
"\n", | ||
" @property\n", | ||
" def fun_names(self) -> dict[str, Addr]:\n", | ||
" raise NotImplementedError()\n" | ||
] | ||
}, | ||
{ | ||
"attachments": {}, | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Most of the methods are self-explanatory but if you want to know more look at the docstring in the file `src/qbindiff/loader/backend/abstract.py`\n", | ||
"or at the python help." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"Help on class AbstractProgramBackend in module qbindiff.loader.backend.abstract:\n", | ||
"\n", | ||
"class AbstractProgramBackend(builtins.object)\n", | ||
" | This is an abstract class and should not be used as is.\n", | ||
" | It represents a generic backend loader for a Program\n", | ||
" | \n", | ||
" | Readonly properties defined here:\n", | ||
" | \n", | ||
" | callgraph\n", | ||
" | The callgraph of the program.\n", | ||
" | \n", | ||
" | exec_path\n", | ||
" | Returns the executable path\n", | ||
" | \n", | ||
" | fun_names\n", | ||
" | Returns a dictionary with function name as key and the function address as value.\n", | ||
" | \n", | ||
" | functions\n", | ||
" | Returns an iterator over backend function objects.\n", | ||
" | \n", | ||
" | name\n", | ||
" | The name of the program.\n", | ||
" | \n", | ||
" | structures\n", | ||
" | Returns the list of structures defined in program.\n", | ||
" | \n", | ||
" | ----------------------------------------------------------------------\n", | ||
" | Data descriptors defined here:\n", | ||
" | \n", | ||
" | __dict__\n", | ||
" | dictionary for instance variables (if defined)\n", | ||
" | \n", | ||
" | __weakref__\n", | ||
" | list of weak references to the object (if defined)\n", | ||
" | \n", | ||
" | ----------------------------------------------------------------------\n", | ||
" | Data and other attributes defined here:\n", | ||
" | \n", | ||
" | __abstractmethods__ = frozenset({'callgraph', 'exec_path', 'fun_names'...\n", | ||
"\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"from qbindiff.loader.backend import AbstractProgramBackend\n", | ||
"\n", | ||
"help(AbstractProgramBackend)" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "venv", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.11.5" | ||
}, | ||
"orig_nbformat": 4 | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters