├── .gitignore ├── AUTHORS ├── LICENSE ├── README.rst ├── bip ├── __init__.py ├── base │ ├── __init__.py │ ├── bipelt.py │ ├── bipenum.py │ ├── biperror.py │ ├── bipida.py │ ├── bipidb.py │ ├── bipstruct.py │ ├── biptype.py │ ├── block.py │ ├── data.py │ ├── func.py │ ├── instr.py │ ├── operand.py │ └── xref.py ├── gui │ ├── __init__.py │ ├── actions.py │ ├── activity.py │ ├── menutb.py │ ├── plugin.py │ ├── pluginmanager.py │ └── userselect.py ├── hexrays │ ├── __init__.py │ ├── astnode.py │ ├── cnode.py │ ├── cnode_visitor.py │ ├── event.py │ ├── hx_cexpr.py │ ├── hx_cfunc.py │ ├── hx_citem.py │ ├── hx_cstmt.py │ ├── hx_lvar.py │ └── hx_visitor.py └── py3compat │ ├── __init__.py │ └── py3compat.py ├── docs ├── .nojekyll ├── Makefile ├── _static │ ├── css │ │ └── fixclassic.css │ └── img │ │ ├── bip_base2.png │ │ ├── bip_gui.png │ │ ├── bip_hexrays.png │ │ └── bip_hexrays_cnode.png ├── base │ ├── bipida.rst │ ├── bipidb.rst │ ├── data.rst │ ├── elt.rst │ ├── enum.rst │ ├── func.rst │ ├── instr.rst │ ├── struct.rst │ ├── type.rst │ └── xref.rst ├── build │ ├── doctrees │ │ ├── base │ │ │ ├── bipida.doctree │ │ │ ├── bipidb.doctree │ │ │ ├── data.doctree │ │ │ ├── elt.doctree │ │ │ ├── enum.doctree │ │ │ ├── func.doctree │ │ │ ├── instr.doctree │ │ │ ├── struct.doctree │ │ │ ├── type.doctree │ │ │ └── xref.doctree │ │ ├── environment.pickle │ │ ├── general │ │ │ ├── archi.doctree │ │ │ ├── changelog.doctree │ │ │ ├── contribution.doctree │ │ │ ├── install.doctree │ │ │ └── overview.doctree │ │ ├── gui │ │ │ ├── activity.doctree │ │ │ ├── plgmanager.doctree │ │ │ ├── plugin.doctree │ │ │ └── userselect.doctree │ │ ├── hexrays │ │ │ ├── astnodes.doctree │ │ │ ├── cfunc.doctree │ │ │ ├── cnode.doctree │ │ │ ├── lvar.doctree │ │ │ └── visit_hx.doctree │ │ └── index.doctree │ └── html │ │ ├── .buildinfo │ │ ├── _images │ │ ├── bip_base2.png │ │ ├── bip_gui.png │ │ └── bip_hexrays_cnode.png │ │ ├── _sources │ │ ├── base │ │ │ ├── bipida.rst.txt │ │ │ ├── bipidb.rst.txt │ │ │ ├── data.rst.txt │ │ │ ├── elt.rst.txt │ │ │ ├── enum.rst.txt │ │ │ ├── func.rst.txt │ │ │ ├── instr.rst.txt │ │ │ ├── struct.rst.txt │ │ │ ├── type.rst.txt │ │ │ └── xref.rst.txt │ │ ├── general │ │ │ ├── archi.rst.txt │ │ │ ├── changelog.rst.txt │ │ │ ├── contribution.rst.txt │ │ │ ├── install.rst.txt │ │ │ └── overview.rst.txt │ │ ├── gui │ │ │ ├── activity.rst.txt │ │ │ ├── plgmanager.rst.txt │ │ │ ├── plugin.rst.txt │ │ │ └── userselect.rst.txt │ │ ├── hexrays │ │ │ ├── astnodes.rst.txt │ │ │ ├── cfunc.rst.txt │ │ │ ├── cnode.rst.txt │ │ │ ├── lvar.rst.txt │ │ │ └── visit_hx.rst.txt │ │ └── index.rst.txt │ │ ├── _static │ │ ├── ajax-loader.gif │ │ ├── basic.css │ │ ├── classic.css │ │ ├── comment-bright.png │ │ ├── comment-close.png │ │ ├── comment.png │ │ ├── css │ │ │ └── fixclassic.css │ │ ├── doctools.js │ │ ├── documentation_options.js │ │ ├── down-pressed.png │ │ ├── down.png │ │ ├── file.png │ │ ├── img │ │ │ ├── bip_base2.png │ │ │ ├── bip_gui.png │ │ │ ├── bip_hexrays.png │ │ │ └── bip_hexrays_cnode.png │ │ ├── jquery-3.2.1.js │ │ ├── jquery.js │ │ ├── language_data.js │ │ ├── minus.png │ │ ├── plus.png │ │ ├── pygments.css │ │ ├── searchtools.js │ │ ├── sidebar.js │ │ ├── underscore-1.3.1.js │ │ ├── underscore.js │ │ ├── up-pressed.png │ │ ├── up.png │ │ └── websupport.js │ │ ├── base │ │ ├── bipida.html │ │ ├── bipidb.html │ │ ├── data.html │ │ ├── elt.html │ │ ├── enum.html │ │ ├── func.html │ │ ├── instr.html │ │ ├── struct.html │ │ ├── type.html │ │ └── xref.html │ │ ├── general │ │ ├── archi.html │ │ ├── changelog.html │ │ ├── contribution.html │ │ ├── install.html │ │ └── overview.html │ │ ├── genindex.html │ │ ├── gui │ │ ├── activity.html │ │ ├── plgmanager.html │ │ ├── plugin.html │ │ └── userselect.html │ │ ├── hexrays │ │ ├── astnodes.html │ │ ├── cfunc.html │ │ ├── cnode.html │ │ ├── lvar.html │ │ └── visit_hx.html │ │ ├── index.html │ │ ├── objects.inv │ │ ├── py-modindex.html │ │ ├── search.html │ │ └── searchindex.js ├── conf.py ├── general │ ├── archi.rst │ ├── changelog.rst │ ├── contribution.rst │ ├── install.rst │ └── overview.rst ├── gui │ ├── activity.rst │ ├── plgmanager.rst │ ├── plugin.rst │ └── userselect.rst ├── hexrays │ ├── astnodes.rst │ ├── cfunc.rst │ ├── cnode.rst │ ├── lvar.rst │ └── visit_hx.rst ├── index.html ├── index.rst └── make.bat ├── install.py ├── install └── idabip_loader.py └── test ├── __init__.py ├── genst_hxast.py ├── launch_test.py ├── ntdll.dll ├── ntdll.dll.i64 ├── test_astnode.py ├── test_bipaction.py ├── test_bipactivity.py ├── test_bipblock.py ├── test_bipdata.py ├── test_bipelt.py ├── test_bipfunc.py ├── test_bipidb.py ├── test_bipinstr.py ├── test_bipoperand.py ├── test_bipplugin.py ├── test_bipstruct.py ├── test_biptype.py ├── test_bipuserselect.py ├── test_bipxref.py ├── test_enum.py ├── test_hxcfunc.py ├── test_hxlvar.py └── test_menutb.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | * Bruno Pujos 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2020, Synacktiv 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /bip/__init__.py: -------------------------------------------------------------------------------- 1 | from .base import * 2 | from .gui import * 3 | from .hexrays import * 4 | 5 | VERSION_BIP_MAJOR = 1 #: Major version of Bip 6 | VERSION_BIP_MINOR = 0 #: Minor version of Bip 7 | 8 | 9 | -------------------------------------------------------------------------------- /bip/base/__init__.py: -------------------------------------------------------------------------------- 1 | from .bipidb import BipIdb, min_ea, max_ea, Here 2 | from .bipida import BipIda 3 | from .bipelt import BipBaseElt, BipRefElt, BipElt, GetElt, GetEltByName 4 | from .instr import BipInstr 5 | from .data import BipData 6 | from .operand import BipOpType, BipDestOpType, BipOperand 7 | from .bipstruct import BipStruct, BStructMember 8 | from .bipenum import BipEnum, BEnumMember 9 | from .xref import _XrefTypes, BipXref 10 | from .biperror import BipError, BipDecompileError 11 | from .func import _BipFuncFlags, BipFunction 12 | from .block import BipBlockType, BipBlock 13 | from .biptype import BipType, BTypeEmpty, BTypePartial, BTypeVoid, BTypeInt, BTypeBool, BTypeFloat, BTypePtr, BTypeArray, BTypeFunc, BTypeStruct, BTypeUnion, BTypeEnum 14 | 15 | -------------------------------------------------------------------------------- /bip/base/biperror.py: -------------------------------------------------------------------------------- 1 | 2 | class BipError(Exception): 3 | pass 4 | 5 | class BipDecompileError(BipError): 6 | """ 7 | :class:`BipError` for decompilation failure. Main reason for this 8 | is that hexrays failed to decompile a function or that the address 9 | provided was not inside a function. 10 | """ 11 | pass 12 | 13 | -------------------------------------------------------------------------------- /bip/base/bipida.py: -------------------------------------------------------------------------------- 1 | import ida_kernwin 2 | 3 | class BipIda(object): 4 | """ 5 | Class for regrouping interfaces with IDA in itself. This can include 6 | configurations and thing specific to the IDA API. 7 | 8 | Currently this contain only static methods. 9 | """ 10 | 11 | @staticmethod 12 | def exec_sync(func, *args, **kwargs): 13 | """ 14 | Wrap around the execute_sync API to perform a call on the function 15 | ``func`` in the main thread. If a function is not marked as 16 | THREAD_SAFE in the headers, then it can only be called from the 17 | main thread of IDA. 18 | 19 | .. todo:: unit test 20 | 21 | :param func: The function to call. 22 | :type func: Python Callable 23 | :param args: Arguments to ``func`` 24 | :param kwargs: Keyworded arguments to ``func`` 25 | :param MFF_FLAG: Flag describing the operation on the database. 26 | Default ``MFF_READ``. Can be ``MFF_FAST``, ``MFF_READ``, 27 | ``MFF_WRITE`` or ``MFF_NOWAIT`` (from ida_kernwin). 28 | :type MFF_FLAG: int 29 | :return: The return of ``func`` 30 | """ 31 | 32 | MFF_FLAG = kwargs.get("MFF_FLAG", ida_kernwin.MFF_READ) 33 | 34 | ret = {"ret": None} 35 | def handle(): 36 | ret["ret"] = func(*args, **kwargs) 37 | return 1 38 | 39 | ida_kernwin.execute_sync(handle, MFF_FLAG) 40 | return ret["ret"] 41 | 42 | -------------------------------------------------------------------------------- /bip/base/bipidb.py: -------------------------------------------------------------------------------- 1 | 2 | # define BipIdb and some helper functions for easier scripting (at the end). 3 | 4 | import ida_kernwin 5 | import idaapi 6 | import idc 7 | 8 | class BipIdb(object): 9 | """ 10 | Class for representing the idb loaded by IDA, this has the goal to 11 | provide access to things specific to the IDB. 12 | 13 | Currently this contain only static methods. 14 | """ 15 | 16 | @staticmethod 17 | def ptr_size(): 18 | """ 19 | Return the number of bits in a pointer. 20 | 21 | :rtype: int 22 | """ 23 | info = idaapi.get_inf_structure() 24 | 25 | if info.is_64bit(): 26 | bits = 64 27 | elif info.is_32bit(): 28 | bits = 32 29 | else: 30 | bits = 16 31 | 32 | return bits 33 | 34 | @staticmethod 35 | def min_ea(): 36 | """ 37 | Return the lowest mapped address of the IDB. 38 | """ 39 | return idc.get_inf_attr(idc.INF_MIN_EA) 40 | 41 | @staticmethod 42 | def max_ea(): 43 | """ 44 | Return the highest mapped address of the IDB. 45 | """ 46 | return idc.get_inf_attr(idc.INF_MAX_EA) 47 | 48 | @staticmethod 49 | def image_base(): 50 | """ 51 | Return the base address of the image loaded in the IDB. 52 | 53 | This is different from :meth:`~BipIdb.min_ea` which is the lowest 54 | *mapped* address. 55 | """ 56 | return idaapi.get_imagebase() 57 | 58 | @staticmethod 59 | def current_addr(): 60 | """ 61 | Return current screen address. 62 | 63 | :return: The current address selected. 64 | """ 65 | return ida_kernwin.get_screen_ea() 66 | 67 | @staticmethod 68 | def relea(addr): 69 | """ 70 | Calculate the relative address compare to the IDA image base. 71 | The calcul done is ``ADDR - IMGBASE``. 72 | 73 | The opposite of this function is :func:`absea`. 74 | 75 | :param int addr: The absolute address to translate. 76 | :return: The offset from image base corresponding to ``addr``. 77 | :rtype: int 78 | """ 79 | return addr-idaapi.get_imagebase() 80 | 81 | @staticmethod 82 | def absea(offset): 83 | """ 84 | Calculate the absolute address from an offset of the image base. 85 | The calcul done is ``OFFSET + IMGBASE`` . 86 | 87 | The opposite of this function is :func:`relea`. 88 | 89 | :param int offset: The offset from the beginning of the image base 90 | to translate. 91 | :return: The absolute address corresponding to the offset. 92 | :rtype: int 93 | """ 94 | return offset+idaapi.get_imagebase() 95 | 96 | def min_ea(): 97 | """ 98 | Return the lowest mapped address of the IDB. 99 | Wrapper on :meth:`BipIdb.min_ea`. 100 | """ 101 | return BipIdb.min_ea() 102 | 103 | def max_ea(): 104 | """ 105 | Return the highest mapped address of the IDB. 106 | Wrapper on :meth:`BipIdb.max_ea`. 107 | """ 108 | return BipIdb.max_ea() 109 | 110 | def Here(): 111 | """ 112 | Return current screen address. 113 | 114 | :return: The current address. 115 | """ 116 | return BipIdb.current_addr() 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /bip/base/xref.py: -------------------------------------------------------------------------------- 1 | import bip.base.bipelt 2 | 3 | class _XrefTypes(object): 4 | """ 5 | Static class allowing to get the type of the xref. Internall class. 6 | """ 7 | # data xref types 8 | dr_O = 0x01 #: Offset 9 | dr_W = 0x02 #: Write access 10 | dr_R = 0x03 #: Read access 11 | dr_T = 0x04 #: Text, forced operands only 12 | dr_I = 0x05 #: Informational 13 | 14 | # code xref types 15 | fl_CF = 0x10 #: Call Far, function at the reference location 16 | fl_CN = 0x11 #: Call Near, function at the reference location 17 | fl_JF = 0x12 #: Jump Far 18 | fl_JN = 0x13 #: Jump Near 19 | fl_USobsolete = 0x14 #: obsolete ?? 20 | fl_F = 0x15 #: Ordinary flow 21 | 22 | # other flags in the type field 23 | XREF_USER = 0x20 # User specified xref 24 | XREF_TAIL = 0x40 # Reference to tail byte in extrn symbols. 25 | XREF_BASE = 0x80 # Reference to the base part of an offset. 26 | XREF_MASK = 0x1F # Mask to get xref type. 27 | XREF_PASTEND = 0x100 28 | 29 | class BipXref(object): 30 | """ 31 | Base class for representing an xref between two elements. 32 | 33 | .. todo:: classmethod allowing to create xref 34 | 35 | .. todo:: classmethod allowing to destroy xref 36 | """ 37 | 38 | def __init__(self, xref): 39 | """ 40 | Constructor for an xref object. There is few reason to directly 41 | use this constructor, properties of :class:`BipBaseElt` and of 42 | :class:`BipFunction` should allow to directly get the xref. 43 | 44 | :param xref: The xref object used in IDA. 45 | :type xref: ``idautils._xref`` . 46 | """ 47 | self._xref = xref #: Internal object representing the xref in IDA 48 | 49 | @property 50 | def _type(self): 51 | """ 52 | Return the type of the xref with the mask applied. 53 | """ 54 | return self._xref.type & _XrefTypes.XREF_MASK 55 | 56 | @property 57 | def is_userdef(self): 58 | """ 59 | Return True if the xref was added by a user. 60 | """ 61 | return self._xref.type & _XrefTypes.XREF_USER != 0 62 | 63 | @property 64 | def src_ea(self): 65 | """ 66 | Source address (or member id for xref on struct) of the XRef: 67 | the object which created it. This is equivalent to the *from* in 68 | the standard IDA api. 69 | """ 70 | return self._xref.frm 71 | 72 | @property 73 | def src(self): 74 | """ 75 | Property which allow to get an object representing the element at 76 | the source address. 77 | 78 | :return: An object representing the element at the source address. 79 | :rtypes: An :class:`BipBaseElt` or one of its subclasses. See 80 | :func:`GetElt`. 81 | """ 82 | return bip.base.bipelt.GetElt(self.src_ea) 83 | 84 | @property 85 | def dst_ea(self): 86 | """ 87 | Destination address (or member id for xref on struct) of the XRef. 88 | This is equivalent to the *to* in the standard IDA api. 89 | """ 90 | return self._xref.to 91 | 92 | @property 93 | def dst(self): 94 | """ 95 | Property which allow to get an object representing the element at 96 | the destination address or id. 97 | 98 | :return: An object representing the element at the destination 99 | address. 100 | :rtypes: An :class:`BipBaseElt` or one of its subclasses. See 101 | :func:`GetElt`. 102 | """ 103 | return bip.base.bipelt.GetElt(self.dst_ea) 104 | 105 | ######### PROPERTY FOR CODE FLOW XREF ########### 106 | 107 | @property 108 | def is_codepath(self): 109 | """ 110 | Property indicating if the xref indicate a path for the control 111 | flow of the program. This can be because of a jmp, a call or simply 112 | a normal path. 113 | """ 114 | return self._type >= 0x10 # see _XrefTypes 115 | 116 | @property 117 | def is_call(self): 118 | """ 119 | Property indicating if this xref was generated by a call 120 | intruction: the source is the call instruction and the destination 121 | is the beginning of a function. 122 | """ 123 | return self._type in [_XrefTypes.fl_CF, _XrefTypes.fl_CN] 124 | 125 | @property 126 | def is_jmp(self): 127 | """ 128 | Property indicating if this xref was generated by a jmp 129 | instruction. 130 | """ 131 | return self._type in [_XrefTypes.fl_JF, _XrefTypes.fl_JN] 132 | 133 | @property 134 | def is_ordinaryflow(self): 135 | """ 136 | Property indicating if this xref indicate an ordinary flow (not 137 | jump or call) between two instructions. 138 | """ 139 | return self._type == _XrefTypes.fl_F 140 | 141 | ########### PROPERTY FOR DATA XREF ################### 142 | 143 | @property 144 | def is_offset(self): 145 | """ 146 | The xref is created by an offset, it can be a ``lea`` instruction 147 | or a reference on a address in an array. 148 | """ 149 | return self._type == _XrefTypes.dr_O 150 | 151 | @property 152 | def is_write_access(self): 153 | """ 154 | The xref is created by a write access. 155 | """ 156 | return self._type == _XrefTypes.dr_W 157 | 158 | @property 159 | def is_read_access(self): 160 | """ 161 | The xref is created by a read access. 162 | """ 163 | return self._type == _XrefTypes.dr_R 164 | 165 | ########## PROPERTY OF DST & SRC ################ 166 | 167 | @property 168 | def is_dst_code(self): 169 | """ 170 | Property which indicate if the destination of the xref is code. 171 | 172 | :return: True or False. 173 | """ 174 | return self.dst.is_code 175 | 176 | @property 177 | def is_src_code(self): 178 | """ 179 | Property which indicate if the source of the xref is code. 180 | 181 | :return: True or False. 182 | """ 183 | return self.src.is_code 184 | 185 | -------------------------------------------------------------------------------- /bip/gui/__init__.py: -------------------------------------------------------------------------------- 1 | from .activity import BipActivity, BipActivityContainer 2 | from .actions import BipAction 3 | from .menutb import * 4 | from .userselect import BipUserSelect 5 | from .pluginmanager import get_plugin_manager, BipPluginLoader 6 | from .plugin import BipPlugin, shortcut, menu 7 | -------------------------------------------------------------------------------- /bip/gui/menutb.py: -------------------------------------------------------------------------------- 1 | """ 2 | Methods for creating top level menu and toolbars. As we currently do not 3 | have access to objects reflected by those elements this is a set of 4 | wrapper on top of IDA API. 5 | """ 6 | import ida_kernwin 7 | 8 | def add_top_menu(name, uid=None, before=None): 9 | """ 10 | Add a top level menu entry in IDA (a directory in the menu at the 11 | top). This should be used only for top level menu and will not work 12 | for subdirectory which can br created directly when register a 13 | :class:`BipAction` (or using the :func:`menu` decorator). 14 | 15 | This is different from the :func:`menu` decorator. This is a 16 | wrapper on the ``create_menu`` from IDAPython. Those top level menu 17 | are in practice different of the submenu, those submenu can 18 | be directly set using a :class:`BipAction` while those top menu can't 19 | be. 20 | 21 | :param str name: The name of the top level menu 22 | (ex.: ``NewTopLevelMenu``). 23 | :param str uid: Unique id for this menu, this will not be shown 24 | in the gui but can be used for deleting it 25 | after (:func:`del_top_menu`) or for the ``before`` argument (see 26 | below). If it not unique this function will fail. By default 27 | (``None``) the value of the ``name`` will be used as there is 28 | few case where having two top level menu of the same name is 29 | useful. 30 | :param str before: The uid of a menu before which to insert this new 31 | menu. If the ``uid`` does not exist it this function will still 32 | succeed but insert the entry at the end. 33 | :return: ``True`` on success, ``False`` otherwise. 34 | """ 35 | if uid is None: 36 | uid = name 37 | return ida_kernwin.create_menu(uid, name, before) 38 | 39 | def del_top_menu(uid): 40 | """ 41 | Delete a top level menu from IDA. 42 | 43 | :param str uid: The unique ID of the menu. For more information see 44 | :func:`add_top_menu` . 45 | """ 46 | ida_kernwin.delete_menu(uid) 47 | 48 | 49 | -------------------------------------------------------------------------------- /bip/gui/userselect.py: -------------------------------------------------------------------------------- 1 | 2 | from re import match 3 | import ida_kernwin 4 | 5 | class BipUserSelect(object): 6 | """ 7 | Class for helping with interfacing with user selection. 8 | 9 | This class contains only static method for now. 10 | """ 11 | 12 | @staticmethod 13 | def get_curr_highlighted_str(): 14 | """ 15 | Return the currently highlighted identifier or None if nothing is 16 | highlighted. This get it from the current view. 17 | 18 | :return: The string of the highlighted object or None if nothing 19 | is highlighted. 20 | """ 21 | t = ida_kernwin.get_highlight(ida_kernwin.get_current_viewer()) 22 | if t is None: 23 | return t 24 | return t[0] 25 | 26 | @staticmethod 27 | def get_curr_highlighted_int(): 28 | """ 29 | Allow to get the value of the currently highlighted identifier (in 30 | the current view) if it is an integer. If it not possible to make 31 | it match a type of integer (hex, oct or dec) or if nothing is 32 | highlighted the function return ``None``. 33 | 34 | :return: the value currently highlighted. 35 | """ 36 | s = BipUserSelect.get_curr_highlighted_str() 37 | if s is None: 38 | return s 39 | h = match('(0x[0-9a-fA-F]+).*', s) 40 | 41 | if h: 42 | return int(h.group(1), 16) 43 | 44 | o = match('(0[0-7]+).*', s) 45 | if o: 46 | return int(o.group(1), 8) 47 | 48 | n = match('([0-9]+).*', s) 49 | if n: 50 | return int(n.group(1)) 51 | 52 | return None 53 | 54 | 55 | -------------------------------------------------------------------------------- /bip/hexrays/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | def _init_hx(): 3 | from ida_hexrays import init_hexrays_plugin 4 | init_hexrays_plugin() 5 | 6 | try: 7 | _init_hx() 8 | except Exception: 9 | pass 10 | 11 | from .event import HxEvent 12 | from .hx_lvar import HxLvar 13 | from .hx_cfunc import HxCFunc 14 | from .astnode import HxCType 15 | from .hx_citem import HxCItem, HxCStmt, HxCExpr 16 | from .hx_cexpr import HxCExprFinal, HxCExprEmpty, HxCExprNum, HxCExprFNum, HxCExprStr, HxCExprObj, HxCExprVar, HxCExprHelper, HxCExprInsn, HxCExprType, HxCExprTernary, HxCExprDoubleOperation, HxCExprComma, HxCExprAssignment, HxCExprAsg, HxCExprAsgbor, HxCExprAsgxor, HxCExprAsgband, HxCExprAsgadd, HxCExprAsgsub, HxCExprAsgmul, HxCExprAsgsshr, HxCExprAsgushr, HxCExprAsgshl, HxCExprAsgsdiv, HxCExprAsgudiv, HxCExprAsgsmod, HxCExprAsgumod, HxCExprLor, HxCExprLand, HxCExprBor, HxCExprXor, HxCExprBand, HxCExprEq, HxCExprNe, HxCExprSge, HxCExprUge, HxCExprSle, HxCExprUle, HxCExprSgt, HxCExprUgt, HxCExprSlt, HxCExprUlt, HxCExprSshr, HxCExprUshr, HxCExprShl, HxCExprAdd, HxCExprSub, HxCExprMul, HxCExprSdiv, HxCExprUdiv, HxCExprSmod, HxCExprUmod, HxCExprFadd, HxCExprFsub, HxCExprFmul, HxCExprFdiv, HxCExprUnaryOperation, HxCExprPtr, HxCExprFneg, HxCExprNeg, HxCExprCast, HxCExprLnot, HxCExprBnot, HxCExprRef, HxCExprPostinc, HxCExprPostdec, HxCExprPreinc, HxCExprPredec, HxCExprSizeof, HxCExprCall, HxCExprMemAccess, HxCExprIdx, HxCExprMemref, HxCExprMemptr 17 | from .hx_cstmt import HxCStmtEmpty, HxCStmtFinal, HxCStmtExpr, HxCStmtGoto, HxCStmtAsm, HxCStmtIf, HxCStmtLoop, HxCStmtFor, HxCStmtWhile, HxCStmtDoWhile, HxCStmtReturn, HxCStmtSwitch, HxCStmtContinue, HxCStmtBreak, HxCStmtBlock 18 | from .cnode import * 19 | 20 | -------------------------------------------------------------------------------- /bip/hexrays/cnode_visitor.py: -------------------------------------------------------------------------------- 1 | #from cnode import CNodeExpr, CNodeStmt 2 | import bip.hexrays.cnode # as modcnode # problem compat py2/py3, py2 do not like the ``as`` 3 | 4 | def visit_dfs_cnode(cnode, callback): 5 | """ 6 | Basic visitor for a CNode: this will allow to call a callback on every 7 | node under the current one (and including the current node) in the 8 | AST. This method does not used the visitor from hexrays 9 | (``ctree_visitor_t``). The callback will receive a :class:`CNode` in 10 | argument. 11 | 12 | This visitor implements a Deep-First Search (DFS) algorithm which will 13 | always visit first the :class:`CNodeExpr` and then the 14 | :class:`CNodeStmt`. The callback is called before visiting deeper. 15 | For an object which inherit from :class:`CNodeExpr` the child nodes 16 | will be called in the same order than returned by 17 | :meth:`~CNodeExpr.ops`; for an object which inherit from 18 | :class:`CNodeStmt` the child nodes will be called in the same order 19 | than returned by :meth:`~CNodeStmt.expr_children` (expression) follow by 20 | the nodes in the same order as :meth:`~CNodeStmt.stmt_children` 21 | (statements). 22 | 23 | If the callback return ``False`` the visitor will stop. Every other 24 | result is ignore. 25 | 26 | .. note:: This function will not visit a statement which is under a 27 | :class:`CNodeExprInsn` . Those should not be present in the last 28 | stage of a ctree and so this should not be a problem. 29 | 30 | An exception raised by the callback will interupt the visitor. 31 | 32 | :param cnode: An object which inherit from :class:`CNode`. This object 33 | and all its child will be visited. 34 | :param callback: A callable taking one argument which will be called 35 | on all the :class:`CNode` visited with the :class:`CNode` as 36 | argument. If it returns False the visitor stops. 37 | """ 38 | # implem using a stack for avoiding recursivity problems 39 | # this is a tree so no need to check if we have already treated a node. 40 | stack = [cnode] 41 | while len(stack) != 0: 42 | elt = stack.pop() # get the next element 43 | if callback(elt) == False: # call the callback before visiting the next 44 | return # if ret False: stop 45 | if isinstance(elt, bip.hexrays.cnode.CNodeExpr): 46 | # if we have an expr just append all the child, we append them 47 | # in reverse order. 48 | ch = list(elt.ops) 49 | ch.reverse() 50 | stack += ch 51 | elif isinstance(elt, bip.hexrays.cnode.CNodeStmt): 52 | ch = list(elt.expr_children) 53 | ch += list(elt.stmt_children) 54 | ch.reverse() 55 | stack += ch 56 | else: 57 | # this should never happen 58 | raise RuntimeError("Unknown type for visiting: {}".format(elt)) 59 | 60 | def visit_dfs_cnode_filterlist(cnode, callback, filter_list): 61 | """ 62 | Visitor for :class:`CNode` with filtering. This function is the same 63 | than :func:`visit_dfs_cnode` but allow to use the callback only on 64 | :class:`CNode` which are in a list (white listing of the node to 65 | visit). 66 | 67 | For information about the visitor implementation see 68 | :func:`visit_dfs_cnode` . If the `filter_list` parameter contain only 69 | statement (:class:`CNodeStmt`) the expression will not be visited at 70 | all, this should allow a little performance gain. 71 | 72 | If the callback return ``False`` the visitor will stop. Every other 73 | result is ignore. 74 | 75 | :param cnode: An object which inherit from :class:`CNode`. This object 76 | and all its child will be visited. 77 | :param callback: A callable taking one argument which will be called 78 | on all the :class:`CNode` visited with the :class:`CNode` as 79 | argument. 80 | :param filter_list: A list or tuple of class or a class which inherit 81 | from :class:`CNode`. The callback will be called only for the node 82 | from a class in this list. If it returns False the visitor stops. 83 | """ 84 | if isinstance(filter_list, (list, tuple)) and len(filter_list) == 0: 85 | # we don't visit anything 86 | return 87 | # check if we need to visit the child of the expression 88 | vist_expr = False 89 | if isinstance(filter_list, (list, tuple)): 90 | for i in filter_list: 91 | if issubclass(i, bip.hexrays.cnode.CNodeExpr): 92 | vist_expr = True 93 | break 94 | elif issubclass(filter_list, bip.hexrays.cnode.CNodeExpr): 95 | vist_expr = True 96 | stack = [cnode] 97 | while len(stack) != 0: 98 | elt = stack.pop() # get the next element 99 | # check if we want the call 100 | if ((isinstance(filter_list, list) and elt.__class__ in filter_list) or 101 | (not isinstance(filter_list, list) 102 | and isinstance(elt, filter_list))): 103 | # check if we want the call 104 | if callback(elt) == False: # call the callback before visiting the next 105 | return 106 | if isinstance(elt, bip.hexrays.cnode.CNodeExpr): 107 | if vist_expr: 108 | ch = list(elt.ops) 109 | ch.reverse() 110 | stack += ch 111 | elif isinstance(elt, bip.hexrays.cnode.CNodeStmt): 112 | if vist_expr: 113 | ch = list(elt.expr_children) 114 | else: 115 | ch = [] 116 | ch += list(elt.stmt_children) 117 | ch.reverse() 118 | stack += ch 119 | else: 120 | # this should never happen 121 | raise RuntimeError("Unknown type for visiting: {}".format(elt)) 122 | 123 | 124 | -------------------------------------------------------------------------------- /bip/hexrays/event.py: -------------------------------------------------------------------------------- 1 | 2 | import ida_hexrays 3 | 4 | class HxEvent(object): 5 | """ 6 | Enum object for the hexrays event. This is documented in 7 | https://www.hex-rays.com/products/decompiler/manual/sdk/hexrays_8hpp.shtml 8 | https://www.hex-rays.com/products/decompiler/manual/sdk/hexrays_8hpp_source.shtml 9 | and defined in ``ida_hexrays`` python file. 10 | 11 | .. todo:: make wrapper on functions and stuff 12 | 13 | """ 14 | hxe_flowchart = ida_hexrays.hxe_flowchart 15 | hxe_stkpnts = ida_hexrays.hxe_stkpnts 16 | hxe_prolog = ida_hexrays.hxe_prolog 17 | hxe_microcode = ida_hexrays.hxe_microcode 18 | hxe_preoptimized = ida_hexrays.hxe_preoptimized 19 | hxe_locopt = ida_hexrays.hxe_locopt 20 | hxe_prealloc = ida_hexrays.hxe_prealloc 21 | hxe_glbopt = ida_hexrays.hxe_glbopt 22 | hxe_structural = ida_hexrays.hxe_structural 23 | hxe_maturity = ida_hexrays.hxe_maturity 24 | hxe_interr = ida_hexrays.hxe_interr 25 | hxe_combine = ida_hexrays.hxe_combine 26 | hxe_print_func = ida_hexrays.hxe_print_func 27 | hxe_func_printed = ida_hexrays.hxe_func_printed 28 | hxe_resolve_stkaddrs = ida_hexrays.hxe_resolve_stkaddrs 29 | hxe_open_pseudocode = ida_hexrays.hxe_open_pseudocode # 100 30 | hxe_switch_pseudocode = ida_hexrays.hxe_switch_pseudocode 31 | hxe_refresh_pseudocode = ida_hexrays.hxe_refresh_pseudocode 32 | hxe_close_pseudocode = ida_hexrays.hxe_close_pseudocode 33 | hxe_keyboard = ida_hexrays.hxe_keyboard 34 | hxe_right_click = ida_hexrays.hxe_right_click 35 | hxe_double_click = ida_hexrays.hxe_double_click 36 | hxe_curpos = ida_hexrays.hxe_curpos 37 | hxe_create_hint = ida_hexrays.hxe_create_hint 38 | hxe_text_ready = ida_hexrays.hxe_text_ready 39 | hxe_populating_popup = ida_hexrays.hxe_populating_popup 40 | lxe_lvar_name_changed = ida_hexrays.lxe_lvar_name_changed 41 | lxe_lvar_type_changed = ida_hexrays.lxe_lvar_type_changed 42 | lxe_lvar_cmt_changed = ida_hexrays.lxe_lvar_cmt_changed 43 | lxe_lvar_mapping_changed = ida_hexrays.lxe_lvar_mapping_changed 44 | USE_KEYBOARD = ida_hexrays.USE_KEYBOARD 45 | USE_MOUSE = ida_hexrays.USE_MOUSE 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /bip/py3compat/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/bip/py3compat/__init__.py -------------------------------------------------------------------------------- /bip/py3compat/py3compat.py: -------------------------------------------------------------------------------- 1 | """ 2 | Functions and trics for supporting both python 2 and python 3 in 3 | Bip. This is for internal use only. 4 | """ 5 | 6 | import sys 7 | 8 | def is_py3(): 9 | """ 10 | Function for checking if we are in python3. This is used in other 11 | part of Bip for compatibility between python2 and python3. 12 | """ 13 | return sys.version_info[0] == 3 14 | 15 | if sys.version_info[0] == 3: 16 | long = int # long does not exist in python3, everything is an int 17 | unicode = str # unicode is the base string type in python3 18 | def int2byte(i): 19 | """ 20 | Method for converting an integer to a byte. This is a replacement of 21 | ``chr(i)`` in python2 and of ``bytes([i])`` in python3. 22 | 23 | :param int i: The value to get for the character. 24 | :return: A byte string (str or bytes in python2, bytes in python3) 25 | for the character. 26 | """ 27 | return bytes([i]) 28 | else: 29 | def int2byte(i): 30 | """ 31 | Method for converting an integer to a byte. This is a replacement of 32 | ``chr(i)`` in python2 and of ``bytes([i])`` in python3. 33 | 34 | :param int i: The value to get for the character. 35 | :return: A byte string (str or bytes in python2, bytes in python3) 36 | for the character. 37 | """ 38 | return chr(i) 39 | 40 | 41 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/.nojekyll -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = Bip 8 | SOURCEDIR = . 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/_static/css/fixclassic.css: -------------------------------------------------------------------------------- 1 | div.body { 2 | min-width: 450px; 3 | max-width: none; 4 | } 5 | 6 | div.bodywrapper { 7 | margin-right: 20px; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /docs/_static/img/bip_base2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/_static/img/bip_base2.png -------------------------------------------------------------------------------- /docs/_static/img/bip_gui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/_static/img/bip_gui.png -------------------------------------------------------------------------------- /docs/_static/img/bip_hexrays.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/_static/img/bip_hexrays.png -------------------------------------------------------------------------------- /docs/_static/img/bip_hexrays_cnode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/_static/img/bip_hexrays_cnode.png -------------------------------------------------------------------------------- /docs/base/bipida.rst: -------------------------------------------------------------------------------- 1 | IDA interface 2 | ############# 3 | 4 | .. module:: bip.base 5 | 6 | Some API allows to affect directly the IDA software, those are accessible 7 | through static methods of the :class:`BipIda` class. Those can include access 8 | to the IDA configuration or thing specific to the API. 9 | 10 | BipIda API 11 | ========== 12 | 13 | .. autoclass:: BipIda 14 | :members: 15 | :member-order: bysource 16 | :special-members: 17 | :private-members: 18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/base/bipidb.rst: -------------------------------------------------------------------------------- 1 | IDB representation 2 | ################## 3 | 4 | .. module:: bip.base 5 | 6 | Some useful information are link to the IDB loaded by IDA, those information 7 | are accessible through static methods of the :class:`BipIdb` class. Those 8 | information include things such as the base address of the image, the minium 9 | and maximum address mapped in the IDB and so on. A few `helper functions`_ are 10 | also defined directly at the top level of ``bipidb.py`` for making it more 11 | easy to script. 12 | 13 | BipIdb API 14 | ========== 15 | 16 | .. autoclass:: BipIdb 17 | :members: 18 | :member-order: bysource 19 | :special-members: 20 | :private-members: 21 | 22 | Helper functions 23 | ================ 24 | 25 | .. autofunction:: min_ea 26 | 27 | .. autofunction:: max_ea 28 | 29 | .. autofunction:: Here 30 | -------------------------------------------------------------------------------- /docs/base/data.rst: -------------------------------------------------------------------------------- 1 | Data 2 | #### 3 | 4 | .. module:: bip.base 5 | 6 | The :class:`BipData` objects inherit from :class:`BipElt` and are used for 7 | representing data which means everything which is not code. 8 | 9 | :class:`BipData` object can be created by calling the constructor with the 10 | data address but in a more generic way it is possible to use the 11 | :func:`GetElt` or :func:`GetEltByName` for recuperating them. 12 | :class:`BipData` will be create by :func:`GetElt` if IDA considered the 13 | address as data or unknown. As they are inheriting from :class:`BipRefElt` it 14 | is possible to use the xref API through them (for access to and from them). 15 | 16 | The most basic usage will be to recuperate or set a value using the property 17 | :meth:`~BipData.value`. This property depends of the type 18 | which can be access and modify through the :meth:`~BipData.type` property, 19 | this property return and expect a :class:`BipType` object. It is also possible 20 | to access directly the :meth:`BipElt.bytes` of the object. 21 | 22 | :class:`BipData` provides some static methods for accessing and 23 | modifying data of the IDB without creating an object, in particular the 24 | :meth:`~BipData.get_cstring` which allow to get a C string from an address. 25 | Finally it is possible to iterate on all defined :class:`BipData` using the 26 | class method :class:`BipData.iter_heads`. 27 | 28 | BipData API 29 | =========== 30 | 31 | .. autoclass:: BipData 32 | :members: 33 | :member-order: bysource 34 | :special-members: 35 | :private-members: 36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/base/elt.rst: -------------------------------------------------------------------------------- 1 | .. _ref-base-elt: 2 | 3 | Elements 4 | ######## 5 | 6 | .. module:: bip.base 7 | 8 | Basic elements in IDA are all refered by an ID. This can be the address of the 9 | element in the database or a particular ID. For allowing to access easily the 10 | correct element from its ID Bip defines a tree of classes with each leaf 11 | classes in charge of a particular element. 12 | 13 | Three abstract classes are defined in Bip: 14 | 15 | * :class:`BipBaseElt` : is the parent class of all element in Bip, in 16 | particular it is in charge of making the interface with :func:`GetElt` and 17 | :func:`GetEltByName`. 18 | * :class:`BipRefElt` : is the parent class of all elements which can be 19 | referenced by xref in IDA. This include :class:`BipInstr`, :class:`BipData`, 20 | :class:`BipStruct` and :class:`BStructMember`. 21 | * :class:`BipElt` : is the parent class of all elements with an actual address 22 | as ID and provide a lot of common API for thoses elements, this is the 23 | parent class of :class:`BipInstr` and :class:`BipData`. 24 | 25 | For getting a correct element from an ID it is enough to call the 26 | :func:`GetElt` and :func:`GetEltByName` function. As those functions can 27 | return diferent types of objects it can be convenient to use ``isinstance`` 28 | for checking the return type of the object. 29 | 30 | Internals 31 | ========= 32 | 33 | Recuperation of the correct element 34 | ----------------------------------- 35 | 36 | For being able to return an object :func:`GetElt` 37 | (:func:`GetEltByName` is simply a wrapper in top of :func:`GetElt`) must 38 | be able to tell which class should be used. This is done by recursivelly 39 | checking the child classes of :class:`BipBaseElt`, each child classes should 40 | implement the class method :meth:`BipBaseElt._is_this_elt` which take an ID 41 | in argument. If this method return True iteration will continue on child 42 | classes of this class, if it return False it will stop. When all child classes 43 | return False or a leaf as been reach an object of this element is created and 44 | returned. 45 | 46 | If two subclasses return True at one level of the recursion, one of them will 47 | be ignored. 48 | 49 | All classes which inherit from :class:`BipBaseElt` are expected to take only 50 | their ID in argument for being able to be instantiated by :func:`GetElt` . 51 | 52 | Element Functions API 53 | ===================== 54 | 55 | 56 | .. autofunction:: GetElt 57 | .. autofunction:: GetEltByName 58 | 59 | BipBaseElt API 60 | ============== 61 | 62 | .. autoclass:: BipBaseElt 63 | :members: 64 | :member-order: bysource 65 | :special-members: 66 | :private-members: 67 | 68 | BipRefElt API 69 | ============= 70 | 71 | .. autoclass:: BipRefElt 72 | :members: 73 | :member-order: bysource 74 | :special-members: 75 | :private-members: 76 | 77 | BipElt API 78 | ========== 79 | 80 | .. autoclass:: BipElt 81 | :members: 82 | :member-order: bysource 83 | :special-members: 84 | :private-members: 85 | 86 | 87 | -------------------------------------------------------------------------------- /docs/base/enum.rst: -------------------------------------------------------------------------------- 1 | Enum 2 | #### 3 | 4 | .. module:: bip.base 5 | 6 | This part describe the enum (:class:`BipEnum`) and enum members 7 | (:class:`BEnumMember`). The :class:`BEnumMember` class inherit from 8 | :class:`BipRefElt` which allow to get access to the enum members through xref 9 | and possible to recuperate using the :func:`GetElt` function. 10 | 11 | Those classes represent 12 | the element view in the ``Enum`` tab. of IDA and are different from the 13 | :class:`BipType` which is used for referencing the type of some elements in 14 | IDA, however they are obviously linked. 15 | 16 | Except xrefs the most common way to get an enum is using the 17 | :meth:`BipEnum.get` class method which expect its name. For creating one 18 | the :meth:`BipEnum.create` class method is available. Once an enum has 19 | been recuperated it is possible to access the members as a dict by using 20 | their name or to iterate on all the members. It is also possible to use 21 | the :meth:`BEnumMember.get` class method for directly recuperating an enum 22 | member. 23 | 24 | BipEnum API 25 | =========== 26 | 27 | .. autoclass:: BipEnum 28 | :members: 29 | :member-order: bysource 30 | :special-members: 31 | :private-members: 32 | 33 | BEnumMember API 34 | =============== 35 | 36 | .. autoclass:: BEnumMember 37 | :members: 38 | :member-order: bysource 39 | :special-members: 40 | :private-members: 41 | 42 | 43 | -------------------------------------------------------------------------------- /docs/base/func.rst: -------------------------------------------------------------------------------- 1 | Functions & Basic blocks 2 | ######################## 3 | 4 | .. module:: bip.base 5 | 6 | :class:`BipFunction` are created by passing them an address. They are 7 | container for basic block (:class:`BipBlock` accessible using 8 | the :meth:`~BipFunction.blocks` property) and instruction (:class:`BipInstr` 9 | accessible using the :meth:`~BipFunction.instr` property). :class:`BipBlock` 10 | them self contain instructions, a link back to the function 11 | (property :meth:`~BipBlock.func`) and a way to navigate them using the 12 | property :meth:`~BipBlock.succ` and :meth:`BipBlock.pred` . 13 | 14 | :class:`BipFunction` can also allow to recuperate the hexrays decompile 15 | version of their code when available, this is done using the 16 | :meth:`~BipFunction.hxcfunc` property which return a 17 | :class:`~bip.hexrays.HxCFunc` object when available. 18 | 19 | For example of how to use functions and blocks see the 20 | :ref:`general-overview` . 21 | 22 | BipFunction API 23 | =============== 24 | 25 | .. autoclass:: BipFunction 26 | :members: 27 | :member-order: bysource 28 | :special-members: 29 | :private-members: 30 | 31 | BipBlock API 32 | ============ 33 | 34 | .. autoclass:: BipBlock 35 | :members: 36 | :member-order: bysource 37 | :special-members: 38 | :private-members: 39 | 40 | .. autoclass:: BipBlockType 41 | :members: 42 | :member-order: bysource 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /docs/base/instr.rst: -------------------------------------------------------------------------------- 1 | Instructions & Operands 2 | ####################### 3 | 4 | .. module:: bip.base 5 | 6 | Instructions are represented by :class:`BipInstr` objects. They inherit from 7 | :class:`BipElt` and as such have access to xrefs and common methods for 8 | objects with an address. They are also link to their function 9 | (:meth:`~BipInstr.func`) and basic block (:meth:`~BipInstr.block`) if any. Finally 10 | an instruction can have :class:`BipOperand` which can be access using the 11 | :meth:`~BipInstr.ops` property. 12 | 13 | The :class:`BipOperand` class represent all types of operand. As this is not the 14 | common design for Bip this will probably be changed soon. For getting the 15 | type of an operand the :meth:`~BipOperand.type` property can be used and 16 | compare with the value of :class:`BipOpType`. The :meth:`~BipOperand.value` allow 17 | to recuperate the value of an operand, the meaning of this value is depending 18 | of its :meth:`~BipOperand.type` and can be architectures dependant. This is 19 | not implemented yet and so is still link to information provided by IDA. 20 | 21 | BipInstr API 22 | ============ 23 | 24 | .. autoclass:: BipInstr 25 | :members: 26 | :member-order: bysource 27 | :special-members: 28 | :private-members: 29 | 30 | BipOperand API 31 | ============== 32 | 33 | .. warning:: This API will probably change in the near future. 34 | 35 | .. autoclass:: BipOperand 36 | :members: 37 | :member-order: bysource 38 | 39 | .. autoclass:: BipOpType 40 | :members: 41 | :member-order: bysource 42 | 43 | .. autoclass:: BipDestOpType 44 | :members: 45 | :member-order: bysource 46 | 47 | -------------------------------------------------------------------------------- /docs/base/struct.rst: -------------------------------------------------------------------------------- 1 | Structures 2 | ########## 3 | 4 | .. module:: bip.base 5 | 6 | This part describe the structures (:class:`BipStruct`) and structure members 7 | (:class:`BStructMember`). This two objects inherit from :class:`BipRefElt` 8 | which make them able to be referenced by xref and possible to recuperate using 9 | the :func:`GetElt` function. 10 | 11 | Those classes represent 12 | the element view in the ``Struct`` tab. of IDA and are different from the 13 | :class:`BipType` which is used for referencing the type of some elements in 14 | IDA, however they are obviously linked. 15 | 16 | Except xrefs the most common way to get a structure is using the 17 | :meth:`~BipStruct.get` class method which expect its name. For creating one 18 | the :meth:`~BipStruct.create` class method is available. Once a struct has 19 | been recuperated it is possible to access the members as a dict by using 20 | their name or their offset (this is not a list and so it is the offset of 21 | the member which is expected not its index). 22 | 23 | BipStruct API 24 | ============= 25 | 26 | .. autoclass:: BipStruct 27 | :members: 28 | :member-order: bysource 29 | :special-members: 30 | :private-members: 31 | 32 | .. automethod:: __init__ 33 | 34 | BStructMember API 35 | ================= 36 | 37 | .. autoclass:: BStructMember 38 | :members: 39 | :member-order: bysource 40 | :special-members: 41 | :private-members: 42 | 43 | .. automethod:: __init__ 44 | 45 | 46 | -------------------------------------------------------------------------------- /docs/base/type.rst: -------------------------------------------------------------------------------- 1 | .. _doc-bip-base-type: 2 | 3 | Type 4 | #### 5 | 6 | .. module:: bip.base 7 | 8 | Types are used every where in IDA: data (:class:`BipData`), 9 | functions (:class:`BipFunction`), local variable 10 | (:class:`~bip.hexrays.HxLvar`) ... In Bip all types are reprensented as 11 | an object which inherit from :class:`BipType`. :class:`BipType` objects can 12 | be recursive: a pointer will be represented by the :class:`BTypePtr` which 13 | will contain a reference on the pointed type, a :class:`BTypeFunc` in the 14 | case of a function pointer for example. All subclasses of :class:`BipType` 15 | start with the prefix ``BType*``. 16 | 17 | For creating a new :class:`BipType` the easiest way is to use the 18 | :meth:`BipType.from_c` static method: it will create an object which inherit 19 | from :class:`BipType` of the correct class from a string representing the C 20 | declaration of the type. 21 | 22 | When recuperating a type from IDA (``tinfo_t``) Bip will try to determine the 23 | correct object much the same way it is done for the :class:`BipBaseElt` when 24 | using :func:`GetElt`. This is made using the static method 25 | :func:`BipType.from_tinfo` and the class method for determining the correct 26 | class is :meth:`BipType.is_handling_type`. 27 | 28 | .. warning:: **Modifying types** 29 | 30 | Modifying types can have unexpected side effects. In particular the object 31 | recuperated through the API (Bip or IDAPython) may not be the one 32 | currently used. For avoiding those problems types are copied before 33 | setting them in most case by the Bip API. However recuperating a type 34 | while it is changed by another script or the IDA GUI will still make 35 | manipulation invalid. 36 | 37 | Here is a quick descriptions of the different types implemented in Bip: 38 | 39 | ======================= ======================================================================================================================================= 40 | Type name Description 41 | ======================= ======================================================================================================================================= 42 | :class:`BTypeEmpty` An empty type, should never happen but... 43 | :class:`BTypePartial` A type where the size is known but without any other information. 44 | :class:`BTypeVoid` The ``void`` type (not ``void*`` just ``void``). 45 | :class:`BTypeInt` An ``int``, can have different size, be signed or unsigned. 46 | :class:`BTypeBool` A boolean, can have different size. 47 | :class:`BTypeFloat` A float or double. 48 | :class:`BTypePtr` A pointer, recursive type, :meth:`~BTypePtr.pointed` for getting the subtype. 49 | :class:`BTypeArray` An array, recursive type (:meth:`BTypeArray.elt_type`), have a number of element. 50 | :class:`BTypeFunc` A function, recursive type for arguments and return value. Also access to the arguments name and their numbers. 51 | :class:`BTypeStruct` A structure, rescursive type for the members. This is different from :class:`BipStruct`. 52 | :class:`BTypeUnion` A union, rescursive type for the members. 53 | :class:`BTypeEnum` An enum, bugged before IDA 7.3, implementation is not finished. 54 | ======================= ======================================================================================================================================= 55 | 56 | 57 | BipType API 58 | =========== 59 | 60 | .. autoclass:: BipType 61 | :members: 62 | :member-order: bysource 63 | :special-members: 64 | :private-members: 65 | 66 | .. autoclass:: BTypeEmpty 67 | :members: 68 | :member-order: bysource 69 | 70 | .. autoclass:: BTypePartial 71 | :members: 72 | :member-order: bysource 73 | :special-members: 74 | :private-members: 75 | 76 | .. autoclass:: BTypeVoid 77 | :members: 78 | :member-order: bysource 79 | :special-members: 80 | :private-members: 81 | 82 | .. autoclass:: BTypeInt 83 | :members: 84 | :member-order: bysource 85 | :special-members: 86 | :private-members: 87 | 88 | .. autoclass:: BTypeBool 89 | :members: 90 | :member-order: bysource 91 | :special-members: 92 | :private-members: 93 | 94 | .. autoclass:: BTypeFloat 95 | :members: 96 | :member-order: bysource 97 | :special-members: 98 | :private-members: 99 | 100 | .. autoclass:: BTypePtr 101 | :members: 102 | :member-order: bysource 103 | :special-members: 104 | :private-members: 105 | 106 | .. autoclass:: BTypeArray 107 | :members: 108 | :member-order: bysource 109 | :special-members: 110 | :private-members: 111 | 112 | .. autoclass:: BTypeFunc 113 | :members: 114 | :member-order: bysource 115 | :special-members: 116 | :private-members: 117 | 118 | .. autoclass:: BTypeStruct 119 | :members: 120 | :member-order: bysource 121 | :special-members: 122 | :private-members: 123 | 124 | .. autoclass:: BTypeUnion 125 | :members: 126 | :member-order: bysource 127 | :special-members: 128 | :private-members: 129 | 130 | .. autoclass:: BTypeEnum 131 | :members: 132 | :member-order: bysource 133 | :special-members: 134 | :private-members: 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/base/xref.rst: -------------------------------------------------------------------------------- 1 | Xref 2 | #### 3 | 4 | .. module:: bip.base 5 | 6 | XRef are a really important feature of IDA which allow to find the links 7 | between different objects. In Bip they are represented by the :class:`BipXref` 8 | objects. All objects which inherit from :class:`BipRefElt` (including those 9 | which inherit from :class:`BipElt`) posess an API for xref. 10 | 11 | An xref is an oriented link between two different element of the IDB. The 12 | object *creating* the xref can be access by using the :meth:`~BipXref.src` 13 | property while the destination can be access using :meth:`~BipXref.dst`, 14 | both of those property return object which inherit from :class:`BipBaseElt`; 15 | it is possible to get their ID using :meth:`~BipXref.src_ea` and 16 | :meth:`~BipXref.dst_ea`. 17 | 18 | Some flags are available allowing to check the type of xref and most object 19 | allowing to access them provide properties allowing to access directly more 20 | specific objects. 21 | 22 | Here is a list of objects which can access xref through the interface 23 | provided by :class:`BipRefElt` : 24 | 25 | * :class:`BipRefElt` 26 | * :class:`BipElt` 27 | * :class:`BipInstr` 28 | * :class:`BipData` 29 | * :class:`BipStruct` 30 | * :class:`BStructMember` 31 | 32 | The :class:`BipFunction` also possess an interface with xrefs. 33 | 34 | BipXref API 35 | =========== 36 | 37 | .. autoclass:: BipXref 38 | :members: 39 | :member-order: bysource 40 | :special-members: 41 | :private-members: 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /docs/build/doctrees/base/bipida.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/base/bipida.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/base/bipidb.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/base/bipidb.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/base/data.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/base/data.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/base/elt.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/base/elt.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/base/enum.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/base/enum.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/base/func.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/base/func.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/base/instr.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/base/instr.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/base/struct.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/base/struct.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/base/type.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/base/type.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/base/xref.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/base/xref.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/environment.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/environment.pickle -------------------------------------------------------------------------------- /docs/build/doctrees/general/archi.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/general/archi.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/general/changelog.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/general/changelog.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/general/contribution.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/general/contribution.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/general/install.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/general/install.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/general/overview.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/general/overview.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/gui/activity.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/gui/activity.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/gui/plgmanager.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/gui/plgmanager.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/gui/plugin.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/gui/plugin.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/gui/userselect.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/gui/userselect.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/hexrays/astnodes.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/hexrays/astnodes.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/hexrays/cfunc.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/hexrays/cfunc.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/hexrays/cnode.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/hexrays/cnode.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/hexrays/lvar.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/hexrays/lvar.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/hexrays/visit_hx.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/hexrays/visit_hx.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/doctrees/index.doctree -------------------------------------------------------------------------------- /docs/build/html/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: 884997a290f5624f9ce37fde98589789 4 | tags: 645f666f9bcd5a90fca523b33c5a78b7 5 | -------------------------------------------------------------------------------- /docs/build/html/_images/bip_base2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/html/_images/bip_base2.png -------------------------------------------------------------------------------- /docs/build/html/_images/bip_gui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/html/_images/bip_gui.png -------------------------------------------------------------------------------- /docs/build/html/_images/bip_hexrays_cnode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/html/_images/bip_hexrays_cnode.png -------------------------------------------------------------------------------- /docs/build/html/_sources/base/bipida.rst.txt: -------------------------------------------------------------------------------- 1 | IDA interface 2 | ############# 3 | 4 | .. module:: bip.base 5 | 6 | Some API allows to affect directly the IDA software, those are accessible 7 | through static methods of the :class:`BipIda` class. Those can include access 8 | to the IDA configuration or thing specific to the API. 9 | 10 | BipIda API 11 | ========== 12 | 13 | .. autoclass:: BipIda 14 | :members: 15 | :member-order: bysource 16 | :special-members: 17 | :private-members: 18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/build/html/_sources/base/bipidb.rst.txt: -------------------------------------------------------------------------------- 1 | IDB representation 2 | ################## 3 | 4 | .. module:: bip.base 5 | 6 | Some useful information are link to the IDB loaded by IDA, those information 7 | are accessible through static methods of the :class:`BipIdb` class. Those 8 | information include things such as the base address of the image, the minium 9 | and maximum address mapped in the IDB and so on. A few `helper functions`_ are 10 | also defined directly at the top level of ``bipidb.py`` for making it more 11 | easy to script. 12 | 13 | BipIdb API 14 | ========== 15 | 16 | .. autoclass:: BipIdb 17 | :members: 18 | :member-order: bysource 19 | :special-members: 20 | :private-members: 21 | 22 | Helper functions 23 | ================ 24 | 25 | .. autofunction:: min_ea 26 | 27 | .. autofunction:: max_ea 28 | 29 | .. autofunction:: Here 30 | -------------------------------------------------------------------------------- /docs/build/html/_sources/base/data.rst.txt: -------------------------------------------------------------------------------- 1 | Data 2 | #### 3 | 4 | .. module:: bip.base 5 | 6 | The :class:`BipData` objects inherit from :class:`BipElt` and are used for 7 | representing data which means everything which is not code. 8 | 9 | :class:`BipData` object can be created by calling the constructor with the 10 | data address but in a more generic way it is possible to use the 11 | :func:`GetElt` or :func:`GetEltByName` for recuperating them. 12 | :class:`BipData` will be create by :func:`GetElt` if IDA considered the 13 | address as data or unknown. As they are inheriting from :class:`BipRefElt` it 14 | is possible to use the xref API through them (for access to and from them). 15 | 16 | The most basic usage will be to recuperate or set a value using the property 17 | :meth:`~BipData.value`. This property depends of the type 18 | which can be access and modify through the :meth:`~BipData.type` property, 19 | this property return and expect a :class:`BipType` object. It is also possible 20 | to access directly the :meth:`BipElt.bytes` of the object. 21 | 22 | :class:`BipData` provides some static methods for accessing and 23 | modifying data of the IDB without creating an object, in particular the 24 | :meth:`~BipData.get_cstring` which allow to get a C string from an address. 25 | Finally it is possible to iterate on all defined :class:`BipData` using the 26 | class method :class:`BipData.iter_heads`. 27 | 28 | BipData API 29 | =========== 30 | 31 | .. autoclass:: BipData 32 | :members: 33 | :member-order: bysource 34 | :special-members: 35 | :private-members: 36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/build/html/_sources/base/elt.rst.txt: -------------------------------------------------------------------------------- 1 | .. _ref-base-elt: 2 | 3 | Elements 4 | ######## 5 | 6 | .. module:: bip.base 7 | 8 | Basic elements in IDA are all refered by an ID. This can be the address of the 9 | element in the database or a particular ID. For allowing to access easily the 10 | correct element from its ID Bip defines a tree of classes with each leaf 11 | classes in charge of a particular element. 12 | 13 | Three abstract classes are defined in Bip: 14 | 15 | * :class:`BipBaseElt` : is the parent class of all element in Bip, in 16 | particular it is in charge of making the interface with :func:`GetElt` and 17 | :func:`GetEltByName`. 18 | * :class:`BipRefElt` : is the parent class of all elements which can be 19 | referenced by xref in IDA. This include :class:`BipInstr`, :class:`BipData`, 20 | :class:`BipStruct` and :class:`BStructMember`. 21 | * :class:`BipElt` : is the parent class of all elements with an actual address 22 | as ID and provide a lot of common API for thoses elements, this is the 23 | parent class of :class:`BipInstr` and :class:`BipData`. 24 | 25 | For getting a correct element from an ID it is enough to call the 26 | :func:`GetElt` and :func:`GetEltByName` function. As those functions can 27 | return diferent types of objects it can be convenient to use ``isinstance`` 28 | for checking the return type of the object. 29 | 30 | Internals 31 | ========= 32 | 33 | Recuperation of the correct element 34 | ----------------------------------- 35 | 36 | For being able to return an object :func:`GetElt` 37 | (:func:`GetEltByName` is simply a wrapper in top of :func:`GetElt`) must 38 | be able to tell which class should be used. This is done by recursivelly 39 | checking the child classes of :class:`BipBaseElt`, each child classes should 40 | implement the class method :meth:`BipBaseElt._is_this_elt` which take an ID 41 | in argument. If this method return True iteration will continue on child 42 | classes of this class, if it return False it will stop. When all child classes 43 | return False or a leaf as been reach an object of this element is created and 44 | returned. 45 | 46 | If two subclasses return True at one level of the recursion, one of them will 47 | be ignored. 48 | 49 | All classes which inherit from :class:`BipBaseElt` are expected to take only 50 | their ID in argument for being able to be instantiated by :func:`GetElt` . 51 | 52 | Element Functions API 53 | ===================== 54 | 55 | 56 | .. autofunction:: GetElt 57 | .. autofunction:: GetEltByName 58 | 59 | BipBaseElt API 60 | ============== 61 | 62 | .. autoclass:: BipBaseElt 63 | :members: 64 | :member-order: bysource 65 | :special-members: 66 | :private-members: 67 | 68 | BipRefElt API 69 | ============= 70 | 71 | .. autoclass:: BipRefElt 72 | :members: 73 | :member-order: bysource 74 | :special-members: 75 | :private-members: 76 | 77 | BipElt API 78 | ========== 79 | 80 | .. autoclass:: BipElt 81 | :members: 82 | :member-order: bysource 83 | :special-members: 84 | :private-members: 85 | 86 | 87 | -------------------------------------------------------------------------------- /docs/build/html/_sources/base/enum.rst.txt: -------------------------------------------------------------------------------- 1 | Enum 2 | #### 3 | 4 | .. module:: bip.base 5 | 6 | This part describe the enum (:class:`BipEnum`) and enum members 7 | (:class:`BEnumMember`). The :class:`BEnumMember` class inherit from 8 | :class:`BipRefElt` which allow to get access to the enum members through xref 9 | and possible to recuperate using the :func:`GetElt` function. 10 | 11 | Those classes represent 12 | the element view in the ``Enum`` tab. of IDA and are different from the 13 | :class:`BipType` which is used for referencing the type of some elements in 14 | IDA, however they are obviously linked. 15 | 16 | Except xrefs the most common way to get an enum is using the 17 | :meth:`BipEnum.get` class method which expect its name. For creating one 18 | the :meth:`BipEnum.create` class method is available. Once an enum has 19 | been recuperated it is possible to access the members as a dict by using 20 | their name or to iterate on all the members. It is also possible to use 21 | the :meth:`BEnumMember.get` class method for directly recuperating an enum 22 | member. 23 | 24 | BipEnum API 25 | =========== 26 | 27 | .. autoclass:: BipEnum 28 | :members: 29 | :member-order: bysource 30 | :special-members: 31 | :private-members: 32 | 33 | BEnumMember API 34 | =============== 35 | 36 | .. autoclass:: BEnumMember 37 | :members: 38 | :member-order: bysource 39 | :special-members: 40 | :private-members: 41 | 42 | 43 | -------------------------------------------------------------------------------- /docs/build/html/_sources/base/func.rst.txt: -------------------------------------------------------------------------------- 1 | Functions & Basic blocks 2 | ######################## 3 | 4 | .. module:: bip.base 5 | 6 | :class:`BipFunction` are created by passing them an address. They are 7 | container for basic block (:class:`BipBlock` accessible using 8 | the :meth:`~BipFunction.blocks` property) and instruction (:class:`BipInstr` 9 | accessible using the :meth:`~BipFunction.instr` property). :class:`BipBlock` 10 | them self contain instructions, a link back to the function 11 | (property :meth:`~BipBlock.func`) and a way to navigate them using the 12 | property :meth:`~BipBlock.succ` and :meth:`BipBlock.pred` . 13 | 14 | :class:`BipFunction` can also allow to recuperate the hexrays decompile 15 | version of their code when available, this is done using the 16 | :meth:`~BipFunction.hxcfunc` property which return a 17 | :class:`~bip.hexrays.HxCFunc` object when available. 18 | 19 | For example of how to use functions and blocks see the 20 | :ref:`general-overview` . 21 | 22 | BipFunction API 23 | =============== 24 | 25 | .. autoclass:: BipFunction 26 | :members: 27 | :member-order: bysource 28 | :special-members: 29 | :private-members: 30 | 31 | BipBlock API 32 | ============ 33 | 34 | .. autoclass:: BipBlock 35 | :members: 36 | :member-order: bysource 37 | :special-members: 38 | :private-members: 39 | 40 | .. autoclass:: BipBlockType 41 | :members: 42 | :member-order: bysource 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /docs/build/html/_sources/base/instr.rst.txt: -------------------------------------------------------------------------------- 1 | Instructions & Operands 2 | ####################### 3 | 4 | .. module:: bip.base 5 | 6 | Instructions are represented by :class:`BipInstr` objects. They inherit from 7 | :class:`BipElt` and as such have access to xrefs and common methods for 8 | objects with an address. They are also link to their function 9 | (:meth:`~BipInstr.func`) and basic block (:meth:`~BipInstr.block`) if any. Finally 10 | an instruction can have :class:`BipOperand` which can be access using the 11 | :meth:`~BipInstr.ops` property. 12 | 13 | The :class:`BipOperand` class represent all types of operand. As this is not the 14 | common design for Bip this will probably be changed soon. For getting the 15 | type of an operand the :meth:`~BipOperand.type` property can be used and 16 | compare with the value of :class:`BipOpType`. The :meth:`~BipOperand.value` allow 17 | to recuperate the value of an operand, the meaning of this value is depending 18 | of its :meth:`~BipOperand.type` and can be architectures dependant. This is 19 | not implemented yet and so is still link to information provided by IDA. 20 | 21 | BipInstr API 22 | ============ 23 | 24 | .. autoclass:: BipInstr 25 | :members: 26 | :member-order: bysource 27 | :special-members: 28 | :private-members: 29 | 30 | BipOperand API 31 | ============== 32 | 33 | .. warning:: This API will probably change in the near future. 34 | 35 | .. autoclass:: BipOperand 36 | :members: 37 | :member-order: bysource 38 | 39 | .. autoclass:: BipOpType 40 | :members: 41 | :member-order: bysource 42 | 43 | .. autoclass:: BipDestOpType 44 | :members: 45 | :member-order: bysource 46 | 47 | -------------------------------------------------------------------------------- /docs/build/html/_sources/base/struct.rst.txt: -------------------------------------------------------------------------------- 1 | Structures 2 | ########## 3 | 4 | .. module:: bip.base 5 | 6 | This part describe the structures (:class:`BipStruct`) and structure members 7 | (:class:`BStructMember`). This two objects inherit from :class:`BipRefElt` 8 | which make them able to be referenced by xref and possible to recuperate using 9 | the :func:`GetElt` function. 10 | 11 | Those classes represent 12 | the element view in the ``Struct`` tab. of IDA and are different from the 13 | :class:`BipType` which is used for referencing the type of some elements in 14 | IDA, however they are obviously linked. 15 | 16 | Except xrefs the most common way to get a structure is using the 17 | :meth:`~BipStruct.get` class method which expect its name. For creating one 18 | the :meth:`~BipStruct.create` class method is available. Once a struct has 19 | been recuperated it is possible to access the members as a dict by using 20 | their name or their offset (this is not a list and so it is the offset of 21 | the member which is expected not its index). 22 | 23 | BipStruct API 24 | ============= 25 | 26 | .. autoclass:: BipStruct 27 | :members: 28 | :member-order: bysource 29 | :special-members: 30 | :private-members: 31 | 32 | .. automethod:: __init__ 33 | 34 | BStructMember API 35 | ================= 36 | 37 | .. autoclass:: BStructMember 38 | :members: 39 | :member-order: bysource 40 | :special-members: 41 | :private-members: 42 | 43 | .. automethod:: __init__ 44 | 45 | 46 | -------------------------------------------------------------------------------- /docs/build/html/_sources/base/type.rst.txt: -------------------------------------------------------------------------------- 1 | .. _doc-bip-base-type: 2 | 3 | Type 4 | #### 5 | 6 | .. module:: bip.base 7 | 8 | Types are used every where in IDA: data (:class:`BipData`), 9 | functions (:class:`BipFunction`), local variable 10 | (:class:`~bip.hexrays.HxLvar`) ... In Bip all types are reprensented as 11 | an object which inherit from :class:`BipType`. :class:`BipType` objects can 12 | be recursive: a pointer will be represented by the :class:`BTypePtr` which 13 | will contain a reference on the pointed type, a :class:`BTypeFunc` in the 14 | case of a function pointer for example. All subclasses of :class:`BipType` 15 | start with the prefix ``BType*``. 16 | 17 | For creating a new :class:`BipType` the easiest way is to use the 18 | :meth:`BipType.from_c` static method: it will create an object which inherit 19 | from :class:`BipType` of the correct class from a string representing the C 20 | declaration of the type. 21 | 22 | When recuperating a type from IDA (``tinfo_t``) Bip will try to determine the 23 | correct object much the same way it is done for the :class:`BipBaseElt` when 24 | using :func:`GetElt`. This is made using the static method 25 | :func:`BipType.from_tinfo` and the class method for determining the correct 26 | class is :meth:`BipType.is_handling_type`. 27 | 28 | .. warning:: **Modifying types** 29 | 30 | Modifying types can have unexpected side effects. In particular the object 31 | recuperated through the API (Bip or IDAPython) may not be the one 32 | currently used. For avoiding those problems types are copied before 33 | setting them in most case by the Bip API. However recuperating a type 34 | while it is changed by another script or the IDA GUI will still make 35 | manipulation invalid. 36 | 37 | Here is a quick descriptions of the different types implemented in Bip: 38 | 39 | ======================= ======================================================================================================================================= 40 | Type name Description 41 | ======================= ======================================================================================================================================= 42 | :class:`BTypeEmpty` An empty type, should never happen but... 43 | :class:`BTypePartial` A type where the size is known but without any other information. 44 | :class:`BTypeVoid` The ``void`` type (not ``void*`` just ``void``). 45 | :class:`BTypeInt` An ``int``, can have different size, be signed or unsigned. 46 | :class:`BTypeBool` A boolean, can have different size. 47 | :class:`BTypeFloat` A float or double. 48 | :class:`BTypePtr` A pointer, recursive type, :meth:`~BTypePtr.pointed` for getting the subtype. 49 | :class:`BTypeArray` An array, recursive type (:meth:`BTypeArray.elt_type`), have a number of element. 50 | :class:`BTypeFunc` A function, recursive type for arguments and return value. Also access to the arguments name and their numbers. 51 | :class:`BTypeStruct` A structure, rescursive type for the members. This is different from :class:`BipStruct`. 52 | :class:`BTypeUnion` A union, rescursive type for the members. 53 | :class:`BTypeEnum` An enum, bugged before IDA 7.3, implementation is not finished. 54 | ======================= ======================================================================================================================================= 55 | 56 | 57 | BipType API 58 | =========== 59 | 60 | .. autoclass:: BipType 61 | :members: 62 | :member-order: bysource 63 | :special-members: 64 | :private-members: 65 | 66 | .. autoclass:: BTypeEmpty 67 | :members: 68 | :member-order: bysource 69 | 70 | .. autoclass:: BTypePartial 71 | :members: 72 | :member-order: bysource 73 | :special-members: 74 | :private-members: 75 | 76 | .. autoclass:: BTypeVoid 77 | :members: 78 | :member-order: bysource 79 | :special-members: 80 | :private-members: 81 | 82 | .. autoclass:: BTypeInt 83 | :members: 84 | :member-order: bysource 85 | :special-members: 86 | :private-members: 87 | 88 | .. autoclass:: BTypeBool 89 | :members: 90 | :member-order: bysource 91 | :special-members: 92 | :private-members: 93 | 94 | .. autoclass:: BTypeFloat 95 | :members: 96 | :member-order: bysource 97 | :special-members: 98 | :private-members: 99 | 100 | .. autoclass:: BTypePtr 101 | :members: 102 | :member-order: bysource 103 | :special-members: 104 | :private-members: 105 | 106 | .. autoclass:: BTypeArray 107 | :members: 108 | :member-order: bysource 109 | :special-members: 110 | :private-members: 111 | 112 | .. autoclass:: BTypeFunc 113 | :members: 114 | :member-order: bysource 115 | :special-members: 116 | :private-members: 117 | 118 | .. autoclass:: BTypeStruct 119 | :members: 120 | :member-order: bysource 121 | :special-members: 122 | :private-members: 123 | 124 | .. autoclass:: BTypeUnion 125 | :members: 126 | :member-order: bysource 127 | :special-members: 128 | :private-members: 129 | 130 | .. autoclass:: BTypeEnum 131 | :members: 132 | :member-order: bysource 133 | :special-members: 134 | :private-members: 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/build/html/_sources/base/xref.rst.txt: -------------------------------------------------------------------------------- 1 | Xref 2 | #### 3 | 4 | .. module:: bip.base 5 | 6 | XRef are a really important feature of IDA which allow to find the links 7 | between different objects. In Bip they are represented by the :class:`BipXref` 8 | objects. All objects which inherit from :class:`BipRefElt` (including those 9 | which inherit from :class:`BipElt`) posess an API for xref. 10 | 11 | An xref is an oriented link between two different element of the IDB. The 12 | object *creating* the xref can be access by using the :meth:`~BipXref.src` 13 | property while the destination can be access using :meth:`~BipXref.dst`, 14 | both of those property return object which inherit from :class:`BipBaseElt`; 15 | it is possible to get their ID using :meth:`~BipXref.src_ea` and 16 | :meth:`~BipXref.dst_ea`. 17 | 18 | Some flags are available allowing to check the type of xref and most object 19 | allowing to access them provide properties allowing to access directly more 20 | specific objects. 21 | 22 | Here is a list of objects which can access xref through the interface 23 | provided by :class:`BipRefElt` : 24 | 25 | * :class:`BipRefElt` 26 | * :class:`BipElt` 27 | * :class:`BipInstr` 28 | * :class:`BipData` 29 | * :class:`BipStruct` 30 | * :class:`BStructMember` 31 | 32 | The :class:`BipFunction` also possess an interface with xrefs. 33 | 34 | BipXref API 35 | =========== 36 | 37 | .. autoclass:: BipXref 38 | :members: 39 | :member-order: bysource 40 | :special-members: 41 | :private-members: 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /docs/build/html/_sources/general/changelog.rst.txt: -------------------------------------------------------------------------------- 1 | Changelog 2 | ######### 3 | 4 | This page has the goal to record breaking change in the API between versions. 5 | New features may be listed but probably not always. 6 | 7 | 8 | Change from v0.3 to v1.0 9 | ======================== 10 | 11 | New features: 12 | 13 | * new class :class:`bip.base.BipIdb` 14 | * new class :class:`bip.base.BipIda` 15 | * new class :class:`bip.gui.BipUserSelect` 16 | 17 | Breaking changes: 18 | 19 | * renaming of ``bip.base.XrefTypes`` to ``bip.base._XrefTypes`` 20 | * renaming of ``bip.base.DestOpType`` to ``bip.base.BipDestOpType`` 21 | * renaming of ``bip.base.OpType`` to ``bip.base.BipOpType`` 22 | * renaming of ``bip.base.Operand`` to ``bip.base.BipOperand`` 23 | * renaming of ``bip.hexrays.HexRaysEvent`` to ``bip.base.HxEvent`` 24 | * renaming of ``bip.base.Instr`` to ``bip.base.BipInstr`` 25 | * renaming of ``bip.base.BipFuncFlags`` to ``bip.base._BipFuncFlags`` 26 | * renaming of ``bip.base.BipFlowChartFlag`` to ``bip.base._BipFlowChartFlag`` 27 | * renaming of ``bip.base.BipType._GetClassBipType`` to ``bip.base.BipType._get_class_bip_type`` 28 | * renaming of ``bip.base.BipType.GetBipTypeNoCopy`` to ``bip.base.BipType.from_tinfo_no_copy`` 29 | * renaming of ``bip.base.BipType.GetBipType`` to ``bip.base.BipType.from_tinfo`` 30 | * renaming of ``bip.base.BipType.FromC`` to ``bip.base.BipType.from_c`` 31 | * renaming of ``bip.base.BipType.ImportCHeader`` to ``bip.base.BipType.import_c_header`` 32 | * renaming of ``bip.base.BipInstr.Make`` to ``bip.base.BipInstr.make`` 33 | * renaming of ``bip.base.BipFunction.ByOrdinal`` to ``bip.base.BipFunction.by_ordinal`` 34 | * renaming of ``bip.base.BipFunction.Entries`` to ``bip.base.BipFunction.entries`` 35 | * renaming of ``bip.base.BipFunction.Entries_iter`` to ``bip.base.BipFunction.entries_iter`` 36 | * renaming of ``bip.base.BipFunction.Count`` to ``bip.base.BipFunction.count`` 37 | * renaming of ``bip.hexrays.HxCItem.GetHxCItem`` to ``bip.hexrays.HxCItem.from_citem`` 38 | * renaming of ``bip.hexrays.HxCItem._createChild`` to ``bip.hexrays.HxCItem._create_child`` 39 | * renaming of ``bip.hexrays.CNode._createChild`` to ``bip.hexrays.CNode._create_child`` 40 | * renaming of ``bip.hexrays.HxCStmt.st_childs`` to ``bip.hexrays.HxCStmt.stmt_children`` 41 | * renaming of ``bip.hexrays.CNodeStmt.st_childs`` to ``bip.hexrays.CNodeStmt.stmt_children`` 42 | * renaming of ``bip.hexrays.CNodeStmt.expr_childs`` to ``bip.hexrays.CNodeStmt.expr_children`` 43 | * renaming of ``bip.hexrays.CNode.GetCNode`` to ``bip.hexrays.CNode.from_citem`` 44 | * renaming of ``bip.hexrays.CNode.cfunc`` to ``bip.hexrays.CNode.hxcfunc`` 45 | * renaming of ``bip.base.BipFunction.hxfunc`` to ``bip.base.BipFunction.hxcfunc`` 46 | * renaming of ``bip.hexrays.HxLvar.hxfunc`` to ``bip.hexrays.HxLvar.hxcfunc`` 47 | * function ``bip.base.utils.get_ptr_size`` became static method ``bip.base.BipIdb.ptr_size`` 48 | * function ``bip.base.utils.absea`` became a static method of ``bip.base.BipIdb`` 49 | * function ``bip.base.utils.relea`` became a static method of ``bip.base.BipIdb`` 50 | * ``min_ea``, ``max_ea`` and ``Here``, functions are now in ``bip.base.bipidb`` 51 | * function ``bip.base.utils.get_addr_by_name`` has been removed. 52 | * function ``bip.base.utils.get_name_by_addr`` has been removed. 53 | * function ``bip.base.utils.get_struct_from_lvar`` has been removed. 54 | * function ``bip.base.utils.Ptr`` became static method of ``bip.base.BipData.get_ptr`` 55 | * function ``bip.base.utils.bip_exec_sync`` became static method ``bip.base.BipIda.exec_sync`` 56 | * function ``bip.base.utils.get_highlighted_identifier_as_int`` became static method ``BipUserSelect.get_curr_highlighted_int`` 57 | * removed classes ``BaseGuiAction`` and ``ContextMenuHooks`` 58 | * renamed method ``bip.base.BipType.childs`` to ``bip.base.BiType.children`` 59 | 60 | 61 | Sed script for automatic update of plugins (no garantee to be perfect or to 62 | avoid colisions) (use with ``sed -f RULEFILE INPUTFILE``): 63 | 64 | .. code-block:: none 65 | 66 | s/XrefTypes/_XrefTypes/g 67 | s/DestOpType/BipDestOpType/g 68 | s/OpType/BipOpType/g 69 | s/Operand/BipOperand/g 70 | s/countBipOperand/countOperand/g 71 | s/HexRaysEvent/HxEvent/g 72 | s/Instr/BipInstr/g 73 | s/BipFuncFlags/_BipFuncFlags/g 74 | s/BipFlowChartFlag/_BipFlowChartFlag/g 75 | s/_GetClassBipType/_get_class_bip_type/g 76 | s/GetBipTypeNoCopy/from_tinfo_no_copy/g 77 | s/GetBipType/from_tinfo/g 78 | s/FromC/from_c/g 79 | s/ImportCHeader/import_c_header/g 80 | s/ByOrdinal/by_ordinal/g 81 | s/Entries/entries/g 82 | s/GetHxCItem/from_citem/g 83 | s/_createChild/_create_child/g 84 | s/st_childs/stmt_children/g 85 | s/expr_childs/expr_children/g 86 | s/GetCNode/from_citem/g 87 | s/get_ptr_size/BipIdb.ptr_size/g 88 | s/bip_exec_sync/BipIda.exec_sync/g 89 | s/get_highlighted_identifier_as_int/BipUserSelect.get_curr_highlighted_int/g 90 | s/childs/children/g 91 | 92 | Are not included in this sed file the change to ``BipInstr.Make``, 93 | ``BipFunction.Count``, ``Cnode.cfunc``, ``Ptr`` which can easilly create 94 | problems. 95 | 96 | This update removed also the ``example``, ``scripts`` and ``plugins`` 97 | directory which will not be maintain as part of Bip (and where probably 98 | already not working since some times). 99 | 100 | 101 | -------------------------------------------------------------------------------- /docs/build/html/_sources/general/contribution.rst.txt: -------------------------------------------------------------------------------- 1 | .. _general-contrib: 2 | 3 | Contributions 4 | ############# 5 | 6 | Contributions to Bip are welcome, it can be Issues, Feature Request or Pull 7 | Request (PR), all of those can be made on github. Those can concern the code 8 | but also the documentation, which has the goal to be clear and complete. 9 | The integrality of Bip is currently maintained by a unique person, so please 10 | take the time to read those and thank you in advance for your patience. 11 | 12 | As general rules for Issues and Feature Request, provided a clear 13 | description, an example (with the line of the API and if needed the content 14 | of IDA) and if possible a way to reproduce or test it. Do not hesitate to 15 | propose an example of what you would like to have as an API in Bip. If you 16 | have it, an example of how to do it with the IDAPython API would be amazing. 17 | 18 | Pull Request 19 | ============ 20 | 21 | For Pull Request, please provide a clear description of what your code does 22 | and, especially if it is a big PR, how you implemented it. The only release of 23 | IDA for which Bip is maintained is the last one, so be sure it works with it. 24 | No pull request will be merged in ``master`` if: 25 | 26 | * the code is not documented, 27 | * the code is not integrated in the documentation, 28 | * the code is not compatible for python2 and python3 (as long as both are 29 | supported in Bip), 30 | * there are no tests for the new functions/methods/classes/... 31 | 32 | You can make a PR without those, however it will take some time for it to be 33 | merged because those will have to be written. 34 | 35 | Regarding the code in itself, no hardline coding convention is enforced (for 36 | now) but please follow as much as possible those rules: 37 | 38 | * use 4 spaces instead of tabulation, 39 | * write python2 and python3 compatible code, 40 | * follow naming convention of Python (``UpperCaseCamel`` for classes 41 | and ``lower_with_underscore`` for methods), 42 | * start the name of the class with ``Bip`` or ``Hx`` (for hexrays) or a clear 43 | prefix which identifies it (the goal is to avoid collisions with IDAPython 44 | and other python packages, as well as to make auto-completion easier), 45 | * write **readable** code (avoid nested list comprehension and so on), 46 | * simpler code is often better, 47 | * stay around 80 chars (a little more is fine). 48 | 49 | Finally, if the PR introduces a breaking change (change in names of a 50 | method or a class, change in arguments, change in behavior, ...), it has to 51 | log in the changelog including in this documentation. Further rules on 52 | breaking changes and Bip versions may be introduced. 53 | 54 | Change of version 55 | ================= 56 | 57 | This is a checklist of things to do for a change of version in Bip: 58 | 59 | * change version in sphinx doc (``docs/conf.py``), 60 | * change Bip Python version (``bip/__init__.py``), 61 | * change last stable version in ``README.rst``, 62 | * check changelog is done and has the right version numbers, 63 | * check all tests pass in py2 and py3, 64 | * check the doc build correctly, build it and push it (for github.io page). 65 | 66 | 67 | -------------------------------------------------------------------------------- /docs/build/html/_sources/general/install.rst.txt: -------------------------------------------------------------------------------- 1 | .. _general-install: 2 | 3 | Installation steps 4 | ################## 5 | 6 | Installing Bip 7 | ============== 8 | 9 | The script ``install.py`` is made for installing Bip, it has been tested only 10 | on Windows and Linux, for making a default install: 11 | 12 | .. code-block:: bash 13 | 14 | python install.py 15 | 16 | This installer do not insall any plugins by default, but simply the core of 17 | Bip. By default the destination folder is the one use by IDA locally 18 | (``%APPDATA%\Hex-Rays\IDA Pro\`` for Windows and ``$HOME/.idapro`` for Linux 19 | and MacOSX). 20 | 21 | It is possible to use an optional `--dest` argument for installing in a 22 | particular folder: 23 | 24 | .. code-block:: none 25 | 26 | usage: install.py [-h] [--dest DEST] 27 | 28 | optional arguments: 29 | -h, --help show this help message and exit 30 | --dest DEST Destination folder where to install Bip 31 | 32 | Installing BipPlugin 33 | ==================== 34 | 35 | Plugin written for Bip, which inherit from :class:`~bip.gui.BipPlugin`, can 36 | be loaded automatically when opening IDA. For a plugin to be loaded 37 | automatically it has to be present in the ``plugins/bipplugin`` folder. This 38 | folder will be created automatically when `installing Bip`_ in the destination 39 | folder of the installation, by default: ``%APPDATA%\Hex-Rays\IDA Pro\`` for 40 | Windows and ``$HOME/.idapro`` for Linux. 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /docs/build/html/_sources/gui/activity.rst.txt: -------------------------------------------------------------------------------- 1 | .. _gui-activity-actions: 2 | 3 | Activities and Actions 4 | ###################### 5 | 6 | .. module:: bip.gui 7 | 8 | For allowing to define interaction between the user-interface and the plugins 9 | Bip define :class:`BipActivity` . The intended way to use :class:`BipActivity` and 10 | :class:`BipAction` is using the :ref:`gui-plugin-activity-decorators` with 11 | a :class:`BipPlugin`. 12 | 13 | The :class:`BipActivity` is an abstract class allowing to define interaction 14 | with the IDA API and UI, in practice there is few reason to use them directly. 15 | 16 | The :class:`BipActivityContainer` is a :class:`BipActivity` containing several 17 | other :class:`BipActivity`, it is used internally for allowing to have several 18 | decorators (and so :class:`BipActivity`) on the same method of a 19 | :class:`BipPlugin`. 20 | 21 | The :class:`BipAction` (which inherit from :class:`BipActivity`) allows 22 | to define hotkeys (:func:`shortcut` decorator) or entries in the IDA menu 23 | (:func:`menu` decorator). It can be created directly as an object for defining 24 | actions dynamically and not link to a particular plugin. 25 | 26 | .. _gui-activity-internals: 27 | 28 | Implementation internals 29 | ======================== 30 | 31 | This part as the goal to describe the internal of the :class:`BipActivity`: 32 | how they interface with :class:`BipPlugin` and how to create a new kind of 33 | :class:`BipActivity` . It is not necessary to read it for simply using them. 34 | 35 | Creating a new BipActivity 36 | -------------------------- 37 | 38 | All :class:`BipActivity` subclasses should implement the methods: 39 | 40 | * :meth:`~BipActivity.register`: register the interface with IDA. This 41 | will be called when a plugin is loaded. 42 | * :meth:`~BipActivity.unregister`: register the interface with IDA. 43 | This is the oposite of :meth:`~BipActivity.register`, it will be 44 | called when a plugin is unloaded. 45 | * :meth:`~BipActivity.handler`: the handler function of the activity 46 | which actually does the action. It is not necessary to implement 47 | this function if the ``handler`` parameter for the constructor is 48 | defined. This method will also be called if the object is called. 49 | 50 | Those are the only mandatory methods to implement. 51 | 52 | Activities have for main goal to be used as decorator when writing 53 | a plugin and as such are *callable* object. *Calling* this object 54 | will triger a call to the :meth:`~BipActivity.handler` method. 55 | 56 | Activity and decorator 57 | ---------------------- 58 | 59 | Some decorators are define for being use inside a 60 | :class:`BipPlugin` class for defining interactions with IDA. Those 61 | decorators will dynamically create :class:`BipActivity` objects. 62 | 63 | When a :class:`BipPlugin` class is created, its constructor will create a 64 | list of the :class:`BipActivity` associtated with the plugin 65 | (stored in ``_activities``) and when the plugin object is created 66 | it will set itself in the :attr:`BipActivity.plugin` of each 67 | :class:`BipActivity` it contains. 68 | 69 | For allowing several :class:`BipActivity` decorators to be used 70 | on the same method the :class:`BipActivityContainer` class is 71 | defined. The decorator will still need to be able to define the 72 | handler function for the new :class:`BipActivity` decorators 73 | after the first one, this is done by storing the function in the 74 | :class:`BipActivityContainer` which is accessible through the 75 | :meth:`~BipActivityContainer.get_original_method` method. 76 | 77 | All decorators should return a :class:`BipActivityContainer` which 78 | will contain the :class:`BipActivity` to define. If the container 79 | was already defined it should simply add the new one using the 80 | :meth:`~BipActivityContainer.add_activity` method. 81 | 82 | BipAction API 83 | ============= 84 | 85 | .. autoclass:: BipAction 86 | :members: 87 | :member-order: bysource 88 | :special-members: 89 | :private-members: 90 | 91 | BipActivity API 92 | =============== 93 | 94 | .. autoclass:: BipActivity 95 | :members: 96 | :member-order: bysource 97 | :special-members: 98 | :private-members: 99 | 100 | BipActivityContainer API 101 | ======================== 102 | 103 | .. autoclass:: BipActivityContainer 104 | :members: 105 | :member-order: bysource 106 | :special-members: 107 | :private-members: 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /docs/build/html/_sources/gui/plgmanager.rst.txt: -------------------------------------------------------------------------------- 1 | Plugin Manager 2 | ############## 3 | 4 | .. module:: bip.gui 5 | 6 | The :class:`~bip.gui.pluginmanager.BipPluginManager` is in charge of loading 7 | the :class:`BipPlugin`, create and register the :class:`BipActivity` link to 8 | them and allow to access the :class:`BipPlugin` instances once loaded. 9 | 10 | The :class:`~bip.gui.pluginmanager.BipPluginManager` is a singleton and 11 | should only be accessed using the :func:`get_plugin_manager` functions. 12 | It is also the only class in Bip which is a *real* IDA plugin. 13 | 14 | The main reason to use the :class:`~bip.gui.pluginmanager.BipPluginManager` 15 | is to recuperate a :class:`BipPlugin` instance: 16 | 17 | .. code-block:: python 18 | 19 | bpm = get_plugin_manager() # get the BipPluginManager 20 | plg = bpm["PLUGINNAME"] # get the plugin PLUGINNAME, PLUGINNAME should be the class of the plugin 21 | 22 | or for loading a new plugin: 23 | 24 | .. code-block:: python 25 | 26 | class MyPlugin(BipPlugin): # define a new class for the plugin 27 | pass # implementation 28 | 29 | bpm = get_plugin_manager() # get the BipPluginManager 30 | bpm.addld_plugin("MyPlugin", MyPlugin, ifneeded=True) # add the plugin 31 | # plugin in bipplugin folder will be loaded automatically and do not need those lines 32 | 33 | The :class:`~bip.gui.pluginmanager.BipPluginManager` is not exposed at the 34 | level of the module for avoiding instantiating a second object which will 35 | trigger bugs, use :func:`get_plugin_manager` for getting the singleton object. 36 | 37 | The :class:`~bip.gui.pluginmanager.BipPluginManager` is also in charge of 38 | loading automatically 39 | 40 | 41 | BipPluginManager API 42 | ==================== 43 | 44 | .. autofunction:: get_plugin_manager 45 | 46 | .. module:: bip.gui.pluginmanager 47 | 48 | .. autoclass:: BipPluginManager 49 | :members: 50 | :member-order: bysource 51 | :special-members: 52 | :private-members: 53 | 54 | .. autoclass:: BipPluginLoader 55 | :members: 56 | :member-order: bysource 57 | :special-members: 58 | :private-members: 59 | 60 | 61 | -------------------------------------------------------------------------------- /docs/build/html/_sources/gui/userselect.rst.txt: -------------------------------------------------------------------------------- 1 | .. _gui-user-select: 2 | 3 | User selections 4 | ############### 5 | 6 | .. module:: bip.gui 7 | 8 | The :class:`BipUserSelect` class is in charge of regrouping several methods 9 | allowing to interact with the user selections. 10 | 11 | As of now this class contains only static methods. 12 | 13 | BipUserSelect API 14 | ================= 15 | 16 | .. autoclass:: BipUserSelect 17 | :members: 18 | :member-order: bysource 19 | :special-members: 20 | :private-members: 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /docs/build/html/_sources/hexrays/cfunc.rst.txt: -------------------------------------------------------------------------------- 1 | Hexrays Functions 2 | ################# 3 | 4 | .. module:: bip.hexrays 5 | 6 | Hexrays function are implemented in Bip by the class :class:`~bip.hexrays.HxCFunc`. 7 | They represent a C function as decompiled by hexrays and are the main 8 | interface for using the features from hexrays in C. 9 | 10 | There are two ways to get a :class:`~bip.hexrays.HxCFunc` object using the Bip 11 | API, the first one is by using the :meth:`~bip.base.BipFunction.hxcfunc` 12 | property method from a :class:`~bip.base.BipFunction`, this property returns 13 | the equivalent :class:`~bip.hexrays.HxCFunc` for 14 | the :class:`~bip.base.BipFunction`. The second way is to use the class method 15 | :meth:`~bip.hexrays.HxCFunc.from_addr` which take an address in argument and try 16 | to create the corresponding :class:`~bip.hexrays.HxCFunc`. Both of those 17 | methods may fail if Hexrays is not able to decompile the function or if the 18 | address given is not part of a function, in that case an exception 19 | :class:`~bip.base.BipDecompileError` is raised by Bip. 20 | 21 | The :class:`~bip.hexrays.HxCFunc` allows to recuperate the C string 22 | of the decompiled function (:meth:`~bip.hexrays.HxCFunc.cstr`), to get the 23 | "normal" :class:`~bip.base.BipFunction` (:meth:`~bip.hexrays.HxCFunc.bfunc`) 24 | and provide to two main features: local variables (lvar) and AST nodes. 25 | 26 | Local variables (lvar) are represented by :class:`~bip.hexrays.HxLvar` objects 27 | and are accessible through several methods. The simplest way is to use the 28 | :meth:`~bip.hexrays.HxCFunc.lvars` property which return an array of the 29 | variable. As those variables also include the arguments of the functions the 30 | :meth:`~bip.hexrays.HxCFunc.args` property allows to get only the 31 | :class:`~bip.hexrays.HxLvar` which are arguments. 32 | 33 | The AST nodes of the :class:`~bip.hexrays.HxCFunc` can be accessed in 34 | different ways. Bip provides :class:`~bip.hexrays.CNode` classes 35 | (:class:`~bip.hexrays.CNode` is the parent class for all nodes) which 36 | represents a node of the AST, those are already a second level of abstraction 37 | on top of the hexrays AST node. There are three main ways to access 38 | the :class:`~bip.hexrays.CNode` for a particular function: 39 | 40 | * by accessing the :meth:`~bip.hexrays.HxCFunc.root_node` of the AST and then 41 | making the visit or the treatment as the user which; 42 | * by using visitors already implemented: :meth:`~bip.hexrays.HxCFunc.visit_cnode` 43 | or :meth:`~bip.hexrays.HxCFunc.visit_cnode_filterlist` and providing a 44 | callback, those visitors use a Deep-First Search (DFS) algorithm; 45 | * by using helper methods :meth:`~bip.hexrays.HxCFunc.get_cnode_filter` or 46 | :meth:`~bip.hexrays.HxCFunc.get_cnode_filter_type` which provide list of 47 | the resulting nodes, those helpers are based on the visitors. 48 | 49 | It is also possible to use the visitor on the first level of abstraction 50 | on top of the hexrays node, those methods start with the prefix 51 | ``hx_visit_``. 52 | 53 | HxCFunc API 54 | =========== 55 | 56 | .. autoclass:: HxCFunc 57 | :members: 58 | :member-order: bysource 59 | 60 | .. automethod:: __init__ 61 | 62 | -------------------------------------------------------------------------------- /docs/build/html/_sources/hexrays/lvar.rst.txt: -------------------------------------------------------------------------------- 1 | Local variables 2 | ############### 3 | 4 | .. module:: bip.hexrays 5 | 6 | Local variables (lvar) are implemented in Bip by the class 7 | :class:`~bip.hexrays.HxLvar`. They represent a local variable (including 8 | arguments) such as view by the decompiler. 9 | 10 | The main way to access the :class:`~bip.hexrays.HxLvar` is through 11 | a :class:`~bip.hexrays.HxCFunc` object using, for example the 12 | :meth:`~bip.hexrays.HxCFunc.lvars` property. 13 | 14 | As of now there is no way to get the equivalent storage for a lvar. 15 | 16 | HxLvar API 17 | ========== 18 | 19 | .. autoclass:: HxLvar 20 | :members: 21 | :member-order: bysource 22 | 23 | .. automethod:: __init__ 24 | 25 | 26 | -------------------------------------------------------------------------------- /docs/build/html/_sources/index.rst.txt: -------------------------------------------------------------------------------- 1 | .. Bip documentation master file, created by 2 | sphinx-quickstart on Fri Jul 27 08:36:06 2018. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to Bip's documentation! 7 | ############################### 8 | 9 | Bip is a project which aimed to simplify the usage of python for interacting 10 | with IDA. Its main goals are to facilitate the usage of python in the 11 | interactive console of IDA and for writing plugins. In a more general way 12 | the goal is to automate the recurrent task done through the python API. 13 | Bip is also developxped for providing a more oriented object, a "python-like" 14 | API and a *real* documentation. 15 | 16 | This code is not complete, and a lot of features are still missing. Development 17 | is prioritized on what people ask for and what the developers use, so do not 18 | hesitate to make PR, Feature Request and Issues (including for the 19 | documentation), see :ref:`general-contrib` for more information. 20 | 21 | This documentation is split in several parts. The `General`_ part should allow 22 | you to start with the project including the install (:ref:`general-install`) 23 | and an overview (:ref:`general-overview`) which explain how to use it. 24 | The :ref:`general-archi` allows to get a better understanding of how the 25 | project works and was intended to be used. 26 | 27 | The main part of the documentation is split in the three parts of 28 | bip: :ref:`index-base` 29 | containing the basic interfaces, the :ref:`index-hexrays` for manipulating 30 | hexrays functions and the :ref:`index-gui` containing interface with the 31 | graphics and explaining how to developed plugins. This is mainly 32 | autodocumentation of bip objects with precisions about usage and potentially 33 | internals when necessary. 34 | 35 | General 36 | ======= 37 | 38 | .. toctree:: 39 | :maxdepth: 3 40 | 41 | general/install 42 | general/overview 43 | general/archi 44 | general/contribution 45 | general/changelog 46 | 47 | .. _index-base: 48 | 49 | Base interface (``bip.base``) 50 | ============================= 51 | 52 | This regroup the part about the base interface on top of the IDA basic API. 53 | All classes in this part are regroup in the ``bip.base`` module. 54 | 55 | .. toctree:: 56 | :maxdepth: 2 57 | 58 | base/elt 59 | base/instr 60 | base/data 61 | base/func 62 | base/xref 63 | base/struct 64 | base/enum 65 | base/type 66 | base/bipidb 67 | base/bipida 68 | 69 | .. _index-hexrays: 70 | 71 | Hexrays interface (``bip.hexrays``) 72 | =================================== 73 | 74 | This regroup the interface on top of the IDA Hexrays API, in particular it 75 | allows to visit the AST generated for the functions. This module will be 76 | useful only if the decompiler for the binary exist and is installed. 77 | 78 | .. toctree:: 79 | :maxdepth: 2 80 | 81 | hexrays/cfunc 82 | hexrays/lvar 83 | hexrays/astnodes 84 | hexrays/cnode 85 | hexrays/visit_hx 86 | 87 | .. _index-gui: 88 | 89 | GUI & Plugins interface (``bip.gui``) 90 | ===================================== 91 | 92 | This part regroup all the functions and classes made for interfacing with the 93 | UI and events of IDA. The most important part of this module is probably the 94 | :class:`BipPlugin` which allow to create plugins and to define actions in IDA. 95 | While bip can be used in normal IDA plugin and scripts, the :class:`BipPlugin` 96 | is the central element for interfacing with the GUI using bip. 97 | 98 | .. toctree:: 99 | :maxdepth: 2 100 | 101 | gui/plugin 102 | gui/plgmanager 103 | gui/activity 104 | gui/userselect 105 | 106 | Indices and tables 107 | ================== 108 | 109 | * :ref:`genindex` 110 | * :ref:`modindex` 111 | * :ref:`search` 112 | 113 | -------------------------------------------------------------------------------- /docs/build/html/_static/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/html/_static/ajax-loader.gif -------------------------------------------------------------------------------- /docs/build/html/_static/classic.css: -------------------------------------------------------------------------------- 1 | /* 2 | * classic.css_t 3 | * ~~~~~~~~~~~~~ 4 | * 5 | * Sphinx stylesheet -- classic theme. 6 | * 7 | * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | 12 | @import url("basic.css"); 13 | 14 | /* -- page layout ----------------------------------------------------------- */ 15 | 16 | body { 17 | font-family: sans-serif; 18 | font-size: 100%; 19 | background-color: #11303d; 20 | color: #000; 21 | margin: 0; 22 | padding: 0; 23 | } 24 | 25 | div.document { 26 | background-color: #1c4e63; 27 | } 28 | 29 | div.documentwrapper { 30 | float: left; 31 | width: 100%; 32 | } 33 | 34 | div.bodywrapper { 35 | margin: 0 0 0 230px; 36 | } 37 | 38 | div.body { 39 | background-color: #ffffff; 40 | color: #000000; 41 | padding: 0 20px 30px 20px; 42 | } 43 | 44 | div.footer { 45 | color: #ffffff; 46 | width: 100%; 47 | padding: 9px 0 9px 0; 48 | text-align: center; 49 | font-size: 75%; 50 | } 51 | 52 | div.footer a { 53 | color: #ffffff; 54 | text-decoration: underline; 55 | } 56 | 57 | div.related { 58 | background-color: #133f52; 59 | line-height: 30px; 60 | color: #ffffff; 61 | } 62 | 63 | div.related a { 64 | color: #ffffff; 65 | } 66 | 67 | div.sphinxsidebar { 68 | } 69 | 70 | div.sphinxsidebar h3 { 71 | font-family: 'Trebuchet MS', sans-serif; 72 | color: #ffffff; 73 | font-size: 1.4em; 74 | font-weight: normal; 75 | margin: 0; 76 | padding: 0; 77 | } 78 | 79 | div.sphinxsidebar h3 a { 80 | color: #ffffff; 81 | } 82 | 83 | div.sphinxsidebar h4 { 84 | font-family: 'Trebuchet MS', sans-serif; 85 | color: #ffffff; 86 | font-size: 1.3em; 87 | font-weight: normal; 88 | margin: 5px 0 0 0; 89 | padding: 0; 90 | } 91 | 92 | div.sphinxsidebar p { 93 | color: #ffffff; 94 | } 95 | 96 | div.sphinxsidebar p.topless { 97 | margin: 5px 10px 10px 10px; 98 | } 99 | 100 | div.sphinxsidebar ul { 101 | margin: 10px; 102 | padding: 0; 103 | color: #ffffff; 104 | } 105 | 106 | div.sphinxsidebar a { 107 | color: #98dbcc; 108 | } 109 | 110 | div.sphinxsidebar input { 111 | border: 1px solid #98dbcc; 112 | font-family: sans-serif; 113 | font-size: 1em; 114 | } 115 | 116 | 117 | 118 | /* -- hyperlink styles ------------------------------------------------------ */ 119 | 120 | a { 121 | color: #355f7c; 122 | text-decoration: none; 123 | } 124 | 125 | a:visited { 126 | color: #355f7c; 127 | text-decoration: none; 128 | } 129 | 130 | a:hover { 131 | text-decoration: underline; 132 | } 133 | 134 | 135 | 136 | /* -- body styles ----------------------------------------------------------- */ 137 | 138 | div.body h1, 139 | div.body h2, 140 | div.body h3, 141 | div.body h4, 142 | div.body h5, 143 | div.body h6 { 144 | font-family: 'Trebuchet MS', sans-serif; 145 | background-color: #f2f2f2; 146 | font-weight: normal; 147 | color: #20435c; 148 | border-bottom: 1px solid #ccc; 149 | margin: 20px -20px 10px -20px; 150 | padding: 3px 0 3px 10px; 151 | } 152 | 153 | div.body h1 { margin-top: 0; font-size: 200%; } 154 | div.body h2 { font-size: 160%; } 155 | div.body h3 { font-size: 140%; } 156 | div.body h4 { font-size: 120%; } 157 | div.body h5 { font-size: 110%; } 158 | div.body h6 { font-size: 100%; } 159 | 160 | a.headerlink { 161 | color: #c60f0f; 162 | font-size: 0.8em; 163 | padding: 0 4px 0 4px; 164 | text-decoration: none; 165 | } 166 | 167 | a.headerlink:hover { 168 | background-color: #c60f0f; 169 | color: white; 170 | } 171 | 172 | div.body p, div.body dd, div.body li, div.body blockquote { 173 | text-align: justify; 174 | line-height: 130%; 175 | } 176 | 177 | div.admonition p.admonition-title + p { 178 | display: inline; 179 | } 180 | 181 | div.admonition p { 182 | margin-bottom: 5px; 183 | } 184 | 185 | div.admonition pre { 186 | margin-bottom: 5px; 187 | } 188 | 189 | div.admonition ul, div.admonition ol { 190 | margin-bottom: 5px; 191 | } 192 | 193 | div.note { 194 | background-color: #eee; 195 | border: 1px solid #ccc; 196 | } 197 | 198 | div.seealso { 199 | background-color: #ffc; 200 | border: 1px solid #ff6; 201 | } 202 | 203 | div.topic { 204 | background-color: #eee; 205 | } 206 | 207 | div.warning { 208 | background-color: #ffe4e4; 209 | border: 1px solid #f66; 210 | } 211 | 212 | p.admonition-title { 213 | display: inline; 214 | } 215 | 216 | p.admonition-title:after { 217 | content: ":"; 218 | } 219 | 220 | pre { 221 | padding: 5px; 222 | background-color: #eeffcc; 223 | color: #333333; 224 | line-height: 120%; 225 | border: 1px solid #ac9; 226 | border-left: none; 227 | border-right: none; 228 | } 229 | 230 | code { 231 | background-color: #ecf0f3; 232 | padding: 0 1px 0 1px; 233 | font-size: 0.95em; 234 | } 235 | 236 | th { 237 | background-color: #ede; 238 | } 239 | 240 | .warning code { 241 | background: #efc2c2; 242 | } 243 | 244 | .note code { 245 | background: #d6d6d6; 246 | } 247 | 248 | .viewcode-back { 249 | font-family: sans-serif; 250 | } 251 | 252 | div.viewcode-block:target { 253 | background-color: #f4debf; 254 | border-top: 1px solid #ac9; 255 | border-bottom: 1px solid #ac9; 256 | } 257 | 258 | div.code-block-caption { 259 | color: #efefef; 260 | background-color: #1c4e63; 261 | } -------------------------------------------------------------------------------- /docs/build/html/_static/comment-bright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/html/_static/comment-bright.png -------------------------------------------------------------------------------- /docs/build/html/_static/comment-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/html/_static/comment-close.png -------------------------------------------------------------------------------- /docs/build/html/_static/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/html/_static/comment.png -------------------------------------------------------------------------------- /docs/build/html/_static/css/fixclassic.css: -------------------------------------------------------------------------------- 1 | div.body { 2 | min-width: 450px; 3 | max-width: none; 4 | } 5 | 6 | div.bodywrapper { 7 | margin-right: 20px; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /docs/build/html/_static/documentation_options.js: -------------------------------------------------------------------------------- 1 | var DOCUMENTATION_OPTIONS = { 2 | URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), 3 | VERSION: '1.0', 4 | LANGUAGE: 'None', 5 | COLLAPSE_INDEX: false, 6 | FILE_SUFFIX: '.html', 7 | HAS_SOURCE: true, 8 | SOURCELINK_SUFFIX: '.txt', 9 | NAVIGATION_WITH_KEYS: false, 10 | }; -------------------------------------------------------------------------------- /docs/build/html/_static/down-pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/html/_static/down-pressed.png -------------------------------------------------------------------------------- /docs/build/html/_static/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/html/_static/down.png -------------------------------------------------------------------------------- /docs/build/html/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/html/_static/file.png -------------------------------------------------------------------------------- /docs/build/html/_static/img/bip_base2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/html/_static/img/bip_base2.png -------------------------------------------------------------------------------- /docs/build/html/_static/img/bip_gui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/html/_static/img/bip_gui.png -------------------------------------------------------------------------------- /docs/build/html/_static/img/bip_hexrays.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/html/_static/img/bip_hexrays.png -------------------------------------------------------------------------------- /docs/build/html/_static/img/bip_hexrays_cnode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/html/_static/img/bip_hexrays_cnode.png -------------------------------------------------------------------------------- /docs/build/html/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/html/_static/minus.png -------------------------------------------------------------------------------- /docs/build/html/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/docs/build/html/_static/plus.png -------------------------------------------------------------------------------- /docs/build/html/_static/pygments.css: -------------------------------------------------------------------------------- 1 | .highlight .hll { background-color: #ffffcc } 2 | .highlight { background: #eeffcc; } 3 | .highlight .c { color: #408090; font-style: italic } /* Comment */ 4 | .highlight .err { border: 1px solid #FF0000 } /* Error */ 5 | .highlight .k { color: #007020; font-weight: bold } /* Keyword */ 6 | .highlight .o { color: #666666 } /* Operator */ 7 | .highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */ 8 | .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ 9 | .highlight .cp { color: #007020 } /* Comment.Preproc */ 10 | .highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */ 11 | .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ 12 | .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ 13 | .highlight .gd { color: #A00000 } /* Generic.Deleted */ 14 | .highlight .ge { font-style: italic } /* Generic.Emph */ 15 | .highlight .gr { color: #FF0000 } /* Generic.Error */ 16 | .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 17 | .highlight .gi { color: #00A000 } /* Generic.Inserted */ 18 | .highlight .go { color: #333333 } /* Generic.Output */ 19 | .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ 20 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 21 | .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 22 | .highlight .gt { color: #0044DD } /* Generic.Traceback */ 23 | .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ 24 | .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ 25 | .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ 26 | .highlight .kp { color: #007020 } /* Keyword.Pseudo */ 27 | .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ 28 | .highlight .kt { color: #902000 } /* Keyword.Type */ 29 | .highlight .m { color: #208050 } /* Literal.Number */ 30 | .highlight .s { color: #4070a0 } /* Literal.String */ 31 | .highlight .na { color: #4070a0 } /* Name.Attribute */ 32 | .highlight .nb { color: #007020 } /* Name.Builtin */ 33 | .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ 34 | .highlight .no { color: #60add5 } /* Name.Constant */ 35 | .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ 36 | .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ 37 | .highlight .ne { color: #007020 } /* Name.Exception */ 38 | .highlight .nf { color: #06287e } /* Name.Function */ 39 | .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ 40 | .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ 41 | .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ 42 | .highlight .nv { color: #bb60d5 } /* Name.Variable */ 43 | .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ 44 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ 45 | .highlight .mb { color: #208050 } /* Literal.Number.Bin */ 46 | .highlight .mf { color: #208050 } /* Literal.Number.Float */ 47 | .highlight .mh { color: #208050 } /* Literal.Number.Hex */ 48 | .highlight .mi { color: #208050 } /* Literal.Number.Integer */ 49 | .highlight .mo { color: #208050 } /* Literal.Number.Oct */ 50 | .highlight .sa { color: #4070a0 } /* Literal.String.Affix */ 51 | .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ 52 | .highlight .sc { color: #4070a0 } /* Literal.String.Char */ 53 | .highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */ 54 | .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ 55 | .highlight .s2 { color: #4070a0 } /* Literal.String.Double */ 56 | .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ 57 | .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ 58 | .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ 59 | .highlight .sx { color: #c65d09 } /* Literal.String.Other */ 60 | .highlight .sr { color: #235388 } /* Literal.String.Regex */ 61 | .highlight .s1 { color: #4070a0 } /* Literal.String.Single */ 62 | .highlight .ss { color: #517918 } /* Literal.String.Symbol */ 63 | .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ 64 | .highlight .fm { color: #06287e } /* Name.Function.Magic */ 65 | .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ 66 | .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ 67 | .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ 68 | .highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */ 69 | .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ -------------------------------------------------------------------------------- /docs/build/html/_static/sidebar.js: -------------------------------------------------------------------------------- 1 | /* 2 | * sidebar.js 3 | * ~~~~~~~~~~ 4 | * 5 | * This script makes the Sphinx sidebar collapsible. 6 | * 7 | * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds 8 | * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton 9 | * used to collapse and expand the sidebar. 10 | * 11 | * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden 12 | * and the width of the sidebar and the margin-left of the document 13 | * are decreased. When the sidebar is expanded the opposite happens. 14 | * This script saves a per-browser/per-session cookie used to 15 | * remember the position of the sidebar among the pages. 16 | * Once the browser is closed the cookie is deleted and the position 17 | * reset to the default (expanded). 18 | * 19 | * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. 20 | * :license: BSD, see LICENSE for details. 21 | * 22 | */ 23 | 24 | $(function() { 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | // global elements used by the functions. 34 | // the 'sidebarbutton' element is defined as global after its 35 | // creation, in the add_sidebar_button function 36 | var bodywrapper = $('.bodywrapper'); 37 | var sidebar = $('.sphinxsidebar'); 38 | var sidebarwrapper = $('.sphinxsidebarwrapper'); 39 | 40 | // for some reason, the document has no sidebar; do not run into errors 41 | if (!sidebar.length) return; 42 | 43 | // original margin-left of the bodywrapper and width of the sidebar 44 | // with the sidebar expanded 45 | var bw_margin_expanded = bodywrapper.css('margin-left'); 46 | var ssb_width_expanded = sidebar.width(); 47 | 48 | // margin-left of the bodywrapper and width of the sidebar 49 | // with the sidebar collapsed 50 | var bw_margin_collapsed = '.8em'; 51 | var ssb_width_collapsed = '.8em'; 52 | 53 | // colors used by the current theme 54 | var dark_color = $('.related').css('background-color'); 55 | var light_color = $('.document').css('background-color'); 56 | 57 | function sidebar_is_collapsed() { 58 | return sidebarwrapper.is(':not(:visible)'); 59 | } 60 | 61 | function toggle_sidebar() { 62 | if (sidebar_is_collapsed()) 63 | expand_sidebar(); 64 | else 65 | collapse_sidebar(); 66 | } 67 | 68 | function collapse_sidebar() { 69 | sidebarwrapper.hide(); 70 | sidebar.css('width', ssb_width_collapsed); 71 | bodywrapper.css('margin-left', bw_margin_collapsed); 72 | sidebarbutton.css({ 73 | 'margin-left': '0', 74 | 'height': bodywrapper.height() 75 | }); 76 | sidebarbutton.find('span').text('»'); 77 | sidebarbutton.attr('title', _('Expand sidebar')); 78 | document.cookie = 'sidebar=collapsed'; 79 | } 80 | 81 | function expand_sidebar() { 82 | bodywrapper.css('margin-left', bw_margin_expanded); 83 | sidebar.css('width', ssb_width_expanded); 84 | sidebarwrapper.show(); 85 | sidebarbutton.css({ 86 | 'margin-left': ssb_width_expanded-12, 87 | 'height': bodywrapper.height() 88 | }); 89 | sidebarbutton.find('span').text('«'); 90 | sidebarbutton.attr('title', _('Collapse sidebar')); 91 | document.cookie = 'sidebar=expanded'; 92 | } 93 | 94 | function add_sidebar_button() { 95 | sidebarwrapper.css({ 96 | 'float': 'left', 97 | 'margin-right': '0', 98 | 'width': ssb_width_expanded - 28 99 | }); 100 | // create the button 101 | sidebar.append( 102 | '
«
' 103 | ); 104 | var sidebarbutton = $('#sidebarbutton'); 105 | light_color = sidebarbutton.css('background-color'); 106 | // find the height of the viewport to center the '<<' in the page 107 | var viewport_height; 108 | if (window.innerHeight) 109 | viewport_height = window.innerHeight; 110 | else 111 | viewport_height = $(window).height(); 112 | sidebarbutton.find('span').css({ 113 | 'display': 'block', 114 | 'margin-top': (viewport_height - sidebar.position().top - 20) / 2 115 | }); 116 | 117 | sidebarbutton.click(toggle_sidebar); 118 | sidebarbutton.attr('title', _('Collapse sidebar')); 119 | sidebarbutton.css({ 120 | 'color': '#FFFFFF', 121 | 'border-left': '1px solid ' + dark_color, 122 | 'font-size': '1.2em', 123 | 'cursor': 'pointer', 124 | 'height': bodywrapper.height(), 125 | 'padding-top': '1px', 126 | 'margin-left': ssb_width_expanded - 12 127 | }); 128 | 129 | sidebarbutton.hover( 130 | function () { 131 | $(this).css('background-color', dark_color); 132 | }, 133 | function () { 134 | $(this).css('background-color', light_color); 135 | } 136 | ); 137 | } 138 | 139 | function set_position_from_cookie() { 140 | if (!document.cookie) 141 | return; 142 | var items = document.cookie.split(';'); 143 | for(var k=0; k 4 | 5 | 6 | 7 | 8 | 9 | Python Module Index — Bip 1.0 documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 38 | 39 |
40 |
41 |
42 |
43 | 44 | 45 |

Python Module Index

46 | 47 |
48 | b 49 |
50 | 51 | 52 | 53 | 55 | 56 | 58 | 61 | 62 | 63 | 66 | 67 | 68 | 71 | 72 | 73 | 76 | 77 | 78 | 81 | 82 | 83 | 86 | 87 | 88 | 91 |
 
54 | b
59 | bip 60 |
    64 | bip.base 65 |
    69 | bip.gui 70 |
    74 | bip.gui.pluginmanager 75 |
    79 | bip.hexrays 80 |
    84 | bip.hexrays.cnode_visitor 85 |
    89 | bip.hexrays.hx_visitor 90 |
92 | 93 | 94 |
95 |
96 |
97 | 113 |
114 |
115 | 127 | 131 | 132 | -------------------------------------------------------------------------------- /docs/build/html/search.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | Search — Bip 1.0 documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 44 | 45 |
46 |
47 |
48 |
49 | 50 |

Search

51 |
52 | 53 |

54 | Please activate JavaScript to enable the search 55 | functionality. 56 |

57 |
58 |

59 | From here you can search these documents. Enter your search 60 | words into the box below and click "search". Note that the search 61 | function will automatically search for all of the words. Pages 62 | containing fewer words won't appear in the result list. 63 |

64 |
65 | 66 | 67 | 68 |
69 | 70 |
71 | 72 |
73 | 74 |
75 |
76 |
77 | 81 |
82 |
83 | 95 | 99 | 100 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Configuration file for the Sphinx documentation builder. 4 | # 5 | # This file does only contain a selection of the most common options. For a 6 | # full list see the documentation: 7 | # http://www.sphinx-doc.org/en/master/config 8 | 9 | # -- Path setup -------------------------------------------------------------- 10 | 11 | # If extensions (or modules to document with autodoc) are in another directory, 12 | # add these directories to sys.path here. If the directory is relative to the 13 | # documentation root, use os.path.abspath to make it absolute, like shown here. 14 | # 15 | import os 16 | import sys 17 | sys.path.insert(0, os.path.abspath('../')) 18 | 19 | autodoc_mock_imports = ["idaapi", "idc", "idautils", "ida_hexrays", "ida_bytes", "ida_ua", "ida_gdl", "ida_funcs", "ida_name", "ida_struct", "ida_typeinf", "ida_nalt", "ida_graph", "ida_kernwin", "ida_search", "ida_enum", "ida_pro", "ida_lines", "ida_idaapi"] 20 | 21 | # -- Project information ----------------------------------------------------- 22 | 23 | project = u'Bip' 24 | copyright = u'2019' 25 | author = u'BrunoPujos' 26 | 27 | # The short X.Y version 28 | version = u'1.0' 29 | # The full version, including alpha/beta/rc tags 30 | release = u'1.0' 31 | 32 | 33 | # -- General configuration --------------------------------------------------- 34 | 35 | # If your documentation needs a minimal Sphinx version, state it here. 36 | # 37 | # needs_sphinx = '1.0' 38 | 39 | # Add any Sphinx extension module names here, as strings. They can be 40 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 41 | # ones. 42 | extensions = [ 43 | 'sphinx.ext.autodoc', 44 | 'sphinx.ext.todo', 45 | 'sphinx.ext.imgmath', 46 | ] 47 | 48 | # Add any paths that contain templates here, relative to this directory. 49 | templates_path = ['_templates'] 50 | 51 | # The suffix(es) of source filenames. 52 | # You can specify multiple suffix as a list of string: 53 | # 54 | # source_suffix = ['.rst', '.md'] 55 | source_suffix = '.rst' 56 | 57 | # The master toctree document. 58 | master_doc = 'index' 59 | 60 | # The language for content autogenerated by Sphinx. Refer to documentation 61 | # for a list of supported languages. 62 | # 63 | # This is also used if you do content translation via gettext catalogs. 64 | # Usually you set "language" from the command line for these cases. 65 | language = None 66 | 67 | # List of patterns, relative to source directory, that match files and 68 | # directories to ignore when looking for source files. 69 | # This pattern also affects html_static_path and html_extra_path . 70 | exclude_patterns = [u'_build', 'Thumbs.db', '.DS_Store'] 71 | 72 | # The name of the Pygments (syntax highlighting) style to use. 73 | pygments_style = 'sphinx' 74 | 75 | 76 | # -- Options for HTML output ------------------------------------------------- 77 | 78 | # The theme to use for HTML and HTML Help pages. See the documentation for 79 | # a list of builtin themes. 80 | # 81 | #html_theme = 'alabaster' 82 | html_theme = 'classic' 83 | 84 | # Theme options are theme-specific and customize the look and feel of a theme 85 | # further. For a list of options available for each theme, see the 86 | # documentation. 87 | # 88 | # html_theme_options = {} 89 | 90 | # Add any paths that contain custom static files (such as style sheets) here, 91 | # relative to this directory. They are copied after the builtin static files, 92 | # so a file named "default.css" will overwrite the builtin "default.css". 93 | html_static_path = ['_static'] 94 | 95 | # Custom sidebar templates, must be a dictionary that maps document names 96 | # to template names. 97 | # 98 | # The default sidebars (for documents that don't match any pattern) are 99 | # defined by theme itself. Builtin themes are using these templates by 100 | # default: ``['localtoc.html', 'relations.html', 'sourcelink.html', 101 | # 'searchbox.html']``. 102 | # 103 | # html_sidebars = {} 104 | 105 | 106 | # -- Options for HTMLHelp output --------------------------------------------- 107 | 108 | # Output file base name for HTML help builder. 109 | htmlhelp_basename = 'Bipdoc' 110 | 111 | 112 | # -- Options for LaTeX output ------------------------------------------------ 113 | 114 | latex_elements = { 115 | # The paper size ('letterpaper' or 'a4paper'). 116 | # 117 | # 'papersize': 'letterpaper', 118 | 119 | # The font size ('10pt', '11pt' or '12pt'). 120 | # 121 | # 'pointsize': '10pt', 122 | 123 | # Additional stuff for the LaTeX preamble. 124 | # 125 | # 'preamble': '', 126 | 127 | # Latex figure (float) alignment 128 | # 129 | # 'figure_align': 'htbp', 130 | } 131 | 132 | # Grouping the document tree into LaTeX files. List of tuples 133 | # (source start file, target name, title, 134 | # author, documentclass [howto, manual, or own class]). 135 | latex_documents = [ 136 | (master_doc, 'Bip.tex', u'Bip Documentation', 137 | u'', 'manual'), 138 | ] 139 | 140 | 141 | # -- Options for manual page output ------------------------------------------ 142 | 143 | # One entry per manual page. List of tuples 144 | # (source start file, name, description, authors, manual section). 145 | man_pages = [ 146 | (master_doc, 'bip', u'Bip Documentation', 147 | [author], 1) 148 | ] 149 | 150 | 151 | # -- Options for Texinfo output ---------------------------------------------- 152 | 153 | # Grouping the document tree into Texinfo files. List of tuples 154 | # (source start file, target name, title, author, 155 | # dir menu entry, description, category) 156 | texinfo_documents = [ 157 | (master_doc, 'Bip', u'Bip Documentation', 158 | author, 'Bip', 'One line description of project.', 159 | 'Miscellaneous'), 160 | ] 161 | 162 | 163 | # -- Extension configuration ------------------------------------------------- 164 | 165 | # -- Options for todo extension ---------------------------------------------- 166 | 167 | # If true, `todo` and `todoList` produce output, else they produce nothing. 168 | todo_include_todos = True 169 | 170 | def setup(app): 171 | app.add_stylesheet('css/fixclassic.css') 172 | -------------------------------------------------------------------------------- /docs/general/changelog.rst: -------------------------------------------------------------------------------- 1 | Changelog 2 | ######### 3 | 4 | This page has the goal to record breaking change in the API between versions. 5 | New features may be listed but probably not always. 6 | 7 | 8 | Change from v0.3 to v1.0 9 | ======================== 10 | 11 | New features: 12 | 13 | * new class :class:`bip.base.BipIdb` 14 | * new class :class:`bip.base.BipIda` 15 | * new class :class:`bip.gui.BipUserSelect` 16 | 17 | Breaking changes: 18 | 19 | * renaming of ``bip.base.XrefTypes`` to ``bip.base._XrefTypes`` 20 | * renaming of ``bip.base.DestOpType`` to ``bip.base.BipDestOpType`` 21 | * renaming of ``bip.base.OpType`` to ``bip.base.BipOpType`` 22 | * renaming of ``bip.base.Operand`` to ``bip.base.BipOperand`` 23 | * renaming of ``bip.hexrays.HexRaysEvent`` to ``bip.base.HxEvent`` 24 | * renaming of ``bip.base.Instr`` to ``bip.base.BipInstr`` 25 | * renaming of ``bip.base.BipFuncFlags`` to ``bip.base._BipFuncFlags`` 26 | * renaming of ``bip.base.BipFlowChartFlag`` to ``bip.base._BipFlowChartFlag`` 27 | * renaming of ``bip.base.BipType._GetClassBipType`` to ``bip.base.BipType._get_class_bip_type`` 28 | * renaming of ``bip.base.BipType.GetBipTypeNoCopy`` to ``bip.base.BipType.from_tinfo_no_copy`` 29 | * renaming of ``bip.base.BipType.GetBipType`` to ``bip.base.BipType.from_tinfo`` 30 | * renaming of ``bip.base.BipType.FromC`` to ``bip.base.BipType.from_c`` 31 | * renaming of ``bip.base.BipType.ImportCHeader`` to ``bip.base.BipType.import_c_header`` 32 | * renaming of ``bip.base.BipInstr.Make`` to ``bip.base.BipInstr.make`` 33 | * renaming of ``bip.base.BipFunction.ByOrdinal`` to ``bip.base.BipFunction.by_ordinal`` 34 | * renaming of ``bip.base.BipFunction.Entries`` to ``bip.base.BipFunction.entries`` 35 | * renaming of ``bip.base.BipFunction.Entries_iter`` to ``bip.base.BipFunction.entries_iter`` 36 | * renaming of ``bip.base.BipFunction.Count`` to ``bip.base.BipFunction.count`` 37 | * renaming of ``bip.hexrays.HxCItem.GetHxCItem`` to ``bip.hexrays.HxCItem.from_citem`` 38 | * renaming of ``bip.hexrays.HxCItem._createChild`` to ``bip.hexrays.HxCItem._create_child`` 39 | * renaming of ``bip.hexrays.CNode._createChild`` to ``bip.hexrays.CNode._create_child`` 40 | * renaming of ``bip.hexrays.HxCStmt.st_childs`` to ``bip.hexrays.HxCStmt.stmt_children`` 41 | * renaming of ``bip.hexrays.CNodeStmt.st_childs`` to ``bip.hexrays.CNodeStmt.stmt_children`` 42 | * renaming of ``bip.hexrays.CNodeStmt.expr_childs`` to ``bip.hexrays.CNodeStmt.expr_children`` 43 | * renaming of ``bip.hexrays.CNode.GetCNode`` to ``bip.hexrays.CNode.from_citem`` 44 | * renaming of ``bip.hexrays.CNode.cfunc`` to ``bip.hexrays.CNode.hxcfunc`` 45 | * renaming of ``bip.base.BipFunction.hxfunc`` to ``bip.base.BipFunction.hxcfunc`` 46 | * renaming of ``bip.hexrays.HxLvar.hxfunc`` to ``bip.hexrays.HxLvar.hxcfunc`` 47 | * function ``bip.base.utils.get_ptr_size`` became static method ``bip.base.BipIdb.ptr_size`` 48 | * function ``bip.base.utils.absea`` became a static method of ``bip.base.BipIdb`` 49 | * function ``bip.base.utils.relea`` became a static method of ``bip.base.BipIdb`` 50 | * ``min_ea``, ``max_ea`` and ``Here``, functions are now in ``bip.base.bipidb`` 51 | * function ``bip.base.utils.get_addr_by_name`` has been removed. 52 | * function ``bip.base.utils.get_name_by_addr`` has been removed. 53 | * function ``bip.base.utils.get_struct_from_lvar`` has been removed. 54 | * function ``bip.base.utils.Ptr`` became static method of ``bip.base.BipData.get_ptr`` 55 | * function ``bip.base.utils.bip_exec_sync`` became static method ``bip.base.BipIda.exec_sync`` 56 | * function ``bip.base.utils.get_highlighted_identifier_as_int`` became static method ``BipUserSelect.get_curr_highlighted_int`` 57 | * removed classes ``BaseGuiAction`` and ``ContextMenuHooks`` 58 | * renamed method ``bip.base.BipType.childs`` to ``bip.base.BiType.children`` 59 | 60 | 61 | Sed script for automatic update of plugins (no garantee to be perfect or to 62 | avoid colisions) (use with ``sed -f RULEFILE INPUTFILE``): 63 | 64 | .. code-block:: none 65 | 66 | s/XrefTypes/_XrefTypes/g 67 | s/DestOpType/BipDestOpType/g 68 | s/OpType/BipOpType/g 69 | s/Operand/BipOperand/g 70 | s/countBipOperand/countOperand/g 71 | s/HexRaysEvent/HxEvent/g 72 | s/Instr/BipInstr/g 73 | s/BipFuncFlags/_BipFuncFlags/g 74 | s/BipFlowChartFlag/_BipFlowChartFlag/g 75 | s/_GetClassBipType/_get_class_bip_type/g 76 | s/GetBipTypeNoCopy/from_tinfo_no_copy/g 77 | s/GetBipType/from_tinfo/g 78 | s/FromC/from_c/g 79 | s/ImportCHeader/import_c_header/g 80 | s/ByOrdinal/by_ordinal/g 81 | s/Entries/entries/g 82 | s/GetHxCItem/from_citem/g 83 | s/_createChild/_create_child/g 84 | s/st_childs/stmt_children/g 85 | s/expr_childs/expr_children/g 86 | s/GetCNode/from_citem/g 87 | s/get_ptr_size/BipIdb.ptr_size/g 88 | s/bip_exec_sync/BipIda.exec_sync/g 89 | s/get_highlighted_identifier_as_int/BipUserSelect.get_curr_highlighted_int/g 90 | s/childs/children/g 91 | 92 | Are not included in this sed file the change to ``BipInstr.Make``, 93 | ``BipFunction.Count``, ``Cnode.cfunc``, ``Ptr`` which can easilly create 94 | problems. 95 | 96 | This update removed also the ``example``, ``scripts`` and ``plugins`` 97 | directory which will not be maintain as part of Bip (and where probably 98 | already not working since some times). 99 | 100 | 101 | -------------------------------------------------------------------------------- /docs/general/contribution.rst: -------------------------------------------------------------------------------- 1 | .. _general-contrib: 2 | 3 | Contributions 4 | ############# 5 | 6 | Contributions to Bip are welcome, it can be Issues, Feature Request or Pull 7 | Request (PR), all of those can be made on github. Those can concern the code 8 | but also the documentation, which has the goal to be clear and complete. 9 | The integrality of Bip is currently maintained by a unique person, so please 10 | take the time to read those and thank you in advance for your patience. 11 | 12 | As general rules for Issues and Feature Request, provided a clear 13 | description, an example (with the line of the API and if needed the content 14 | of IDA) and if possible a way to reproduce or test it. Do not hesitate to 15 | propose an example of what you would like to have as an API in Bip. If you 16 | have it, an example of how to do it with the IDAPython API would be amazing. 17 | 18 | Pull Request 19 | ============ 20 | 21 | For Pull Request, please provide a clear description of what your code does 22 | and, especially if it is a big PR, how you implemented it. The only release of 23 | IDA for which Bip is maintained is the last one, so be sure it works with it. 24 | No pull request will be merged in ``master`` if: 25 | 26 | * the code is not documented, 27 | * the code is not integrated in the documentation, 28 | * the code is not compatible for python2 and python3 (as long as both are 29 | supported in Bip), 30 | * there are no tests for the new functions/methods/classes/... 31 | 32 | You can make a PR without those, however it will take some time for it to be 33 | merged because those will have to be written. 34 | 35 | Regarding the code in itself, no hardline coding convention is enforced (for 36 | now) but please follow as much as possible those rules: 37 | 38 | * use 4 spaces instead of tabulation, 39 | * write python2 and python3 compatible code, 40 | * follow naming convention of Python (``UpperCaseCamel`` for classes 41 | and ``lower_with_underscore`` for methods), 42 | * start the name of the class with ``Bip`` or ``Hx`` (for hexrays) or a clear 43 | prefix which identifies it (the goal is to avoid collisions with IDAPython 44 | and other python packages, as well as to make auto-completion easier), 45 | * write **readable** code (avoid nested list comprehension and so on), 46 | * simpler code is often better, 47 | * stay around 80 chars (a little more is fine). 48 | 49 | Finally, if the PR introduces a breaking change (change in names of a 50 | method or a class, change in arguments, change in behavior, ...), it has to 51 | log in the changelog including in this documentation. Further rules on 52 | breaking changes and Bip versions may be introduced. 53 | 54 | Change of version 55 | ================= 56 | 57 | This is a checklist of things to do for a change of version in Bip: 58 | 59 | * change version in sphinx doc (``docs/conf.py``), 60 | * change Bip Python version (``bip/__init__.py``), 61 | * change last stable version in ``README.rst``, 62 | * check changelog is done and has the right version numbers, 63 | * check all tests pass in py2 and py3, 64 | * check the doc build correctly, build it and push it (for github.io page). 65 | 66 | 67 | -------------------------------------------------------------------------------- /docs/general/install.rst: -------------------------------------------------------------------------------- 1 | .. _general-install: 2 | 3 | Installation steps 4 | ################## 5 | 6 | Installing Bip 7 | ============== 8 | 9 | The script ``install.py`` is made for installing Bip, it has been tested only 10 | on Windows and Linux, for making a default install: 11 | 12 | .. code-block:: bash 13 | 14 | python install.py 15 | 16 | This installer does not install any plugins by default, but simply the core of 17 | Bip. By default the destination folder is the one use by IDA locally 18 | (``%APPDATA%\Hex-Rays\IDA Pro\`` for Windows and ``$HOME/.idapro`` for Linux 19 | and MacOSX). 20 | 21 | It is possible to use an optional `--dest` argument to install in a 22 | particular folder: 23 | 24 | .. code-block:: none 25 | 26 | usage: install.py [-h] [--dest DEST] 27 | 28 | optional arguments: 29 | -h, --help show this help message and exit 30 | --dest DEST Destination folder where to install Bip 31 | 32 | Installing BipPlugin 33 | ==================== 34 | 35 | Plugin written for Bip, which inherit from :class:`~bip.gui.BipPlugin`, can 36 | be loaded automatically when opening IDA. For a plugin to be loaded 37 | automatically it has to be present in the ``plugins/bipplugin`` folder. This 38 | folder will be created automatically when `installing Bip`_ in the destination 39 | folder of the installation, by default: ``%APPDATA%\Hex-Rays\IDA Pro\`` for 40 | Windows and ``$HOME/.idapro`` for Linux. 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /docs/gui/activity.rst: -------------------------------------------------------------------------------- 1 | .. _gui-activity-actions: 2 | 3 | Activities and Actions 4 | ###################### 5 | 6 | .. module:: bip.gui 7 | 8 | For allowing to define interaction between the user-interface and the plugins 9 | Bip define :class:`BipActivity` . The intended way to use :class:`BipActivity` and 10 | :class:`BipAction` is using the :ref:`gui-plugin-activity-decorators` with 11 | a :class:`BipPlugin`. 12 | 13 | The :class:`BipActivity` is an abstract class allowing to define interaction 14 | with the IDA API and UI, in practice there is few reason to use them directly. 15 | 16 | The :class:`BipActivityContainer` is a :class:`BipActivity` containing several 17 | other :class:`BipActivity`, it is used internally for allowing to have several 18 | decorators (and so :class:`BipActivity`) on the same method of a 19 | :class:`BipPlugin`. 20 | 21 | The :class:`BipAction` (which inherit from :class:`BipActivity`) allows 22 | to define hotkeys (:func:`shortcut` decorator) or entries in the IDA menu 23 | (:func:`menu` decorator). It can be created directly as an object for defining 24 | actions dynamically and not link to a particular plugin. 25 | 26 | .. _gui-activity-internals: 27 | 28 | Implementation internals 29 | ======================== 30 | 31 | This part as the goal to describe the internal of the :class:`BipActivity`: 32 | how they interface with :class:`BipPlugin` and how to create a new kind of 33 | :class:`BipActivity` . It is not necessary to read it for simply using them. 34 | 35 | Creating a new BipActivity 36 | -------------------------- 37 | 38 | All :class:`BipActivity` subclasses should implement the methods: 39 | 40 | * :meth:`~BipActivity.register`: register the interface with IDA. This 41 | will be called when a plugin is loaded. 42 | * :meth:`~BipActivity.unregister`: register the interface with IDA. 43 | This is the oposite of :meth:`~BipActivity.register`, it will be 44 | called when a plugin is unloaded. 45 | * :meth:`~BipActivity.handler`: the handler function of the activity 46 | which actually does the action. It is not necessary to implement 47 | this function if the ``handler`` parameter for the constructor is 48 | defined. This method will also be called if the object is called. 49 | 50 | Those are the only mandatory methods to implement. 51 | 52 | Activities have for main goal to be used as decorator when writing 53 | a plugin and as such are *callable* object. *Calling* this object 54 | will triger a call to the :meth:`~BipActivity.handler` method. 55 | 56 | Activity and decorator 57 | ---------------------- 58 | 59 | Some decorators are define for being use inside a 60 | :class:`BipPlugin` class for defining interactions with IDA. Those 61 | decorators will dynamically create :class:`BipActivity` objects. 62 | 63 | When a :class:`BipPlugin` class is created, its constructor will create a 64 | list of the :class:`BipActivity` associtated with the plugin 65 | (stored in ``_activities``) and when the plugin object is created 66 | it will set itself in the :attr:`BipActivity.plugin` of each 67 | :class:`BipActivity` it contains. 68 | 69 | For allowing several :class:`BipActivity` decorators to be used 70 | on the same method the :class:`BipActivityContainer` class is 71 | defined. The decorator will still need to be able to define the 72 | handler function for the new :class:`BipActivity` decorators 73 | after the first one, this is done by storing the function in the 74 | :class:`BipActivityContainer` which is accessible through the 75 | :meth:`~BipActivityContainer.get_original_method` method. 76 | 77 | All decorators should return a :class:`BipActivityContainer` which 78 | will contain the :class:`BipActivity` to define. If the container 79 | was already defined it should simply add the new one using the 80 | :meth:`~BipActivityContainer.add_activity` method. 81 | 82 | BipAction API 83 | ============= 84 | 85 | .. autoclass:: BipAction 86 | :members: 87 | :member-order: bysource 88 | :special-members: 89 | :private-members: 90 | 91 | BipActivity API 92 | =============== 93 | 94 | .. autoclass:: BipActivity 95 | :members: 96 | :member-order: bysource 97 | :special-members: 98 | :private-members: 99 | 100 | BipActivityContainer API 101 | ======================== 102 | 103 | .. autoclass:: BipActivityContainer 104 | :members: 105 | :member-order: bysource 106 | :special-members: 107 | :private-members: 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /docs/gui/plgmanager.rst: -------------------------------------------------------------------------------- 1 | Plugin Manager 2 | ############## 3 | 4 | .. module:: bip.gui 5 | 6 | The :class:`~bip.gui.pluginmanager.BipPluginManager` is in charge of loading 7 | the :class:`BipPlugin`, create and register the :class:`BipActivity` link to 8 | them and allow to access the :class:`BipPlugin` instances once loaded. 9 | 10 | The :class:`~bip.gui.pluginmanager.BipPluginManager` is a singleton and 11 | should only be accessed using the :func:`get_plugin_manager` functions. 12 | It is also the only class in Bip which is a *real* IDA plugin. 13 | 14 | The main reason to use the :class:`~bip.gui.pluginmanager.BipPluginManager` 15 | is to recuperate a :class:`BipPlugin` instance: 16 | 17 | .. code-block:: python 18 | 19 | bpm = get_plugin_manager() # get the BipPluginManager 20 | plg = bpm["PLUGINNAME"] # get the plugin PLUGINNAME, PLUGINNAME should be the class of the plugin 21 | 22 | or for loading a new plugin: 23 | 24 | .. code-block:: python 25 | 26 | class MyPlugin(BipPlugin): # define a new class for the plugin 27 | pass # implementation 28 | 29 | bpm = get_plugin_manager() # get the BipPluginManager 30 | bpm.addld_plugin("MyPlugin", MyPlugin, ifneeded=True) # add the plugin 31 | # plugin in bipplugin folder will be loaded automatically and do not need those lines 32 | 33 | The :class:`~bip.gui.pluginmanager.BipPluginManager` is not exposed at the 34 | level of the module for avoiding instantiating a second object which will 35 | trigger bugs, use :func:`get_plugin_manager` for getting the singleton object. 36 | 37 | The :class:`~bip.gui.pluginmanager.BipPluginManager` is also in charge of 38 | loading automatically 39 | 40 | 41 | BipPluginManager API 42 | ==================== 43 | 44 | .. autofunction:: get_plugin_manager 45 | 46 | .. module:: bip.gui.pluginmanager 47 | 48 | .. autoclass:: BipPluginManager 49 | :members: 50 | :member-order: bysource 51 | :special-members: 52 | :private-members: 53 | 54 | .. autoclass:: BipPluginLoader 55 | :members: 56 | :member-order: bysource 57 | :special-members: 58 | :private-members: 59 | 60 | 61 | -------------------------------------------------------------------------------- /docs/gui/userselect.rst: -------------------------------------------------------------------------------- 1 | .. _gui-user-select: 2 | 3 | User selections 4 | ############### 5 | 6 | .. module:: bip.gui 7 | 8 | The :class:`BipUserSelect` class is in charge of regrouping several methods 9 | allowing to interact with the user selections. 10 | 11 | As of now this class contains only static methods. 12 | 13 | BipUserSelect API 14 | ================= 15 | 16 | .. autoclass:: BipUserSelect 17 | :members: 18 | :member-order: bysource 19 | :special-members: 20 | :private-members: 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /docs/hexrays/cfunc.rst: -------------------------------------------------------------------------------- 1 | Hexrays Functions 2 | ################# 3 | 4 | .. module:: bip.hexrays 5 | 6 | Hexrays function are implemented in Bip by the class :class:`~bip.hexrays.HxCFunc`. 7 | They represent a C function as decompiled by hexrays and are the main 8 | interface for using the features from hexrays in C. 9 | 10 | There are two ways to get a :class:`~bip.hexrays.HxCFunc` object using the Bip 11 | API, the first one is by using the :meth:`~bip.base.BipFunction.hxcfunc` 12 | property method from a :class:`~bip.base.BipFunction`, this property returns 13 | the equivalent :class:`~bip.hexrays.HxCFunc` for 14 | the :class:`~bip.base.BipFunction`. The second way is to use the class method 15 | :meth:`~bip.hexrays.HxCFunc.from_addr` which take an address in argument and try 16 | to create the corresponding :class:`~bip.hexrays.HxCFunc`. Both of those 17 | methods may fail if Hexrays is not able to decompile the function or if the 18 | address given is not part of a function, in that case an exception 19 | :class:`~bip.base.BipDecompileError` is raised by Bip. 20 | 21 | The :class:`~bip.hexrays.HxCFunc` allows to recuperate the C string 22 | of the decompiled function (:meth:`~bip.hexrays.HxCFunc.cstr`), to get the 23 | "normal" :class:`~bip.base.BipFunction` (:meth:`~bip.hexrays.HxCFunc.bfunc`) 24 | and provide to two main features: local variables (lvar) and AST nodes. 25 | 26 | Local variables (lvar) are represented by :class:`~bip.hexrays.HxLvar` objects 27 | and are accessible through several methods. The simplest way is to use the 28 | :meth:`~bip.hexrays.HxCFunc.lvars` property which return an array of the 29 | variable. As those variables also include the arguments of the functions the 30 | :meth:`~bip.hexrays.HxCFunc.args` property allows to get only the 31 | :class:`~bip.hexrays.HxLvar` which are arguments. 32 | 33 | The AST nodes of the :class:`~bip.hexrays.HxCFunc` can be accessed in 34 | different ways. Bip provides :class:`~bip.hexrays.CNode` classes 35 | (:class:`~bip.hexrays.CNode` is the parent class for all nodes) which 36 | represents a node of the AST, those are already a second level of abstraction 37 | on top of the hexrays AST node. There are three main ways to access 38 | the :class:`~bip.hexrays.CNode` for a particular function: 39 | 40 | * by accessing the :meth:`~bip.hexrays.HxCFunc.root_node` of the AST and then 41 | making the visit or the treatment as the user which; 42 | * by using visitors already implemented: :meth:`~bip.hexrays.HxCFunc.visit_cnode` 43 | or :meth:`~bip.hexrays.HxCFunc.visit_cnode_filterlist` and providing a 44 | callback, those visitors use a Deep-First Search (DFS) algorithm; 45 | * by using helper methods :meth:`~bip.hexrays.HxCFunc.get_cnode_filter` or 46 | :meth:`~bip.hexrays.HxCFunc.get_cnode_filter_type` which provide list of 47 | the resulting nodes, those helpers are based on the visitors. 48 | 49 | It is also possible to use the visitor on the first level of abstraction 50 | on top of the hexrays node, those methods start with the prefix 51 | ``hx_visit_``. 52 | 53 | HxCFunc API 54 | =========== 55 | 56 | .. autoclass:: HxCFunc 57 | :members: 58 | :member-order: bysource 59 | 60 | .. automethod:: __init__ 61 | 62 | -------------------------------------------------------------------------------- /docs/hexrays/lvar.rst: -------------------------------------------------------------------------------- 1 | Local variables 2 | ############### 3 | 4 | .. module:: bip.hexrays 5 | 6 | Local variables (lvar) are implemented in Bip by the class 7 | :class:`~bip.hexrays.HxLvar`. They represent a local variable (including 8 | arguments) such as view by the decompiler. 9 | 10 | The main way to access the :class:`~bip.hexrays.HxLvar` is through 11 | a :class:`~bip.hexrays.HxCFunc` object using, for example the 12 | :meth:`~bip.hexrays.HxCFunc.lvars` property. 13 | 14 | As of now there is no way to get the equivalent storage for a lvar. 15 | 16 | HxLvar API 17 | ========== 18 | 19 | .. autoclass:: HxLvar 20 | :members: 21 | :member-order: bysource 22 | 23 | .. automethod:: __init__ 24 | 25 | 26 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Redirection to _build/html 4 | 5 | 6 | 7 | Nothing here. 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. Bip documentation master file, created by 2 | sphinx-quickstart on Fri Jul 27 08:36:06 2018. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to Bip's documentation! 7 | ############################### 8 | 9 | Bip is a project which aims to simplify the usage of python for interacting 10 | with IDA. Its main goals are to facilitate the usage of python in the 11 | interactive console of IDA and the writing of plugins. In a more general way 12 | the goal is to automate recurrent tasks done through the python API. 13 | Bip is also developed to provide a more object oriented, a "python-like" 14 | API and a *real* documentation. 15 | 16 | This code is not complete, and a lot of features are still missing. Development 17 | is prioritized on what people ask for and what the developers use, so do not 18 | hesitate to make PR, Feature Request and Issues (including for the 19 | documentation), see :ref:`general-contrib` for more information. 20 | 21 | This documentation is split in several parts. The `General`_ part should allow 22 | you to start with the project including the install (:ref:`general-install`) 23 | and an overview (:ref:`general-overview`) which explain how to use it. 24 | The :ref:`general-archi` allows to get a better understanding of how the 25 | project works and was intended to be used. 26 | 27 | The main part of the documentation is split in the three parts of 28 | bip: :ref:`index-base` 29 | containing the basic interfaces, the :ref:`index-hexrays` for manipulating 30 | hexrays functions and the :ref:`index-gui` containing interface with the 31 | graphics and explaining how to developed plugins. This is mainly 32 | autodocumentation of bip objects with precisions about usage and potentially 33 | internals when necessary. 34 | 35 | General 36 | ======= 37 | 38 | .. toctree:: 39 | :maxdepth: 3 40 | 41 | general/install 42 | general/overview 43 | general/archi 44 | general/contribution 45 | general/changelog 46 | 47 | .. _index-base: 48 | 49 | Base interface (``bip.base``) 50 | ============================= 51 | 52 | This regroup the part about the base interface on top of the IDA basic API. 53 | All classes in this part are regroup in the ``bip.base`` module. 54 | 55 | .. toctree:: 56 | :maxdepth: 2 57 | 58 | base/elt 59 | base/instr 60 | base/data 61 | base/func 62 | base/xref 63 | base/struct 64 | base/enum 65 | base/type 66 | base/bipidb 67 | base/bipida 68 | 69 | .. _index-hexrays: 70 | 71 | Hexrays interface (``bip.hexrays``) 72 | =================================== 73 | 74 | This regroup the interface on top of the IDA Hexrays API, in particular it 75 | allows to visit the AST generated for the functions. This module will be 76 | useful only if the decompiler for the binary exist and is installed. 77 | 78 | .. toctree:: 79 | :maxdepth: 2 80 | 81 | hexrays/cfunc 82 | hexrays/lvar 83 | hexrays/astnodes 84 | hexrays/cnode 85 | hexrays/visit_hx 86 | 87 | .. _index-gui: 88 | 89 | GUI & Plugins interface (``bip.gui``) 90 | ===================================== 91 | 92 | This part regroup all the functions and classes made for interfacing with the 93 | UI and events of IDA. The most important part of this module is probably the 94 | :class:`BipPlugin` which allow to create plugins and to define actions in IDA. 95 | While bip can be used in normal IDA plugin and scripts, the :class:`BipPlugin` 96 | is the central element for interfacing with the GUI using bip. 97 | 98 | .. toctree:: 99 | :maxdepth: 2 100 | 101 | gui/plugin 102 | gui/plgmanager 103 | gui/activity 104 | gui/userselect 105 | 106 | Indices and tables 107 | ================== 108 | 109 | * :ref:`genindex` 110 | * :ref:`modindex` 111 | * :ref:`search` 112 | 113 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=build 12 | set SPHINXPROJ=Bip 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 20 | echo.installed, then set the SPHINXBUILD environment variable to point 21 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 22 | echo.may add the Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /install.py: -------------------------------------------------------------------------------- 1 | #! python 2 | 3 | import os 4 | import sys 5 | import shutil 6 | import argparse 7 | from distutils.dir_util import copy_tree 8 | 9 | 10 | def install_generic(dest): 11 | """ 12 | Method for installing Bip on Windows, this method do not install any 13 | plugins. This method will copy the bip folder and the plugin loader 14 | to their destination. Calling this method will delete previous version 15 | of Bip. 16 | 17 | :param str dest: The destination folder in which to install Bip. 18 | :return: True if the installation succeeded, False otherwise. 19 | """ 20 | # Destination folders 21 | ida_plg = os.path.join(dest, "plugins") # ida folder for plugins 22 | ida_bipdst = os.path.join(ida_plg, "bip") # dest folder for bip 23 | ida_bipplg = os.path.join(ida_plg, "bipplugin") # folder for bip plugins 24 | ida_bipplginit = os.path.join(ida_bipplg, "__init__.py") # init file for bip plugins 25 | # Source folders 26 | current_dir = os.path.dirname(os.path.realpath(__file__)) 27 | bip_dir = os.path.join(current_dir, "bip") 28 | bip_ldr = os.path.join(current_dir, "install", "idabip_loader.py") 29 | # check folders exist and create/delete them if necessary 30 | if not os.path.isdir(dest): 31 | print("{} path do not seems to exist, is IDA installed ?".format(dest)) 32 | print("Aborting installation") 33 | return False 34 | if os.path.exists(ida_plg) and not os.path.isdir(ida_plg): 35 | print("{} path exist but is not a directory".format(ida_plg)) 36 | print("Aborting installation") 37 | return False 38 | elif not os.path.exists(ida_plg): 39 | os.mkdir(ida_plg) 40 | if os.path.exists(ida_bipplg) and not os.path.isdir(ida_bipplg): 41 | print("{} path exist but is not a directory".format(ida_bipplg)) 42 | print("Aborting installation") 43 | return False 44 | elif not os.path.exists(ida_bipplg): 45 | os.mkdir(ida_bipplg) 46 | if os.path.exists(ida_bipdst): 47 | shutil.rmtree(ida_bipdst) 48 | # copy the bip folder in plugin directory 49 | shutil.copytree(bip_dir, ida_bipdst) 50 | # copy bip plugin loader in ida directory 51 | shutil.copy(bip_ldr, ida_plg) 52 | # create __init__.py in bipplugin folder 53 | if not os.path.exists(ida_bipplginit): 54 | with open(ida_bipplginit, 'w'): pass 55 | return True 56 | 57 | 58 | 59 | def install(dest=None): 60 | """ 61 | This method will install bip at the destination folder. If a 62 | destination folder is not provided, this will take the default IDA 63 | folder: ``%APPDATA%\Hex-Rays\IDA Pro\`` for Windows and 64 | ``$HOME/.idapro`` for Linux and MacOSX. 65 | 66 | :param str dest: The destination folder in which to install Bip. 67 | """ 68 | if dest is None: 69 | if sys.platform in ("linux", "linux2", "darwin"): 70 | dest = os.path.join(os.getenv('HOME'), '.idapro') 71 | elif sys.platform == "win32": 72 | dest = os.path.join(os.getenv('APPDATA'), 'Hex-Rays', 'IDA Pro') 73 | else: 74 | print("Unknwown OS do not know where to install") 75 | return 76 | print("Launching Bip install") 77 | if not install_generic(dest): 78 | print("Unable to install Bip") 79 | else: 80 | print("Bip has been succesfully installed") 81 | 82 | def main(): 83 | parser = argparse.ArgumentParser() 84 | parser.add_argument('--dest', type=str, default=None, 85 | help='Destination folder where to install Bip') 86 | args = parser.parse_args() 87 | install(dest=args.dest) 88 | 89 | if __name__ == "__main__": 90 | # execute only if run as a script 91 | main() 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /install/idabip_loader.py: -------------------------------------------------------------------------------- 1 | 2 | # import everything needed in the plugin manager 3 | from bip.gui import get_plugin_manager 4 | 5 | 6 | def PLUGIN_ENTRY(): 7 | return get_plugin_manager() 8 | -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/test/__init__.py -------------------------------------------------------------------------------- /test/launch_test.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import sys 3 | 4 | ## Setup Python3/IDA for pytest 5 | 6 | if sys.version_info[0] == 3: 7 | import io, tempfile 8 | # IDA replace sys.__stderr__ by None when in python 3 9 | sys.__stderr__ = io.TextIOWrapper(tempfile.TemporaryFile()) 10 | 11 | 12 | ## Base 13 | pytest.main([r"test_bipidb.py", "--capture=sys"]) 14 | pytest.main([r"test_bipelt.py", "--capture=sys"]) 15 | pytest.main([r"test_bipinstr.py", "--capture=sys"]) 16 | pytest.main([r"test_enum.py", "--capture=sys"]) 17 | pytest.main([r"test_bipfunc.py", "--capture=sys"]) 18 | pytest.main([r"test_bipstruct.py", "--capture=sys"]) 19 | pytest.main([r"test_bipblock.py", "--capture=sys"]) 20 | pytest.main([r"test_bipdata.py", "--capture=sys"]) 21 | pytest.main([r"test_biptype.py", "--capture=sys"]) 22 | pytest.main([r"test_bipxref.py", "--capture=sys"]) 23 | pytest.main([r"test_bipoperand.py", "--capture=sys"]) 24 | 25 | ## Gui 26 | pytest.main([r"test_bipactivity.py", "--capture=sys"]) 27 | pytest.main([r"test_menutb.py", "--capture=sys"]) 28 | pytest.main([r"test_bipaction.py", "--capture=sys"]) 29 | pytest.main([r"test_bipplugin.py", "--capture=sys"]) 30 | pytest.main([r"test_bipuserselect.py", "--capture=sys"]) 31 | 32 | ## Hexrays 33 | pytest.main([r"test_hxcfunc.py", "--capture=sys"]) 34 | pytest.main([r"test_hxlvar.py", "--capture=sys"]) 35 | pytest.main([r"test_astnode.py", "--capture=sys"]) 36 | 37 | ## Clean Python3/IDA for pytest 38 | 39 | if sys.version_info[0] == 3: 40 | sys.__stderr__ = None 41 | 42 | 43 | -------------------------------------------------------------------------------- /test/ntdll.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/test/ntdll.dll -------------------------------------------------------------------------------- /test/ntdll.dll.i64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synacktiv/bip/901adc4ee368cd02666410099e9382b068f7ae68/test/ntdll.dll.i64 -------------------------------------------------------------------------------- /test/test_astnode.py: -------------------------------------------------------------------------------- 1 | from bip import * 2 | 3 | import idc 4 | 5 | import pytest 6 | 7 | """ 8 | Test for all classes used for representing ast nodes are tested by this 9 | file, this is also used for testing the visitors. 10 | 11 | Are tested in this file the following: 12 | 13 | * :class:`AbstractCItem` from ``bip/hexrays/astnode.py`` 14 | * :class:`CNode`, :class:`CNodeExpr` and :class:`CNodeStmt` from 15 | ``bip/hexrays/cnode.py`` 16 | * :class:`HxCItem`, :class:`HxCExpr` and :class:`HxCStmt` from 17 | ``bip/hexrays/hx_citem.py`` 18 | * classes in ``bip/hexrays/hx_cexpr.py`` and ``bip/hexrays/hx_cstmt.py`` 19 | and their equivalent dynamoically create by ``bip/hexrays/cnode.py`` 20 | * visitors functions in ``bip/hexrays/hx_visitor.py`` and 21 | ``bip/hexrays/cnode_visitor.py`` (indirectly). 22 | 23 | This also use the function from ``test/genst_hxast.py`` for performing 24 | test on all nodes through visitors. 25 | 26 | The function starting by ``gentst_`` are made to be able to run on which 27 | ever node which inherit from this class and check generic properties which 28 | should be valid for all node. Those are use for allowing to get more test 29 | executed when using the visitors. 30 | """ 31 | 32 | from genst_hxast import * 33 | 34 | 35 | def test_bipabstractcitem00(): 36 | ## fix abstract citem test, made on the root_node 37 | hxf = HxCFunc.from_addr(0x01800D2FF0) 38 | aci = hxf.root_node 39 | gentst_abstractcitem(aci) # generic test for all abstractcitem 40 | # base 41 | #assert aci.ea == 0x1800D300B # first instruction after the header 42 | assert aci.is_expr == False 43 | assert aci.is_statement == True 44 | assert aci._ctype == HxCType.CIT_BLOCK 45 | # equality 46 | assert id(aci) != id(hxf.root_node) 47 | assert aci == hxf.root_node 48 | assert aci != hxf.root_node.stmt_children[0] 49 | assert aci.__eq__(0x10) == NotImplemented 50 | assert aci.__ne__(0x10) == NotImplemented 51 | assert aci != 0x10 52 | 53 | def test_bipcnode00(): 54 | ## fix CNode, CNodeExpr and CNodeStmt test, made from the root_node 55 | hxf = HxCFunc.from_addr(0x01800D2FF0) 56 | cn = hxf.root_node 57 | assert isinstance(cn, CNodeStmtBlock) # root node is always a block 58 | assert cn.is_statement 59 | assert not cn.is_expr 60 | gentst_cnode(cn) 61 | gentst_cnodestmt(cn) 62 | cnc = cn.stmt_children[0] # first child, this should be a CNodeStmtExpr 63 | assert isinstance(cnc, CNodeStmtExpr) 64 | assert cnc.is_statement 65 | assert not cnc.is_expr 66 | gentst_cnode(cnc) 67 | gentst_cnodestmt(cnc) 68 | cna = cnc.value # first asg 69 | assert isinstance(cna, CNodeExprAsg) 70 | assert cna.is_expr 71 | assert not cna.is_statement 72 | gentst_cnodeexpr(cna) 73 | # base 74 | #assert cn.closest_ea == 0x1800D300B 75 | # access 76 | assert cn.has_parent == False 77 | assert cnc.has_parent == True 78 | with pytest.raises(RuntimeError): cn.parent 79 | assert cnc.parent == cn 80 | assert cn.hxcfunc == hxf 81 | # comment 82 | assert cna.comment is None 83 | cna.comment = "cmt4test" 84 | assert cna.comment == "cmt4test" 85 | # cnodeExpr 86 | assert len(cna.ops) == 2 87 | assert isinstance(cna.find_final_left_node(), CNodeExprVar) 88 | # cnodeStmt 89 | assert len(cn.stmt_children) != 0 90 | assert len(cnc.stmt_children) == 0 91 | assert len(cn.expr_children) == 0 92 | assert len(cnc.expr_children) == 1 93 | hxf2 = HxCFunc.from_addr(0x0180002524) 94 | assert isinstance(hxf2.get_cnode_label(6), CNode) 95 | assert hxf2.get_cnode_label(42) is None 96 | cnl = hxf2.cnodes_with_label 97 | assert isinstance(cnl, list) 98 | for cn in cnl: 99 | assert isinstance(cn, CNode) 100 | assert cn.has_label == True 101 | 102 | 103 | def test_biphxcitem00(): 104 | ## fix HxCItem test, just apply generic as most is the same as in the test_bipcnode00 105 | hxf = HxCFunc.from_addr(0x01800D2FF0) 106 | hi = hxf.hx_root_stmt 107 | gentst_hxcstmt(hi) 108 | hic = hi.stmt_children[0] # first child, this should be a CNodeStmtExpr 109 | assert isinstance(hic, HxCStmtExpr) 110 | gentst_hxcstmt(hic) 111 | hia = hic.value # first asg 112 | assert isinstance(hia, HxCExprAsg) 113 | gentst_hxcexpr(hia) 114 | hxf2 = HxCFunc.from_addr(0x0180002524) 115 | assert isinstance(hxf2.hx_get_label(6), HxCItem) 116 | 117 | def test_biphxvisitor00(): 118 | # test for the HxCItem visitors 119 | hxf = HxCFunc.from_addr(0x01800D2FF0) 120 | hxf.hx_visit_expr(genst_all) 121 | hxf.hx_visit_list_expr([HxCExprCall], genst_all) 122 | hxf.hx_visit_stmt(genst_all) 123 | hxf.hx_visit_list_stmt([HxCStmtExpr], genst_all) 124 | hxf.hx_visit_all(genst_all) 125 | hxf.hx_visit_list_all([HxCExprCall, HxCStmtExpr], genst_all) 126 | 127 | def test_bipcnodevisitor00(): 128 | # Visitor for the cnode, as visitor functions in HxCFunc are wrapper on top 129 | # of the CNode functions this is considered enough. Internally those 130 | # use the functions in cnode_visitor.py 131 | hxf = HxCFunc.from_addr(0x01800D2FF0) 132 | hxf.visit_cnode(genst_all) 133 | def _intern_testfilter(cn): 134 | assert isinstance(cn, (CNodeExprCall, CNodeStmtExpr)) 135 | genst_all(cn) 136 | hxf.visit_cnode_filterlist(_intern_testfilter, [CNodeExprCall, CNodeStmtExpr]) 137 | hxf = HxCFunc.from_addr(0x0180002524) 138 | hxf.visit_cnode(genst_all) 139 | ln = hxf.get_cnode_filter_type([CNodeStmtReturn]) 140 | for cnr in ln: 141 | cn = cnr.value 142 | assert isinstance(cn, CNodeExpr) 143 | assert len(cn.get_cnode_filter(lambda x: True)) <= 8 # 8 should be more than sufficient 144 | hxf = HxCFunc.from_addr(0x0180078F20) 145 | def _intern_testfilter2(cn): # return the call to an Helper function 146 | return isinstance(cn, CNodeExprCall) and isinstance(cn.caller, CNodeExprHelper) 147 | ln = hxf.get_cnode_filter(_intern_testfilter2) 148 | assert isinstance(ln, list) 149 | assert len(ln) == 1 150 | assert isinstance(ln[0], CNodeExprCall) and isinstance(ln[0].caller, CNodeExprHelper) 151 | ln = hxf.get_cnode_filter_type([CNodeExprHelper]) 152 | assert isinstance(ln, list) 153 | assert len(ln) == 1 154 | assert isinstance(ln[0], CNodeExprHelper) 155 | hxf = HxCFunc.from_addr(0x018009BF50) 156 | hxf.visit_cnode(genst_all) 157 | 158 | 159 | -------------------------------------------------------------------------------- /test/test_bipaction.py: -------------------------------------------------------------------------------- 1 | from bip.gui import * 2 | 3 | import pytest 4 | 5 | """ 6 | Test for class :class:`BipAction` in ``bip/gui/actions.py``. 7 | Only few test here because test with user actions are more complex. 8 | """ 9 | 10 | def test_bipaction00(): 11 | # BipAction 12 | ba = BipAction("test") 13 | assert isinstance(ba, BipAction) 14 | assert isinstance(ba, BipActivity) 15 | with pytest.raises(RuntimeError): ba.handler() 16 | with pytest.raises(RuntimeError): ba() 17 | assert ba._name == "test" # TODO: this is an internal property 18 | assert ba.is_register == False 19 | ba.register() 20 | assert ba.is_register == True 21 | ba2 = BipAction("test") 22 | ba2.register() 23 | assert ba2.is_register == False 24 | ba.unregister() 25 | assert ba.is_register == False 26 | ba2.register() 27 | assert ba2.is_register == True 28 | ba3 = BipAction("test2", label="test") # diff name, same label 29 | ba3.register() 30 | assert ba3.is_register == True 31 | ba2.unregister() 32 | assert ba2.is_register == False 33 | ba3.unregister() 34 | assert ba3.is_register == False 35 | 36 | def test_bipaction01(): 37 | # BipAction handler 38 | ta = BipAction("test2", handler=lambda act: 2) 39 | assert ta.handler() == 2 40 | assert ta() == 2 41 | ta = BipAction("test3", handler=lambda act: act) 42 | assert ta() == ta 43 | def f(act): 44 | act.test = 2 45 | ta = BipAction("test4", handler=f) 46 | ta() 47 | assert ta.test == 2 48 | 49 | def test_bipaction02(): 50 | # BipAction menu 51 | ta = BipAction("testm0", handler=lambda *args: 2) 52 | ta.register() 53 | assert ta.is_register == True 54 | assert ta.attach_to_menu("Edit/Plugins/") == True 55 | ta2 = BipAction("testm1", handler=lambda *args: 3, path_menu="Edit/Plugins/") 56 | ta2.register() 57 | assert ta2.is_register == True 58 | ta.unregister() 59 | ta2.unregister() 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /test/test_bipactivity.py: -------------------------------------------------------------------------------- 1 | from bip.gui import * 2 | 3 | import pytest 4 | 5 | """ 6 | Test for classes :class:`BipActivity` and :class:`BipActivityContainer` 7 | in ``bip/gui/activity.py``. 8 | """ 9 | 10 | def test_bipactivity00(): 11 | # BipActivity 12 | ba = BipActivity() 13 | assert ba.plugin is None 14 | with pytest.raises(RuntimeError): ba() 15 | with pytest.raises(RuntimeError): ba.register() 16 | with pytest.raises(RuntimeError): ba.unregister() 17 | with pytest.raises(RuntimeError): ba.handler() 18 | # BipActivity child basic 19 | class TestBA(BipActivity): 20 | def register(self): 21 | return 1 22 | def unregister(self): 23 | return 2 24 | def handler(self, a, b): 25 | return a + b 26 | tba = TestBA() 27 | assert tba.plugin is None 28 | assert tba(2, 3) == 5 29 | assert tba.handler(2, 3) == 5 30 | assert tba.register() == 1 31 | assert tba.unregister() == 2 32 | 33 | # TODO: test link BipActivity and plugins 34 | 35 | 36 | def test_bipactivitycontainer00(): 37 | # base 38 | def f(plg): 39 | return 3 40 | bac = BipActivityContainer(f) 41 | assert bac.plugin is None 42 | assert bac.get_original_method() == f 43 | assert len(bac) == 0 44 | assert bac.handler() == 3 45 | assert bac() == 3 46 | 47 | def test_bipactivitycontainer01(): 48 | # with activity 49 | def f(plg): 50 | return 3 51 | class TestBA(BipActivity): 52 | def register(self): 53 | self.is_register = True 54 | def unregister(self): 55 | self.is_register = False 56 | bac = BipActivityContainer(f) 57 | ta0 = TestBA() 58 | ta1 = TestBA() 59 | bac.add_activity(ta0) 60 | bac.add_activity(ta1) 61 | assert len(bac) == 2 62 | bac.plugin = 3 63 | assert bac.plugin == 3 64 | assert ta0.plugin == 3 65 | assert ta1.plugin == 3 66 | bac.register() 67 | assert ta0.is_register 68 | assert ta1.is_register 69 | bac.unregister() 70 | assert ta0.is_register == False 71 | assert ta1.is_register == False 72 | 73 | def test_bipactivitycontainer02(): 74 | # get_container 75 | def f(plg): 76 | return 3 77 | bac = BipActivityContainer.get_container(f) 78 | assert isinstance(bac, BipActivityContainer) 79 | assert isinstance(BipActivityContainer.get_container(bac), BipActivityContainer) 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /test/test_bipblock.py: -------------------------------------------------------------------------------- 1 | from bip.base import * 2 | 3 | import pytest 4 | 5 | """ 6 | Test for class :class:`BipBlock` in ``bip/base/bipblock.py``. 7 | """ 8 | 9 | 10 | 11 | def test_bipblock00(): 12 | # base 13 | assert BipBlock(0x0180099990).ea == BipFunction(0x0180099990).ea 14 | assert BipBlock(0x0180099990).ea == BipBlock(0x0180099992).ea 15 | assert BipBlock(0x0180099990).end == 0x01800999DC 16 | with pytest.raises(TypeError): BipBlock("AString") 17 | with pytest.raises(ValueError): BipBlock(0x10) # invalid addr 18 | assert str(BipBlock(0x0180099990)) == 'BipBlock: 0x180099990 (from Func: RtlRaiseStatus (0x180099990))' 19 | assert isinstance(BipFunction(0x0180099990).blocks[0], BipBlock) == True 20 | assert BipFunction(0x0180099990).blocks[0].ea == 0x180099990 21 | 22 | def test_bipblock01(): 23 | # Type & info 24 | assert BipBlock(0x0180099990).type == BipBlockType.FCB_NORMAL 25 | assert BipBlock(0x0180099990).is_ret == False 26 | assert BipBlock(0x0180099990).is_noret == False 27 | assert BipBlock(0x0180099990).is_external == False 28 | assert BipBlock(0x01800999F0).type == BipBlockType.FCB_NORET 29 | assert BipBlock(0x01800999F0).is_ret == False 30 | assert BipBlock(0x01800999F0).is_noret == True 31 | assert BipBlock(0x01800999F0).is_external == False 32 | 33 | def test_bipblock02(): 34 | # control flow 35 | assert len(BipBlock(0x0180099990).succ) == 2 36 | ss = BipBlock(0x0180099990).succ 37 | assert isinstance(ss[0], BipBlock) 38 | assert ss[0].ea == 0x01800999DC 39 | assert ss[1].ea == 0x01800999F0 40 | b = BipBlock(0x0180099990) 41 | ss = b.succ 42 | i = 0 43 | for bb in b.succ_iter: 44 | assert ss[i].ea == bb.ea 45 | i += 1 46 | assert len(BipBlock(0x01800999E4).succ) == 1 47 | assert len(BipBlock(0x01800999F0).succ) == 0 48 | assert len(BipBlock(0x01800999F0).pred) == 2 49 | assert len(BipBlock(0x0180099990).pred) == 0 50 | b = BipBlock(0x01800999F0) 51 | ss = b.pred 52 | i = 0 53 | for bb in b.pred_iter: 54 | assert ss[i].ea == bb.ea 55 | i += 1 56 | 57 | def test_bipblock03(): 58 | # func, instr, items, bytes 59 | assert isinstance(BipBlock(0x01800999F0).func, BipFunction) 60 | assert BipBlock(0x01800999F0).func.ea == 0x0180099990 61 | assert len(BipBlock(0x01800999DC).items) == 4 62 | for i in BipBlock(0x01800999DC).items: 63 | assert i.__class__ == BipInstr 64 | assert len(BipBlock(0x01800999DC).instr) == 4 65 | for i in BipBlock(0x01800999DC).instr: 66 | assert i.__class__ == BipInstr 67 | assert BipBlock(0x01800999DC).instr[-1].ea == 0x01800999EE 68 | assert BipBlock(0x01800999DC).bytes == [0x48, 0x8D, 0x94, 0x24, 0xC0, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x4C, 0x24, 0x20, 0xE8, 0xD2, 0xCE, 0xF6, 0xFF, 0x84, 0xDB] 69 | 70 | 71 | def test_bipblock04(): 72 | # color 73 | assert BipBlock(0x0180099990).color == 0xffffffff 74 | BipBlock(0x0180099990).color = 0xaabbcc 75 | assert BipBlock(0x0180099990).color == 0xaabbcc 76 | BipBlock(0x0180099990).color = None 77 | assert BipBlock(0x0180099990).color == 0xffffffff 78 | BipBlock(0x0180099990).color = 0xaabbcc 79 | assert BipBlock(0x0180099990).color == 0xaabbcc 80 | del BipBlock(0x0180099990).color 81 | assert BipBlock(0x0180099990).color == 0xffffffff 82 | with pytest.raises(TypeError): BipBlock(0x0180099990).color = "abcd" 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /test/test_bipidb.py: -------------------------------------------------------------------------------- 1 | from bip import * 2 | 3 | import pytest 4 | 5 | """ 6 | Test for class :class:`BipIdb` in ``bip/base/bipidb.py``. 7 | """ 8 | 9 | 10 | def test_bipidb00(): 11 | assert BipIdb.ptr_size() == 64 12 | assert BipIdb.min_ea() == 0x180001000 13 | assert min_ea() == 0x180001000 14 | assert BipIdb.max_ea() == 0x180174000 15 | assert max_ea() == 0x180174000 16 | assert BipIdb.image_base() == 0x180000000 17 | assert BipIdb.relea(0x0180110018) == 0x110018 18 | assert BipIdb.absea(0x110018) == 0x180110018 19 | BipIdb.current_addr() # check for no exception/API changes 20 | Here() 21 | 22 | 23 | -------------------------------------------------------------------------------- /test/test_bipinstr.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from bip.base import * 4 | 5 | import idc 6 | import ida_bytes 7 | 8 | import pytest 9 | 10 | """ 11 | Test for classes in ``bip/base/instr.py``. This allows to test the 12 | basic :class:`BipInstr` features. 13 | """ 14 | 15 | 16 | def test_bipinstr00(): 17 | # constructor, ea, mnem, str, __str__ 18 | assert BipInstr(0x01800D325A).ea == 0x01800D325A 19 | with pytest.raises(BipError): 20 | BipInstr(0x0180120800) 21 | assert GetElt(0x01800D325A).__class__ == BipInstr 22 | assert BipInstr(0x01800D325A).mnem == "add" 23 | assert BipInstr(0x01800D325A).mnem != "xadd" 24 | assert BipInstr(0x01800D325A).str == 'add rsp, 60h' 25 | assert str(BipInstr(0x01800D325A)) == 'BipInstr: 0x1800D325A (add rsp, 60h)' 26 | 27 | def test_bipinstr01(): 28 | # class method 29 | i = BipInstr.make(0x0180117004) 30 | assert isinstance(i, BipInstr) 31 | assert i.ea == 0x0180117004 32 | assert isinstance(BipInstr.make(0x01800D325A), BipInstr) 33 | with pytest.raises(RuntimeError): BipInstr.make(0x018011700A) 34 | 35 | def test_bipinstr02(): 36 | # operands 37 | assert BipInstr(0x01800D325A).countOperand == 2 38 | assert len(BipInstr(0x01800D325A).ops) == 2 39 | assert BipInstr(0x01800D3269).countOperand == 0 40 | with pytest.raises(ValueError): 41 | BipInstr(0x01800D3269).op(0) 42 | assert BipInstr(0x01800D3268).countOperand == 1 43 | with pytest.raises(ValueError): 44 | BipInstr(0x01800D3269).op(1) 45 | assert BipInstr(0x01800D3268).op(0).str == 'rbx' 46 | assert BipInstr(0x01800D3268).ops[0].str == 'rbx' 47 | 48 | 49 | def test_bipinstr03(): 50 | # flags 51 | assert BipInstr(0x01800D325A).has_prev_instr == True 52 | assert BipInstr(0x01800D2FF0).has_prev_instr == False 53 | assert BipInstr(0x01800D326A).has_prev_instr == False 54 | assert BipInstr(0x01800D2FF0).is_call == False 55 | assert BipInstr(0x01800D327F).is_call == False 56 | assert BipInstr(0x01800D3011).is_call == True 57 | assert BipInstr(0x01800D31E8).is_call == False 58 | 59 | assert BipInstr(0x01800D324E).is_ret == False 60 | assert BipInstr(0x01800D3269).is_ret == True 61 | 62 | assert BipInstr(0x01800D3269).is_indirect_jmp == False 63 | assert BipInstr(0x01800D324E).is_indirect_jmp == False 64 | assert BipInstr(0x01800D323A).is_indirect_jmp == False 65 | assert BipInstr(0x01800D3240).is_indirect_jmp == False 66 | assert BipInstr(0x01800FF5D7).is_indirect_jmp == True 67 | 68 | assert BipInstr(0x01800D3269).is_end_block == True 69 | assert BipInstr(0x01800D324E).is_end_block == True 70 | assert BipInstr(0x01800D324B).is_end_block == False 71 | assert BipInstr(0x01800D3240).is_end_block == True 72 | assert BipInstr(0x01800D3253).is_end_block == True 73 | assert BipInstr(0x01800D322E).is_end_block == False 74 | 75 | assert BipInstr(0x01800D3269).is_end_block_call == True 76 | assert BipInstr(0x01800D324E).is_end_block_call == True 77 | assert BipInstr(0x01800D324B).is_end_block_call == False 78 | assert BipInstr(0x01800D3240).is_end_block_call == True 79 | assert BipInstr(0x01800D3253).is_end_block_call == True 80 | assert BipInstr(0x01800D322E).is_end_block_call == True 81 | 82 | assert BipInstr(0x01800D327F).is_in_func == True 83 | assert BipInstr(0x0180117004).is_in_func == False 84 | 85 | def test_bipinstr04(): 86 | # utils 87 | assert BipInstr(0x01800D325A).prev.ea == 0x01800D3253 88 | assert BipInstr(0x01800D325A).next.ea == 0x01800D325E 89 | assert BipInstr(0x01800D3269).next.ea == 0X01800D326A 90 | assert BipInstr(0x01800D327F).next is None 91 | 92 | def test_bipinstr05(): 93 | # func and block 94 | assert BipInstr(0x01800D6B33).func.ea == 0x01800D6B30 95 | assert BipInstr(0x01800D6B33).func.__class__ == BipFunction 96 | assert BipInstr(0x01800D323A).block.ea == 0x01800D3227 97 | assert BipInstr(0x01800D323A).block.__class__ == BipBlock 98 | with pytest.raises(ValueError): BipInstr(0x0180117004).func 99 | with pytest.raises(ValueError): BipInstr(0x0180117004).block 100 | 101 | def test_bipinstr06(): 102 | # control flow 103 | assert BipInstr(0x01800D325A).xOrdinaryCfNext.ea == 0x01800D325E 104 | assert [x.ea for x in BipInstr(0x01800D325A).xCfNext] == [0x01800D325E] 105 | assert [x.ea for x in BipInstr(0x01800D325A).xCfPrev] == [0x01800D3253, 0x01800D3028] 106 | assert BipInstr(0x01800D3028).xOrdinaryCfNext is None 107 | assert [x.ea for x in BipInstr(0x01800D3028).xCfNext] == [0x01800D325A] 108 | assert [x.ea for x in BipInstr(0x01800D3028).xCfPrev] == [0x01800D3023] 109 | assert [x.ea for x in BipInstr(0x01800D324E).xCfNext] == [0x01800D3253, 0x01800D35E8] 110 | assert [x.ea for x in BipInstr(0x01800D323A).xCfNext] == [0x01800D323C, 0x01800D3242] 111 | 112 | def test_bipinstr07(): 113 | # cmp and hash 114 | assert BipElt(0x01800D325A) == BipInstr(0x01800D325A) 115 | assert BipInstr(0x01800D325A) == BipInstr(0x01800D325A) 116 | assert BipInstr(0x01800D325A) > BipInstr(0x01800D3028) 117 | assert BipInstr(0x01800D3028) < BipInstr(0x01800D325A) 118 | assert len([BipInstr(0x01800D325A), BipInstr(0x01800D325A)]) == 2 119 | assert len(set([BipInstr(0x01800D325A), BipInstr(0x01800D325A)])) == 1 120 | assert len(set([BipElt(0x01800D325A), BipInstr(0x01800D325A)])) == 2 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /test/test_bipoperand.py: -------------------------------------------------------------------------------- 1 | from bip.base import * 2 | 3 | import pytest 4 | 5 | """ 6 | Test for class :class:`BipBipOperand` in ``bip/base/bipoperand.py``. 7 | """ 8 | 9 | def test_bipoperand00(): 10 | # base 11 | elt = GetElt(0x01800D324B) 12 | assert isinstance(elt.op(0), BipOperand) == True 13 | assert elt.op(0).ea == 0x1800d324b 14 | assert elt.op(0).instr == elt 15 | assert elt.op(0).opnum == 0 16 | assert elt.op(0).str == 'rcx' 17 | assert elt.op(0).type == BipOpType.REG 18 | assert elt.op(0).dtype == 7 19 | assert elt.op(0).type_info is None 20 | elt.op(0).type_info = "void *" 21 | assert isinstance(elt.op(0).type_info, BTypePtr) == True 22 | del elt.op(0).type_info 23 | assert elt.op(0).type_info is None 24 | assert elt.op(0).value == 0x1 25 | elt = GetElt(0x01800D3242) 26 | assert elt.op(1).opnum == 1 27 | assert elt.op(1).value == 0x8 28 | assert elt.op(1).dtype == 0x2 29 | assert elt.op(1).type == BipOpType.IMM 30 | assert GetElt(0x01800D3094).op(1).value == 0xc0000017 31 | 32 | def test_bipoperand01(): 33 | # test type 34 | assert GetElt(0x01800D314C).op(0).is_void == False # reg 35 | assert GetElt(0x01800D314C).op(0).is_reg == True 36 | assert GetElt(0x01800D314C).op(0).is_memref == False 37 | assert GetElt(0x01800D314C).op(0).is_imm == False 38 | assert GetElt(0x01800D314C).op(0).is_addr == False 39 | assert GetElt(0x01800D314C).op(0).is_proc_specific == False 40 | 41 | assert GetElt(0x01800D3094).op(1).is_void == False # imm 42 | assert GetElt(0x01800D3094).op(1).is_reg == False 43 | assert GetElt(0x01800D3094).op(1).is_memref == False 44 | assert GetElt(0x01800D3094).op(1).is_imm == True 45 | assert GetElt(0x01800D3094).op(1).is_addr == False 46 | assert GetElt(0x01800D3094).op(1).is_proc_specific == False 47 | 48 | assert GetElt(0x01800D314C).op(1).is_void == False # memref 49 | assert GetElt(0x01800D314C).op(1).is_reg == False 50 | assert GetElt(0x01800D314C).op(1).is_memref == True 51 | assert GetElt(0x01800D314C).op(1).is_imm == False 52 | assert GetElt(0x01800D314C).op(1).is_addr == False 53 | assert GetElt(0x01800D314C).op(1).is_proc_specific == False 54 | 55 | assert GetElt(0x01800D31DD).op(0).is_void == False # addr 56 | assert GetElt(0x01800D31DD).op(0).is_reg == False 57 | assert GetElt(0x01800D31DD).op(0).is_memref == False 58 | assert GetElt(0x01800D31DD).op(0).is_imm == False 59 | assert GetElt(0x01800D31DD).op(0).is_addr == True 60 | assert GetElt(0x01800D31DD).op(0).is_proc_specific == False 61 | 62 | # TODO: other binary for is_proc_specific 63 | 64 | # TODO: set_offset 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /test/test_bipplugin.py: -------------------------------------------------------------------------------- 1 | from bip.gui import * 2 | from bip.gui.pluginmanager import BipPluginManager 3 | 4 | import pytest 5 | import importlib 6 | import inspect 7 | import tempfile 8 | import os, sys 9 | 10 | """ 11 | Test for class :class:`BipPlugin` in ``bip/gui/plugin.py``, include 12 | also the test for the decorators and test for the 13 | :class:`BipPluginManager` from ``bip/gui/pluginmanager.py``. 14 | Only few test here because test with user actions are more complex. 15 | """ 16 | 17 | ### BipPlugin classes for test ### 18 | 19 | class Plugin4Test(BipPlugin): 20 | na = "mytestaction" 21 | myaction = BipAction(na, handler=lambda *args: 1) 22 | def __init__(self): 23 | super(Plugin4Test, self).__init__() 24 | 25 | class Plugin4Test2(BipPlugin): 26 | def __init__(self): 27 | super(Plugin4Test2, self).__init__() 28 | self.shortcounter = 0 29 | self.menucounter = 0 30 | self.bothcounter = 0 31 | 32 | @shortcut("Ctrl-H") 33 | def mytest_shortcut(self): 34 | # self is the MyPlugin object 35 | self.shortcounter += 1 36 | 37 | @menu("Edit/Plugins/") 38 | def mytest_menu(self): 39 | # self is the MyPlugin object 40 | self.menucounter += 1 41 | 42 | @shortcut("Ctrl-5") 43 | @menu("Edit/Plugins/") 44 | def mytest_both(self): 45 | self.bothcounter += 1 46 | 47 | ### BipPluginLoader ### 48 | 49 | def test_bippluginloader00(): 50 | # get_plugins_from_module 51 | mod = importlib.import_module(Plugin4Test2.__module__) 52 | assert inspect.ismodule(mod) 53 | d = BipPluginLoader.get_plugins_from_module(mod) 54 | assert isinstance(d, dict) 55 | assert d["Plugin4Test"] == Plugin4Test 56 | assert d["Plugin4Test2"] == Plugin4Test2 57 | assert "BipPlugin" not in d 58 | assert len(d) == 2 59 | 60 | def test_bippluginloader01(): 61 | # get_plg_from_files_in_module 62 | fo = tempfile.mkdtemp() 63 | modname = "plgtest" 64 | fold = os.path.join(fo, modname) 65 | os.mkdir(fold) 66 | f = open(os.path.join(fold, "__init__.py"), "w") 67 | f.close() 68 | f = open(os.path.join(fold, "test.py"), "w") 69 | f.write("from bip import *\nclass PlgTestLoader(BipPlugin):\n pass\n") 70 | f.close() 71 | f = open(os.path.join(fold, "test2.py"), "w") 72 | f.write("from bip import *\nclass PlgTestLoader2(BipPlugin):\n pass\n") 73 | f.close() 74 | sys.path.append(fo) 75 | d = BipPluginLoader.get_plg_from_files_in_module(modname) 76 | assert isinstance(d, dict) 77 | assert issubclass(d["PlgTestLoader"], BipPlugin) 78 | assert issubclass(d["PlgTestLoader2"], BipPlugin) 79 | assert "BipPlugin" not in d 80 | assert len(d) == 2 81 | sys.path.pop() 82 | 83 | ### Bip Plugin Manager ### 84 | 85 | def test_bippluginmanag00(): 86 | # Getting the bip plugin manager. 87 | bpm = get_plugin_manager() 88 | assert isinstance(bpm, BipPluginManager) == True 89 | assert bpm._is_loaded == True 90 | assert bpm.is_ready == True 91 | bpm2 = get_plugin_manager() 92 | assert bpm == bpm2 93 | 94 | def test_bippluginmanag01(): 95 | # plugin access 96 | bpm = get_plugin_manager() 97 | bpm.addld_plugin("Plugin4Test", Plugin4Test) 98 | tp = bpm.get_plugin(Plugin4Test) 99 | assert isinstance(tp, Plugin4Test) 100 | assert tp == bpm.get_plugin(Plugin4Test) 101 | assert tp == bpm.get_plugin("Plugin4Test") 102 | assert tp == bpm[Plugin4Test] 103 | assert tp == bpm["Plugin4Test"] 104 | assert Plugin4Test in bpm 105 | assert "Plugin4Test" in bpm 106 | assert ("DoNotExist" in bpm) == False 107 | assert bpm.get_plugin("DoNotExist") is None 108 | with pytest.raises(KeyError): bpm["DoNotExist"] 109 | with pytest.raises(RuntimeError): bpm.addld_plugin("Plugin4Test", Plugin4Test) 110 | bpm.addld_plugin("Plugin4Test", Plugin4Test, ifneeded=True) 111 | 112 | ### Bip Plugin ### 113 | 114 | def test_bipplugin00(): 115 | # base bip plugin 116 | bp = BipPlugin() 117 | assert isinstance(bp, BipPlugin) 118 | assert bp._activities == {} 119 | assert BipPlugin.to_load() == True 120 | class TestActivities(object): # Fake object which match BipActivity 121 | def __init__(self): 122 | self.plugin = None 123 | self.is_register = False 124 | def register(self): 125 | self.is_register = True 126 | ta = TestActivities() 127 | assert ta.plugin is None 128 | assert ta.is_register == False 129 | bp._activities["test"] = ta 130 | bp.load() 131 | assert ta.is_register == True 132 | 133 | 134 | def test_bipplugin01(): 135 | # Activities link 136 | bpm = get_plugin_manager() 137 | na = "mytestaction" 138 | tp = bpm.get_plugin(Plugin4Test) #Plugin4Test() 139 | assert tp.myaction.plugin == tp 140 | assert tp.myaction.is_register == True # automatically loaded by the pluginmanager 141 | tp.myaction.unregister() 142 | assert tp.myaction.is_register == False 143 | 144 | def test_bipplugin02(): 145 | # Activities link 146 | bpm = get_plugin_manager() 147 | bpm.addld_plugin("Plugin4Test2", Plugin4Test2) 148 | tp = bpm.get_plugin(Plugin4Test2) 149 | assert isinstance(tp.mytest_shortcut, BipActivityContainer) == True 150 | assert isinstance(tp.mytest_menu, BipActivityContainer) == True 151 | assert isinstance(tp.mytest_both, BipActivityContainer) == True 152 | assert tp.mytest_shortcut.plugin == tp 153 | assert tp.mytest_menu.plugin == tp 154 | assert tp.mytest_both.plugin == tp 155 | assert tp.mytest_shortcut._activities[0].is_register == True 156 | assert tp.mytest_menu._activities[0].is_register == True 157 | assert tp.mytest_both._activities[0].is_register == True 158 | assert tp.mytest_both._activities[1].is_register == True 159 | assert len(tp.mytest_shortcut) == 1 160 | assert len(tp.mytest_menu) == 1 161 | assert len(tp.mytest_both) == 2 162 | assert tp.shortcounter == 0 163 | assert tp.menucounter == 0 164 | assert tp.bothcounter == 0 165 | tp.mytest_shortcut() 166 | assert tp.shortcounter == 1 167 | tp.mytest_menu() 168 | assert tp.menucounter == 1 169 | tp.mytest_both() 170 | assert tp.bothcounter == 1 171 | tp.mytest_shortcut.unregister() 172 | tp.mytest_menu.unregister() 173 | tp.mytest_both.unregister() 174 | assert tp.mytest_shortcut._activities[0].is_register == False 175 | assert tp.mytest_menu._activities[0].is_register == False 176 | assert tp.mytest_both._activities[0].is_register == False 177 | assert tp.mytest_both._activities[1].is_register == False 178 | 179 | 180 | -------------------------------------------------------------------------------- /test/test_bipuserselect.py: -------------------------------------------------------------------------------- 1 | from bip.gui import * 2 | 3 | import pytest 4 | 5 | """ 6 | Test for class :class:`BipUserSelect` in ``bip/gui/userselect.py``. 7 | """ 8 | 9 | def test_bipuserselect00(): 10 | # staticmethod 11 | # as complicated to test only call them for checking of API problems 12 | BipUserSelect.get_curr_highlighted_str() 13 | BipUserSelect.get_curr_highlighted_int() 14 | 15 | -------------------------------------------------------------------------------- /test/test_bipxref.py: -------------------------------------------------------------------------------- 1 | from bip.base import * 2 | 3 | import pytest 4 | 5 | """ 6 | Test for class :class:`BipXref` in ``bip/base/bipxref.py``. 7 | """ 8 | 9 | def test_bipxref00(): 10 | # base 11 | ins = GetElt(0x01800D3138) # recuperate from an instruction 12 | assert len(ins.xFrom) == 1 13 | assert isinstance(ins, BipInstr) == True 14 | xf = ins.xFrom[0] 15 | assert isinstance(xf, BipXref) == True 16 | assert xf.is_userdef == False 17 | assert xf.src_ea == 0x1800d3138 18 | assert xf.src.ea == 0x1800d3138 19 | assert xf.dst_ea == 0x1800d31e9 20 | assert xf.dst.ea == 0x1800d31e9 21 | assert isinstance(xf.src, BipInstr) == True 22 | assert isinstance(xf.dst, BipInstr) == True 23 | 24 | def test_bipxref01(): 25 | # code flow 26 | ins = GetElt(0x01800D3138) 27 | xf = ins.xFrom[0] 28 | assert xf.is_codepath == True 29 | assert xf.is_call == False 30 | assert xf.is_jmp == True 31 | assert xf.is_ordinaryflow == False 32 | assert xf.is_src_code == True 33 | assert xf.is_dst_code == True 34 | xf = ins.xTo[0] 35 | assert xf.is_codepath == True 36 | assert xf.is_call == False 37 | assert xf.is_jmp == False 38 | assert xf.is_ordinaryflow == True 39 | ins = GetElt(0x01800D322E) 40 | xf = ins.xFrom[1] 41 | assert xf.is_codepath == True 42 | assert xf.is_call == True 43 | assert xf.is_jmp == False 44 | assert xf.is_ordinaryflow == False 45 | ins = GetElt(0x01800D3227) # data xref 46 | xf = ins.xFrom[-1] 47 | assert xf.is_codepath == False 48 | assert xf.is_call == False 49 | assert xf.is_jmp == False 50 | assert xf.is_ordinaryflow == False 51 | assert xf.is_src_code == True 52 | assert xf.is_dst_code == False 53 | 54 | def test_bipxref02(): 55 | # data property 56 | ins = GetElt(0x01800D3138) # instr xref 57 | xf = ins.xFrom[0] 58 | assert xf.is_offset == False 59 | assert xf.is_write_access == False 60 | assert xf.is_read_access == False 61 | ins = GetElt(0x01800D3227) # data xref 62 | xf = ins.xFrom[-1] 63 | assert xf.is_offset == True 64 | assert xf.is_write_access == False 65 | assert xf.is_read_access == False 66 | ins = GetElt(0x01800D304F) 67 | xf = ins.xFrom[-1] 68 | assert xf.is_offset == False 69 | assert xf.is_write_access == False 70 | assert xf.is_read_access == True 71 | ins = GetElt(0x01800DF453) 72 | xf = ins.xFrom[-1] 73 | assert xf.is_offset == False 74 | assert xf.is_write_access == True 75 | assert xf.is_read_access == False 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /test/test_enum.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import pytest 3 | 4 | from bip.base import * 5 | 6 | import idc 7 | import ida_bytes 8 | 9 | 10 | def test_bipenum1(): 11 | # create 12 | be = BipEnum.create("testenum") 13 | assert be is not None 14 | assert isinstance(be, BipEnum) 15 | # get 16 | be2 = BipEnum.get("testenum") 17 | assert be is not None 18 | assert isinstance(be, BipEnum) 19 | # equality 20 | assert be == be2 21 | assert (be != be2) == False 22 | assert be == be._eid 23 | assert be != 0 24 | assert be != idc.BADADDR 25 | # _is_this_elt 26 | assert BipEnum._is_this_elt(be._eid) == True 27 | assert BipEnum._is_this_elt(0) == False 28 | with pytest.raises(TypeError): 29 | BipEnum._is_this_elt(None) 30 | assert BipEnum._is_this_elt(idc.BADADDR) == False 31 | assert BipEnum._is_this_elt(0x01800F1C60) == False 32 | # name 33 | assert be.name == "testenum" 34 | be.name = "testenum_newname" 35 | assert be.name == "testenum_newname" 36 | be.name = "testenum" 37 | # width 38 | assert be.width == 0 39 | be.width = 4 40 | assert be.width == 4 41 | with pytest.raises(ValueError): 42 | be.width = 5 43 | assert be.width == 4 44 | # bitfield 45 | assert be.is_bitfield == False 46 | be.is_bitfield = True 47 | assert be.is_bitfield == True 48 | be.is_bitfield = False 49 | assert be.is_bitfield == False 50 | # __str__ 51 | str(be) 52 | # comment 53 | assert be.comment is None 54 | assert be.rcomment is None 55 | be.comment = "hello" 56 | be.rcomment = "hello2" 57 | assert be.comment == "hello" 58 | assert be.rcomment == "hello2" 59 | BipEnum.delete("testenum") 60 | 61 | def test_bipenum2(): 62 | # create, get, delete 63 | be = BipEnum.create("testenum") 64 | BipEnum.delete("testenum") 65 | with pytest.raises(ValueError): 66 | BipEnum.get("testenum") 67 | be = BipEnum.create("testenum2") 68 | BipEnum.delete(be) 69 | with pytest.raises(ValueError): 70 | BipEnum.get("testenum2") 71 | be = BipEnum.create("testenum3") 72 | with pytest.raises(ValueError): 73 | be2 = BipEnum.create("testenum3") 74 | BipEnum.delete(be._eid) 75 | with pytest.raises(ValueError): 76 | BipEnum.get("testenum3") 77 | 78 | def test_bipenum3(): 79 | # creating, accessing and deleting members 80 | be = BipEnum.create("testenum") 81 | assert be.nb_members == 0 82 | be.add("testmem", 0x10) 83 | assert be.nb_members == 1 84 | bem = be.member_by_name("testmem") 85 | assert bem is not None 86 | assert isinstance(bem, BEnumMember) 87 | assert bem.name == "testmem" 88 | assert bem.value == 0x10 89 | assert bem == be["testmem"] 90 | beml = be.members_by_value(0x10) 91 | assert len(beml) == 1 92 | assert beml[0] == bem 93 | with pytest.raises(RuntimeError): 94 | be.add("testmem", 0x11) 95 | be.add("testmem2", 0x10) 96 | beml = be.members_by_value(0x10) 97 | assert len(beml) == 2 98 | assert beml[0] != beml[1] 99 | be.add("testmem3", 0x10) 100 | be.add("testmem4", 0x1) 101 | assert be.nb_members == 4 102 | be.del_member("testmem2") 103 | assert be.nb_members == 3 104 | with pytest.raises(ValueError): 105 | be.del_member("testmem2") 106 | beml = be.members_by_value(0x10) 107 | assert len(beml) == 2 108 | assert beml[0] != beml[1] 109 | assert "testmem3" in [m.name for m in beml] 110 | assert "testmem4" not in [m.name for m in beml] 111 | assert len(be.members) == 3 112 | for m in be: 113 | str(m) 114 | BipEnum.delete("testenum") 115 | 116 | def test_bipenum4(): 117 | # members 118 | be = BipEnum.create("testenum") 119 | assert be.nb_members == 0 120 | be.add("testmem", 0x10) 121 | assert be.nb_members == 1 122 | bem = be.member_by_name("testmem") 123 | bem2 = BEnumMember.get("testmem") 124 | assert bem == bem2 125 | assert bem.name == "testmem" 126 | assert bem.value == 0x10 127 | bem.name = "newname" 128 | assert bem.name == "newname" 129 | assert bem2.name == "newname" 130 | assert bem2.enum == be 131 | assert bem2.value == 0x10 132 | bem.name = "testmem" 133 | assert bem.name == "testmem" 134 | assert bem.comment is None 135 | assert bem.rcomment is None 136 | bem.comment = "hello" 137 | bem.rcomment = "test rcom" 138 | assert bem.comment == "hello" 139 | assert bem.rcomment == "test rcom" 140 | BipEnum.delete("testenum") 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /test/test_hxcfunc.py: -------------------------------------------------------------------------------- 1 | from bip.hexrays import * 2 | from bip.base import BipDecompileError, BipFunction 3 | 4 | import idc 5 | 6 | import pytest 7 | 8 | """ 9 | Test for basics in class :class:`HxCFunc` in ``bip/hexrays/hx_cfunc.py``. 10 | This do not include test for visitor, cnodes and hxitem. 11 | """ 12 | 13 | def test_biphxcfunc00(): 14 | # hxcfunc base, other and class/static methods 15 | hxf = HxCFunc.from_addr(0x01800D2FF0) 16 | assert isinstance(hxf, HxCFunc) 17 | assert hxf.ea == 0x01800D2FF0 18 | assert isinstance(BipFunction(0x01800D2FF0).hxcfunc, HxCFunc) 19 | assert hxf.ea == BipFunction(0x01800D2FF0).hxcfunc.ea 20 | hxf = HxCFunc.from_addr(0x01800D2FF7) 21 | assert isinstance(hxf, HxCFunc) 22 | assert hxf.ea == 0x01800D2FF0 23 | assert hxf.bfunc == BipFunction(0x01800D2FF0) 24 | assert isinstance(hxf.cstr, str) 25 | with pytest.raises(BipDecompileError): HxCFunc.from_addr(0x018012D400) 26 | with pytest.raises(BipDecompileError): HxCFunc.from_addr(idc.BADADDR) 27 | hxf.invalidate_cache() # just check it exist and do not raise an exception 28 | hxf = HxCFunc.from_addr(0x01800D2FF0) 29 | HxCFunc.invalidate_all_caches() # same as before 30 | 31 | def test_biphxcfunc01(): 32 | # cmp 33 | hxf = HxCFunc.from_addr(0x01800D2FF0) 34 | hxf2 = HxCFunc.from_addr(0x01800D2FF7) 35 | hxf3 = HxCFunc.from_addr(0x01800DDDA0) 36 | assert hxf == hxf2 37 | assert hxf != hxf3 38 | assert (hxf == hxf3) == False 39 | assert hxf == BipFunction(0x01800D2FF0) 40 | assert hxf != BipFunction(0x01800DDDA0) 41 | assert hxf.__eq__("test") == NotImplemented 42 | assert hxf.__ne__("test") == NotImplemented 43 | assert hxf != "test" 44 | 45 | def test_biphxcfunc02(): 46 | # comment 47 | hxf = HxCFunc.from_addr(0x01800D2FF0) 48 | assert hxf.get_cmt(0x01800D322E) is None 49 | hxf.add_cmt(0x01800D322E, "newcmt") 50 | assert hxf.get_cmt(0x01800D322E) == "newcmt" 51 | hxf.add_cmt(0x01800D322E, "newcmt2") 52 | assert hxf.get_cmt(0x01800D322E) == "newcmt2" 53 | 54 | 55 | def test_biphxcfunc03(): 56 | # lvars access 57 | hxf = HxCFunc.from_addr(0x01800D2FF0) 58 | assert isinstance(hxf.lvar_at(0), HxLvar) 59 | assert isinstance(hxf.lvars, list) 60 | count = 0 61 | for lv in hxf.lvars_iter(): 62 | assert isinstance(lv, HxLvar) 63 | lv2 = hxf.lvars[count] 64 | assert isinstance(lv2, HxLvar) 65 | assert lv == lv2 66 | count += 1 67 | assert isinstance(hxf.lvar_by_name("a1"), HxLvar) 68 | assert hxf.lvar_by_name("donotexist") is None 69 | assert isinstance(hxf.args, list) 70 | assert len(hxf.args) == 1 71 | assert isinstance(hxf.args[0], HxLvar) 72 | 73 | def test_biphxcfunc04(): 74 | # root_node and hx_root_stmt 75 | hxf = HxCFunc.from_addr(0x01800D2FF0) 76 | assert hxf.root_node is not None 77 | assert isinstance(hxf.root_node, CNodeStmtBlock) 78 | assert hxf.root_node.hxcfunc == hxf 79 | assert hxf.hx_root_stmt is not None 80 | assert isinstance(hxf.hx_root_stmt, HxCStmtBlock) 81 | 82 | 83 | -------------------------------------------------------------------------------- /test/test_hxlvar.py: -------------------------------------------------------------------------------- 1 | from bip.hexrays import * 2 | from bip.base import * 3 | 4 | import pytest 5 | 6 | """ 7 | Test for class :class:`HxLvar` in ``bip/hexrays/hx_lvar.py``. 8 | """ 9 | 10 | def test_biphxlvar00(): 11 | # base 12 | hxf = HxCFunc.from_addr(0x01800D2FF0) 13 | lv1 = hxf.lvar_at(0) 14 | lv2 = hxf.lvar_at(2) 15 | assert isinstance(lv1, HxLvar) 16 | assert lv1.name == 'a1' 17 | assert isinstance(lv2, HxLvar) 18 | assert lv2.name == 'v2' 19 | assert lv1.has_user_name == False 20 | assert lv2.has_user_name == False 21 | lv1.name = "newname" 22 | assert lv1.name == "newname" 23 | assert lv1.has_user_name == True 24 | assert lv2.has_user_name == False 25 | lv1.name = "newname" 26 | assert lv1.name == "newname" 27 | hxf.invalidate_cache() # check for the save 28 | assert lv1.name == "newname" 29 | assert lv1.has_user_name == True 30 | assert lv2.has_user_name == False 31 | lv2.name = "newname2" 32 | assert lv2.name == 'newname2' 33 | assert lv1.size == 8 34 | assert lv2.size == 8 35 | assert lv1.hxcfunc == hxf 36 | assert lv2.hxcfunc == hxf 37 | assert lv1.comment == "" 38 | assert lv2.comment == "" 39 | lv1.comment = "new comment" 40 | assert lv1.comment == "new comment" 41 | assert lv2.comment == "" 42 | lv2.comment = "new comment2" 43 | assert lv1.comment == "new comment" 44 | assert lv2.comment == "new comment2" 45 | lv1.comment = "" 46 | lv2.comment = "" 47 | assert lv1.comment == "" 48 | assert lv2.comment == "" 49 | assert isinstance(lv1.type, BipType) 50 | assert isinstance(lv2.type, BipType) 51 | assert isinstance(lv1.type, BTypeInt) 52 | assert isinstance(lv2.type, BTypePtr) 53 | assert lv1.has_user_type == False 54 | assert lv2.has_user_type == False 55 | lv1.type = BipType.from_c("__int16 *") 56 | assert isinstance(lv1.type, BTypePtr) 57 | assert lv1.size == 8 58 | lv1.type = "__int64" 59 | assert isinstance(lv1.type, BTypeInt) 60 | assert lv1.size == 8 61 | lv1.type = "char" 62 | assert isinstance(lv1.type, BTypeInt) 63 | assert lv1.size == 1 64 | assert lv1.has_user_type == True 65 | assert lv2.has_user_type == False 66 | with pytest.raises(TypeError): lv1.type = 8 67 | with pytest.raises(RuntimeError): lv1.type = "void" 68 | 69 | def test_biphxlvar01(): 70 | # flags 71 | hxf = HxCFunc.from_addr(0x01800D2FF0) 72 | lv1 = hxf.lvar_at(0) 73 | lv2 = hxf.lvar_at(2) 74 | lvstck = hxf.lvar_at(13) 75 | assert lv1.is_arg == True 76 | assert lv2.is_arg == False 77 | assert lvstck.is_arg == False 78 | assert lv1.is_reg == True 79 | assert lv2.is_reg == True 80 | assert lvstck.is_reg == False 81 | assert lv1.is_stk == False 82 | assert lv2.is_stk == False 83 | assert lvstck.is_stk == True 84 | assert lvstck.has_user_name == False # also tested in 00 85 | assert lvstck.has_user_type == False # also tested in 00 86 | 87 | def test_biphxlvar02(): 88 | # cmp 89 | hxf = HxCFunc.from_addr(0x01800D2FF0) 90 | lv1 = hxf.lvar_at(0) 91 | lv1_bis = hxf.lvar_at(0) 92 | lv2 = hxf.lvar_at(2) 93 | assert lv1 != lv2 94 | assert not (lv1 == lv2) 95 | assert lv1 == lv1 96 | assert lv1 == lv1_bis 97 | assert lv1.__eq__(3) == NotImplemented 98 | assert lv1.__ne__(3) == NotImplemented 99 | assert lv1 != 3 100 | 101 | 102 | -------------------------------------------------------------------------------- /test/test_menutb.py: -------------------------------------------------------------------------------- 1 | from bip.gui import * 2 | 3 | import pytest 4 | 5 | """ 6 | Small and artificial test for the top menu functions 7 | in ``bip/gui/menutb.py``. As there is no simple way to test if they are 8 | correctly set, this just make the calls to the function, this allow at 9 | minima to check that the API is not broken. 10 | """ 11 | 12 | def test_menutb00(): 13 | assert add_top_menu("NewTopLevelMenu", before="Edit") 14 | assert add_top_menu("NewTopLevelMenu", before="Edit") == False 15 | assert add_top_menu("NewTopLevelMenu", uid="NewTopLevelMenu2", before="Edit") 16 | del_top_menu("NewTopLevelMenu") 17 | del_top_menu("NewTopLevelMenu2") 18 | 19 | 20 | --------------------------------------------------------------------------------