xref: /aosp_15_r20/external/perfetto/src/profiling/deobfuscator.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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