Exemplo n.º 1
0
    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"
        ),