1 /**
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "entity.h"
17
18 #include "configs/guard_context.h"
19 #include "file_path.h"
20 #include "program.h"
21
22 namespace {
23 constexpr std::string_view TAG = "[Entity]";
24 constexpr std::string_view SCOPE_DELIMITER = "#";
25 } // namespace
26
Create()27 void panda::guard::Entity::Create()
28 {
29 this->Build();
30 this->RefreshNeedUpdate();
31
32 LOG(INFO, PANDAGUARD) << TAG << "needUpdate:" << (this->needUpdate ? "true" : "false");
33 }
34
Obfuscate()35 void panda::guard::Entity::Obfuscate()
36 {
37 if (!this->needUpdate) {
38 return;
39 }
40
41 this->Update();
42
43 this->obfuscated = true;
44 }
45
Build()46 void panda::guard::Entity::Build() {}
47
RefreshNeedUpdate()48 void panda::guard::Entity::RefreshNeedUpdate() {}
49
Update()50 void panda::guard::Entity::Update() {}
51
WriteNameCache(const std::string & filePath)52 void panda::guard::Entity::WriteNameCache(const std::string &filePath)
53 {
54 this->WriteFileCache(filePath);
55 this->WritePropertyCache();
56 }
57
SetNameCacheScope(const std::string & name)58 void panda::guard::Entity::SetNameCacheScope(const std::string &name)
59 {
60 if (this->scope_ == TOP_LEVEL) {
61 this->nameCacheScope_ = name;
62 } else {
63 if (!this->defineInsList_.empty() && this->defineInsList_[0].function_) {
64 this->nameCacheScope_ = this->defineInsList_[0].function_->nameCacheScope_ + SCOPE_DELIMITER.data() + name;
65 }
66 }
67 }
68
GetNameCacheScope() const69 std::string panda::guard::Entity::GetNameCacheScope() const
70 {
71 return this->scope_ == TOP_LEVEL ? SCOPE_DELIMITER.data() + this->nameCacheScope_ : this->nameCacheScope_;
72 }
73
IsExport() const74 bool panda::guard::Entity::IsExport() const
75 {
76 if (this->scope_ != TOP_LEVEL) {
77 return false;
78 }
79
80 return this->export_;
81 }
82
WriteFileCache(const std::string & filePath)83 void panda::guard::Entity::WriteFileCache(const std::string &filePath) {}
84
WritePropertyCache()85 void panda::guard::Entity::WritePropertyCache() {}
86
GetName() const87 std::string panda::guard::Entity::GetName() const
88 {
89 return this->name_;
90 }
91
GetObfName() const92 std::string panda::guard::Entity::GetObfName() const
93 {
94 return this->obfName_;
95 }
96
NeedUpdate(const Entity & entity)97 bool panda::guard::TopLevelOptionEntity::NeedUpdate(const Entity &entity)
98 {
99 bool needUpdate = true;
100 do {
101 const auto options = GuardContext::GetInstance()->GetGuardOptions();
102 if (entity.IsExport()) {
103 needUpdate = options->IsExportObfEnabled() && options->IsToplevelObfEnabled();
104 break;
105 }
106
107 if (entity.scope_ == TOP_LEVEL) {
108 needUpdate = options->IsToplevelObfEnabled();
109 break;
110 }
111 } while (false);
112
113 if (!needUpdate) {
114 GuardContext::GetInstance()->GetNameMapping()->AddNameMapping(entity.name_);
115 }
116
117 return needUpdate;
118 }
119
RefreshNeedUpdate()120 void panda::guard::TopLevelOptionEntity::RefreshNeedUpdate()
121 {
122 this->needUpdate = NeedUpdate(*this);
123 }
124
WritePropertyCache(const panda::guard::Entity & entity)125 void panda::guard::TopLevelOptionEntity::WritePropertyCache(const panda::guard::Entity &entity)
126 {
127 if (!entity.obfuscated || entity.GetName().empty() || entity.GetObfName().empty() || (entity.scope_ != TOP_LEVEL)) {
128 return;
129 }
130
131 const auto options = GuardContext::GetInstance()->GetGuardOptions();
132 if (!options->IsPropertyObfEnabled() || !options->IsToplevelObfEnabled()) {
133 return;
134 }
135
136 if (entity.IsExport()) {
137 if (options->IsExportObfEnabled()) {
138 GuardContext::GetInstance()->GetNameCache()->AddObfPropertyName(entity.GetName(), entity.GetObfName());
139 }
140 } else {
141 GuardContext::GetInstance()->GetNameCache()->AddObfPropertyName(entity.GetName(), entity.GetObfName());
142 }
143 }
144
WritePropertyCache()145 void panda::guard::TopLevelOptionEntity::WritePropertyCache()
146 {
147 return WritePropertyCache(*this);
148 }
149
NeedUpdate(const Entity & entity)150 bool panda::guard::PropertyOptionEntity::NeedUpdate(const Entity &entity)
151 {
152 const auto options = GuardContext::GetInstance()->GetGuardOptions();
153 bool needUpdate;
154 if (entity.IsExport()) {
155 needUpdate = options->IsExportObfEnabled() && options->IsPropertyObfEnabled();
156 } else {
157 needUpdate = options->IsPropertyObfEnabled();
158 }
159 if (!needUpdate) {
160 GuardContext::GetInstance()->GetNameMapping()->AddNameMapping(entity.name_);
161 }
162 return needUpdate;
163 }
164
RefreshNeedUpdate()165 void panda::guard::PropertyOptionEntity::RefreshNeedUpdate()
166 {
167 this->needUpdate = NeedUpdate(*this);
168 }
169
WritePropertyCache(const panda::guard::Entity & entity)170 void panda::guard::PropertyOptionEntity::WritePropertyCache(const panda::guard::Entity &entity)
171 {
172 if (!entity.obfuscated || entity.GetName().empty() || entity.GetObfName().empty()) {
173 return;
174 }
175
176 const auto options = GuardContext::GetInstance()->GetGuardOptions();
177 if (!options->IsPropertyObfEnabled()) {
178 return;
179 }
180
181 if (entity.IsExport()) {
182 if (options->IsExportObfEnabled()) {
183 GuardContext::GetInstance()->GetNameCache()->AddObfPropertyName(entity.GetName(), entity.GetObfName());
184 }
185 } else {
186 GuardContext::GetInstance()->GetNameCache()->AddObfPropertyName(entity.GetName(), entity.GetObfName());
187 }
188 }
189
WritePropertyCache()190 void panda::guard::PropertyOptionEntity::WritePropertyCache()
191 {
192 return WritePropertyCache(*this);
193 }
194
IsInnerReg() const195 bool panda::guard::InstructionInfo::IsInnerReg() const
196 {
197 // if regs[0] is less than regsNum, the register is v, otherwise, the register is a
198 return this->ins_->regs[0] < this->function_->regsNum;
199 }
200
UpdateInsName(bool generateNewName)201 void panda::guard::InstructionInfo::UpdateInsName(bool generateNewName)
202 {
203 this->origin_ = this->ins_->ids[0];
204 this->obfName_ = GuardContext::GetInstance()->GetNameMapping()->GetName(this->origin_, generateNewName);
205 this->ins_->ids[0] = this->obfName_;
206 this->function_->program_->prog_->strings.emplace(this->obfName_);
207 }
208
UpdateInsFileName()209 void panda::guard::InstructionInfo::UpdateInsFileName()
210 {
211 this->origin_ = this->ins_->ids[0];
212 ReferenceFilePath filePath(this->function_->program_);
213 filePath.SetFilePath(this->origin_);
214 filePath.Init();
215 filePath.Update();
216 this->obfName_ = filePath.obfFilePath_;
217 this->ins_->ids[0] = this->obfName_;
218 this->function_->program_->prog_->strings.emplace(this->obfName_);
219 }
220
WriteNameCache()221 void panda::guard::InstructionInfo::WriteNameCache()
222 {
223 GuardContext::GetInstance()->GetNameCache()->AddObfPropertyName(this->origin_, this->obfName_);
224 }
225
IsValid() const226 bool panda::guard::InstructionInfo::IsValid() const
227 {
228 return this->ins_ != nullptr;
229 }
230