Skip to content

Commit

Permalink
Merge pull request #9 from quarkslab/custom_backend_tutorial
Browse files Browse the repository at this point in the history
Add custom backend loader tutorial
  • Loading branch information
RobinDavid committed Oct 12, 2023
2 parents ac8d28e + 8dbf739 commit 7a2329b
Show file tree
Hide file tree
Showing 3 changed files with 239 additions and 5 deletions.
238 changes: 238 additions & 0 deletions tutorials/custom-backend-loader.ipynb
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
}
4 changes: 0 additions & 4 deletions tutorials/custom-backend-loader.rst

This file was deleted.

2 changes: 1 addition & 1 deletion tutorials/tutorials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ QBinDiff
Choosing Features <features-choosing>
Diffing with Custom Anchors <diffing-custom-anchors>
Using Qbindiff Pass Mechanism <using-passes>
Custom Backend Loader <custom-backend-loader>
Custom Backend Loader <custom-backend-loader.ipynb>

0 comments on commit 7a2329b

Please sign in to comment.