1*6dbdd20aSAndroid Build Coastguard Worker /* 2*6dbdd20aSAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project 3*6dbdd20aSAndroid Build Coastguard Worker * 4*6dbdd20aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*6dbdd20aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*6dbdd20aSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*6dbdd20aSAndroid Build Coastguard Worker * 8*6dbdd20aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*6dbdd20aSAndroid Build Coastguard Worker * 10*6dbdd20aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*6dbdd20aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*6dbdd20aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*6dbdd20aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*6dbdd20aSAndroid Build Coastguard Worker * limitations under the License. 15*6dbdd20aSAndroid Build Coastguard Worker */ 16*6dbdd20aSAndroid Build Coastguard Worker 17*6dbdd20aSAndroid Build Coastguard Worker #ifndef SRC_PROFILING_DEOBFUSCATOR_H_ 18*6dbdd20aSAndroid Build Coastguard Worker #define SRC_PROFILING_DEOBFUSCATOR_H_ 19*6dbdd20aSAndroid Build Coastguard Worker 20*6dbdd20aSAndroid Build Coastguard Worker #include <functional> 21*6dbdd20aSAndroid Build Coastguard Worker #include <map> 22*6dbdd20aSAndroid Build Coastguard Worker #include <string> 23*6dbdd20aSAndroid Build Coastguard Worker #include <utility> 24*6dbdd20aSAndroid Build Coastguard Worker #include <vector> 25*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/status.h" 26*6dbdd20aSAndroid Build Coastguard Worker 27*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto { 28*6dbdd20aSAndroid Build Coastguard Worker namespace profiling { 29*6dbdd20aSAndroid Build Coastguard Worker 30*6dbdd20aSAndroid Build Coastguard Worker std::string FlattenClasses( 31*6dbdd20aSAndroid Build Coastguard Worker const std::map<std::string, std::vector<std::string>>& m); 32*6dbdd20aSAndroid Build Coastguard Worker 33*6dbdd20aSAndroid Build Coastguard Worker class ObfuscatedClass { 34*6dbdd20aSAndroid Build Coastguard Worker public: ObfuscatedClass(std::string d)35*6dbdd20aSAndroid Build Coastguard Worker 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)36*6dbdd20aSAndroid Build Coastguard Worker ObfuscatedClass( 37*6dbdd20aSAndroid Build Coastguard Worker std::string d, 38*6dbdd20aSAndroid Build Coastguard Worker std::map<std::string, std::string> f, 39*6dbdd20aSAndroid Build Coastguard Worker std::map<std::string, std::map<std::string, std::vector<std::string>>> m) 40*6dbdd20aSAndroid Build Coastguard Worker : deobfuscated_name_(std::move(d)), 41*6dbdd20aSAndroid Build Coastguard Worker deobfuscated_fields_(std::move(f)), 42*6dbdd20aSAndroid Build Coastguard Worker deobfuscated_methods_(std::move(m)) {} 43*6dbdd20aSAndroid Build Coastguard Worker deobfuscated_name()44*6dbdd20aSAndroid Build Coastguard Worker const std::string& deobfuscated_name() const { return deobfuscated_name_; } 45*6dbdd20aSAndroid Build Coastguard Worker deobfuscated_fields()46*6dbdd20aSAndroid Build Coastguard Worker const std::map<std::string, std::string>& deobfuscated_fields() const { 47*6dbdd20aSAndroid Build Coastguard Worker return deobfuscated_fields_; 48*6dbdd20aSAndroid Build Coastguard Worker } 49*6dbdd20aSAndroid Build Coastguard Worker deobfuscated_methods()50*6dbdd20aSAndroid Build Coastguard Worker std::map<std::string, std::string> deobfuscated_methods() const { 51*6dbdd20aSAndroid Build Coastguard Worker std::map<std::string, std::string> result; 52*6dbdd20aSAndroid Build Coastguard Worker for (const auto& p : deobfuscated_methods_) { 53*6dbdd20aSAndroid Build Coastguard Worker result.emplace(p.first, FlattenClasses(p.second)); 54*6dbdd20aSAndroid Build Coastguard Worker } 55*6dbdd20aSAndroid Build Coastguard Worker return result; 56*6dbdd20aSAndroid Build Coastguard Worker } 57*6dbdd20aSAndroid Build Coastguard Worker redefined_methods()58*6dbdd20aSAndroid Build Coastguard Worker bool redefined_methods() const { return redefined_methods_; } 59*6dbdd20aSAndroid Build Coastguard Worker AddField(std::string obfuscated_name,std::string deobfuscated_name)60*6dbdd20aSAndroid Build Coastguard Worker bool AddField(std::string obfuscated_name, std::string deobfuscated_name) { 61*6dbdd20aSAndroid Build Coastguard Worker auto p = deobfuscated_fields_.emplace(std::move(obfuscated_name), 62*6dbdd20aSAndroid Build Coastguard Worker deobfuscated_name); 63*6dbdd20aSAndroid Build Coastguard Worker return p.second || p.first->second == deobfuscated_name; 64*6dbdd20aSAndroid Build Coastguard Worker } 65*6dbdd20aSAndroid Build Coastguard Worker AddMethod(std::string obfuscated_name,std::string deobfuscated_name)66*6dbdd20aSAndroid Build Coastguard Worker void AddMethod(std::string obfuscated_name, std::string deobfuscated_name) { 67*6dbdd20aSAndroid Build Coastguard Worker std::string cls = deobfuscated_name_; 68*6dbdd20aSAndroid Build Coastguard Worker auto dot = deobfuscated_name.rfind('.'); 69*6dbdd20aSAndroid Build Coastguard Worker if (dot != std::string::npos) { 70*6dbdd20aSAndroid Build Coastguard Worker cls = deobfuscated_name.substr(0, dot); 71*6dbdd20aSAndroid Build Coastguard Worker deobfuscated_name = deobfuscated_name.substr(dot + 1); 72*6dbdd20aSAndroid Build Coastguard Worker } 73*6dbdd20aSAndroid Build Coastguard Worker auto& deobfuscated_names_for_cls = 74*6dbdd20aSAndroid Build Coastguard Worker deobfuscated_methods_[std::move(obfuscated_name)][std::move(cls)]; 75*6dbdd20aSAndroid Build Coastguard Worker deobfuscated_names_for_cls.push_back(std::move(deobfuscated_name)); 76*6dbdd20aSAndroid Build Coastguard Worker if (deobfuscated_names_for_cls.size() > 1 || 77*6dbdd20aSAndroid Build Coastguard Worker deobfuscated_methods_.size() > 1) { 78*6dbdd20aSAndroid Build Coastguard Worker redefined_methods_ = true; 79*6dbdd20aSAndroid Build Coastguard Worker } 80*6dbdd20aSAndroid Build Coastguard Worker } 81*6dbdd20aSAndroid Build Coastguard Worker 82*6dbdd20aSAndroid Build Coastguard Worker private: 83*6dbdd20aSAndroid Build Coastguard Worker std::string deobfuscated_name_; 84*6dbdd20aSAndroid Build Coastguard Worker std::map<std::string, std::string> deobfuscated_fields_; 85*6dbdd20aSAndroid Build Coastguard Worker std::map<std::string, std::map<std::string, std::vector<std::string>>> 86*6dbdd20aSAndroid Build Coastguard Worker deobfuscated_methods_; 87*6dbdd20aSAndroid Build Coastguard Worker bool redefined_methods_ = false; 88*6dbdd20aSAndroid Build Coastguard Worker }; 89*6dbdd20aSAndroid Build Coastguard Worker 90*6dbdd20aSAndroid Build Coastguard Worker class ProguardParser { 91*6dbdd20aSAndroid Build Coastguard Worker public: 92*6dbdd20aSAndroid Build Coastguard Worker // A return value of false means this line failed to parse. This leaves the 93*6dbdd20aSAndroid Build Coastguard Worker // parser in an undefined state and it should no longer be used. 94*6dbdd20aSAndroid Build Coastguard Worker base::Status AddLine(std::string line); 95*6dbdd20aSAndroid Build Coastguard Worker bool AddLines(std::string contents); 96*6dbdd20aSAndroid Build Coastguard Worker ConsumeMapping()97*6dbdd20aSAndroid Build Coastguard Worker std::map<std::string, ObfuscatedClass> ConsumeMapping() { 98*6dbdd20aSAndroid Build Coastguard Worker return std::move(mapping_); 99*6dbdd20aSAndroid Build Coastguard Worker } 100*6dbdd20aSAndroid Build Coastguard Worker 101*6dbdd20aSAndroid Build Coastguard Worker private: 102*6dbdd20aSAndroid Build Coastguard Worker std::map<std::string, ObfuscatedClass> mapping_; 103*6dbdd20aSAndroid Build Coastguard Worker ObfuscatedClass* current_class_ = nullptr; 104*6dbdd20aSAndroid Build Coastguard Worker }; 105*6dbdd20aSAndroid Build Coastguard Worker 106*6dbdd20aSAndroid Build Coastguard Worker struct ProguardMap { 107*6dbdd20aSAndroid Build Coastguard Worker std::string package; 108*6dbdd20aSAndroid Build Coastguard Worker std::string filename; 109*6dbdd20aSAndroid Build Coastguard Worker }; 110*6dbdd20aSAndroid Build Coastguard Worker 111*6dbdd20aSAndroid Build Coastguard Worker void MakeDeobfuscationPackets( 112*6dbdd20aSAndroid Build Coastguard Worker const std::string& package_name, 113*6dbdd20aSAndroid Build Coastguard Worker const std::map<std::string, profiling::ObfuscatedClass>& mapping, 114*6dbdd20aSAndroid Build Coastguard Worker std::function<void(const std::string&)> callback); 115*6dbdd20aSAndroid Build Coastguard Worker 116*6dbdd20aSAndroid Build Coastguard Worker std::vector<ProguardMap> GetPerfettoProguardMapPath(); 117*6dbdd20aSAndroid Build Coastguard Worker 118*6dbdd20aSAndroid Build Coastguard Worker bool ReadProguardMapsToDeobfuscationPackets( 119*6dbdd20aSAndroid Build Coastguard Worker const std::vector<ProguardMap>& maps, 120*6dbdd20aSAndroid Build Coastguard Worker std::function<void(std::string)> fn); 121*6dbdd20aSAndroid Build Coastguard Worker 122*6dbdd20aSAndroid Build Coastguard Worker } // namespace profiling 123*6dbdd20aSAndroid Build Coastguard Worker } // namespace perfetto 124*6dbdd20aSAndroid Build Coastguard Worker 125*6dbdd20aSAndroid Build Coastguard Worker #endif // SRC_PROFILING_DEOBFUSCATOR_H_ 126