blob: 061b5da7e18dc798ca33761f3fb6fbeb26608af8 [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 Mayer82375962019-11-20 16:45:28 +000025
26namespace perfetto {
27namespace profiling {
28
Florian Mayer08b03bc2020-12-15 16:20:32 +000029std::string FlattenClasses(
30 const std::map<std::string, std::vector<std::string>>& m);
Florian Mayer82375962019-11-20 16:45:28 +000031
Florian Mayer08b03bc2020-12-15 16:20:32 +000032class ObfuscatedClass {
33 public:
34 explicit ObfuscatedClass(std::string d) : deobfuscated_name_(std::move(d)) {}
35 ObfuscatedClass(
36 std::string d,
37 std::map<std::string, std::string> f,
38 std::map<std::string, std::map<std::string, std::vector<std::string>>> m)
39 : deobfuscated_name_(std::move(d)),
40 deobfuscated_fields_(std::move(f)),
41 deobfuscated_methods_(std::move(m)) {}
42
43 const std::string& deobfuscated_name() const { return deobfuscated_name_; }
44
45 const std::map<std::string, std::string>& deobfuscated_fields() const {
46 return deobfuscated_fields_;
47 }
48
49 std::map<std::string, std::string> deobfuscated_methods() const {
50 std::map<std::string, std::string> result;
51 for (const auto& p : deobfuscated_methods_) {
52 result.emplace(p.first, FlattenClasses(p.second));
53 }
54 return result;
55 }
56
57 bool redefined_methods() const { return redefined_methods_; }
58
59 bool AddField(std::string obfuscated_name, std::string deobfuscated_name) {
60 auto p = deobfuscated_fields_.emplace(std::move(obfuscated_name),
61 deobfuscated_name);
62 return p.second && p.first->second == deobfuscated_name;
63 }
64
65 void AddMethod(std::string obfuscated_name, std::string deobfuscated_name) {
66 std::string cls = deobfuscated_name_;
67 auto dot = deobfuscated_name.rfind('.');
68 if (dot != std::string::npos) {
69 cls = deobfuscated_name.substr(0, dot);
70 deobfuscated_name = deobfuscated_name.substr(dot + 1);
71 }
72 auto& deobfuscated_names_for_cls =
73 deobfuscated_methods_[std::move(obfuscated_name)][std::move(cls)];
74 deobfuscated_names_for_cls.push_back(std::move(deobfuscated_name));
75 if (deobfuscated_names_for_cls.size() > 1 ||
76 deobfuscated_methods_.size() > 1) {
77 redefined_methods_ = true;
78 }
79 }
80
81 private:
82 std::string deobfuscated_name_;
83 std::map<std::string, std::string> deobfuscated_fields_;
84 std::map<std::string, std::map<std::string, std::vector<std::string>>>
85 deobfuscated_methods_;
86 bool redefined_methods_ = false;
Florian Mayer82375962019-11-20 16:45:28 +000087};
88
89class ProguardParser {
90 public:
91 // A return value of false means this line failed to parse. This leaves the
92 // parser in an undefined state and it should no longer be used.
93 bool AddLine(std::string line);
Florian Mayerf4255a42020-12-14 19:12:34 +000094 bool AddLines(std::string contents);
Florian Mayer82375962019-11-20 16:45:28 +000095
96 std::map<std::string, ObfuscatedClass> ConsumeMapping() {
97 return std::move(mapping_);
98 }
99
100 private:
101 std::map<std::string, ObfuscatedClass> mapping_;
102 ObfuscatedClass* current_class_ = nullptr;
103};
104
Florian Mayerf4255a42020-12-14 19:12:34 +0000105struct ProguardMap {
106 std::string package;
107 std::string filename;
108};
109
110void MakeDeobfuscationPackets(
111 const std::string& package_name,
112 const std::map<std::string, profiling::ObfuscatedClass>& mapping,
113 std::function<void(const std::string&)> callback);
114
115std::vector<ProguardMap> GetPerfettoProguardMapPath();
116
117bool ReadProguardMapsToDeobfuscationPackets(
118 const std::vector<ProguardMap>& maps,
119 std::function<void(std::string)> fn);
120
Florian Mayer82375962019-11-20 16:45:28 +0000121} // namespace profiling
122} // namespace perfetto
123
Florian Mayer9a683092020-12-23 18:30:00 +0000124#endif // SRC_PROFILING_DEOBFUSCATOR_H_