def init(self): self.platform = Platform['8049_rb0mb0'] length = len(self.parent_view) try: # create the data memory segment and section self.add_auto_segment( 0, 128, 0, 0, SegmentFlag.SegmentContainsData | SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable) self.add_auto_section( '.ram', 0, 128, SectionSemantics.ReadWriteDataSectionSemantics) # create the program memory segment, section and entry point self.add_auto_segment( self.CODE_OFFSET, length, 0, length, SegmentFlag.SegmentContainsCode | SegmentFlag.SegmentContainsData | SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable) self.add_auto_section( '.rom', self.CODE_OFFSET, length, SectionSemantics.ReadOnlyCodeSectionSemantics) self.add_entry_point(self.CODE_OFFSET) self.define_auto_symbol_and_var_or_function( Symbol(SymbolType.FunctionSymbol, self.CODE_OFFSET | 0, 'reset'), None, self.platform) self.define_auto_symbol_and_var_or_function( Symbol(SymbolType.FunctionSymbol, self.CODE_OFFSET | 3, 'interrupt'), None, self.platform) self.define_auto_symbol_and_var_or_function( Symbol(SymbolType.FunctionSymbol, self.CODE_OFFSET | 7, 'timer'), None, self.platform) # working registers for n in range(8): self.define_auto_symbol_and_var_or_function( Symbol(SymbolType.DataSymbol, n, 'R{}'.format(n)), Type.int(1, False), self.platform) self.define_auto_symbol_and_var_or_function( Symbol(SymbolType.DataSymbol, n + 24, 'R{}\''.format(n)), Type.int(1, False), self.platform) # stack registers for n in range(8): self.define_auto_symbol_and_var_or_function( Symbol(SymbolType.DataSymbol, n * 2 + 8, 'S{}'.format(n)), Type.int(2, False), self.platform) return True except: log_error(traceback.format_exc()) return False
def import_ida(json_file, bv, options): if json_file is None: return False, "No json file specified" imported = None try: f = open(json_file, "rb") imported = json.load(f) except Exception as e: return False, "Failed to parse json file {} {}".format(json_file, e) resolved_functions = imported["functions"] resolved_strings = imported["strings"] # TODO: import segments # TODO: Handle Conflicts if options.import_functions: log("Applying import data", options.verbose) for name, rec in resolved_functions.items(): bv.add_function(rec["start"]) func = bv.get_function_at(rec["start"]) if name != ("sub_%x" % rec["start"]): func.name = name if options.import_comments: if "comment" in rec: func.comment = rec["comment"] if "comments" in rec: for comment, addr in rec["comments"].items(): func.set_comment_at(addr, comment) if "can_return" in rec: func.can_return = rec["can_return"] bv.update_analysis_and_wait() if options.import_strings: log("Importing string types", options.verbose) for addr, (name, length, t, data_refs) in resolved_strings.items(): bv.define_user_data_var(int(addr), Type.array(Type.int(1, None, "char"), length)) if options.import_strings_names: bv.define_user_symbol(Symbol(SymbolType.DataSymbol, int(addr), name)) for ref in data_refs: # references to this data for block in bv.get_basic_blocks_at(ref): # find any references in code for i in block.get_disassembly_text(): # go through all the instructions in the block if i.address == ref: for token in i.tokens: if token.type == InstructionTextTokenType.PossibleAddressToken: print "setting token", i.address, token.value, token.operand, IntegerDisplayType.PointerDisplayType, block.arch block.function.set_int_display_type(i.address, token.value, token.operand, IntegerDisplayType.PointerDisplayType, block.arch) break log("Updating Analysis", options.verbose) bv.update_analysis_and_wait() return True, None
def load_svd(bv, svd_file=None): if not svd_file: svd_file = get_open_filename_input("SVD File") if isinstance(svd_file, str): svd_file = bytes(svd_file, encoding="utf-8") if not os.access(svd_file, os.R_OK): log_error(f"SVD Browser: Unable to open {svd_file}") return log_info(f"SVD Loader: Loading {svd_file}") device = parse(svd_file) peripherals = device['peripherals'].values() base_peripherals = [p for p in peripherals if 'derives' not in p] derived_peripherals = [p for p in peripherals if 'derives' in p] def register_peripheral(p, struct_type): bv.add_user_section(p['name'], p['base'], p['size'], SectionSemantics.ReadWriteDataSectionSemantics) bv.add_user_segment( p['base'], p['size'], 0, 0, SegmentFlag.SegmentContainsData | SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable) bv.define_data_var(p['base'], struct_type) bv.define_user_symbol( Symbol(SymbolType.ImportedDataSymbol, p['base'], p['name'])) for p in base_peripherals: s = Structure() for r in p['registers'].values(): if r['size'] is None: s.insert(r['offset'], Type.int(4, False), r['name']) else: s.insert(r['offset'], Type.int(int(r['size'] / 8), False), r['name']) struct_type = Type.structure_type(s) bv.define_user_type(p['name'], struct_type) register_peripheral(p, struct_type) for p in derived_peripherals: struct_type = bv.get_type_by_name( device['peripherals'][p['derives']]['name']) register_peripheral(p, struct_type)
def make_code(bv: BinaryView, start: int, end: int) -> None: if bv.get_basic_blocks_at(start): return if end - start <= 1: # find the next basic block, data variable, or segment/section end data_var = bv.get_next_data_var_after(start) if data_var is not None: end = data_var.address else: end = bv.end end = min(bv.get_next_basic_block_start_after(start), end) seg = bv.get_segment_at(start) if seg is not None: end = min(seg.end, end) section_ends = [s.end for s in bv.get_sections_at(start)] end = min(*section_ends, end) bv.define_data_var(start, Type.array(Type.int(1, False), end - start), f"CODE_{start:08x}")
def find_dynamically_linked_funcs(bv): platform_info = get_platform_info(bv) funcs_to_check = set() for lookup in platform_info["sym_lookups"]: for ref in bv.get_code_refs(lookup): ref.function.analysis_skip_override = FunctionAnalysisSkipOverride.NeverSkipFunctionAnalysis funcs_to_check.add(ref.function) bv.update_analysis() time.sleep(1) for f in funcs_to_check: mlil_ssa = f.medium_level_il.ssa_form for call in find_mlil_calls_to_targets(mlil_ssa, platform_info["sym_lookups"]): if len(call.params) < 2 or len(call.output.vars_written) < 1: continue symbol_name_addr = call.params[1].value if symbol_name_addr.type not in [ RegisterValueType.ConstantPointerValue, RegisterValueType.ConstantValue ]: continue output_var = call.output.vars_written[0] symbol_name = bv.get_ascii_string_at(symbol_name_addr.value).value #Add confidence to both the args and the return of zero symbol_type = Type.pointer(bv.arch, bv.parse_type_string("void foo()")[0]) if len(symbol_name) == 0: continue bv.define_user_data_var(symbol_name_addr.value, Type.array(Type.int(1), len(symbol_name))) output_name = symbol_name + "@DYN" f.create_user_var(output_var.var, symbol_type, output_name) propagate_var_name(f, mlil_ssa, output_var, output_name, symbol_type)
def ty_from_demangler_node(node, cv_qual=frozenset(), arg_count_hint=None): if node.kind == 'builtin': if node.value in ty_for_cxx_builtin: return ty_for_cxx_builtin[node.value] else: return None elif node.kind in ['name', 'qual_name']: named_ty_ref = NamedTypeReference(name=str(node)) return Type.named_type(named_ty_ref) elif node.kind in ['pointer', 'lvalue', 'rvalue']: pointee_ty = ty_from_demangler_node(node.value) if pointee_ty is None: return None is_const = ('const' in cv_qual) is_volatile = ('volatile' in cv_qual) if node.kind == 'pointer': return Type.pointer(arch, pointee_ty, is_const, is_volatile) elif node.kind == 'lvalue': return Type.pointer( arch, pointee_ty, is_const, is_volatile, ref_type=ReferenceType.ReferenceReferenceType) elif node.kind == 'rvalue': return Type.pointer(arch, pointee_ty, is_const, is_volatile, ref_type=ReferenceType.RValueReferenceType) elif node.kind == 'cv_qual': return ty_from_demangler_node(node.value, cv_qual=node.qual) elif node.kind == 'func': is_ctor_dtor = False if node.name and node.name.kind == 'qual_name': qual_name = node.name.value if qual_name[-1].kind in ['ctor', 'dtor']: is_ctor_dtor = True if is_ctor_dtor: ret_ty = Type.void() elif node.ret_ty is not None: ret_ty = ty_from_demangler_node(node.ret_ty) if ret_ty is None: return None else: ret_ty = Type.int(arch.default_int_size).with_confidence(0) arg_nodes = list(node.arg_tys) arg_tys = [] var_arg = False if arg_nodes[-1].kind == 'builtin' and arg_nodes[-1].value == '...': arg_nodes.pop() var_arg = True elif arg_nodes[0].kind == 'builtin' and arg_nodes[ 0].value == 'void': arg_nodes = arg_nodes[1:] this_arg = False if node.name and node.name.kind == 'qual_name': qual_name = node.name.value if is_ctor_dtor or (arg_count_hint is not None and len(arg_nodes) == arg_count_hint - 1): this_arg = True this_node = Node('qual_name', qual_name[:-1]) this_ty = ty_from_demangler_node(this_node) if this_ty is None: return None arg_tys.append(Type.pointer(arch, this_ty)) for arg_node in arg_nodes: arg_ty = ty_from_demangler_node(arg_node) if arg_ty is None: return None arg_tys.append(arg_ty) ty = Type.function(ret_ty, arg_tys, variable_arguments=var_arg) if arg_count_hint is not None: # toplevel invocation, so return whether we inferred a this argument return this_arg, ty else: return ty else: log.log_warn("Cannot convert demangled AST {} to a type".format( repr(node)))
def char_array_ty(length): return Type.array(Type.int(1), strings[0].length)
def analyze_cxx_abi(view, start=None, length=None, task=None): platform = view.platform arch = platform.arch void_p_ty = Type.pointer(arch, Type.void()) char_p_ty = Type.pointer(arch, Type.int(1)) unsigned_int_ty = Type.int(arch.default_int_size, False) signed_int_ty = Type.int(arch.default_int_size, True) base_type_info_ty = Type.named_type( NamedTypeReference(name='std::type_info')) base_type_info_ptr_ty = Type.pointer(arch, base_type_info_ty) def char_array_ty(length): return Type.array(Type.int(1), strings[0].length) def type_info_ty(kind=None): type_info_struct = Structure() type_info_struct.append(void_p_ty, 'vtable') type_info_struct.append(char_p_ty, 'name') if kind == 'si_class': type_info_struct.append(base_type_info_ptr_ty, 'base_type') return Type.structure_type(type_info_struct) def vtable_ty(vfunc_count): vtable_struct = Structure() vtable_struct.append(signed_int_ty, 'top_offset') vtable_struct.append(base_type_info_ptr_ty, 'typeinfo') vtable_struct.append(Type.array(void_p_ty, vfunc_count), 'functions') return Type.structure_type(vtable_struct) if platform.name.startswith("windows-"): long_size = arch.default_int_size else: long_size = arch.address_size if arch.name.startswith('x86'): char_signed = True else: char_signed = False # not always true short_size = 2 # not always true long_long_size = 8 # not always true ty_for_cxx_builtin = { 'void': Type.void(), 'wchar_t': Type.int(2, sign=char_signed, altname='wchar_t'), 'bool': Type.bool(), 'char': Type.int(1, sign=char_signed), 'signed char': Type.int(1, sign=True), 'unsigned char': Type.int(1, sign=False), 'short': Type.int(short_size, sign=True), 'unsigned short': Type.int(short_size, sign=False), 'int': Type.int(arch.default_int_size, sign=True), 'unsigned int': Type.int(arch.default_int_size, sign=False), 'long': Type.int(long_size, sign=True), 'unsigned long': Type.int(long_size, sign=False), 'long long': Type.int(long_long_size, sign=True), 'unsigned long long': Type.int(long_long_size, sign=False), '__int128': Type.int(16, sign=True), 'unsigned __int128': Type.int(16, sign=False), 'float': Type.float(4), 'double': Type.float(8), '__float80': Type.float(10), '__float128': Type.float(16), 'char32_t': Type.int(4, sign=char_signed, altname='char32_t'), 'char16_t': Type.int(2, sign=char_signed, altname='char16_t'), } def ty_from_demangler_node(node, cv_qual=frozenset(), arg_count_hint=None): if node.kind == 'builtin': if node.value in ty_for_cxx_builtin: return ty_for_cxx_builtin[node.value] else: return None elif node.kind in ['name', 'qual_name']: named_ty_ref = NamedTypeReference(name=str(node)) return Type.named_type(named_ty_ref) elif node.kind in ['pointer', 'lvalue', 'rvalue']: pointee_ty = ty_from_demangler_node(node.value) if pointee_ty is None: return None is_const = ('const' in cv_qual) is_volatile = ('volatile' in cv_qual) if node.kind == 'pointer': return Type.pointer(arch, pointee_ty, is_const, is_volatile) elif node.kind == 'lvalue': return Type.pointer( arch, pointee_ty, is_const, is_volatile, ref_type=ReferenceType.ReferenceReferenceType) elif node.kind == 'rvalue': return Type.pointer(arch, pointee_ty, is_const, is_volatile, ref_type=ReferenceType.RValueReferenceType) elif node.kind == 'cv_qual': return ty_from_demangler_node(node.value, cv_qual=node.qual) elif node.kind == 'func': is_ctor_dtor = False if node.name and node.name.kind == 'qual_name': qual_name = node.name.value if qual_name[-1].kind in ['ctor', 'dtor']: is_ctor_dtor = True if is_ctor_dtor: ret_ty = Type.void() elif node.ret_ty is not None: ret_ty = ty_from_demangler_node(node.ret_ty) if ret_ty is None: return None else: ret_ty = Type.int(arch.default_int_size).with_confidence(0) arg_nodes = list(node.arg_tys) arg_tys = [] var_arg = False if arg_nodes[-1].kind == 'builtin' and arg_nodes[-1].value == '...': arg_nodes.pop() var_arg = True elif arg_nodes[0].kind == 'builtin' and arg_nodes[ 0].value == 'void': arg_nodes = arg_nodes[1:] this_arg = False if node.name and node.name.kind == 'qual_name': qual_name = node.name.value if is_ctor_dtor or (arg_count_hint is not None and len(arg_nodes) == arg_count_hint - 1): this_arg = True this_node = Node('qual_name', qual_name[:-1]) this_ty = ty_from_demangler_node(this_node) if this_ty is None: return None arg_tys.append(Type.pointer(arch, this_ty)) for arg_node in arg_nodes: arg_ty = ty_from_demangler_node(arg_node) if arg_ty is None: return None arg_tys.append(arg_ty) ty = Type.function(ret_ty, arg_tys, variable_arguments=var_arg) if arg_count_hint is not None: # toplevel invocation, so return whether we inferred a this argument return this_arg, ty else: return ty else: log.log_warn("Cannot convert demangled AST {} to a type".format( repr(node))) reader = BinaryReader(view) def read(size): if size == 4: return reader.read32() elif size == 8: return reader.read64() else: assert False symbols = view.get_symbols(start, length) if task: task.set_total(len(symbols)) mangled_re = re.compile('_?_Z') demangler_failures = 0 for symbol in symbols: if task and not task.advance(): break if not mangled_re.match(symbol.raw_name): continue is_data = (symbol.type == SymbolType.DataSymbol) is_code = (symbol.type in [ SymbolType.FunctionSymbol, SymbolType.ImportedFunctionSymbol ]) raw_name, suffix = symbol.raw_name, '' if '@' in raw_name: match = re.match(r'^(.+?)(@.+)$', raw_name) raw_name, suffix = match.group(1), match.group(2) try: name_ast = parse_mangled(raw_name) if name_ast is None: log.log_warn( "Demangler failed to recognize {}".format(raw_name)) demangler_failures += 1 except NotImplementedError as e: log.log_warn("Demangler feature missing on {}: {}".format( raw_name, str(e))) demangler_failures += 1 if name_ast: if name_ast.kind == 'func': short_name = str(name_ast.name) else: short_name = str(name_ast) symbol = Symbol(symbol.type, symbol.address, short_name=short_name + suffix, full_name=str(name_ast) + suffix, raw_name=symbol.raw_name) else: symbol = Symbol(symbol.type, symbol.address, short_name=symbol.raw_name, full_name=None, raw_name=symbol.raw_name) view.define_auto_symbol(symbol) if name_ast is None: continue elif is_data and name_ast.kind == 'typeinfo_name': strings = view.get_strings(symbol.address, 1) if not strings: continue view.define_data_var(symbol.address, char_array_ty(length)) elif is_data and name_ast.kind == 'typeinfo': reader.offset = symbol.address + arch.address_size * 2 kind = None # heuristic: is this is an abi::__si_class_type_info? base_or_flags = read(arch.default_int_size) base_symbol = view.get_symbol_at(base_or_flags) if base_symbol and base_symbol.raw_name.startswith('_ZTI'): kind = 'si_class' view.define_data_var(symbol.address, type_info_ty(kind)) elif is_data and name_ast.kind == 'vtable': vtable_addr = symbol.address reader.offset = vtable_addr + arch.address_size * 2 while True: vfunc_count = 0 check_next = True while True: vfunc_ptr_symbol = view.get_symbol_at(reader.offset) if vfunc_ptr_symbol and vfunc_ptr_symbol.raw_name.startswith( '_Z'): # any C++ symbol definitely terminates the vtable check_next = False break # heuristic: existing function vfunc_addr = read(arch.address_size) if view.get_function_at(vfunc_addr): vfunc_count += 1 continue # explicitly reject null pointers; in position-independent code # address zero can belong to the executable segment if vfunc_addr == 0: check_next = False break # heuristic: pointer to executable memory vfunc_segment = view.get_segment_at(vfunc_addr) if vfunc_addr != 0 and vfunc_segment and vfunc_segment.executable: view.add_function(vfunc_addr) vfunc_count += 1 log.log_info( 'Discovered function at {:#x} via {}'.format( vfunc_addr, symbol.full_name or symbol.short_name)) changed = True continue # we've fell off the end of the vtable break view.define_data_var(vtable_addr, vtable_ty(vfunc_count)) if check_next: # heuristic: can another vtable follow this one? let's see if it has typeinfo, # since that should be always true for when we have a virtual base typeinfo_ptr = read(arch.address_size) typeinfo_ptr_symbol = view.get_symbol_at(typeinfo_ptr) if typeinfo_ptr_symbol and typeinfo_ptr_symbol.raw_name.startswith( '_ZTI'): vtable_addr = reader.offset - 2 * arch.address_size # documentat it with a symbol secondary_symbol_name = '{}_secondary_{:x}'.format( symbol.short_name, vtable_addr - symbol.address) secondary_symbol = Symbol( SymbolType.DataSymbol, vtable_addr, short_name=secondary_symbol_name) view.define_auto_symbol(secondary_symbol) continue break elif is_code and name_ast.kind == 'func': func = view.get_function_at(symbol.address) demangled = ty_from_demangler_node( name_ast, arg_count_hint=len(func.function_type.parameters)) if demangled is not None: this_arg, ty = demangled func.apply_auto_discovered_type(ty) view.update_analysis() if demangler_failures: log.log_warn('{} demangler failures'.format(demangler_failures))
class Intel8086(Architecture): name = "8086" endianness = Endianness.LittleEndian default_int_size = 2 address_size = 3 stack_pointer = 'sp' regs = { # General 'ax': RegisterInfo('ax', 2, 0), 'al': RegisterInfo('ax', 1, 0), 'ah': RegisterInfo('ax', 1, 1), 'cx': RegisterInfo('cx', 2, 0), 'cl': RegisterInfo('cx', 1, 0), 'ch': RegisterInfo('cx', 1, 1), 'bx': RegisterInfo('bx', 2, 0), 'bl': RegisterInfo('bx', 1, 0), 'bh': RegisterInfo('bx', 1, 1), 'dx': RegisterInfo('dx', 2, 0), 'dl': RegisterInfo('dx', 1, 0), 'dh': RegisterInfo('dx', 1, 1), 'sp': RegisterInfo('sp', 2), 'bp': RegisterInfo('bp', 2), 'si': RegisterInfo('si', 2), 'di': RegisterInfo('di', 2), # Segment 'cs': RegisterInfo('cs', 2), 'ds': RegisterInfo('ds', 2), 'es': RegisterInfo('es', 2), 'ss': RegisterInfo('ss', 2), # Instruction pointer 'ip': RegisterInfo('ip', 2) } flags = [ # Status 'c', # carry 'p', # parity 'a', # aux carry 'z', # zero 's', # sign 'o', # overflow # Control 'i', # interrupt 'd', # direction 't', # trap ] flag_roles = { 'c': FlagRole.CarryFlagRole, 'p': FlagRole.OddParityFlagRole, 'a': FlagRole.HalfCarryFlagRole, 'z': FlagRole.ZeroFlagRole, 's': FlagRole.NegativeSignFlagRole, 't': FlagRole.SpecialFlagRole, 'i': FlagRole.SpecialFlagRole, 'd': FlagRole.SpecialFlagRole, 'o': FlagRole.OverflowFlagRole, } flag_write_types = [ '', '*', '!c', 'co', ] flags_written_by_flag_write_type = { '*': ['c', 'p', 'a', 'z', 's', 'o'], '!c': ['p', 'a', 'z', 's', 'o'], 'co': ['c', 'o'], } flags_required_for_flag_condition = { LowLevelILFlagCondition.LLFC_E: ['z'], LowLevelILFlagCondition.LLFC_NE: ['z'], LowLevelILFlagCondition.LLFC_SLT: ['s', 'o'], LowLevelILFlagCondition.LLFC_ULT: ['c'], LowLevelILFlagCondition.LLFC_SLE: ['z', 's', 'o'], LowLevelILFlagCondition.LLFC_ULE: ['c', 'z'], LowLevelILFlagCondition.LLFC_SGE: ['s', 'o'], LowLevelILFlagCondition.LLFC_UGE: ['c'], LowLevelILFlagCondition.LLFC_SGT: ['z', 's', 'o'], LowLevelILFlagCondition.LLFC_UGT: ['c', 'z'], LowLevelILFlagCondition.LLFC_NEG: ['s'], LowLevelILFlagCondition.LLFC_POS: ['s'], LowLevelILFlagCondition.LLFC_O: ['o'], LowLevelILFlagCondition.LLFC_NO: ['o'], } intrinsics = { 'outb': IntrinsicInfo([Type.int(2), Type.int(1)], []), 'outw': IntrinsicInfo([Type.int(2), Type.int(2)], []), 'inb': IntrinsicInfo([Type.int(1)], [Type.int(2)]), 'inw': IntrinsicInfo([Type.int(2)], [Type.int(2)]), } def get_instruction_info(self, data, addr): decoded = mc.decode(data, addr) if decoded: info = InstructionInfo() decoded.analyze(info, addr) return info def get_instruction_text(self, data, addr): decoded = mc.decode(data, addr) if decoded: encoded = data[:decoded.total_length()] recoded = mc.encode(decoded, addr) if encoded != recoded: log_error("Instruction roundtrip error") log_error("".join([str(x) for x in decoded.render(addr)])) log_error("Orig: {}".format(encoded.hex())) log_error("New: {}".format(recoded.hex())) return decoded.render(addr), decoded.total_length() def get_instruction_low_level_il(self, data, addr, il): decoded = mc.decode(data, addr) if decoded: decoded.lift(il, addr) return decoded.total_length() def convert_to_nop(self, data, addr): return b'\x90' * len(data) def is_always_branch_patch_available(self, data, addr): decoded = mc.decode(data, addr) if decoded: return isinstance(decoded, mc.instr.jmp.JmpCond) def always_branch(self, data, addr): branch = mc.decode(data, addr) branch = branch.to_always() return mc.encode(branch, addr) def is_invert_branch_patch_available(self, data, addr): decoded = mc.decode(data, addr) if decoded: return isinstance(decoded, mc.instr.jmp.JmpCond) def invert_branch(self, data, addr): branch = mc.decode(data, addr) branch = branch.to_inverted() return mc.encode(branch, addr)
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