| /* |
| * Copyright (C) 2019 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef SRC_PROFILING_DEOBFUSCATOR_H_ |
| #define SRC_PROFILING_DEOBFUSCATOR_H_ |
| |
| #include <functional> |
| #include <map> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| #include "perfetto/base/status.h" |
| |
| namespace perfetto { |
| namespace profiling { |
| |
| std::string FlattenClasses( |
| const std::map<std::string, std::vector<std::string>>& m); |
| |
| class ObfuscatedClass { |
| public: |
| explicit ObfuscatedClass(std::string d) : deobfuscated_name_(std::move(d)) {} |
| ObfuscatedClass( |
| std::string d, |
| std::map<std::string, std::string> f, |
| std::map<std::string, std::map<std::string, std::vector<std::string>>> m) |
| : deobfuscated_name_(std::move(d)), |
| deobfuscated_fields_(std::move(f)), |
| deobfuscated_methods_(std::move(m)) {} |
| |
| const std::string& deobfuscated_name() const { return deobfuscated_name_; } |
| |
| const std::map<std::string, std::string>& deobfuscated_fields() const { |
| return deobfuscated_fields_; |
| } |
| |
| std::map<std::string, std::string> deobfuscated_methods() const { |
| std::map<std::string, std::string> result; |
| for (const auto& p : deobfuscated_methods_) { |
| result.emplace(p.first, FlattenClasses(p.second)); |
| } |
| return result; |
| } |
| |
| bool redefined_methods() const { return redefined_methods_; } |
| |
| bool AddField(std::string obfuscated_name, std::string deobfuscated_name) { |
| auto p = deobfuscated_fields_.emplace(std::move(obfuscated_name), |
| deobfuscated_name); |
| return p.second || p.first->second == deobfuscated_name; |
| } |
| |
| void AddMethod(std::string obfuscated_name, std::string deobfuscated_name) { |
| std::string cls = deobfuscated_name_; |
| auto dot = deobfuscated_name.rfind('.'); |
| if (dot != std::string::npos) { |
| cls = deobfuscated_name.substr(0, dot); |
| deobfuscated_name = deobfuscated_name.substr(dot + 1); |
| } |
| auto& deobfuscated_names_for_cls = |
| deobfuscated_methods_[std::move(obfuscated_name)][std::move(cls)]; |
| deobfuscated_names_for_cls.push_back(std::move(deobfuscated_name)); |
| if (deobfuscated_names_for_cls.size() > 1 || |
| deobfuscated_methods_.size() > 1) { |
| redefined_methods_ = true; |
| } |
| } |
| |
| private: |
| std::string deobfuscated_name_; |
| std::map<std::string, std::string> deobfuscated_fields_; |
| std::map<std::string, std::map<std::string, std::vector<std::string>>> |
| deobfuscated_methods_; |
| bool redefined_methods_ = false; |
| }; |
| |
| class ProguardParser { |
| public: |
| // A return value of false means this line failed to parse. This leaves the |
| // parser in an undefined state and it should no longer be used. |
| base::Status AddLine(std::string line); |
| bool AddLines(std::string contents); |
| |
| std::map<std::string, ObfuscatedClass> ConsumeMapping() { |
| return std::move(mapping_); |
| } |
| |
| private: |
| std::map<std::string, ObfuscatedClass> mapping_; |
| ObfuscatedClass* current_class_ = nullptr; |
| }; |
| |
| struct ProguardMap { |
| std::string package; |
| std::string filename; |
| }; |
| |
| void MakeDeobfuscationPackets( |
| const std::string& package_name, |
| const std::map<std::string, profiling::ObfuscatedClass>& mapping, |
| std::function<void(const std::string&)> callback); |
| |
| std::vector<ProguardMap> GetPerfettoProguardMapPath(); |
| |
| bool ReadProguardMapsToDeobfuscationPackets( |
| const std::vector<ProguardMap>& maps, |
| std::function<void(std::string)> fn); |
| |
| } // namespace profiling |
| } // namespace perfetto |
| |
| #endif // SRC_PROFILING_DEOBFUSCATOR_H_ |