Exemplo n.º 1
0
void reportReachableClasses(const Scope& scope, std::string reportFileName) {
  TRACE(PGR, 4, "Total numner of classes: %d\n", scope.size());
  // Report classes that the reflection filter says can't be deleted.
  std::ofstream reportFileCanDelete(reportFileName + ".cant_delete");
  for (auto const& cls : scope) {
    if (!can_delete(cls)) {
      reportFileCanDelete << cls->get_name()->c_str() << "\n";
    }
  }
  reportFileCanDelete.close();
  // Report classes that the reflection filter says can't be renamed.
  std::ofstream reportFileCanRename(reportFileName + ".cant_rename");
  for (auto const& cls : scope) {
    if (!can_rename(cls)) {
      reportFileCanRename << cls->get_name()->c_str() << "\n";
    }
  }
  reportFileCanRename.close();
  // Report classes marked for keep from ProGuard flat file list.
  std::ofstream reportFileKeep(reportFileName + ".must_keep");
  for (auto const& cls : scope) {
    if (is_seed(cls)) {
      reportFileKeep << cls->get_name()->c_str() << "\n";
    }
  }
  reportFileKeep.close();
}
Exemplo n.º 2
0
bool can_rename_scope(const VirtualScope* scope) {
  for (const auto& vmeth : scope->methods) {
    if (!can_rename(vmeth.first) || (vmeth.second & ESCAPED) != 0) {
      return false;
    }
  }
  return true;
}
Exemplo n.º 3
0
bool should_rename(DexClass *clazz,
    std::vector<std::string>& pre_patterns,
    std::vector<std::string>& post_patterns,
    std::unordered_set<const DexType*>& untouchables,
    bool rename_annotations,
    PassManager& mgr) {
  if (!rename_annotations && is_annotation(clazz)) {
    mgr.incr_metric(METRIC_CANT_RENAME_ANNOTATION, 1);
    return false;
  }
  if (untouchables.count(clazz->get_type())) {
    mgr.incr_metric(METRIC_CANT_RENAME_UNTOUCHABLE, 1);
    return false;
  }
  auto chstring = clazz->get_type()->get_name()->c_str();
  /* We're assuming anonymous classes are safe always safe to rename. */
  auto last_cash = strrchr(chstring, '$');
  if (last_cash != nullptr) {
    auto val = *++last_cash;
    if (val >= '0' && val <= '9') {
      match_inner++;
      return true;
    }
  }
  /* Check for more aggressive, but finer grained filters first */
  for (auto p : pre_patterns) {
    auto substr = strstr(chstring, p.c_str());
    if (substr != nullptr) {
      if (p.length() > 1) {
        match_long++;
      } else {
        match_short++;
      }
      return true;
    }
  }
  if (!can_rename(clazz) && !can_delete(clazz)) {
    mgr.incr_metric(METRIC_CANT_RENAME_AND_CANT_DELETE, 1);
    return false;
  }
  /* Check for wider, less precise filters */
  for (auto p : post_patterns) {
    auto substr = strstr(chstring, p.c_str());
    if (substr != nullptr) {
      if (p.length() > 1) {
        match_long++;
      } else {
        match_short++;
      }
      return true;
    }
  }
  mgr.incr_metric(METRIC_NOT_WHITELISTED, 1);
  return false;
}
Exemplo n.º 4
0
bool should_rename(DexClass *clazz,
    std::vector<std::string>& pre_patterns,
    std::vector<std::string>& post_patterns,
    std::unordered_set<const DexType*>& untouchables,
    bool rename_annotations) {
  if (!rename_annotations && is_annotation(clazz)) return false;
  if (untouchables.count(clazz->get_type())) return false;
  auto chstring = clazz->get_type()->get_name()->c_str();
  /* We're assuming anonymous classes are safe always safe to rename. */
  auto substr = strrchr(chstring, '$');
  if (substr != nullptr) {
    auto val = *++substr;
    if (val >= '0' && val <= '9') {
      match_inner++;
      return true;
    }
  }
  /* Check for more aggressive, but finer grained filters first */
  for (auto p : pre_patterns) {
    auto substr = strstr(chstring, p.c_str());
    if (substr != nullptr) {
      if (p.length() > 1) {
        match_long++;
      } else {
        match_short++;
      }
      return true;
    }
  }
  if (!can_rename(clazz) && !can_delete(clazz)) {
    return false;
  }
  /* Check for wider, less precise filters */
  for (auto p : post_patterns) {
    auto substr = strstr(chstring, p.c_str());
    if (substr != nullptr) {
      if (p.length() > 1) {
        match_long++;
      } else {
        match_short++;
      }
      return true;
    }
  }
  return false;
}
Exemplo n.º 5
0
/**
 * Remove any chance for collisions.
 */
void OptimizationImpl::rename_possible_collisions(
    DexType* intf, SingleImplData& data) {

  const auto& rename = [](DexMethodRef* meth, DexString* name) {
    DexMethodSpec spec;
    spec.cls = meth->get_class();
    spec.name = name;
    spec.proto = meth->get_proto();
    meth->change(spec, false);
  };

  TRACE(INTF, 9, "Changing name related to %s\n", SHOW(intf));
  for (const auto& meth : data.methoddefs) {
    if (!can_rename(meth)) {
      TRACE(INTF, 9, "Changing name but cannot rename %s, give up\n",
          SHOW(meth));
      return;
    }
  }

  std::unordered_map<DexString*, DexString*> names;
  const auto new_name = [&](DexString* name) {
    const auto& name_it = names.find(name);
    if (name_it != names.end()) {
      return name_it->second;
    }
    DexString* possible_name = nullptr;
    static std::string sufx("$r");
    static int intf_id = 0;
    while(true) {
      const auto& str = name->str() + sufx + std::to_string(intf_id++);
      possible_name = DexString::get_string(str.c_str());
      if (possible_name == nullptr) {
        possible_name = DexString::make_string(str.c_str());
        break;
      }
    }
    names[name] = possible_name;
    return possible_name;
  };

  for (const auto& meth : data.methoddefs) {
    if (is_constructor(meth)) continue;
    auto name = new_name(meth->get_name());
    TRACE(INTF, 9, "Changing name for %s to %s\n", SHOW(meth), SHOW(name));
    rename(meth, name);
  }
  for (const auto& refs_it : data.methodrefs) {
    if (refs_it.first->is_def()) continue;
    static auto init = DexString::make_string("<init>");
    always_assert(refs_it.first->get_name() != init);
    auto name = new_name(refs_it.first->get_name());
    TRACE(INTF, 9, "Changing name for %s to %s\n",
        SHOW(refs_it.first), SHOW(name));
    if (names.count(refs_it.first->get_name()) == 0) {
      TRACE(INTF, 9, "Changing name on missing method def %s",
          SHOW(refs_it.first));
    }
    rename(refs_it.first, name);
  }
}