Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6757d436 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Use lambda to refactor the obfuscating resource name."

parents 026072cd 8ceb39c9
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -154,8 +154,8 @@ class Optimizer {
      return 1;
    }

    if (options_.shorten_resource_paths) {
      Obfuscator obfuscator(options_.table_flattener_options.shortened_path_map);
    Obfuscator obfuscator(options_);
    if (obfuscator.IsEnabled()) {
      if (!obfuscator.Consume(context_, apk->GetResourceTable())) {
        context_->GetDiagnostics()->Error(android::DiagMessage()
                                          << "failed shortening resource paths");
+16 −17
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include "format/binary/ChunkWriter.h"
#include "format/binary/ResEntryWriter.h"
#include "format/binary/ResourceTypeExtensions.h"
#include "optimize/Obfuscator.h"
#include "trace/TraceBuffer.h"

using namespace android;
@@ -466,9 +467,6 @@ class PackageFlattener {
      // table.
      std::map<ConfigDescription, std::vector<FlatEntry>> config_to_entry_list_map;

      // hardcoded string uses characters which make it an invalid resource name
      const std::string obfuscated_resource_name = "0_resource_name_obfuscated";

      for (const ResourceTableEntryView& entry : type.entries) {
        if (entry.staged_id) {
          aliases_.insert(std::make_pair(
@@ -477,30 +475,31 @@ class PackageFlattener {
        }

        uint32_t local_key_index;
        ResourceName resource_name({}, type.named_type, entry.name);
        if (!collapse_key_stringpool_ ||
            name_collapse_exemptions_.find(resource_name) != name_collapse_exemptions_.end()) {
        auto onObfuscate = [this, &local_key_index, &entry](Obfuscator::Result obfuscatedResult,
                                                            const ResourceName& resource_name) {
          if (obfuscatedResult == Obfuscator::Result::Keep_ExemptionList) {
            local_key_index = (uint32_t)key_pool_.MakeRef(entry.name).index();
        } else {
          // resource isn't exempt from collapse, add it as obfuscated value
          if (entry.overlayable_item) {
          } else if (obfuscatedResult == Obfuscator::Result::Keep_Overlayable) {
            // if the resource name of the specific entry is obfuscated and this
            // entry is in the overlayable list, the overlay can't work on this
            // overlayable at runtime because the name has been obfuscated in
            // resources.arsc during flatten operation.
            const OverlayableItem& item = entry.overlayable_item.value();
            context_->GetDiagnostics()->Warn(android::DiagMessage(item.overlayable->source)
                                             << "The resource name of overlayable entry "
                                             << resource_name.to_string() << "'"
                                             << " shouldn't be obfuscated in resources.arsc");
                                             << "The resource name of overlayable entry '"
                                             << resource_name.to_string()
                                             << "' shouldn't be obfuscated in resources.arsc");

            local_key_index = (uint32_t)key_pool_.MakeRef(entry.name).index();
          } else {
            // TODO(b/228192695): output the entry.name and Resource id to make
            //  de-obfuscated possible.
            local_key_index = (uint32_t)key_pool_.MakeRef(obfuscated_resource_name).index();
          }
            local_key_index =
                (uint32_t)key_pool_.MakeRef(Obfuscator::kObfuscatedResourceName).index();
          }
        };

        Obfuscator::ObfuscateResourceName(collapse_key_stringpool_, name_collapse_exemptions_,
                                          type.named_type, entry, onObfuscate);

        // Group values by configuration.
        for (auto& config_value : entry.values) {
          config_to_entry_list_map[config_value->config].push_back(
+13 −5
Original line number Diff line number Diff line
@@ -14,8 +14,13 @@
 * limitations under the License.
 */

#ifndef AAPT_FORMAT_BINARY_TABLEFLATTENER_H
#define AAPT_FORMAT_BINARY_TABLEFLATTENER_H
#ifndef TOOLS_AAPT2_FORMAT_BINARY_TABLEFLATTENER_H_
#define TOOLS_AAPT2_FORMAT_BINARY_TABLEFLATTENER_H_

#include <map>
#include <set>
#include <string>
#include <unordered_map>

#include "Resource.h"
#include "ResourceTable.h"
@@ -71,6 +76,9 @@ struct TableFlattenerOptions {
  //
  // This applies only to simple entries (entry->flags & ResTable_entry::FLAG_COMPLEX == 0).
  bool deduplicate_entry_values = false;

  // Map from original resource ids to obfuscated names.
  std::unordered_map<uint32_t, std::string> id_resource_map;
};

class TableFlattener : public IResourceTableConsumer {
@@ -82,12 +90,12 @@ class TableFlattener : public IResourceTableConsumer {
  bool Consume(IAaptContext* context, ResourceTable* table) override;

 private:
  DISALLOW_COPY_AND_ASSIGN(TableFlattener);

  TableFlattenerOptions options_;
  android::BigBuffer* buffer_;

  DISALLOW_COPY_AND_ASSIGN(TableFlattener);
};

}  // namespace aapt

#endif /* AAPT_FORMAT_BINARY_TABLEFLATTENER_H */
#endif  // TOOLS_AAPT2_FORMAT_BINARY_TABLEFLATTENER_H_
+11 −10
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include "ValueVisitor.h"
#include "androidfw/BigBuffer.h"
#include "optimize/Obfuscator.h"

using android::ConfigDescription;

@@ -366,21 +367,21 @@ void SerializeTableToPb(const ResourceTable& table, pb::ResourceTable* out_table
      }
      pb_type->set_name(type.named_type.to_string());

      // hardcoded string uses characters which make it an invalid resource name
      static const char* obfuscated_resource_name = "0_resource_name_obfuscated";
      for (const auto& entry : type.entries) {
        pb::Entry* pb_entry = pb_type->add_entry();
        if (entry.id) {
          pb_entry->mutable_entry_id()->set_id(entry.id.value());
        }
        ResourceName resource_name({}, type.named_type, entry.name);
        if (options.collapse_key_stringpool &&
            options.name_collapse_exemptions.find(resource_name) ==
            options.name_collapse_exemptions.end()) {
          pb_entry->set_name(obfuscated_resource_name);
        } else {
          pb_entry->set_name(entry.name);
        }
        auto onObfuscate = [pb_entry, &entry](Obfuscator::Result obfuscatedResult,
                                              const ResourceName& resource_name) {
          pb_entry->set_name(obfuscatedResult == Obfuscator::Result::Obfuscated
                                 ? Obfuscator::kObfuscatedResourceName
                                 : entry.name);
        };

        Obfuscator::ObfuscateResourceName(options.collapse_key_stringpool,
                                          options.name_collapse_exemptions, type.named_type, entry,
                                          onObfuscate);

        // Write the Visibility struct.
        pb::Visibility* pb_visibility = pb_entry->mutable_visibility();
+92 −3
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#include "optimize/Obfuscator.h"

#include <map>
#include <set>
#include <string>
#include <unordered_set>
@@ -32,7 +33,10 @@ static const char base64_chars[] =

namespace aapt {

Obfuscator::Obfuscator(std::map<std::string, std::string>& path_map_out) : path_map_(path_map_out) {
Obfuscator::Obfuscator(OptimizeOptions& optimizeOptions)
    : options_(optimizeOptions.table_flattener_options),
      shorten_resource_paths_(optimizeOptions.shorten_resource_paths),
      collapse_key_stringpool_(optimizeOptions.table_flattener_options.collapse_key_stringpool) {
}

std::string ShortenFileName(android::StringPiece file_path, int output_length) {
@@ -77,7 +81,8 @@ struct PathComparator {
  }
};

bool Obfuscator::Consume(IAaptContext* context, ResourceTable* table) {
static bool HandleShortenFilePaths(ResourceTable* table,
                                   std::map<std::string, std::string>& shortened_path_map) {
  // used to detect collisions
  std::unordered_set<std::string> shortened_paths;
  std::set<FileReference*, PathComparator> file_refs;
@@ -109,10 +114,94 @@ bool Obfuscator::Consume(IAaptContext* context, ResourceTable* table) {
      shortened_path = GetShortenedPath(shortened_filename, extension, collision_count);
    }
    shortened_paths.insert(shortened_path);
    path_map_.insert({*file_ref->path, shortened_path});
    shortened_path_map.insert({*file_ref->path, shortened_path});
    file_ref->path = table->string_pool.MakeRef(shortened_path, file_ref->path.GetContext());
  }
  return true;
}

void Obfuscator::ObfuscateResourceName(
    const bool collapse_key_stringpool, const std::set<ResourceName>& name_collapse_exemptions,
    const ResourceNamedType& type_name, const ResourceTableEntryView& entry,
    const android::base::function_ref<void(Result obfuscatedResult, const ResourceName&)>
        onObfuscate) {
  ResourceName resource_name({}, type_name, entry.name);
  if (!collapse_key_stringpool ||
      name_collapse_exemptions.find(resource_name) != name_collapse_exemptions.end()) {
    onObfuscate(Result::Keep_ExemptionList, resource_name);
  } else {
    // resource isn't exempt from collapse, add it as obfuscated value
    if (entry.overlayable_item) {
      // if the resource name of the specific entry is obfuscated and this
      // entry is in the overlayable list, the overlay can't work on this
      // overlayable at runtime because the name has been obfuscated in
      // resources.arsc during flatten operation.
      onObfuscate(Result::Keep_Overlayable, resource_name);
    } else {
      onObfuscate(Result::Obfuscated, resource_name);
    }
  }
}

static bool HandleCollapseKeyStringPool(
    const ResourceTable* table, const bool collapse_key_string_pool,
    const std::set<ResourceName>& name_collapse_exemptions,
    std::unordered_map<uint32_t, std::string>& id_resource_map) {
  if (!collapse_key_string_pool) {
    return true;
  }

  int entryResId = 0;
  auto onObfuscate = [&entryResId, &id_resource_map](const Obfuscator::Result obfuscatedResult,
                                                     const ResourceName& resource_name) {
    if (obfuscatedResult == Obfuscator::Result::Obfuscated) {
      id_resource_map.insert({entryResId, resource_name.entry});
    }
  };

  for (auto& package : table->packages) {
    for (auto& type : package->types) {
      for (auto& entry : type->entries) {
        if (!entry->id.has_value() || entry->name.empty()) {
          continue;
        }
        entryResId = entry->id->id;
        ResourceTableEntryView entry_view{
            .name = entry->name,
            .id = entry->id ? entry->id.value().entry_id() : (std::optional<uint16_t>)std::nullopt,
            .visibility = entry->visibility,
            .allow_new = entry->allow_new,
            .overlayable_item = entry->overlayable_item,
            .staged_id = entry->staged_id};

        Obfuscator::ObfuscateResourceName(collapse_key_string_pool, name_collapse_exemptions,
                                          type->named_type, entry_view, onObfuscate);
      }
    }
  }

  return true;
}

bool Obfuscator::Consume(IAaptContext* context, ResourceTable* table) {
  HandleCollapseKeyStringPool(table, options_.collapse_key_stringpool,
                              options_.name_collapse_exemptions, options_.id_resource_map);
  if (shorten_resource_paths_) {
    return HandleShortenFilePaths(table, options_.shortened_path_map);
  }
  return true;
}

/**
 * Tell the optimizer whether it's needed to dump information for de-obfuscating.
 *
 * There are two conditions need to dump the information for de-obfuscating.
 * * the option of shortening file paths is enabled.
 * * the option of collapsing resource names is enabled.
 * @return true if the information needed for de-obfuscating, otherwise false
 */
bool Obfuscator::IsEnabled() const {
  return shorten_resource_paths_ || collapse_key_stringpool_;
}

}  // namespace aapt
Loading