• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "verifier.h"
17 
18 #include <algorithm>
19 #include <cstdlib>
20 #include <gtest/gtest.h>
21 #include <string>
22 #include <unordered_map>
23 
24 #include "file.h"
25 #include "utils.h"
26 
27 using namespace testing::ext;
28 
29 namespace panda::verifier {
30 class VerifierConstantPool : public testing::Test {
31 public:
SetUpTestCase(void)32     static void SetUpTestCase(void) {};
TearDownTestCase(void)33     static void TearDownTestCase(void) {};
SetUp()34     void SetUp() {};
TearDown()35     void TearDown() {};
36 };
37 
38 /**
39 * @tc.name: verifier_constant_pool_001
40 * @tc.desc: Verify abc file.
41 * @tc.type: FUNC
42 * @tc.require: file path and name
43 */
44 HWTEST_F(VerifierConstantPool, verifier_constant_pool_001, TestSize.Level1)
45 {
46     const std::string file_name = GRAPH_TEST_ABC_DIR "test_constant_pool.abc";
47     panda::verifier::Verifier ver {file_name};
48     ver.CollectIdInfos();
49     EXPECT_TRUE(ver.VerifyConstantPoolIndex());
50 }
51 
52 /**
53 * @tc.name: verifier_constant_pool_002
54 * @tc.desc: Verify the method id of the abc file.
55 * @tc.type: FUNC
56 * @tc.require: file path and name
57 */
58 HWTEST_F(VerifierConstantPool, verifier_constant_pool_002, TestSize.Level1)
59 {
60     const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool.abc";
61     {
62         panda::verifier::Verifier ver {base_file_name};
63         ver.CollectIdInfos();
64         EXPECT_TRUE(ver.VerifyConstantPoolIndex());
65     }
66     std::ifstream base_file(base_file_name, std::ios::binary);
67     EXPECT_TRUE(base_file.is_open());
68 
69     std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {});
70 
71     std::vector<uint8_t> new_method_id = {0x0c, 0x00}; // The known string id in the abc file
72     std::vector<uint8_t> method_id = {0x0e, 0x00}; // The known method id in the abc file
73 
74     for (size_t i = buffer.size() - 1; i >= 0; --i) {
75         if (buffer[i] == method_id[0] && buffer[i + 1] == method_id[1]) {
76             buffer[i] = static_cast<unsigned char>(new_method_id[0]);
77             buffer[i + 1] = static_cast<unsigned char>(new_method_id[1]);
78             break;
79         }
80     }
81 
82     const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_002.abc";
83     GenerateModifiedAbc(buffer, target_file_name);
84     base_file.close();
85 
86     {
87         panda::verifier::Verifier ver {target_file_name};
88         ver.CollectIdInfos();
89         EXPECT_FALSE(ver.VerifyConstantPoolIndex());
90     }
91 }
92 
93 /**
94 * @tc.name: verifier_constant_pool_003
95 * @tc.desc: Verify the literal id of the abc file.
96 * @tc.type: FUNC
97 * @tc.require: file path and name
98 */
99 HWTEST_F(VerifierConstantPool, verifier_constant_pool_003, TestSize.Level1)
100 {
101     const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool.abc";
102     {
103         panda::verifier::Verifier ver {base_file_name};
104         ver.CollectIdInfos();
105         EXPECT_TRUE(ver.VerifyConstantPoolIndex());
106     }
107     std::ifstream base_file(base_file_name, std::ios::binary);
108     EXPECT_TRUE(base_file.is_open());
109 
110     std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {});
111 
112     std::vector<uint8_t> new_literal_id = {0x0e, 0x00}; // The known method id in the abc file
113     std::vector<uint8_t> literal_id = {0x0f, 0x00}; // The known literal id in the abc file
114 
115     for (size_t i = 0; i < buffer.size(); ++i) {
116         if (buffer[i] == literal_id[0] && buffer[i + 1] == literal_id[1]) {
117             buffer[i] = static_cast<unsigned char>(new_literal_id[0]);
118             buffer[i + 1] = static_cast<unsigned char>(new_literal_id[1]);
119             break;
120         }
121     }
122 
123     const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_003.abc";
124 
125     GenerateModifiedAbc(buffer, target_file_name);
126 
127     base_file.close();
128 
129     {
130         panda::verifier::Verifier ver {target_file_name};
131         ver.CollectIdInfos();
132         EXPECT_FALSE(ver.VerifyConstantPoolIndex());
133     }
134 }
135 
136 /**
137 * @tc.name: verifier_constant_pool_004
138 * @tc.desc: Verify the string id of the abc file.
139 * @tc.type: FUNC
140 * @tc.require: file path and name
141 */
142 HWTEST_F(VerifierConstantPool, verifier_constant_pool_004, TestSize.Level1)
143 {
144     const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool.abc";
145     {
146         panda::verifier::Verifier ver {base_file_name};
147         ver.CollectIdInfos();
148         EXPECT_TRUE(ver.VerifyConstantPoolIndex());
149     }
150     std::ifstream base_file(base_file_name, std::ios::binary);
151     EXPECT_TRUE(base_file.is_open());
152 
153     std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {});
154 
155     std::vector<uint8_t> new_string_id = {0x0f, 0x00}; // The known literal id in the abc file
156     std::vector<uint8_t> string_id = {0x0c, 0x00}; // The known string id in the abc file
157 
158     for (size_t i = sizeof(panda_file::File::Header); i < buffer.size(); ++i) {
159         if (buffer[i] == string_id[0] && buffer[i + 1] == string_id[1]) {
160             buffer[i] = static_cast<unsigned char>(new_string_id[0]);
161             buffer[i + 1] = static_cast<unsigned char>(new_string_id[1]);
162             break;
163         }
164     }
165 
166     const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_004.abc";
167     GenerateModifiedAbc(buffer, target_file_name);
168     base_file.close();
169 
170     {
171         panda::verifier::Verifier ver {target_file_name};
172         ver.CollectIdInfos();
173         EXPECT_FALSE(ver.VerifyConstantPoolIndex());
174     }
175 }
176 
177 /**
178 * @tc.name: verifier_constant_pool_006
179 * @tc.desc: Verify the format of the abc file.
180 * @tc.type: FUNC
181 * @tc.require: file path and name
182 */
183 HWTEST_F(VerifierConstantPool, verifier_constant_pool_006, TestSize.Level1)
184 {
185     const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool_content.abc";
186     {
187         panda::verifier::Verifier ver {base_file_name};
188         ver.CollectIdInfos();
189         EXPECT_TRUE(ver.VerifyConstantPoolContent());
190     }
191     std::ifstream base_file(base_file_name, std::ios::binary);
192     EXPECT_TRUE(base_file.is_open());
193 
194     std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {});
195 
196     unsigned char new_opcode = 0xff;
197     std::vector<unsigned char> opcode_imm8 = {0x4f, 0x13}; // The known instruction in the abc file
198     for (size_t i = 0; i < buffer.size() - opcode_imm8.size(); ++i) {
199         if (buffer[i] == opcode_imm8[0] && buffer[i + 1] == opcode_imm8[1]) {
200             buffer[i] = new_opcode;
201             break;
202         }
203     }
204 
205     const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_006.abc";
206     GenerateModifiedAbc(buffer, target_file_name);
207     base_file.close();
208 
209     {
210         panda::verifier::Verifier ver {target_file_name};
211         ver.CollectIdInfos();
212         EXPECT_FALSE(ver.VerifyConstantPoolContent());
213     }
214 }
215 
216 /**
217 * @tc.name: verifier_constant_pool_007
218 * @tc.desc: Verify the jump instruction of the abc file.
219 * @tc.type: FUNC
220 * @tc.require: file path and name
221 */
222 HWTEST_F(VerifierConstantPool, verifier_constant_pool_007, TestSize.Level1)
223 {
224     const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool_content.abc";
225     {
226         panda::verifier::Verifier ver {base_file_name};
227         ver.CollectIdInfos();
228         EXPECT_TRUE(ver.VerifyConstantPoolContent());
229     }
230     std::ifstream base_file(base_file_name, std::ios::binary);
231     EXPECT_TRUE(base_file.is_open());
232 
233     std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {});
234 
235     unsigned char new_imm8 = 0x4f;
236     std::vector<unsigned char> opcode_imm8 = {0x4f, 0x13}; // The known jump instruction in the abc file
237     for (size_t i = 0; i < buffer.size() - opcode_imm8.size(); ++i) {
238         if (buffer[i] == opcode_imm8[0] && buffer[i + 1] == opcode_imm8[1]) {
239             buffer[i + 1] = new_imm8;
240             break;
241         }
242     }
243 
244     const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_007.abc";
245     GenerateModifiedAbc(buffer, target_file_name);
246     base_file.close();
247 
248     {
249         panda::verifier::Verifier ver {target_file_name};
250         ver.CollectIdInfos();
251         EXPECT_FALSE(ver.VerifyConstantPoolContent());
252     }
253 }
254 
255 /**
256 * @tc.name: verifier_constant_pool_008
257 * @tc.desc: Verify the literal tag of the abc file.
258 * @tc.type: FUNC
259 * @tc.require: file path and name
260 */
261 HWTEST_F(VerifierConstantPool, verifier_constant_pool_008, TestSize.Level1)
262 {
263     const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool_content.abc";
264     std::vector<uint32_t> literal_ids;
265     {
266         panda::verifier::Verifier ver {base_file_name};
267         ver.CollectIdInfos();
268         EXPECT_TRUE(ver.VerifyConstantPoolContent());
269         std::copy(ver.literal_ids_.begin(), ver.literal_ids_.end(), std::back_inserter(literal_ids));
270     }
271     std::ifstream base_file(base_file_name, std::ios::binary);
272     EXPECT_TRUE(base_file.is_open());
273 
274     std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {});
275 
276     unsigned char invalid_tag = 0x5c; // a invalid tag
277 
278     for (const auto &literal_id : literal_ids) {
279         size_t tag_off = static_cast<size_t>(literal_id) + sizeof(uint32_t);
280         buffer[tag_off] = invalid_tag;
281     }
282 
283     const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_008.abc";
284     GenerateModifiedAbc(buffer, target_file_name);
285     base_file.close();
286 
287     {
288         panda::verifier::Verifier ver {target_file_name};
289         ver.CollectIdInfos();
290         EXPECT_FALSE(ver.VerifyConstantPoolContent());
291     }
292 }
293 
294 /**
295 * @tc.name: verifier_constant_pool_010
296 * @tc.desc: Verify the literal id in the literal array of the abc file.
297 * @tc.type: FUNC
298 * @tc.require: file path and name
299 */
300 HWTEST_F(VerifierConstantPool, verifier_constant_pool_010, TestSize.Level1)
301 {
302     const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_literal_array.abc";
303     std::unordered_map<uint32_t, uint32_t> inner_literal_map;
304     {
305         panda::verifier::Verifier ver {base_file_name};
306         ver.CollectIdInfos();
307         EXPECT_TRUE(ver.VerifyConstantPoolContent());
308         inner_literal_map.insert(ver.inner_literal_map_.begin(), ver.inner_literal_map_.end());
309     }
310     std::ifstream base_file(base_file_name, std::ios::binary);
311     EXPECT_TRUE(base_file.is_open());
312 
313     std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {});
314 
315     ModifyBuffer(inner_literal_map, buffer);
316 
317     const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_010.abc";
318     GenerateModifiedAbc(buffer, target_file_name);
319     base_file.close();
320 
321     {
322         panda::verifier::Verifier ver {target_file_name};
323         ver.CollectIdInfos();
324         EXPECT_TRUE(ver.VerifyConstantPoolContent());
325     }
326 }
327 
328 /**
329 * @tc.name: verifier_constant_pool_011
330 * @tc.desc: Verify the method id in the literal array of the abc file.
331 * @tc.type: FUNC
332 * @tc.require: file path and name
333 */
334 HWTEST_F(VerifierConstantPool, verifier_constant_pool_011, TestSize.Level1)
335 {
336     const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_literal_array.abc";
337     std::unordered_map<uint32_t, uint32_t> inner_method_map;
338     {
339         panda::verifier::Verifier ver {base_file_name};
340         ver.CollectIdInfos();
341         EXPECT_TRUE(ver.VerifyConstantPoolContent());
342         inner_method_map.insert(ver.inner_method_map_.begin(), ver.inner_method_map_.end());
343     }
344     std::ifstream base_file(base_file_name, std::ios::binary);
345     EXPECT_TRUE(base_file.is_open());
346 
347     std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {});
348 
349     ModifyBuffer(inner_method_map, buffer);
350 
351     const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_011.abc";
352     GenerateModifiedAbc(buffer, target_file_name);
353     base_file.close();
354 
355     {
356         panda::verifier::Verifier ver {target_file_name};
357         ver.CollectIdInfos();
358         EXPECT_FALSE(ver.VerifyConstantPoolContent());
359     }
360 }
361 
362 }; // namespace panda::verifier
363