| 324 | |
| 325 | |
| 326 | void preSpecialize(AppSpecializeArgs *args) { |
| 327 | unsigned int flags = api->getFlags(); |
| 328 | const bool whitelist = access("/data/adb/nohello/whitelist", F_OK) == 0; |
| 329 | const bool nodirtyro = access("/data/adb/nohello/no_dirtyro_ar", F_OK) == 0; |
| 330 | if (flags & zygisk::StateFlag::PROCESS_GRANTED_ROOT) { |
| 331 | api->setOption(zygisk::Option::DLCLOSE_MODULE_LIBRARY); |
| 332 | return; |
| 333 | } |
| 334 | auto fn = [this](const std::string& lib) { |
| 335 | auto di = devinoby(lib.c_str()); |
| 336 | if (di) { |
| 337 | return *di; |
| 338 | } else { |
| 339 | LOGW("#[zygisk::?] devino[dl_iterate_phdr]: Failed to get device & inode for %s", lib.c_str()); |
| 340 | LOGI("#[zygisk::?] Fallback to use `/proc/self/maps`"); |
| 341 | return devinobymap(lib); |
| 342 | } |
| 343 | }; |
| 344 | if ((whitelist && isuserapp(args->uid)) || flags & zygisk::StateFlag::PROCESS_ON_DENYLIST) { |
| 345 | pid_t pid = getpid(), ppid = getppid(); |
| 346 | cfd = api->connectCompanion(); // Companion FD |
| 347 | api->exemptFd(cfd); |
| 348 | if (write(cfd, &ppid, sizeof(ppid)) != sizeof(ppid)) { |
| 349 | LOGE("#[zygisk::preSpecialize] write: [-> ppid]: %s", strerror(errno)); |
| 350 | close(cfd); |
| 351 | api->setOption(zygisk::Option::DLCLOSE_MODULE_LIBRARY); |
| 352 | return; |
| 353 | } |
| 354 | int advice; |
| 355 | if (read(cfd, &advice, sizeof(advice)) != sizeof(advice)) { |
| 356 | LOGE("#[zygisk::preSpecialize] read: [<- status]: %s", strerror(errno)); |
| 357 | close(cfd); |
| 358 | api->setOption(zygisk::Option::DLCLOSE_MODULE_LIBRARY); |
| 359 | return; |
| 360 | } |
| 361 | if (advice == MODULE_CONFLICT) { |
| 362 | close(cfd); |
| 363 | api->setOption(zygisk::Option::DLCLOSE_MODULE_LIBRARY); |
| 364 | return; |
| 365 | } |
| 366 | std::tie(cdev, cinode) = fn("libc.so"); |
| 367 | if (!cdev && !cinode) { |
| 368 | LOGE("#[zygisk::preSpecialize] Failed to get device & inode for libc.so"); |
| 369 | close(cfd); |
| 370 | api->setOption(zygisk::Option::DLCLOSE_MODULE_LIBRARY); |
| 371 | return; |
| 372 | } |
| 373 | std::tie(rundev, runinode) = fn("libandroid_runtime.so"); |
| 374 | if (!rundev && !runinode) { |
| 375 | LOGE("#[zygisk::preSpecialize] Failed to get device & inode for libandroid_runtime.so"); |
| 376 | close(cfd); |
| 377 | api->setOption(zygisk::Option::DLCLOSE_MODULE_LIBRARY); |
| 378 | return; |
| 379 | } |
| 380 | api->pltHookRegister(rundev, runinode, "unshare", (void*) reshare, (void**) &ar_unshare); |
| 381 | api->pltHookCommit(); |
| 382 | if (!nodirtyro) { |
| 383 | if (auto res = robaseby(rundev, runinode)) { |
nothing calls this directly
no test coverage detected