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 "node.h"
17
18 #include "utils/logger.h"
19
20 #include "configs/guard_context.h"
21 #include "graph_analyzer.h"
22 #include "program.h"
23 #include "util/assert_util.h"
24 #include "util/string_util.h"
25
26 namespace {
27 using OpcodeList = std::vector<panda::pandasm::Opcode>;
28
29 constexpr std::string_view TAG = "[Node]";
30 constexpr std::string_view ENTRY_FUNC_NAME = ".func_main_0";
31 constexpr std::string_view NORMALIZED_OHM_DELIMITER = "&";
32 constexpr std::string_view PATH_DELIMITER = "/";
33 constexpr std::string_view PACKAGE_MODULES_PREFIX = "pkg_modules";
34 constexpr std::string_view PKG_NAME_PREFIX = "pkgName@";
35 constexpr std::string_view SCOPE_NAMES_FIELD = "scopeNames";
36 constexpr std::string_view JSON_FILE_FIELD = "jsonFileContent";
37
38 const OpcodeList METHOD_NAME_DIRECT_LIST = {
39 panda::pandasm::Opcode::STOWNBYNAME,
40 panda::pandasm::Opcode::STOWNBYNAMEWITHNAMESET,
41 };
42
43 const OpcodeList METHOD_NAME_INDIRECT_LIST = {
44 panda::pandasm::Opcode::DEFINEGETTERSETTERBYVALUE,
45 panda::pandasm::Opcode::STOWNBYVALUE,
46 panda::pandasm::Opcode::STOWNBYVALUEWITHNAMESET,
47 };
48
InOpcodeList(const panda::guard::InstructionInfo & info,const OpcodeList & list)49 bool InOpcodeList(const panda::guard::InstructionInfo &info, const OpcodeList &list)
50 {
51 return std::any_of(list.begin(), list.end(), [&](const auto &elem) { return elem == info.ins_->opcode; });
52 }
53
UpdateScopeNamesLiteralArray(panda::pandasm::LiteralArray & literalArray)54 void UpdateScopeNamesLiteralArray(panda::pandasm::LiteralArray &literalArray)
55 {
56 for (auto &literal : literalArray.literals_) {
57 if (!literal.IsStringValue()) {
58 continue;
59 }
60
61 const auto &value = std::get<std::string>(literal.value_);
62 literal.value_ = panda::guard::GuardContext::GetInstance()->GetNameMapping()->GetName(value);
63 }
64 }
65
66 } // namespace
67
Build()68 void panda::guard::Node::Build()
69 {
70 LOG(INFO, PANDAGUARD) << TAG << "node create for " << this->name_ << " start";
71
72 this->sourceName_ = GuardContext::GetInstance()->GetGuardOptions()->GetSourceName(this->name_);
73 this->obfSourceName_ = this->sourceName_;
74 LOG(INFO, PANDAGUARD) << TAG << "node sourceName_ " << this->sourceName_;
75
76 this->isNormalizedOhmUrl_ = GuardContext::GetInstance()->GetGuardOptions()->IsUseNormalizedOhmUrl();
77 CreateFilePath();
78 this->filepath_.obfName = this->filepath_.name;
79 LOG(INFO, PANDAGUARD) << TAG << "pre part: " << this->filepath_.prePart;
80 LOG(INFO, PANDAGUARD) << TAG << "file path: " << this->filepath_.name;
81 LOG(INFO, PANDAGUARD) << TAG << "post part: " << this->filepath_.postPart;
82
83 moduleRecord_.Create();
84 if (!Node::IsJsonFile(this->program_->prog_->record_table.at(this->name_))) {
85 Function entryFunc(this->program_, this->name_ + ENTRY_FUNC_NAME.data(), false);
86 entryFunc.Init();
87 entryFunc.Create();
88
89 const auto &function = entryFunc.GetOriginFunction();
90 this->sourceFile_ = function.source_file;
91 this->obfSourceFile_ = function.source_file;
92
93 this->functionTable_.emplace(entryFunc.idx_, entryFunc);
94
95 entryFunc.ForEachIns([&](const InstructionInfo &info) -> void { ForEachIns(info, TOP_LEVEL); });
96 } else {
97 LOG(INFO, PANDAGUARD) << "json file record:" << this->name_;
98 }
99
100 this->ExtractNames();
101
102 LOG(INFO, PANDAGUARD) << TAG << "node create for " << this->name_ << " end";
103 }
104
ForEachIns(const panda::guard::InstructionInfo & info,panda::guard::Scope scope)105 void panda::guard::Node::ForEachIns(const panda::guard::InstructionInfo &info, panda::guard::Scope scope)
106 {
107 CreateFunction(info, scope);
108 CreateClass(info, scope);
109 CreateOuterMethod(info);
110 CreateObject(info, scope);
111 CreateObjectOuterProperty(info);
112 CreateOuterProperty(info);
113 FindStLexVarName(info);
114 }
115
CreateFunction(const InstructionInfo & info,const Scope scope)116 void panda::guard::Node::CreateFunction(const InstructionInfo &info, const Scope scope)
117 {
118 if (info.ins_->opcode != pandasm::Opcode::DEFINEFUNC) {
119 return;
120 }
121
122 const std::string idx = info.ins_->ids[0];
123 if (this->functionTable_.find(idx) != this->functionTable_.end()) {
124 this->functionTable_.at(idx).defineInsList_.push_back(info);
125 return;
126 }
127
128 Function function(this->program_, idx);
129 function.scope_ = scope;
130 function.defineInsList_.push_back(info);
131
132 function.Init();
133
134 function.export_ = this->moduleRecord_.IsExportVar(function.name_);
135 function.Create();
136
137 function.ForEachIns([&](const InstructionInfo &insInfo) -> void { ForEachIns(insInfo, FUNCTION); });
138
139 this->functionTable_.emplace(function.idx_, function);
140 }
141
CreateClass(const InstructionInfo & info,const Scope scope)142 void panda::guard::Node::CreateClass(const InstructionInfo &info, const Scope scope)
143 {
144 if ((info.ins_->opcode != pandasm::Opcode::DEFINECLASSWITHBUFFER) &&
145 (info.ins_->opcode != pandasm::Opcode::CALLRUNTIME_DEFINESENDABLECLASS)) {
146 return;
147 }
148
149 const std::string idx = info.ins_->ids[1];
150 if (this->classTable_.find(idx) != this->classTable_.end()) {
151 this->classTable_.at(idx).defineInsList_.push_back(info);
152 return;
153 }
154
155 Class clazz(this->program_, info.ins_->ids[0]);
156 clazz.moduleRecord_ = &this->moduleRecord_;
157 clazz.literalArrayIdx_ = idx;
158 clazz.defineInsList_.push_back(info);
159 clazz.component = GraphAnalyzer::IsComponentClass(info);
160 clazz.scope_ = scope;
161 if (info.ins_->opcode == pandasm::Opcode::CALLRUNTIME_DEFINESENDABLECLASS) {
162 clazz.callRunTimeInst_ = true;
163 }
164 clazz.Create();
165
166 clazz.ForEachMethodIns([&](const InstructionInfo &insInfo) -> void { ForEachIns(insInfo, FUNCTION); });
167
168 this->classTable_.emplace(clazz.literalArrayIdx_, clazz);
169 }
170
CreateOuterMethod(const InstructionInfo & info)171 void panda::guard::Node::CreateOuterMethod(const InstructionInfo &info)
172 {
173 if (info.ins_->opcode != pandasm::Opcode::DEFINEMETHOD) {
174 return;
175 }
176
177 InstructionInfo defineInsInfo;
178 InstructionInfo nameInsInfo;
179 GraphAnalyzer::HandleDefineMethod(info, defineInsInfo, nameInsInfo);
180
181 const std::string methodIdx = info.ins_->ids[0];
182 std::string literalArrayIdx;
183 if ((defineInsInfo.ins_->opcode == pandasm::Opcode::DEFINECLASSWITHBUFFER) ||
184 (defineInsInfo.ins_->opcode == pandasm::Opcode::CALLRUNTIME_DEFINESENDABLECLASS)) {
185 literalArrayIdx = defineInsInfo.ins_->ids[1];
186 } else { // createobjectwithbuffer
187 literalArrayIdx = defineInsInfo.ins_->ids[0];
188 }
189
190 OuterMethod outerMethod(this->program_, methodIdx);
191 outerMethod.defineInsList_.push_back(info);
192 GetMethodNameInfo(nameInsInfo, outerMethod.nameInfo_);
193 outerMethod.Init();
194
195 if (this->classTable_.find(literalArrayIdx) != this->classTable_.end()) {
196 auto &clazz = this->classTable_.at(literalArrayIdx);
197 outerMethod.className_ = clazz.name_;
198 outerMethod.export_ = clazz.export_;
199 outerMethod.scope_ = clazz.scope_;
200
201 outerMethod.Create();
202
203 LOG(INFO, PANDAGUARD) << TAG << "found method:" << methodIdx << " for class:" << clazz.constructor_.name_;
204 clazz.outerMethods_.push_back(outerMethod);
205 } else if (this->objectTable_.find(literalArrayIdx) != this->objectTable_.end()) {
206 auto &obj = this->objectTable_.at(literalArrayIdx);
207 outerMethod.export_ = obj.export_;
208 outerMethod.scope_ = obj.scope_;
209
210 outerMethod.Create();
211
212 LOG(INFO, PANDAGUARD) << TAG << "found method:" << methodIdx << " for obj:" << obj.literalArrayIdx_;
213 obj.outerMethods_.push_back(outerMethod);
214 } else {
215 PANDA_GUARD_ABORT_PRINT(TAG, ErrorCode::GENERIC_ERROR, "unexpect outer method for:" << literalArrayIdx);
216 }
217
218 outerMethod.ForEachIns([&](const InstructionInfo &insInfo) -> void { ForEachIns(insInfo, FUNCTION); });
219 }
220
CreateObject(const InstructionInfo & info,const Scope scope)221 void panda::guard::Node::CreateObject(const InstructionInfo &info, const Scope scope)
222 {
223 if (info.ins_->opcode != pandasm::Opcode::CREATEOBJECTWITHBUFFER) {
224 return;
225 }
226
227 const std::string idx = info.ins_->ids[0];
228 if (this->objectTable_.find(idx) != this->objectTable_.end()) {
229 this->objectTable_.at(idx).defineInsList_.push_back(info);
230 return;
231 }
232
233 Object object(this->program_, idx);
234 LOG(INFO, PANDAGUARD) << TAG << "found record object:" << object.literalArrayIdx_;
235 object.defineInsList_.push_back(info);
236 object.scope_ = scope;
237 object.moduleRecord = &this->moduleRecord_;
238 object.Create();
239
240 object.ForEachMethod([&](Function &function) -> void {
241 function.ForEachIns([&](const InstructionInfo &insInfo) -> void { ForEachIns(insInfo, FUNCTION); });
242 });
243
244 this->objectTable_.emplace(object.literalArrayIdx_, object);
245 }
246
CreateObjectOuterProperty(const panda::guard::InstructionInfo & info)247 void panda::guard::Node::CreateObjectOuterProperty(const panda::guard::InstructionInfo &info)
248 {
249 if (info.ins_->opcode != pandasm::Opcode::DEFINEPROPERTYBYNAME) {
250 return;
251 }
252
253 InstructionInfo defineIns;
254 GraphAnalyzer::HandleDefineProperty(info, defineIns);
255 if (!defineIns.IsValid()) {
256 return;
257 }
258
259 PANDA_GUARD_ASSERT_PRINT(defineIns.ins_->opcode != pandasm::Opcode::CREATEOBJECTWITHBUFFER, TAG,
260 ErrorCode::GENERIC_ERROR, "unexpect related define ins");
261
262 const std::string literalArrayIdx = defineIns.ins_->ids[0];
263 PANDA_GUARD_ASSERT_PRINT(this->objectTable_.find(literalArrayIdx) == this->objectTable_.end(), TAG,
264 ErrorCode::GENERIC_ERROR, "no record object for literalArrayIdx:" << literalArrayIdx);
265
266 auto &object = this->objectTable_.at(literalArrayIdx);
267 Property property(this->program_, info.ins_->ids[0]);
268 property.defineInsList_.push_back(info);
269 property.nameInfo_ = info;
270 property.export_ = object.export_;
271 property.scope_ = object.scope_;
272
273 property.Create();
274
275 object.outerProperties_.push_back(property);
276 LOG(INFO, PANDAGUARD) << TAG << "found object outer property:" << property.name_;
277 }
278
CreateOuterProperty(const InstructionInfo & info)279 void panda::guard::Node::CreateOuterProperty(const InstructionInfo &info)
280 {
281 if ((info.ins_->opcode != pandasm::Opcode::STOBJBYNAME) && (info.ins_->opcode != pandasm::Opcode::STOBJBYVALUE)) {
282 return;
283 }
284
285 InstructionInfo nameInfo;
286 Property::GetPropertyNameInfo(info, nameInfo);
287 if (!nameInfo.IsValid()) {
288 LOG(INFO, PANDAGUARD) << TAG << "invalid nameInfo:" << info.index_ << " " << info.ins_->ToString();
289 return;
290 }
291
292 Property property(this->program_, nameInfo.ins_->ids[0]);
293 property.defineInsList_.push_back(info);
294 property.nameInfo_ = nameInfo;
295
296 property.Create();
297
298 this->outerProperties_.push_back(property);
299 LOG(INFO, PANDAGUARD) << TAG << "found outer property:" << property.name_;
300 }
301
FindStLexVarName(const panda::guard::InstructionInfo & info)302 void panda::guard::Node::FindStLexVarName(const panda::guard::InstructionInfo &info)
303 {
304 if (info.ins_->opcode != pandasm::Opcode::STLEXVAR) {
305 return;
306 }
307
308 InstructionInfo outInfo;
309 GraphAnalyzer::GetLdaStr(info, outInfo);
310 if (!outInfo.IsValid()) {
311 return;
312 }
313
314 LOG(INFO, PANDAGUARD) << TAG << "found stlexvar name:" << outInfo.ins_->ids[0];
315 GuardContext::GetInstance()->GetNameMapping()->AddNameMapping(outInfo.ins_->ids[0]);
316 }
317
CreateFilePath()318 void panda::guard::Node::CreateFilePath()
319 {
320 if (!GuardContext::GetInstance()->GetGuardOptions()->IsFileNameObfEnabled()) {
321 this->filepath_.name = this->name_;
322 return;
323 }
324
325 if (this->isNormalizedOhmUrl_) {
326 CreateFilePathForNormalizedMode();
327 } else {
328 CreateFilePathForDefaultMode();
329 }
330 }
331
CreateFilePathForDefaultMode()332 void panda::guard::Node::CreateFilePathForDefaultMode()
333 {
334 bool isRemoteHar = StringUtil::IsPrefixMatched(name_, PACKAGE_MODULES_PREFIX.data());
335 if (isRemoteHar) {
336 std::string prefix = pkgName_ + PATH_DELIMITER.data();
337 PANDA_GUARD_ASSERT_PRINT(!StringUtil::IsPrefixMatched(name_, prefix), TAG, ErrorCode::GENERIC_ERROR,
338 "invalid remote har prefix");
339 filepath_.prePart = std::move(prefix);
340
341 filepath_.name = name_.substr(filepath_.prePart.size(), name_.size() - filepath_.prePart.size());
342 return;
343 }
344
345 // format: bundleName/hapPkgName@pkgName/filepath
346 size_t startPos = name_.find_first_of(PATH_DELIMITER.data(), 0);
347 if (startPos == std::string::npos) {
348 filepath_.name = name_;
349 return;
350 }
351
352 std::string toFound = pkgName_ + PATH_DELIMITER.data();
353 size_t foundPos = name_.find(toFound, startPos);
354 if (foundPos == std::string::npos) {
355 filepath_.name = name_;
356 return;
357 }
358
359 foundPos += toFound.size();
360 filepath_.prePart = name_.substr(0, foundPos);
361 filepath_.name = name_.substr(foundPos, name_.size() - foundPos);
362 }
363
CreateFilePathForNormalizedMode()364 void panda::guard::Node::CreateFilePathForNormalizedMode()
365 {
366 // [<bundle name>?]&<package name>/<file path>&[<version>?]
367 size_t startPos = name_.find_first_of(NORMALIZED_OHM_DELIMITER.data(), 0);
368 std::string prefix = NORMALIZED_OHM_DELIMITER.data() + pkgName_ + PATH_DELIMITER.data();
369 PANDA_GUARD_ASSERT_PRINT(!StringUtil::IsPrefixMatched(name_, prefix, startPos), TAG, ErrorCode::GENERIC_ERROR,
370 "invalid normalizedOhmUrl prefix");
371 size_t prefixEnd = startPos + prefix.size();
372 filepath_.prePart = name_.substr(0, prefixEnd);
373
374 size_t filePathEnd = name_.find_first_of(NORMALIZED_OHM_DELIMITER.data(), prefixEnd);
375 PANDA_GUARD_ASSERT_PRINT(filePathEnd == std::string::npos, TAG, ErrorCode::GENERIC_ERROR,
376 "invalid normalizedOhmUrl format");
377 filepath_.name = name_.substr(prefixEnd, filePathEnd - prefixEnd);
378
379 filepath_.postPart = name_.substr(filePathEnd, name_.size() - filePathEnd);
380 }
381
ExtractNames()382 void panda::guard::Node::ExtractNames()
383 {
384 moduleRecord_.ExtractNames(this->strings_);
385
386 for (const auto &[_, function] : this->functionTable_) {
387 function.ExtractNames(this->strings_);
388 }
389
390 for (const auto &[_, clazz] : this->classTable_) {
391 clazz.ExtractNames(this->strings_);
392 }
393
394 for (const auto &[_, object] : this->objectTable_) {
395 object.ExtractNames(this->strings_);
396 }
397
398 auto parts = StringUtil::Split(filepath_.name, PATH_DELIMITER.data());
399 for (const auto &part : parts) {
400 this->strings_.emplace(part);
401 }
402
403 GuardContext::GetInstance()->GetNameMapping()->AddReservedNames(this->strings_);
404
405 LOG(INFO, PANDAGUARD) << TAG << "strings:";
406 for (const auto &str : this->strings_) {
407 LOG(INFO, PANDAGUARD) << TAG << str;
408 }
409 }
410
RefreshNeedUpdate()411 void panda::guard::Node::RefreshNeedUpdate()
412 {
413 this->fileNameNeedUpdate_ = GuardContext::GetInstance()->GetGuardOptions()->IsFileNameObfEnabled();
414
415 if (GuardContext::GetInstance()->GetGuardOptions()->IsKeepPath(this->name_)) {
416 LOG(INFO, PANDAGUARD) << TAG << "found keep rule for:" << this->name_;
417 this->contentNeedUpdate_ = false;
418 GuardContext::GetInstance()->GetNameMapping()->AddNameMapping(this->strings_);
419 }
420
421 for (auto &[_, object] : this->objectTable_) {
422 object.SetContentNeedUpdate(this->contentNeedUpdate_);
423 }
424
425 this->needUpdate = this->fileNameNeedUpdate_ || this->contentNeedUpdate_;
426 }
427
ForEachFunction(const std::function<FunctionTraver> & callback)428 void panda::guard::Node::ForEachFunction(const std::function<FunctionTraver> &callback)
429 {
430 for (auto &[_, function] : this->functionTable_) {
431 callback(function);
432 }
433
434 for (auto &[_, clazz] : this->classTable_) {
435 clazz.ForEachFunction(callback);
436 }
437
438 for (auto &[_, object] : this->objectTable_) {
439 object.ForEachMethod(callback);
440 }
441 }
442
Update()443 void panda::guard::Node::Update()
444 {
445 LOG(INFO, PANDAGUARD) << TAG << "node update for " << this->name_ << " start";
446
447 if (this->fileNameNeedUpdate_) {
448 UpdateFileNameDefine();
449 }
450
451 // fileNameNeedUpdate_ || contentNeedUpdate_
452 for (auto &[_, function] : this->functionTable_) {
453 function.Obfuscate();
454 function.WriteNameCache(this->sourceName_);
455 }
456
457 for (auto &[_, clazz] : this->classTable_) {
458 clazz.Obfuscate();
459 clazz.WriteNameCache(this->sourceName_);
460 }
461
462 for (auto &[_, object] : this->objectTable_) {
463 object.Obfuscate();
464 object.WriteNameCache(this->sourceName_);
465 }
466
467 for (auto &property : this->outerProperties_) {
468 property.Obfuscate();
469 property.WriteNameCache(this->sourceName_);
470 }
471
472 if (this->contentNeedUpdate_) {
473 moduleRecord_.Obfuscate();
474 moduleRecord_.WriteNameCache(this->sourceName_);
475 }
476
477 this->WriteFileCache(this->sourceName_);
478
479 LOG(INFO, PANDAGUARD) << TAG << "node update for " << this->name_ << " end";
480 }
481
WriteFileCache(const std::string & filePath)482 void panda::guard::Node::WriteFileCache(const std::string &filePath)
483 {
484 GuardContext::GetInstance()->GetNameCache()->AddObfName(filePath, this->obfSourceName_);
485 GuardContext::GetInstance()->GetNameCache()->AddSourceFile(filePath, this->sourceFile_, this->obfSourceFile_);
486 }
487
UpdateRecordTable()488 void panda::guard::Node::UpdateRecordTable()
489 {
490 auto entry = this->program_->prog_->record_table.extract(this->name_);
491 entry.key() = this->obfName_;
492 entry.mapped().name = this->obfName_;
493 if (!entry.mapped().source_file.empty()) {
494 this->UpdateSourceFile(entry.mapped().source_file);
495 entry.mapped().source_file = this->obfSourceFile_;
496 }
497 this->program_->prog_->record_table.insert(std::move(entry));
498 }
499
UpdateFileNameDefine()500 void panda::guard::Node::UpdateFileNameDefine()
501 {
502 filepath_.obfName = GuardContext::GetInstance()->GetNameMapping()->GetFilePath(filepath_.name);
503 obfName_ = filepath_.prePart + filepath_.obfName + filepath_.postPart;
504 UpdateRecordTable();
505
506 /* e.g.
507 * sourceName_: entry/src/main/ets/entryability/EntryAbility.ets
508 * filepath_.name: src/main/ets/entryability/EntryAbility
509 * sourceNamePrePart: entry/
510 * sourceNamePostPart: .ets
511 */
512 const auto &[sourceNamePrePart, sourceNamePostPart] = StringUtil::RSplitOnce(this->sourceName_, filepath_.name);
513 if (sourceNamePrePart.empty() && sourceNamePostPart.empty()) {
514 this->obfSourceName_ = obfName_;
515 } else {
516 this->obfSourceName_ = sourceNamePrePart + filepath_.obfName + sourceNamePostPart;
517 }
518 }
519
UpdateFileNameReferences()520 void panda::guard::Node::UpdateFileNameReferences()
521 {
522 moduleRecord_.UpdateFileNameReferences();
523 }
524
UpdateSourceFile(const std::string & file)525 void panda::guard::Node::UpdateSourceFile(const std::string &file)
526 {
527 PANDA_GUARD_ASSERT_PRINT(file != this->sourceFile_, TAG, ErrorCode::GENERIC_ERROR, "duplicate source file" << file);
528 if (this->sourceFileUpdated_) {
529 return;
530 }
531
532 this->sourceFile_ = file;
533
534 /* e.g.
535 * file: entry|entry|1.0.0|src/main/ets/entryability/EntryAbility.ets
536 * filepath_.name: src/main/ets/entryability/EntryAbility
537 * prefix: entry|entry|1.0.0|
538 * suffix: .ets
539 */
540 const auto &[prefix, suffix] = StringUtil::RSplitOnce(file, filepath_.name);
541 PANDA_GUARD_ASSERT_PRINT(file != filepath_.name && prefix.empty() && suffix.empty(), TAG, ErrorCode::GENERIC_ERROR,
542 "invalid source file" << file << ",record: " << this->name_);
543 this->obfSourceFile_ = prefix + filepath_.obfName + suffix;
544 this->sourceFileUpdated_ = true;
545
546 LOG(INFO, PANDAGUARD) << TAG << "source_file: " << this->sourceFile_;
547 }
548
UpdateScopeNames()549 void panda::guard::Node::UpdateScopeNames()
550 {
551 LOG(INFO, PANDAGUARD) << TAG << "update scopeNames for:" << this->name_;
552 auto &record = this->program_->prog_->record_table.at(this->obfName_);
553 for (auto &it : record.field_list) {
554 if (it.name == SCOPE_NAMES_FIELD) {
555 const auto &literalArrayIdx = it.metadata->GetValue()->GetValue<std::string>();
556 LOG(INFO, PANDAGUARD) << TAG << "scopeNames literalArrayIdx:" << literalArrayIdx;
557 auto &literalArray = this->program_->prog_->literalarray_table.at(literalArrayIdx);
558 UpdateScopeNamesLiteralArray(literalArray);
559 break;
560 }
561 }
562 }
563
FindPkgName(const panda::pandasm::Record & record,std::string & pkgName)564 bool panda::guard::Node::FindPkgName(const panda::pandasm::Record &record, std::string &pkgName)
565 {
566 return std::any_of(
567 record.field_list.begin(), record.field_list.end(), [&](const panda::pandasm::Field &field) -> bool {
568 bool found = field.name.rfind(PKG_NAME_PREFIX, 0) == 0;
569 if (found) {
570 pkgName = field.name.substr(PKG_NAME_PREFIX.size(), field.name.size() - PKG_NAME_PREFIX.size());
571 }
572 return found;
573 });
574 }
575
IsJsonFile(const pandasm::Record & record)576 bool panda::guard::Node::IsJsonFile(const pandasm::Record &record)
577 {
578 return std::any_of(record.field_list.begin(), record.field_list.end(),
579 [](const auto &field) { return field.name == JSON_FILE_FIELD; });
580 }
581
GetMethodNameInfo(const panda::guard::InstructionInfo & info,panda::guard::InstructionInfo & nameInfo)582 void panda::guard::Node::GetMethodNameInfo(const panda::guard::InstructionInfo &info,
583 panda::guard::InstructionInfo &nameInfo)
584 {
585 if (!info.IsValid()) {
586 return;
587 }
588
589 if (InOpcodeList(info, METHOD_NAME_DIRECT_LIST)) {
590 nameInfo = info;
591 } else if (InOpcodeList(info, METHOD_NAME_INDIRECT_LIST)) {
592 GraphAnalyzer::GetLdaStr(info, nameInfo);
593 }
594 }
595