def FUNCTION_DECL_handler(self, current_node_hash): with self.driver.session() as session: result = session.run("MATCH (func:FUNCTION_DECL {Hash: {current_node_hash}})-[:FunctionArgument]->" "(func_param:PARM_DECL) " "RETURN func_param.Hash as param_hash, " " func_param.TypeDefinition as type_definition," " func_param.TypeName as type_name ", current_node_hash=current_node_hash) # Parse function arguments function_parameter_list = list() if result.peek(): for record in result: # If parameter type is already defined move on to the next parameter if not self.type_definition_cache.get(record['param_hash']): if self.insert_type_definition_into_binaryView('PARM_DECL', record['param_hash']): self.type_definition_cache[record['param_hash']] = True else: print("Failed to insert definition for function parameter ", record['type_name']) return False try: # Define the Function parameter binaryNinja object function_parameter_list.append( types.FunctionParameter(self.bv.get_type_by_name(record['type_name']), record['type_name'])) except Exception as e: print("FUNCTION_DECL_handler: Failed to process function parameter" + str(e)) return False # Parse return value and function name result = session.run("MATCH (func:FUNCTION_DECL {Hash: {current_node_hash}})-[:ReturnType]->" "(return_type) " "RETURN return_type.Hash as return_hash, " " labels(return_type)[0] as return_label, " " return_type.TypeDefinition as type_definition, " " return_type.TypeName as type_name ", current_node_hash=current_node_hash) return_type = types.Type.void() if result.peek(): for record in result: # If return type is already defined move on, otherwise define it if not self.type_definition_cache.get(record['return_hash']): if self.insert_type_definition_into_binaryView(record['return_label'], record['return_hash']): self.type_definition_cache[record['return_hash']] = True else: print("Failed to insert definition for function return value ", record['type_name']) return False try: # Define the Function return value binaryNinja type object if record['type_definition'] == 'PointerTo': # Return type is a pointer var_type, name = self.bv.parse_type_string(record['type_name'][:-1]) return_type = Type.pointer(self.bv.arch, var_type) else: var_type, name = self.bv.parse_type_string( record['type_definition'] + " " + record['type_name']) self.bv.define_user_type(name, var_type) return_type = Type.named_type_from_type(name, self.bv.get_type_by_name(name)) except Exception as e: print("FUNCTION_DECL_handler: Failed to process return value, " + str(e)) return False else: # A function might not have any return value or arguments pass # Define the function itself result = session.run("MATCH (func:FUNCTION_DECL {Hash: {current_node_hash}}) " "RETURN func.TypeName as func_name", current_node_hash=current_node_hash) if result.peek(): func_name = result.peek()['func_name'] try: for func in self.bv.functions: if func.name == func_name: func_cc = func.calling_convention function_type = Type.function(return_type, function_parameter_list, func_cc) func.set_user_type(function_type) if not self.fix_tailcall(func, function_parameter_list, return_type, func_cc): return False self.type_definition_cache[current_node_hash] = True except Exception as e: print("Failed to process function :", func_name) print(str(e)) return False print("Successfully defined function: ", func_name) return True
FunctionParameter, Platform, QualifiedName, Type, TypeLibrary, Structure ) advapi32_x86 = TypeLibrary.new(Architecture["x86"], "advapi32.dll") advapi32_x86.add_platform(Platform["windows-x86"]) BOOL = Type.int(4, altname="BOOL") HCRYPTPROV_type = Type.structure_type(Structure()) HCRYPTPROV = Type.named_type_from_type( "HCRYPTPROV", HCRYPTPROV_type ) LPCSTR_type = Type.pointer(Architecture["x86"], Type.char()) LPCSTR = Type.named_type_from_type('LPCSTR', LPCSTR_type) DWORD = Type.int(4, sign=False, altname="DWORD") advapi32_x86.add_named_type("HCRYPTPROV", HCRYPTPROV_type) CryptAcquireContextA = Type.function( BOOL, [ FunctionParameter( Type.pointer(Architecture["x86"], HCRYPTPROV), "phProv" ),