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 "program.h"
17
18 #include "utils/logger.h"
19 #include "util/string_util.h"
20 #include "util/assert_util.h"
21 #include "configs/guard_context.h"
22 #include "graph_analyzer.h"
23 #include "annotation.h"
24
25 namespace {
26 constexpr std::string_view TAG = "[Program]";
27 constexpr std::string_view ANNOTATION_NODE_DELIMITER = ".";
28 } // namespace
29
Create()30 void panda::guard::Program::Create()
31 {
32 LOG(INFO, PANDAGUARD) << TAG << "===== program create start =====";
33
34 for (const auto &[_, record] : this->prog_->record_table) {
35 this->CreateNode(record);
36 }
37
38 LOG(INFO, PANDAGUARD) << TAG << "===== program create end =====";
39 }
40
CreateNode(const pandasm::Record & record)41 void panda::guard::Program::CreateNode(const pandasm::Record &record)
42 {
43 auto node = std::make_shared<Node>(this, record.name);
44 node->InitWithRecord(record);
45
46 if (node->type_ == NodeType::JSON_FILE) {
47 node->Create();
48 this->nodeTable_.emplace(record.name, node);
49 return;
50 }
51
52 if (node->type_ == NodeType::SOURCE_FILE) {
53 if (GuardContext::GetInstance()->GetGuardOptions()->IsSkippedRemoteHar(node->pkgName_)) {
54 LOG(INFO, PANDAGUARD) << TAG << "skip record: " << record.name;
55 return;
56 }
57
58 node->Create();
59 this->nodeTable_.emplace(record.name, node);
60 return;
61 }
62
63 if (node->type_ == NodeType::ANNOTATION) {
64 this->CreateAnnotation(record);
65 }
66 }
67
CreateAnnotation(const pandasm::Record & record)68 void panda::guard::Program::CreateAnnotation(const pandasm::Record &record)
69 {
70 if (Annotation::IsWhiteListAnnotation(record.name)) {
71 return;
72 }
73
74 auto [nodeName, annoName] = StringUtil::RSplitOnce(record.name, ANNOTATION_NODE_DELIMITER.data());
75 auto node = this->nodeTable_.find(nodeName);
76 PANDA_GUARD_ASSERT_PRINT(node == this->nodeTable_.end(), TAG, ErrorCode::GENERIC_ERROR,
77 "parse annotation get bad nodeName:" << nodeName);
78 auto annotation = std::make_shared<Annotation>(this, annoName);
79 annotation->nodeName_ = nodeName;
80 annotation->recordName_ = record.name;
81 annotation->needUpdate_ = node->second->needUpdate_;
82 annotation->scope_ = TOP_LEVEL;
83 annotation->export_ = node->second->moduleRecord_.IsExportVar(annoName);
84 annotation->Create();
85 node->second->annotations_.emplace_back(annotation);
86 }
87
EnumerateFunctions(const std::function<FunctionTraver> & callback)88 void panda::guard::Program::EnumerateFunctions(const std::function<FunctionTraver> &callback)
89 {
90 for (auto &[_, node] : this->nodeTable_) {
91 node->EnumerateFunctions(callback);
92 }
93 }
94
RemoveConsoleLog()95 void panda::guard::Program::RemoveConsoleLog()
96 {
97 if (!GuardContext::GetInstance()->GetGuardOptions()->IsRemoveLogObfEnabled()) {
98 return;
99 }
100
101 this->EnumerateFunctions([](Function &function) { function.RemoveConsoleLog(); });
102 }
103
RemoveLineNumber()104 void panda::guard::Program::RemoveLineNumber()
105 {
106 if (!GuardContext::GetInstance()->GetGuardOptions()->IsCompactObfEnabled()) {
107 return;
108 }
109
110 this->EnumerateFunctions([](Function &function) { function.RemoveLineNumber(); });
111 }
112
Obfuscate()113 void panda::guard::Program::Obfuscate()
114 {
115 LOG(INFO, PANDAGUARD) << TAG << "===== program obfuscate start =====";
116
117 for (auto &[name, node] : this->nodeTable_) {
118 node->Obfuscate();
119 }
120
121 this->UpdateReference();
122
123 this->RemoveConsoleLog();
124
125 this->RemoveLineNumber();
126
127 LOG(INFO, PANDAGUARD) << TAG << "===== program obfuscate end =====";
128 }
129
UpdateReference()130 void panda::guard::Program::UpdateReference()
131 {
132 this->EnumerateFunctions([](Function &function) -> void {
133 function.UpdateReference();
134 function.UpdateAnnotationReference();
135 });
136 for (auto &[_, node] : this->nodeTable_) {
137 node->UpdateFileNameReferences();
138 }
139 }
140