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 // The known method id in the abc file 37 std::vector<uint8_t> method_id_in_test_constant_pool = {0x0e, 0x00}; 38 // The known string id in the abc file 39 std::vector<uint8_t> string_id_in_test_constant_pool = {0x0c, 0x00}; 40 // The known literal id in the abc file 41 std::vector<uint8_t> literal_id_in_test_constant_pool = {0x0f, 0x00}; 42 // The known jump instruction in the abc file 43 std::vector<uint8_t> jump_ins_id_in_test_constant_pool = {0x4f, 0x0c}; 44 TestVerifierWithAbcVersionTampered(const std::string & file_name,std::array<uint8_t,panda_file::File::VERSION_SIZE> & original_version)45 void TestVerifierWithAbcVersionTampered(const std::string &file_name, 46 std::array<uint8_t, panda_file::File::VERSION_SIZE> &original_version) 47 { 48 panda::verifier::Verifier ver {file_name}; 49 50 ver.CollectIdInfos(); 51 if (panda_file::IsVersionLessOrEqual(original_version, panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION)) { 52 EXPECT_TRUE(ver.VerifyConstantPoolIndex()); 53 EXPECT_TRUE(ver.VerifyConstantPool()); 54 } else { 55 EXPECT_FALSE(ver.VerifyConstantPoolIndex()); 56 EXPECT_FALSE(ver.VerifyConstantPool()); 57 } 58 } 59 }; 60 61 /** 62 * @tc.name: verifier_constant_pool_001 63 * @tc.desc: Verify abc file. 64 * @tc.type: FUNC 65 * @tc.require: file path and name 66 */ 67 HWTEST_F(VerifierConstantPool, verifier_constant_pool_001, TestSize.Level1) 68 { 69 const std::string file_name = GRAPH_TEST_ABC_DIR "test_constant_pool.abc"; 70 panda::verifier::Verifier ver {file_name}; 71 ver.CollectIdInfos(); 72 EXPECT_TRUE(ver.VerifyConstantPoolIndex()); 73 EXPECT_TRUE(ver.Verify()); 74 } 75 76 /** 77 * @tc.name: verifier_constant_pool_002 78 * @tc.desc: Verify the method id of the abc file. 79 * @tc.type: FUNC 80 * @tc.require: file path and name 81 */ 82 HWTEST_F(VerifierConstantPool, verifier_constant_pool_002, TestSize.Level1) 83 { 84 const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool.abc"; 85 std::vector<uint32_t> literal_ids; 86 { 87 panda::verifier::Verifier ver {base_file_name}; 88 ver.CollectIdInfos(); 89 EXPECT_TRUE(ver.VerifyConstantPoolIndex()); 90 std::copy(ver.literal_ids_.begin(), ver.literal_ids_.end(), std::back_inserter(literal_ids)); 91 } 92 std::ifstream base_file(base_file_name, std::ios::binary); 93 EXPECT_TRUE(base_file.is_open()); 94 95 std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {}); 96 97 std::vector<uint8_t> new_method_id = string_id_in_test_constant_pool; 98 std::vector<uint8_t> method_id = method_id_in_test_constant_pool; 99 100 for (size_t i = buffer.size() - 1; i >= 0; --i) { 101 if (buffer[i] == method_id[0] && buffer[i + 1] == method_id[1]) { 102 buffer[i] = static_cast<unsigned char>(new_method_id[0]); 103 buffer[i + 1] = static_cast<unsigned char>(new_method_id[1]); 104 break; 105 } 106 } 107 108 const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_002.abc"; 109 GenerateModifiedAbc(buffer, target_file_name); 110 base_file.close(); 111 112 { 113 panda::verifier::Verifier ver {target_file_name}; 114 ver.include_literal_array_ids = false; 115 ver.CollectIdInfos(); 116 ver.literal_ids_ = literal_ids; 117 EXPECT_FALSE(ver.VerifyConstantPoolIndex()); 118 } 119 120 std::ifstream base_file_02(base_file_name, std::ios::binary); 121 EXPECT_TRUE(base_file_02.is_open()); 122 std::vector<unsigned char> buffer_0(std::istreambuf_iterator<char>(base_file_02), {}); 123 std::array<uint8_t, panda_file::File::VERSION_SIZE> version {buffer_0[12], buffer_0[13], 124 buffer_0[14], buffer_0[15]}; 125 buffer_0[12] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[0]); 126 buffer_0[13] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[1]); 127 buffer_0[14] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[2]); 128 buffer_0[15] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[3]); 129 const std::string target_file_name_02 = GRAPH_TEST_ABC_DIR "verifier_constant_pool_002_2.abc"; 130 GenerateModifiedAbc(buffer_0, target_file_name_02); 131 base_file_02.close(); 132 133 TestVerifierWithAbcVersionTampered(target_file_name_02, version); 134 } 135 136 /** 137 * @tc.name: verifier_constant_pool_003 138 * @tc.desc: Verify the literal id of the abc file. 139 * @tc.type: FUNC 140 * @tc.require: file path and name 141 */ 142 HWTEST_F(VerifierConstantPool, verifier_constant_pool_003, TestSize.Level1) 143 { 144 const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool.abc"; 145 std::vector<uint32_t> literal_ids; 146 { 147 panda::verifier::Verifier ver {base_file_name}; 148 ver.CollectIdInfos(); 149 EXPECT_TRUE(ver.VerifyConstantPoolIndex()); 150 std::copy(ver.literal_ids_.begin(), ver.literal_ids_.end(), std::back_inserter(literal_ids)); 151 } 152 std::ifstream base_file(base_file_name, std::ios::binary); 153 EXPECT_TRUE(base_file.is_open()); 154 155 std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {}); 156 157 std::vector<uint8_t> new_literal_id = method_id_in_test_constant_pool; 158 std::vector<uint8_t> literal_id = literal_id_in_test_constant_pool; 159 160 for (size_t i = 0; i < buffer.size(); ++i) { 161 if (buffer[i] == literal_id[0] && buffer[i + 1] == literal_id[1]) { 162 buffer[i] = static_cast<unsigned char>(new_literal_id[0]); 163 buffer[i + 1] = static_cast<unsigned char>(new_literal_id[1]); 164 break; 165 } 166 } 167 168 const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_003.abc"; 169 GenerateModifiedAbc(buffer, target_file_name); 170 base_file.close(); 171 172 { 173 panda::verifier::Verifier ver {target_file_name}; 174 ver.include_literal_array_ids = false; 175 ver.CollectIdInfos(); 176 ver.literal_ids_ = literal_ids; 177 EXPECT_FALSE(ver.VerifyConstantPoolIndex()); 178 } 179 180 std::ifstream base_file_02(base_file_name, std::ios::binary); 181 EXPECT_TRUE(base_file_02.is_open()); 182 std::vector<unsigned char> buffer_0(std::istreambuf_iterator<char>(base_file_02), {}); 183 std::array<uint8_t, panda_file::File::VERSION_SIZE> version {buffer_0[12], buffer_0[13], 184 buffer_0[14], buffer_0[15]}; 185 buffer_0[12] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[0]); 186 buffer_0[13] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[1]); 187 buffer_0[14] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[2]); 188 buffer_0[15] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[3]); 189 const std::string target_file_name_02 = GRAPH_TEST_ABC_DIR "verifier_constant_pool_003_2.abc"; 190 GenerateModifiedAbc(buffer_0, target_file_name_02); 191 base_file_02.close(); 192 193 TestVerifierWithAbcVersionTampered(target_file_name_02, version); 194 } 195 196 /** 197 * @tc.name: verifier_constant_pool_004 198 * @tc.desc: Verify the string id of the abc file. 199 * @tc.type: FUNC 200 * @tc.require: file path and name 201 */ 202 HWTEST_F(VerifierConstantPool, verifier_constant_pool_004, TestSize.Level1) 203 { 204 const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool.abc"; 205 std::vector<uint32_t> literal_ids; 206 { 207 panda::verifier::Verifier ver {base_file_name}; 208 ver.CollectIdInfos(); 209 EXPECT_TRUE(ver.VerifyConstantPoolIndex()); 210 std::copy(ver.literal_ids_.begin(), ver.literal_ids_.end(), std::back_inserter(literal_ids)); 211 } 212 std::ifstream base_file(base_file_name, std::ios::binary); 213 EXPECT_TRUE(base_file.is_open()); 214 215 std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {}); 216 217 std::vector<uint8_t> new_string_id = literal_id_in_test_constant_pool; 218 std::vector<uint8_t> string_id = string_id_in_test_constant_pool; 219 220 for (size_t i = sizeof(panda_file::File::Header); i < buffer.size(); ++i) { 221 if (buffer[i] == string_id[0] && buffer[i + 1] == string_id[1]) { 222 buffer[i] = static_cast<unsigned char>(new_string_id[0]); 223 buffer[i + 1] = static_cast<unsigned char>(new_string_id[1]); 224 break; 225 } 226 } 227 228 const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_004.abc"; 229 GenerateModifiedAbc(buffer, target_file_name); 230 base_file.close(); 231 232 { 233 panda::verifier::Verifier ver {target_file_name}; 234 ver.include_literal_array_ids = false; 235 ver.CollectIdInfos(); 236 ver.literal_ids_ = literal_ids; 237 EXPECT_FALSE(ver.VerifyConstantPoolIndex()); 238 } 239 240 std::ifstream base_file_02(base_file_name, std::ios::binary); 241 EXPECT_TRUE(base_file_02.is_open()); 242 std::vector<unsigned char> buffer_0(std::istreambuf_iterator<char>(base_file_02), {}); 243 std::array<uint8_t, panda_file::File::VERSION_SIZE> version {buffer_0[12], buffer_0[13], 244 buffer_0[14], buffer_0[15]}; 245 buffer_0[12] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[0]); 246 buffer_0[13] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[1]); 247 buffer_0[14] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[2]); 248 buffer_0[15] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[3]); 249 const std::string target_file_name_02 = GRAPH_TEST_ABC_DIR "verifier_constant_pool_004_2.abc"; 250 GenerateModifiedAbc(buffer_0, target_file_name_02); 251 base_file_02.close(); 252 253 TestVerifierWithAbcVersionTampered(target_file_name_02, version); 254 } 255 256 /** 257 * @tc.name: verifier_constant_pool_006 258 * @tc.desc: Verify the format of the abc file. 259 * @tc.type: FUNC 260 * @tc.require: file path and name 261 */ 262 HWTEST_F(VerifierConstantPool, verifier_constant_pool_006, TestSize.Level1) 263 { 264 const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool_content.abc"; 265 std::vector<uint32_t> literal_ids; 266 { 267 panda::verifier::Verifier ver {base_file_name}; 268 ver.CollectIdInfos(); 269 EXPECT_TRUE(ver.VerifyConstantPoolContent()); 270 std::copy(ver.literal_ids_.begin(), ver.literal_ids_.end(), std::back_inserter(literal_ids)); 271 } 272 std::ifstream base_file(base_file_name, std::ios::binary); 273 EXPECT_TRUE(base_file.is_open()); 274 275 std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {}); 276 277 unsigned char new_opcode = 0xff; 278 std::vector<unsigned char> opcode_imm8 = 279 jump_ins_id_in_test_constant_pool; 280 for (size_t i = 0; i < buffer.size() - opcode_imm8.size(); ++i) { 281 if (buffer[i] == opcode_imm8[0] && buffer[i + 1] == opcode_imm8[1]) { 282 buffer[i] = new_opcode; 283 break; 284 } 285 } 286 287 const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_006.abc"; 288 GenerateModifiedAbc(buffer, target_file_name); 289 base_file.close(); 290 291 { 292 panda::verifier::Verifier ver {target_file_name}; 293 ver.include_literal_array_ids = false; 294 ver.CollectIdInfos(); 295 ver.literal_ids_ = literal_ids; 296 EXPECT_FALSE(ver.VerifyConstantPoolContent()); 297 } 298 299 std::ifstream base_file_02(base_file_name, std::ios::binary); 300 EXPECT_TRUE(base_file_02.is_open()); 301 std::vector<unsigned char> buffer_0(std::istreambuf_iterator<char>(base_file_02), {}); 302 std::array<uint8_t, panda_file::File::VERSION_SIZE> version {buffer_0[12], buffer_0[13], 303 buffer_0[14], buffer_0[15]}; 304 buffer_0[12] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[0]); 305 buffer_0[13] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[1]); 306 buffer_0[14] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[2]); 307 buffer_0[15] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[3]); 308 const std::string target_file_name_02 = GRAPH_TEST_ABC_DIR "verifier_constant_pool_006_2.abc"; 309 GenerateModifiedAbc(buffer_0, target_file_name_02); 310 base_file_02.close(); 311 312 TestVerifierWithAbcVersionTampered(target_file_name_02, version); 313 } 314 315 /** 316 * @tc.name: verifier_constant_pool_007 317 * @tc.desc: Verify the jump instruction of the abc file. 318 * @tc.type: FUNC 319 * @tc.require: file path and name 320 */ 321 HWTEST_F(VerifierConstantPool, verifier_constant_pool_007, TestSize.Level1) 322 { 323 const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool_content.abc"; 324 std::vector<uint32_t> literal_ids; 325 { 326 panda::verifier::Verifier ver {base_file_name}; 327 ver.CollectIdInfos(); 328 EXPECT_TRUE(ver.VerifyConstantPoolContent()); 329 std::copy(ver.literal_ids_.begin(), ver.literal_ids_.end(), std::back_inserter(literal_ids)); 330 } 331 std::ifstream base_file(base_file_name, std::ios::binary); 332 EXPECT_TRUE(base_file.is_open()); 333 334 std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {}); 335 336 unsigned char new_imm8 = 0x4f; 337 std::vector<unsigned char> opcode_imm8 = jump_ins_id_in_test_constant_pool; 338 for (size_t i = 0; i < buffer.size() - opcode_imm8.size(); ++i) { 339 if (buffer[i] == opcode_imm8[0] && buffer[i + 1] == opcode_imm8[1]) { 340 buffer[i + 1] = new_imm8; 341 break; 342 } 343 } 344 345 const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_007.abc"; 346 GenerateModifiedAbc(buffer, target_file_name); 347 base_file.close(); 348 349 { 350 panda::verifier::Verifier ver {target_file_name}; 351 ver.CollectIdInfos(); 352 EXPECT_FALSE(ver.VerifyConstantPoolContent()); 353 } 354 } 355 356 /** 357 * @tc.name: verifier_constant_pool_008 358 * @tc.desc: Verify the literal tag of the abc file. 359 * @tc.type: FUNC 360 * @tc.require: file path and name 361 */ 362 HWTEST_F(VerifierConstantPool, verifier_constant_pool_008, TestSize.Level1) 363 { 364 const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool_content.abc"; 365 std::vector<uint32_t> literal_ids; 366 { 367 panda::verifier::Verifier ver {base_file_name}; 368 ver.CollectIdInfos(); 369 EXPECT_TRUE(ver.VerifyConstantPoolContent()); 370 std::copy(ver.literal_ids_.begin(), ver.literal_ids_.end(), std::back_inserter(literal_ids)); 371 } 372 std::ifstream base_file(base_file_name, std::ios::binary); 373 EXPECT_TRUE(base_file.is_open()); 374 375 std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {}); 376 377 unsigned char invalid_tag = 0x5c; // a invalid tag 378 379 for (const auto &literal_id : literal_ids) { 380 size_t tag_off = static_cast<size_t>(literal_id) + sizeof(uint32_t); 381 buffer[tag_off] = invalid_tag; 382 } 383 384 const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_008.abc"; 385 GenerateModifiedAbc(buffer, target_file_name); 386 base_file.close(); 387 388 { 389 panda::verifier::Verifier ver {target_file_name}; 390 ver.include_literal_array_ids = false; 391 ver.CollectIdInfos(); 392 ver.literal_ids_ = literal_ids; 393 EXPECT_FALSE(ver.VerifyConstantPoolContent()); 394 } 395 396 std::ifstream base_file_02(base_file_name, std::ios::binary); 397 EXPECT_TRUE(base_file_02.is_open()); 398 std::vector<unsigned char> buffer_0(std::istreambuf_iterator<char>(base_file_02), {}); 399 std::array<uint8_t, panda_file::File::VERSION_SIZE> version {buffer_0[12], buffer_0[13], 400 buffer_0[14], buffer_0[15]}; 401 buffer_0[12] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[0]); 402 buffer_0[13] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[1]); 403 buffer_0[14] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[2]); 404 buffer_0[15] = static_cast<unsigned char>(panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION[3]); 405 const std::string target_file_name_02 = GRAPH_TEST_ABC_DIR "verifier_constant_pool_008_2.abc"; 406 GenerateModifiedAbc(buffer_0, target_file_name_02); 407 base_file_02.close(); 408 409 { 410 panda::verifier::Verifier ver {target_file_name_02}; 411 ver.CollectIdInfos(); 412 if (panda_file::IsVersionLessOrEqual(version, panda_file::LAST_CONTAINS_LITERAL_IN_HEADER_VERSION)) { 413 EXPECT_TRUE(ver.VerifyConstantPoolIndex()); 414 } else { 415 EXPECT_FALSE(ver.VerifyConstantPoolIndex()); 416 } 417 } 418 } 419 420 /** 421 * @tc.name: verifier_constant_pool_010 422 * @tc.desc: Verify the literal id in the literal array of the abc file. 423 * @tc.type: FUNC 424 * @tc.require: file path and name 425 */ 426 HWTEST_F(VerifierConstantPool, verifier_constant_pool_010, TestSize.Level1) 427 { 428 const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_literal_array.abc"; 429 std::unordered_map<uint32_t, uint32_t> inner_literal_map; 430 { 431 panda::verifier::Verifier ver {base_file_name}; 432 ver.CollectIdInfos(); 433 EXPECT_TRUE(ver.VerifyConstantPoolContent()); 434 inner_literal_map.insert(ver.inner_literal_map_.begin(), ver.inner_literal_map_.end()); 435 } 436 std::ifstream base_file(base_file_name, std::ios::binary); 437 EXPECT_TRUE(base_file.is_open()); 438 439 std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {}); 440 441 ModifyBuffer(inner_literal_map, buffer); 442 443 const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_010.abc"; 444 GenerateModifiedAbc(buffer, target_file_name); 445 base_file.close(); 446 447 { 448 panda::verifier::Verifier ver {target_file_name}; 449 ver.CollectIdInfos(); 450 EXPECT_TRUE(ver.VerifyConstantPoolContent()); 451 } 452 } 453 454 /** 455 * @tc.name: verifier_constant_pool_011 456 * @tc.desc: Verify the method id in the literal array of the abc file. 457 * @tc.type: FUNC 458 * @tc.require: file path and name 459 */ 460 HWTEST_F(VerifierConstantPool, verifier_constant_pool_011, TestSize.Level1) 461 { 462 const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_literal_array.abc"; 463 std::unordered_map<uint32_t, uint32_t> inner_method_map; 464 { 465 panda::verifier::Verifier ver {base_file_name}; 466 ver.CollectIdInfos(); 467 EXPECT_TRUE(ver.VerifyConstantPoolContent()); 468 inner_method_map.insert(ver.inner_method_map_.begin(), ver.inner_method_map_.end()); 469 } 470 std::ifstream base_file(base_file_name, std::ios::binary); 471 EXPECT_TRUE(base_file.is_open()); 472 473 std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {}); 474 475 ModifyBuffer(inner_method_map, buffer); 476 477 const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_011.abc"; 478 GenerateModifiedAbc(buffer, target_file_name); 479 base_file.close(); 480 481 { 482 panda::verifier::Verifier ver {target_file_name}; 483 ver.CollectIdInfos(); 484 EXPECT_FALSE(ver.VerifyConstantPoolContent()); 485 } 486 } 487 488 /** 489 * @tc.name: verifier_null_file 490 * @tc.desc: verify not-exist abc file. 491 * @tc.type: FUNC 492 * @tc.require: file path and name 493 */ 494 HWTEST_F(VerifierConstantPool, verifier_not_exist, TestSize.Level1) 495 { 496 const std::string not_exist_file_name = GRAPH_TEST_ABC_DIR "test_not_exist_file.abc"; 497 panda::verifier::Verifier ver {not_exist_file_name}; 498 ver.CollectIdInfos(); 499 EXPECT_FALSE(ver.VerifyConstantPool()); 500 EXPECT_FALSE(ver.VerifyConstantPoolIndex()); 501 EXPECT_FALSE(ver.VerifyConstantPoolContent()); 502 EXPECT_FALSE(ver.Verify()); 503 } 504 505 /** 506 * @tc.name: verifier_constant_pool_012 507 * @tc.desc: Verify the try blocks in the abc file. 508 * @tc.type: FUNC 509 * @tc.require: file path and name 510 */ 511 HWTEST_F(VerifierConstantPool, verifier_constant_pool_012, TestSize.Level1) 512 { 513 const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool_content.abc"; 514 { 515 panda::verifier::Verifier ver {base_file_name}; 516 ver.CollectIdInfos(); 517 EXPECT_TRUE(ver.VerifyConstantPoolContent()); 518 } 519 std::ifstream base_file(base_file_name, std::ios::binary); 520 EXPECT_TRUE(base_file.is_open()); 521 522 std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {}); 523 524 unsigned char try_start_pc = 0x01; // The known try.start_pc in the abc file 525 unsigned char try_length = 0x0f; // The known try.length in the abc file 526 unsigned char code_size = 0x35; // The known code_size of the try block in the abc file 527 528 for (size_t i = 0; i < buffer.size() - 1; ++i) { 529 if (buffer[i] == try_start_pc && buffer[i + 1] == try_length) { 530 auto invalid_try_start_pc = try_start_pc + code_size; 531 buffer[i] = static_cast<unsigned char>(invalid_try_start_pc); 532 break; 533 } 534 } 535 536 const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_012.abc"; 537 GenerateModifiedAbc(buffer, target_file_name); 538 base_file.close(); 539 540 { 541 panda::verifier::Verifier ver {target_file_name}; 542 ver.CollectIdInfos(); 543 EXPECT_FALSE(ver.VerifyConstantPoolContent()); 544 } 545 } 546 547 /** 548 * @tc.name: verifier_constant_pool_013 549 * @tc.desc: Verify the catch blocks in the abc file. 550 * @tc.type: FUNC 551 * @tc.require: file path and name 552 */ 553 HWTEST_F(VerifierConstantPool, verifier_constant_pool_013, TestSize.Level1) 554 { 555 const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool_content.abc"; 556 { 557 panda::verifier::Verifier ver {base_file_name}; 558 ver.CollectIdInfos(); 559 EXPECT_TRUE(ver.VerifyConstantPoolContent()); 560 } 561 std::ifstream base_file(base_file_name, std::ios::binary); 562 EXPECT_TRUE(base_file.is_open()); 563 564 std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {}); 565 566 unsigned char catch_type_idx = 0x00; // The known catch.type_idx in the abc file 567 unsigned char catch_handler_pc = 0x12; // The known catch.handler_pc in the abc file 568 unsigned char code_size = 0x00; // The known code_size of the catch block in the abc file 569 unsigned char method_code_size = 0x35; // The known code_size of the method in the abc file 570 571 for (size_t i = 0; i < buffer.size() - 1; ++i) { 572 if (buffer[i] == catch_type_idx && buffer[i + 1] == catch_handler_pc && buffer[i + 2] == code_size) { 573 auto invalid_catch_handler_pc = catch_handler_pc + method_code_size; 574 buffer[i + 1] = static_cast<unsigned char>(invalid_catch_handler_pc); 575 break; 576 } 577 } 578 579 const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_013.abc"; 580 GenerateModifiedAbc(buffer, target_file_name); 581 base_file.close(); 582 583 { 584 panda::verifier::Verifier ver {target_file_name}; 585 ver.CollectIdInfos(); 586 EXPECT_FALSE(ver.VerifyConstantPoolContent()); 587 } 588 } 589 590 /** 591 * @tc.name: verifier_constant_pool_014 592 * @tc.desc: Verify the code size in the abc file. 593 * @tc.type: FUNC 594 * @tc.require: file path and name 595 */ 596 HWTEST_F(VerifierConstantPool, verifier_constant_pool_014, TestSize.Level1) 597 { 598 const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool_content.abc"; 599 { 600 panda::verifier::Verifier ver {base_file_name}; 601 ver.CollectIdInfos(); 602 EXPECT_TRUE(ver.VerifyConstantPoolContent()); 603 } 604 std::ifstream base_file(base_file_name, std::ios::binary); 605 EXPECT_TRUE(base_file.is_open()); 606 607 std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {}); 608 609 unsigned char tries_size = 0x00; // The known tries_size of the method in the abc file 610 unsigned char method_code_size = 0x35; // The known code_size of the method in the abc file 611 612 for (size_t i = 0; i < buffer.size() - 1; ++i) { 613 if (buffer[i] == method_code_size && buffer[i + 1] == tries_size) { 614 auto invalid_code_size = 0; 615 buffer[i] = static_cast<unsigned char>(invalid_code_size); 616 break; 617 } 618 } 619 620 const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_014.abc"; 621 GenerateModifiedAbc(buffer, target_file_name); 622 base_file.close(); 623 624 { 625 panda::verifier::Verifier ver {target_file_name}; 626 ver.CollectIdInfos(); 627 EXPECT_FALSE(ver.VerifyConstantPoolContent()); 628 } 629 } 630 631 /** 632 * @tc.name: verifier_constant_pool_015 633 * @tc.desc: Verify the literal tag is double value in the abc file. 634 * @tc.type: FUNC 635 * @tc.require: file path and name 636 */ 637 HWTEST_F(VerifierConstantPool, verifier_constant_pool_015, TestSize.Level1) 638 { 639 const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool_content.abc"; 640 { 641 panda::verifier::Verifier ver {base_file_name}; 642 ver.CollectIdInfos(); 643 EXPECT_TRUE(ver.VerifyConstantPoolContent()); 644 } 645 std::ifstream base_file(base_file_name, std::ios::binary); 646 EXPECT_TRUE(base_file.is_open()); 647 648 std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {}); 649 650 std::vector<unsigned char> double_literal_value = {0xae, 0x47, 651 0xe1, 0x7a, 652 0x14, 0xae, 653 0x28, 0x40}; // The known double literal 654 std::vector<unsigned char> invalid_double_literal_value = {0x00, 0x00, 655 0x00, 0x00, 656 0x00, 0x00, 657 0xff, 0xff}; // a invalid double tag 658 659 for (size_t i = 0; i <= buffer.size() - double_literal_value.size(); ++i) { 660 if (buffer[i] == double_literal_value[0] && buffer[i + 1] == double_literal_value[1]) { 661 for (size_t j = 0; j < invalid_double_literal_value.size(); ++j) { 662 buffer[i + j] = invalid_double_literal_value[j]; 663 } 664 break; 665 } 666 } 667 668 const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_015.abc"; 669 GenerateModifiedAbc(buffer, target_file_name); 670 base_file.close(); 671 672 { 673 panda::verifier::Verifier ver {target_file_name}; 674 ver.CollectIdInfos(); 675 EXPECT_FALSE(ver.VerifyConstantPoolContent()); 676 } 677 } 678 679 /** 680 * @tc.name: verifier_constant_pool_016 681 * @tc.desc: Verify the jump in the abc file. 682 * @tc.type: FUNC 683 * @tc.require: file path and name 684 */ 685 HWTEST_F(VerifierConstantPool, verifier_constant_pool_016, TestSize.Level1) 686 { 687 const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool_content.abc"; 688 { 689 panda::verifier::Verifier ver {base_file_name}; 690 ver.CollectIdInfos(); 691 EXPECT_TRUE(ver.VerifyConstantPoolContent()); 692 } 693 std::ifstream base_file(base_file_name, std::ios::binary); 694 EXPECT_TRUE(base_file.is_open()); 695 696 std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(base_file), {}); 697 698 std::vector<unsigned char> opcode_imm8 = {0x4f, 0x13}; // The known jump instruction in the abc file 699 700 for (size_t i = 0; i < buffer.size() - opcode_imm8.size(); ++i) { 701 if (buffer[i] == opcode_imm8[0] && buffer[i + 1] == opcode_imm8[1]) { 702 buffer[i + 1] = opcode_imm8[1] + 1; // jump instruction middle 703 break; 704 } 705 } 706 707 const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_016.abc"; 708 GenerateModifiedAbc(buffer, target_file_name); 709 base_file.close(); 710 711 { 712 panda::verifier::Verifier ver {target_file_name}; 713 ver.CollectIdInfos(); 714 EXPECT_FALSE(ver.VerifyConstantPoolContent()); 715 } 716 } 717 718 }; // namespace panda::verifier 719