summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rwxr-xr-xpython/examples/typelib_create.py126
-rwxr-xr-xpython/examples/typelib_dump.py120
2 files changed, 246 insertions, 0 deletions
diff --git a/python/examples/typelib_create.py b/python/examples/typelib_create.py
new file mode 100755
index 00000000..6974c68f
--- /dev/null
+++ b/python/examples/typelib_create.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+# demonstrate creating a type library
+
+import binaryninja
+from binaryninja.enums import *
+from binaryninja.types import *
+
+arch = binaryninja.Architecture['x86_64']
+typelib = binaryninja.typelibrary.TypeLibrary.new(arch, 'libtest.so.1')
+typelib.add_platform(binaryninja.Platform['mac-x86_64'])
+typelib.add_alternate_name('libtest.so')
+
+#------------------------------------------------------------------------------
+# PART1: Named Types
+#------------------------------------------------------------------------------
+
+# example: VoidTypeClass
+typelib.add_named_type('MyVoidType', Type.void())
+
+# example: BoolTypeClass
+typelib.add_named_type('MyBoolType', Type.bool())
+
+# example: IntegerTypeClass
+typelib.add_named_type('MyCharType', Type.char())
+typelib.add_named_type('MyIntType', Type.int(4, True))
+typelib.add_named_type('MyUnsignedIntType', Type.int(4, False))
+
+# example: FloatTypeClass
+typelib.add_named_type('MyFloatType', Type.float(4))
+
+# example: PointerTypeClass
+# char *
+typelib.add_named_type('MyPointerType', Type.pointer(arch, Type.char()))
+
+# example of typedef to primitive type
+# typedef int MyTypedefType;
+typelib.add_named_type('MyTypedefType', Type.int(4))
+
+# example of typedef to typedef
+# typedef MyTypedefType MySuperSpecialType;
+def create_named_type_reference(type_name:str, to_what:NamedTypeReferenceClass):
+ ntr = NamedTypeReference(type_class=to_what, name=type_name)
+ return Type.named_type(ntr)
+
+typelib.add_named_type('MySuperSpecialType',
+ create_named_type_reference('MySpecialType', NamedTypeReferenceClass.TypedefNamedTypeClass))
+
+# We can demonstrate three type classes in the following example:
+# StructureTypeClass, PointerTypeClass, NamedTypeReferenceClass
+
+# add a named type "Rectangle":
+#
+# struct
+# {
+# int width;
+# int height;
+# struct Point *center; // pointer to possibly undeclared struct
+# }
+
+tmp = Structure()
+tmp.append(Type.int(4), 'width')
+tmp.append(Type.int(4), 'height')
+tmp.append(Type.pointer(arch,
+ create_named_type_reference('Point', NamedTypeReferenceClass.StructNamedTypeClass)),
+ 'center')
+struct_type = Type.structure_type(tmp)
+typelib.add_named_type('Rectangle', struct_type)
+
+# add a named type "Rectangle2":
+# this type cannot be applied to variables until struct Point is declared
+#
+# struct
+# {
+# int width;
+# int height;
+# struct Point center; // actual undeclared struct
+# }
+tmp = Structure()
+tmp.append(Type.int(4), 'width')
+tmp.append(Type.int(4), 'height')
+tmp.append(create_named_type_reference('Point', NamedTypeReferenceClass.StructNamedTypeClass),
+ 'center')
+struct_type = Type.structure_type(tmp)
+typelib.add_named_type('Rectangle2', struct_type)
+
+# example: EnumerationTypeClass
+tmp = Enumeration()
+tmp.append('RED', 0)
+tmp.append('ORANGE', 1)
+tmp.append('YELLOW', 2)
+tmp.append('GREEN', 3)
+tmp.append('BLUE', 4)
+tmp.append('INDIGO', 5)
+tmp.append('VIOLET', 6)
+enum_type = Type.enumeration_type(arch, tmp)
+typelib.add_named_type('MyEnumerationType', enum_type)
+
+# example: ArrayTypeClass
+#
+# unsigned char[256]
+typelib.add_named_type('MyArrayType', Type.array(Type.int(1), 256))
+
+# example: FunctionTypeClass
+#
+# int ()(int, int, int)
+ret = Type.int(4)
+params = [Type.int(4), Type.int(4), Type.int(4)]
+ftype = Type.function(ret, params)
+typelib.add_named_type('MyFunctionType', ftype)
+
+#------------------------------------------------------------------------------
+# PART2: Named Objects
+#------------------------------------------------------------------------------
+
+# example: any external/imported functions named _MySuperComputation
+# are typed int _MySuperComputation(int, int)
+
+ret = Type.int(4)
+params = [Type.int(4), Type.int(4)]
+ftype = Type.function(ret, params)
+typelib.add_named_object('_MySuperComputation', ftype)
+
+# finalize
+typelib.finalize()
+typelib.write_to_file('test.bntl')
+
diff --git a/python/examples/typelib_dump.py b/python/examples/typelib_dump.py
new file mode 100755
index 00000000..90f6700d
--- /dev/null
+++ b/python/examples/typelib_dump.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python
+# binja type library info utility
+
+import os, sys, re, random
+import binaryninja
+from binaryninja.enums import *
+from binaryninja import typelibrary
+
+# The class Type as defined in api/python/types.py is nearly a discriminated union.
+# By examining the .type_class member you can decide which properties make sense to access.
+#
+# For example, if .type_class == FunctionTypeClass then you can access:
+# .return_value binaryninja.types.Type
+# .parameters [binaryninja.types.FunctionParameter]
+#
+# For example, if .type_class == StructureTypeClass then you can access:
+# .structure binaryninja.types.Structure
+#
+# etc...
+
+def obj2str(t, depth=0):
+ indent = ' '*depth
+ result = ''
+
+ if type(t) == binaryninja.types.Structure:
+ result = '%sStructure\n' % (indent)
+ for m in t.members:
+ result += obj2str(m, depth+1)
+ elif type(t) == binaryninja.types.StructureMember:
+ result = '%sStructureMember "%s"\n' % (indent, t._name)
+ result += type2str(t.type, depth+1)
+ elif type(t) == binaryninja.types.FunctionParameter:
+ result = '%sFunctionParameter "%s"\n' % (indent, t.name)
+ result += type2str(t.type, depth+1)
+ elif type(t) == binaryninja.types.NamedTypeReference:
+ result = '%sNamedTypeReference %s\n' % (indent, repr(t))
+ elif type(t) == binaryninja.types.Enumeration:
+ result = '%sEnumeration\n' % indent
+ for m in t.members:
+ result += obj2str(m, depth+1)
+ elif type(t) == binaryninja.types.EnumerationMember:
+ result = '%sEnumerationMember %s==%d\n' % (indent, t.name, t.value)
+ elif t == None:
+ result = 'unimplemented'
+
+ return result
+
+def type2str(t:binaryninja.types.Type, depth=0):
+ indent = ' '*depth
+ result = 'unimplemented'
+
+ assert type(t) == binaryninja.types.Type
+ tc = t.type_class
+
+ if tc == TypeClass.VoidTypeClass:
+ result = '%sType class=Void\n' % indent
+ elif tc == TypeClass.BoolTypeClass:
+ result = '%sType class=Bool\n' % indent
+ elif tc == TypeClass.IntegerTypeClass:
+ result = '%sType class=Integer width=%d\n' % (indent, t.width)
+ elif tc == TypeClass.FloatTypeClass:
+ result = '%sType class=Float\n' % indent
+ elif tc == TypeClass.StructureTypeClass:
+ result = '%sType class=Structure\n' % indent
+ result += obj2str(t.structure, depth+1)
+ elif tc == TypeClass.EnumerationTypeClass:
+ result = '%sType class=Enumeration\n' % indent
+ result += obj2str(t.enumeration, depth+1)
+ elif tc == TypeClass.PointerTypeClass:
+ result = '%sType class=Pointer\n' % indent
+ result += type2str(t.element_type, depth+1)
+ elif tc == TypeClass.ArrayTypeClass:
+ result = '%sType class=Array\n' % indent
+ elif tc == TypeClass.FunctionTypeClass:
+ result = '%sType class=Function\n' % indent
+ result += type2str(t.return_value, depth+1)
+ for param in t.parameters:
+ result += obj2str(param, depth+1)
+ elif tc == TypeClass.VarArgsTypeClass:
+ result = '%sType class=VarArgs\n' % indent
+ elif tc == TypeClass.ValueTypeClass:
+ result = '%sType class=Value\n' % indent
+ elif tc == TypeClass.NamedTypeReferenceClass:
+ result = '%sType class=NamedTypeReference\n' % indent
+ result += obj2str(t.named_type_reference, depth+1)
+ elif tc == TypeClass.WideCharTypeClass:
+ result = '%sType class=WideChar\n' % indent
+
+ return result
+
+if __name__ == '__main__':
+ binaryninja._init_plugins()
+
+ if len(sys.argv) <= 1:
+ raise Exception('supply typelib file')
+
+ fpath = sys.argv[-1]
+ print(' reading: %s' % fpath)
+
+ tl = typelibrary.TypeLibrary.load_from_file(fpath)
+ print(' name: %s' % tl.name)
+ print(' arch: %s' % tl.arch)
+ print(' guid: %s' % tl.guid)
+ print('dependency_name: %s' % tl.dependency_name)
+ print('alternate_names: %s' % tl.alternate_names)
+ print(' platform_names: %s' % tl.platform_names)
+ print('')
+
+ print(' named_objects: %d' % len(tl.named_objects))
+ for (key, val) in tl.named_objects.items():
+ print('\t"%s" %s' % (str(key), str(val)))
+
+ print('')
+
+ print(' named_types: %d' % len(tl.named_types))
+ for (key,val) in tl.named_types.items():
+ line = 'typelib.named_types["%s"] =' % (str(key))
+ print(line)
+ print('-'*len(line))
+ print(type2str(val))