Пример #1
0
def parse_one_parcel_function(filename):

    logger.debug("Start dealing with " + filename)
    data = xml2json(os.path.join(rough_function_data_dir, filename))

    tmp_function_file = os.path.join(interface_model_extractor_tmp_dir,
                                     "tmp_function_file.json")
    open(tmp_function_file, "w").write(get_formatted_json(data))

    function = data["function"]
    func_name = function["funcName"]["$"]
    if func_name.startswith("class "):
        func_name = func_name.split("class ")[1]
    if func_name.startswith("struct "):
        func_name = func_name.split("struct ")[1]
    signature = function["signature"]["$"]
    if not check_funcname(func_name):
        return
    if func_name + "+" + signature in already_parsed_functions:
        return
    if len(function) > 2:
        ast_walker = ASTVisitor(type_map)
        parcel = ast_walker.walk_parcel_function(function)
        # add_qualified_name(parcel, func_name)
        # add_qualified_name(parcel, struct_name)
        data = OrderedDict()
        data[func_name + "+" + signature] = parcel
        open(os.path.join(precise_function_data_dir, filename[:-4] + ".json"),
             "w").write(get_formatted_json(data))
    logging.info("Finish parsing one parcel function: " + filename)
    open(already_parsed_functions_file,
         "a").write(func_name + "+" + signature + "\n")
Пример #2
0
def parse_one_interface(filename):
    logger.info("Start parsing file: " + filename)
    funcname = filename.split("::")[-2]
    data = xml2json(os.path.join(rough_interface_data_dir, filename))

    tmp_interface_file = os.path.join(
        interface_model_extractor_tmp_dir, "tmp_interface_file.json")
    open(tmp_interface_file, "w").write(get_formatted_json(data))
    last_switch = data['onTransact'].keys()[-1]
    transactions = data['onTransact'][last_switch]
    del transactions["DeclRef"]

    if funcname not in func2svc:
        print(funcname+"is not in func2svc")
        return 

    serviceName = func2svc[funcname]["serviceName"]
    interfaceToken = func2svc[funcname]["interfaceToken"]
    interfaceName =func2svc[funcname]["interfaceName"]

    all_txs = parse_transactions(transactions, interfaceName)

    for key in all_txs:
        all_txs[key]["serviceName"] = serviceName
        all_txs[key]["interfaceName"] = interfaceName
        all_txs[key]["interfaceToken"] = interfaceToken
    interface_model_service_dir = os.path.join(interface_model_dir, "service")
    interface_file = os.path.join(interface_model_service_dir,funcname + ".json")
    open(interface_file, "w").write(
        get_formatted_json(all_txs))
    logger.info("Finish parsing file: " + filename)
Пример #3
0
    def update_self_constraint(self, cons):
        logger.debug(get_formatted_json(cons))
        opcode = cons["opcode"]
        if opcode == "!" or opcode == "":
            if "opcode" in cons["lhs"]:
                cons["lhs"]["name"] = cons["name"] + "_lhs"
                self.update_self_constraint(cons["lhs"])
                return
            lhs_name = cons["lhs"]["name"]
            new_cons = self.get_variable_attr(lhs_name, "self_constraint")
            if new_cons is not None:
                new_cons.append(cons["name"])
                self.update_variable_attr(lhs_name, "self_constraint",
                                          new_cons)
        elif opcode == "&&" or opcode == "||" or opcode == "&":
            lhs = cons["lhs"]
            lhs["name"] = cons["name"] + "_lhs"
            lhs["probability"] = cons["probability"]
            rhs = cons["rhs"]
            rhs["name"] = cons["name"] + "_rhs"
            rhs["probability"] = cons["probability"]
            self.update_self_constraint(lhs)
            self.update_self_constraint(rhs)
        else:
            if "opcode" not in cons["lhs"]:
                lhs_name = cons["lhs"]["name"]
                lhs_self_constraint = self.get_variable_attr(
                    lhs_name, "self_constraint")
                if lhs_self_constraint is not None:
                    lhs_self_constraint.append(cons["name"])
                    self.update_variable_attr(lhs_name, "self_constraint",
                                              lhs_self_constraint)
            elif cons["lhs"]["opcode"] == "&" or cons["lhs"]["opcode"] == "-":
                pass
            elif cons["lhs"]["opcode"] == ">=":
                cons["lhs"]["name"] = cons["name"] + "_lhs"
                self.update_self_constraint(cons["lhs"])
            else:
                logger.error("update_self_constraint lhs is not completed.")
                logger.debug(get_formatted_json(cons))
                exit(0)

            if "opcode" not in cons["rhs"]:
                rhsname = cons["rhs"]["name"]
                rhs_self_constraint = self.get_variable_attr(
                    rhsname, "self_constraint")
                if rhs_self_constraint is not None:
                    rhs_self_constraint.append(cons["name"])
                    self.update_variable_attr(rhsname, "self_constraint",
                                              rhs_self_constraint)
            elif cons["rhs"]["opcode"] == "&" or cons["rhs"]["opcode"] == "-":
                pass
            else:
                logger.error("update_self_constraint rhs is not completed.")
                logger.debug(get_formatted_json(cons))
                exit(0)
Пример #4
0
def parse_one_raw_structure(filename):
    logger.info("Start dealing with " + filename)
    struct_name = filename[:-4]
    if os.path.exists(os.path.join(rough_raw_structure_data_dir, filename)):
        structure = xml2json(
            os.path.join(rough_raw_structure_data_dir, filename))
    else:
        logger.info("try again...")
        if struct_name in type_map:
            # for the following kind..
            # struct audio_config_base {
            #     uint32_t sample_rate;
            #     audio_channel_mask_t channel_mask;
            #     audio_format_t  format;
            # };
            # typedef struct audio_config_base audio_config_base_t;
            filename = type_map[struct_name] + ".xml"
            structure = xml2json(
                os.path.join(rough_raw_structure_data_dir, filename))
        else:
            logger.error(
                str(os.path.join(rough_raw_structure_data_dir, filename)) +
                " do not exists..")
            exit(0)
    tmp_raw_structure_file = os.path.join(interface_model_extractor_tmp_dir,
                                          "tmp_raw_structure_file.json")
    open(tmp_raw_structure_file, "w").write(get_formatted_json(structure))

    key = structure.keys()[0]

    ast_walker = ASTVisitor(type_map)
    parcel, raw_structure_set = ast_walker.walk_raw_structure(structure)
    # convert to the true complex type.
    struct_name = get_true_complex_type(type_map, struct_name)
    # TODO: do we need update name to qualified name?
    # add_qualified_name(parcel, struct_name)
    data = OrderedDict()
    data[struct_name] = parcel
    parcel = get_formatted_json(data)

    if key == "union":
        outfile = os.path.join(precise_union_data_dir, struct_name + ".json")
    else:
        outfile = os.path.join(precise_raw_structure_data_dir,
                               struct_name + ".json")
    open(outfile, "w").write(parcel)
    logger.info("Finish parsing one raw structure: " + filename)
    return raw_structure_set
Пример #5
0
def parse_transactions(transactions, interface_name):
    """Walk transactions one by one in data.
    """
    logger.debug("Start walking trasanctions.")
    all_txs = OrderedDict()
    for key, transaction in transactions.items():
        if key.startswith("code"):
            logger.info("Start dealing code " + key.strip("code"))
            ast_walker = ASTVisitor(type_map)
            codelist,tx = ast_walker.parse_one_transaction(transaction)
            tx_key = interface_name + "::" + str(codelist[0]) + "-" + str(codelist[-1])
            special_deal(tx_key,tx)
            all_txs[tx_key] = tx
        elif key.startswith("ReturnStmt"):
            continue
        elif key.startswith("BinaryOperator"):
            continue
        elif key.startswith("CompoundStmt"):
            continue
        else:
            logger.error("Unexpected key: " + key+" in parse_transactions")
            logger.error(get_formatted_json(transactions[key]))
            exit(0)
    logger.debug("Finish walking trasanctions.")
    return all_txs
Пример #6
0
def parse_one_structure(filename):
    print("Start dealing with " + filename)
    structure = xml2json(os.path.join(rough_structure_data_dir, filename))

    tmp_structure_file = os.path.join(interface_model_extractor_tmp_dir,
                                      "tmp_structure_file.json")
    open(tmp_structure_file, "w").write(get_formatted_json(structure))

    qualified_function_name = filename[:-4]
    if "-" in qualified_function_name:
        qualified_function_name = qualified_function_name.split("-")[0]
    tmp = qualified_function_name.split("::")
    non_qualified_function_name = tmp[-1]
    struct_name = "::".join(tmp[:-1])

    if non_qualified_function_name in ["readFromParcel", "writeToParcel"]:
        struct_name = "::".join(tmp[:-1])
        structure_read_write = non_qualified_function_name
    else:
        flag = False
        for item in special_parcelable_function_splited:
            # even there is no "::", it does not matter
            suffix = "::".join(item[0].split("::")[-2:])
            if item[0] == qualified_function_name or qualified_function_name.endswith(
                    suffix):
                structure_read_write = item[-1]
                struct_name = item[-2]
                flag = True
                break
        if flag is False:
            return
        else:
            open(already_parsed_functions_file,
                 "a").write(item[0] + "+" + item[1] + "\n")

    ast_walker = ASTVisitor(type_map)
    ast_walker.set_structure_read_write(structure_read_write)
    parcel = ast_walker.walk_structure(structure)
    # TODO: do we need update name to qualified name?
    # if updated, consider argv in function variable.
    # add_qualified_name(parcel, struct_name)
    data = OrderedDict()
    data[struct_name] = parcel
    info = get_formatted_json(data)
    if structure_read_write == "readFromParcel":
        outfile = os.path.join(precise_parcelable_structure_data_dir, "data",
                               struct_name + ".json")
        open(outfile, "w").write(info)
    elif structure_read_write == "writeToParcel":
        outfile = os.path.join(precise_parcelable_structure_data_dir, "reply",
                               struct_name + ".json")
        open(outfile, "w").write(info)
        # very special
        if struct_name == "class android::MetaDataBase":
            struct_name = "class android::MetaData"
            data[struct_name] = parcel
            info = get_formatted_json(data)
            outfile = os.path.join(precise_parcelable_structure_data_dir,
                                   "reply", struct_name + ".json")
            open(outfile, "w").write(info)
    else:
        logger.error(filename)
        logger.error("Unexpected thing meeted when parsing structure.")
        exit(0)
    logger.info("Finish parsing one structure: " + filename)
    open(already_parsed_structures_file, "a").write(filename + "\n")