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