• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef PANDA_GUARD_OBFUSCATE_NODE_H
17 #define PANDA_GUARD_OBFUSCATE_NODE_H
18 
19 #include "array.h"
20 #include "class.h"
21 #include "entity.h"
22 #include "file_path.h"
23 #include "function.h"
24 #include "module_record.h"
25 #include "object.h"
26 #include "ui_decorator.h"
27 #include "annotation.h"
28 
29 namespace panda::guard {
30 
31 enum class NodeType {
32     NONE = 0,
33     SOURCE_FILE = 1,  // common source file
34     JSON_FILE = 2,    // json file,
35     ANNOTATION = 3,   // annotation
36 };
37 
38 class Node final : public Entity {
39 public:
Node(Program * program,const std::string & name)40     Node(Program *program, const std::string &name)
41         : Entity(program, name), moduleRecord_(program, name), sourceName_(name), obfSourceName_(name)
42     {
43     }
44 
45     /**
46      * Find PkgName field in pandasm::Record
47      */
48     static bool FindPkgName(const pandasm::Record &record, std::string &pkgName);
49 
50     /**
51      * record is json file
52      * @param record record
53      * @return true, false
54      */
55     static bool IsJsonFile(const pandasm::Record &record);
56 
57     /**
58      * init type pkgName with record
59      * @param record IR record
60      */
61     void InitWithRecord(const pandasm::Record &record);
62 
63     void Build() override;
64 
65     /**
66      *  get origin IR program record
67      * @return pandasm::Record
68      */
69     [[nodiscard]] pandasm::Record &GetRecord() const;
70 
71     /**
72      * For Each Function In Node
73      * 1. Functions
74      * 2. For Each Function In Classes
75      */
76     void EnumerateFunctions(const std::function<FunctionTraver> &callback);
77 
78     /**
79      * Update file name references in this node
80      */
81     void UpdateFileNameReferences();
82 
83     /**
84      * Update SourceFile with obf file name
85      * SourceFile: file path in "abc record's source_file"
86      */
87     void UpdateSourceFile(const std::string &file);
88 
89     /**
90      * NameCache write interface, used when the current file does not need to be obfuscated
91      */
92     void WriteNameCache() override;
93 
94 protected:
95     void RefreshNeedUpdate() override;
96 
97     void Update() override;
98 
99 private:
100     void EnumerateIns(const InstructionInfo &info, Scope scope);
101 
102     /**
103      * create function
104      * @param info instruction info
105      * @param scope function scope
106      */
107     void CreateFunction(const InstructionInfo &info, Scope scope);
108 
109     /**
110      * create property for function
111      * @param info instruction info
112      */
113     void CreateProperty(const InstructionInfo &info) const;
114 
115     void CreateObjectDecoratorProperty(const InstructionInfo &info);
116 
117     void CreateClass(const InstructionInfo &info, Scope scope);
118 
119     /**
120      * e.g. method in class
121      * class A { get b() {return 1;}}
122      * bytecode:
123      * defineclasswithbuffer
124      * definemethod
125      *
126      * e.g. method in object
127      * let obj = { get b() {return 1;}}
128      * bytecode:
129      * createobjectwithbuffer
130      * definemethod
131      */
132     void CreateOuterMethod(const InstructionInfo &info);
133 
134     void CreateObject(const InstructionInfo &info, Scope scope);
135 
136     /**
137      * when obj field is array, outer ins definepropertybyname will add an property for object
138      * let obj = { arr:[] }
139      * bytecode:
140      * createobjectwithbuffer
141      * sta v0
142      * definepropertybyname arr v0
143      * @param info instruction info
144      */
145     void CreateObjectOuterProperty(const InstructionInfo &info);
146 
147     /**
148      * add name for export object
149      *
150      * export const obj = {};
151      * pa:
152      * createobjectwithbuffer
153      *
154      * stmodulevar 0x00(index for export name)
155      *
156      * @param info input ins(stmodulevar)
157      */
158     void AddNameForExportObject(const InstructionInfo &info);
159 
160     /**
161      * update namespace member export
162      * @param info input instruction
163      */
164     void UpdateExportForNamespaceMember(const InstructionInfo &info) const;
165 
166     /**
167      * create array
168      * e.g.
169      * const array = [1, 2, 3];
170      * byteCode:
171      *  main_573 { 6 [ tag_value: 2, i32:1, tag_value: 2, i32:2, tag_value: 2, i32:3, ] }
172      *  createarraywithbuffer 0x0 main_573
173      * @param info instruction info
174      */
175     void CreateArray(const InstructionInfo &info);
176 
177     /**
178      * this instruction crosses functions and cannot be analyzed by graph, therefore it has been added to the whitelist
179      * e.g.
180      * class A { ['field'] = 1; }
181      * bytecode:
182      *  func1: stlexvar
183      *  func2: defineclasswithbuffer
184      */
185     static void FindStLexVarName(const InstructionInfo &info);
186 
187     void CreateUiDecorator(const InstructionInfo &info, Scope scope);
188 
189     void CreateFilePath();
190 
191     void CreateFilePathForDefaultMode();
192 
193     void CreateFilePathForNormalizedMode();
194 
195     void ExtractNames();
196 
197     void WriteFileCache(const std::string &filePath) override;
198 
199     void UpdateRecordTable();
200 
201     void UpdateFileNameDefine();
202 
203     /**
204      * update record scopeNames
205      */
206     void UpdateScopeNames() const;
207 
208     /**
209      * update record fields literalArrayIdx to updated recordName
210      * fields: scopeNames, moduleRecordIdx
211      */
212     void UpdateFieldsLiteralArrayIdx();
213 
214     static void GetMethodNameInfo(const InstructionInfo &info, InstructionInfo &nameInfo);
215 
216 public:
217     ModuleRecord moduleRecord_;
218     FilePath filepath_;
219     std::unordered_map<std::string, std::shared_ptr<Function>> functionTable_ {};  // key: Function idx
220     std::unordered_map<std::string, std::shared_ptr<Class>> classTable_ {};        // key: class literalArray idx
221     std::unordered_map<std::string, std::shared_ptr<Object>> objectTable_ {};      // key: object literalArray idx
222     std::vector<std::shared_ptr<UiDecorator>> uiDecorator_ {};
223     std::vector<std::shared_ptr<Annotation>> annotations_ {};
224     std::vector<std::shared_ptr<Array>> arrays_ {};
225     std::set<std::string> strings_ {};
226     std::string pkgName_;
227     bool fileNameNeedUpdate_ = true;
228     bool contentNeedUpdate_ = true;
229     bool isNormalizedOhmUrl_ = false;
230     std::string sourceName_;  // file path in "nameCache key" format
231     std::string obfSourceName_;
232     std::string sourceFile_;  // file path in "abc record's source_file"
233     std::string obfSourceFile_;
234     bool sourceFileUpdated_ = false;  // is sourceFile updated
235     NodeType type_ = NodeType::NONE;  // node type
236 };
237 
238 }  // namespace panda::guard
239 
240 #endif  // PANDA_GUARD_OBFUSCATE_NODE_H
241