The Magic Mask for Android
This report summarizes scanner evidence for topjohnwu/Magisk, a Kotlin project with 63,190 GitHub stars. SynthScan examined 75,714 lines of code across 463 source files, recording 178 pattern matches distributed across 12 syntactic categories. The legacy adjusted pattern signal is 4.1 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 139 finding(s).
Are imports declared and package/API names verified? 1 finding(s).
Are wrappers, guards, and repeated structures necessary? 38 finding(s).
Which changes need focused human review? 178 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 178 distinct pattern matches across 12 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 31 | // ┌───────┐ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 34 | // │ │ ┌────────────────┐ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 35 | // │ └────────────────────────────────────────►│LoadNativeBridge│ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 36 | // │ └───────┬────────┘ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 37 | // ┌────────────────┐ │ │ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 38 | // │LoadNativeBridge│◄────────────┼───────────────────────────────────────────────────┘ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 39 | // └───────┬────┬───┘ │ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 40 | // │ │ │ ┌───────────────┐ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 41 | // │ └─────────────────┼────────────────────►│NativeBridgeItf│ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 42 | // │ │ └──────┬────────┘ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 45 | // │ │ ┌────────┐ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 47 | // ▼ │ └────────┘ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 48 | // ┌───────┐ │ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 52 | // │ │ ┌───────────────────────┐ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 53 | // └──────────────────────┼────────────────►│post_native_bridge_load│ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 54 | // │ └───────────────────────┘ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 56 | // ┌──────────────────────┐ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 58 | // └───────────┬────┬─────┘ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 59 | // │ │ ┌───────────────┐ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 60 | // │ └───────────────►│hook_zygote_jni│ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 61 | // │ └───────────────┘ ┌─────────┐ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 63 | // └────────────────────────────────────────────►│ JVM │ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 66 | // ┌───────────────────┐ │ │ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 67 | // │nativeXXXSpecialize│◄─────────────────────────────────────┘ │ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 68 | // └─────────────┬─────┘ │ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 69 | // │ ┌─────────────┐ │ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 70 | // └────────────────►│ZygiskContext│ │ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 71 | // └─────────────┘ ▼ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 72 | // ┌────────────────────┐ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 74 | // └─────────┬──────────┘ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 75 | // ┌────────────────┐ │ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 76 | // │restore_plt_hook│◄───────────┘ | COMMENT |
| MEDIUM⚡ | native/src/core/zygisk/hook.cpp | 77 | // └────────────────┘ | COMMENT |
| MEDIUM | scripts/app_functions.sh | 237 | # ============================================================================== | COMMENT |
| MEDIUM | scripts/app_functions.sh | 239 | # ============================================================================== | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | native/src/init/twostage.rs | 41 | } | COMMENT |
| LOW | native/src/init/selinux.rs | 21 | const SELINUX_ENFORCE: &Utf8CStr = cstr!(concatcp!(SELINUX_MNT, "/enforce")); | COMMENT |
| LOW | native/src/core/utils.cpp | 1 | #include <csignal> | COMMENT |
| LOW | native/src/core/logging.rs | 141 | } | COMMENT |
| LOW | native/src/core/magisk.rs | 81 | #[derive(FromArgs)] | COMMENT |
| LOW | native/src/core/zygisk/zygisk.hpp | 1 | #pragma once | COMMENT |
| LOW | native/src/core/zygisk/hook.cpp | 1 | #include <sys/mman.h> | COMMENT |
| LOW | native/src/core/zygisk/hook.cpp | 21 | // | COMMENT |
| LOW | native/src/core/zygisk/hook.cpp | 41 | // │ └─────────────────┼────────────────────►│NativeBridgeItf│ | COMMENT |
| LOW | native/src/core/zygisk/hook.cpp | 61 | // │ └───────────────┘ ┌─────────┐ | COMMENT |
| LOW | native/src/core/zygisk/api.hpp | 121 | // AppSpecializeArgs object. You can read and overwrite these arguments to change how the app | COMMENT |
| LOW | native/src/core/zygisk/api.hpp | 181 | struct api_table; | COMMENT |
| LOW | native/src/core/zygisk/api.hpp | 201 | COMMENT | |
| LOW | native/src/core/zygisk/api.hpp | 221 | // function that would be called in the root process with REGISTER_ZYGISK_COMPANION(func). | COMMENT |
| LOW | native/src/core/zygisk/api.hpp | 241 | // | COMMENT |
| LOW | native/src/core/zygisk/api.hpp | 261 | COMMENT | |
| LOW | native/src/core/include/core.hpp | 1 | #pragma once | COMMENT |
| LOW | native/src/core/su/su.cpp | 1 | /* | COMMENT |
| LOW | native/src/core/deny/utils.cpp | 1 | #include <sys/types.h> | COMMENT |
| LOW | native/src/boot/futility.rs | 1 | // ChromeOS verified boot kernel signing, ported from vboot_reference futility. | COMMENT |
| LOW | native/src/boot/zimage.rs | 1 | //! ARM 32-bit Linux zImage Parsing and Piggy Resizing / Relocation | COMMENT |
| LOW | native/src/boot/zimage.rs | 21 | //! | COMMENT |
| LOW | native/src/boot/zimage.rs | 41 | //! are shifted by `+ delta_got`. | COMMENT |
| LOW | native/src/boot/bootimg.cpp | 1 | #include <bit> | COMMENT |
| LOW | native/src/boot/magiskboot.hpp | 1 | #pragma once | COMMENT |
| LOW | native/src/boot/magiskboot.hpp | 21 | #define VENDOR_BOOT_MAGIC "VNDRBOOT" | COMMENT |
| LOW | native/src/include/consts.hpp | 1 | #pragma once | COMMENT |
| LOW | native/src/include/consts.hpp | 21 | COMMENT | |
| LOW | native/src/external/xz_config/xz_config.h | 21 | #elif defined(__arm__) | COMMENT |
| LOW | native/src/external/xz_config/xz_config.h | 41 | #include <stdlib.h> | COMMENT |
| LOW | native/src/external/lz4-sys/src/wasm_shim.rs | 1 | //! A shim for the libc functions used in lz4-rs that are not available when building for wasm | COMMENT |
| LOW | native/src/external/lz4-sys/src/lib.rs | 201 | // This is achieved using LZ4F_createCompressionContext(), which takes as argument a version | COMMENT |
| LOW | native/src/external/lz4-sys/src/lib.rs | 221 | // LZ4F_compressBegin() : | COMMENT |
| LOW | native/src/external/lz4-sys/src/lib.rs | 241 | // LZ4F_compressBound() : | COMMENT |
| LOW | native/src/external/lz4-sys/src/lib.rs | 261 | // meaning input data was just buffered. | COMMENT |
| LOW | native/src/external/lz4-sys/src/lib.rs | 281 | // to be be filled, you can call LZ4_flush(), which will immediately compress any remaining | COMMENT |
| LOW | native/src/external/lz4-sys/src/lib.rs | 301 | // It will flush whatever data remained within compressionContext (like LZ4_flush()) | COMMENT |
| LOW | native/src/external/lz4-sys/src/lib.rs | 321 | // The first thing to do is to create a decompressionContext object, which will be used | COMMENT |
| LOW | native/src/external/lz4-sys/src/lib.rs | 341 | COMMENT | |
| LOW | native/src/external/lz4-sys/src/lib.rs | 361 | srcBuffer: *const u8, | COMMENT |
| LOW | native/src/external/lz4-sys/src/lib.rs | 381 | // | COMMENT |
| LOW | native/src/sepolicy/include/sepolicy.hpp | 1 | #pragma once | COMMENT |
| LOW | native/src/base/argh.rs | 1 | // Copyright (c) 2020 Google LLC All rights reserved. | COMMENT |
| LOW | native/src/base/argh.rs | 21 | //! /// whether or not to jump | COMMENT |
| LOW | native/src/base/argh.rs | 41 | //! | COMMENT |
| LOW | native/src/base/argh.rs | 61 | //! `#[argh(default = "<your_code_here>")]` attribute, and in this case an | COMMENT |
| LOW | native/src/base/argh.rs | 81 | //! height: usize, | COMMENT |
| LOW | native/src/base/argh.rs | 101 | //! #[derive(FromArgs)] | COMMENT |
| LOW | native/src/base/argh.rs | 121 | //! /// A command with positional arguments. | COMMENT |
| LOW | native/src/base/argh.rs | 141 | //! #[argh(option)] | COMMENT |
| LOW | native/src/base/argh.rs | 161 | //! over each command: | COMMENT |
| LOW | native/src/base/argh.rs | 181 | //! /// First subcommand. | COMMENT |
| LOW | native/src/base/argh.rs | 201 | //! `dynamic` attribute. Instead of deriving `FromArgs`, the value inside the | COMMENT |
| LOW | native/src/base/argh.rs | 221 | //! Normal(NormalSubCommand), | COMMENT |
| LOW | native/src/base/argh.rs | 241 | //! impl DynamicSubCommand for Dynamic { | COMMENT |
| LOW | native/src/base/argh.rs | 261 | //! } | COMMENT |
| LOW | native/src/base/argh.rs | 281 | //! for command in Self::commands() { | COMMENT |
| LOW | native/src/base/argh.rs | 301 | //! # use argh::FromArgs; | COMMENT |
| LOW | native/src/base/argh.rs | 341 | } | COMMENT |
| LOW | native/src/base/argh.rs | 361 | /// /// Command to manage a classroom. | COMMENT |
| 17 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | native/src/init/selinux.rs | 102 | // Step 0: determine strategy | COMMENT |
| LOW | native/src/init/selinux.rs | 126 | // Step 1: setup for intercepting init boot control flow | COMMENT |
| LOW | native/src/init/selinux.rs | 187 | // Step 2: wait for selinuxfs to be mounted (only for LEGACY) | COMMENT |
| LOW | native/src/init/selinux.rs | 219 | // Step 3: obtain sepolicy, patch, and load the patched sepolicy | COMMENT |
| LOW⚡ | native/src/core/sqlite.cpp | 111 | // Step 1: prepare statement | COMMENT |
| LOW⚡ | native/src/core/sqlite.cpp | 119 | // Step 2: bind arguments | COMMENT |
| LOW⚡ | native/src/core/sqlite.cpp | 129 | // Step 3: execute | COMMENT |
| LOW | native/src/core/module.rs | 848 | // Step 1: Create virtual filesystem tree | COMMENT |
| LOW | native/src/core/module.rs | 878 | // Step 2: Inject custom files | COMMENT |
| LOW | native/src/core/module.rs | 897 | // Step 3: Extract all supported read-only partition roots | COMMENT |
| LOW | native/src/core/module.rs | 925 | // Step 4: Convert virtual filesystem tree into concrete operations | COMMENT |
| LOW | native/src/core/zygisk/hook.cpp | 276 | // On arm32, we need to check if the pc is in thumb mode, | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 323 | // Step 1: Calculate offset delta for GOT and trailing sections based on 4-byte realignment | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 331 | // Step 2: Patch zimage_hdr->end (offset 0x2C) with new total image end address | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 335 | // Step 3: Patch .Linflated_image_size_offset pointer table entry | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 342 | // Step 4: Patch the LC0 position table (arch/arm/boot/compressed/head.S) | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 358 | // Step 5: Patch LC1 relocation table in newer kernels | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 367 | // Step 6: Patch .table (_magic_table) TagKernelSize entry | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 374 | // Step 7: Disassemble and patch R_ARM_GOTPC PC-relative literal pool entries in .text | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 455 | // Step 1: Re-pad leading gap before the GOT with zeros to maintain 4-byte alignment | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 461 | // Step 2: Relocate internal GOT pointers (arch/arm/boot/compressed/vmlinux.lds.S) | COMMENT |
| LOW | native/src/boot/zimage.rs | 108 | // Step 1: Validate 32-bit ARM zImage header (magic 0x016f2818 at offset 0x24) | COMMENT |
| LOW | native/src/boot/zimage.rs | 123 | // Step 2: Locate the start of compressed piggy payload by scanning forward from 0x28. | COMMENT |
| LOW | native/src/boot/zimage.rs | 154 | // Step 3: Scan for the LC0 position table (arch/arm/boot/compressed/head.S) | COMMENT |
| LOW | native/src/boot/zimage.rs | 194 | // Step 4: Determine piggy_end using a 3-tier heuristic strategy | COMMENT |
| LOW | native/src/boot/zimage.rs | 266 | // Step 5: Locate .Linflated_image_size_offset matching known piggy_end | COMMENT |
| LOW | native/src/boot/zimage.rs | 286 | // Step 6: Scan for LC1 relocation table in newer kernels (where p1 + off + start == end) | COMMENT |
| LOW | native/src/boot/zimage.rs | 304 | // Step 7: Construct zero-copy ZImage struct slicing head, piggy, and tail | COMMENT |
| LOW | native/src/boot/bootimg.cpp | 206 | // We need to check if it is LZ4_LG | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | native/src/init/selinux.rs | 102 | // Step 0: determine strategy | COMMENT |
| LOW | native/src/init/selinux.rs | 126 | // Step 1: setup for intercepting init boot control flow | COMMENT |
| LOW | native/src/init/selinux.rs | 187 | // Step 2: wait for selinuxfs to be mounted (only for LEGACY) | COMMENT |
| LOW | native/src/init/selinux.rs | 219 | // Step 3: obtain sepolicy, patch, and load the patched sepolicy | COMMENT |
| LOW⚡ | native/src/core/sqlite.cpp | 111 | // Step 1: prepare statement | COMMENT |
| LOW⚡ | native/src/core/sqlite.cpp | 119 | // Step 2: bind arguments | COMMENT |
| LOW⚡ | native/src/core/sqlite.cpp | 129 | // Step 3: execute | COMMENT |
| LOW | native/src/core/module.rs | 848 | // Step 1: Create virtual filesystem tree | COMMENT |
| LOW | native/src/core/module.rs | 878 | // Step 2: Inject custom files | COMMENT |
| LOW | native/src/core/module.rs | 897 | // Step 3: Extract all supported read-only partition roots | COMMENT |
| LOW | native/src/core/module.rs | 925 | // Step 4: Convert virtual filesystem tree into concrete operations | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 323 | // Step 1: Calculate offset delta for GOT and trailing sections based on 4-byte realignment | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 331 | // Step 2: Patch zimage_hdr->end (offset 0x2C) with new total image end address | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 335 | // Step 3: Patch .Linflated_image_size_offset pointer table entry | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 342 | // Step 4: Patch the LC0 position table (arch/arm/boot/compressed/head.S) | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 358 | // Step 5: Patch LC1 relocation table in newer kernels | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 367 | // Step 6: Patch .table (_magic_table) TagKernelSize entry | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 374 | // Step 7: Disassemble and patch R_ARM_GOTPC PC-relative literal pool entries in .text | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 455 | // Step 1: Re-pad leading gap before the GOT with zeros to maintain 4-byte alignment | COMMENT |
| LOW⚡ | native/src/boot/zimage.rs | 461 | // Step 2: Relocate internal GOT pointers (arch/arm/boot/compressed/vmlinux.lds.S) | COMMENT |
| LOW | native/src/boot/zimage.rs | 108 | // Step 1: Validate 32-bit ARM zImage header (magic 0x016f2818 at offset 0x24) | COMMENT |
| LOW | native/src/boot/zimage.rs | 123 | // Step 2: Locate the start of compressed piggy payload by scanning forward from 0x28. | COMMENT |
| LOW | native/src/boot/zimage.rs | 154 | // Step 3: Scan for the LC0 position table (arch/arm/boot/compressed/head.S) | COMMENT |
| LOW | native/src/boot/zimage.rs | 194 | // Step 4: Determine piggy_end using a 3-tier heuristic strategy | COMMENT |
| LOW | native/src/boot/zimage.rs | 266 | // Step 5: Locate .Linflated_image_size_offset matching known piggy_end | COMMENT |
| LOW | native/src/boot/zimage.rs | 286 | // Step 6: Scan for LC1 relocation table in newer kernels (where p1 + off + start == end) | COMMENT |
| LOW | native/src/boot/zimage.rs | 304 | // Step 7: Construct zero-copy ZImage struct slicing head, piggy, and tail | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | build.py | 87 | except FileNotFoundError: | CODE |
| HIGH | build.py | 97 | except FileNotFoundError as e: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | …pk/src/main/java/com/topjohnwu/magisk/ui/MainScreen.kt | 176 | // In rail mode this slot is also composed (unplaced) by the scaffold, | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | scripts/avd_setup.sh | 140 | # Create a marker file to understand it is a live setup | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | build.py | 565 | CODE | |
| LOW | build.py | 623 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | scripts/avd_setup.sh | 7 | # For developing Magisk, just use: | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | scripts/flash_script.sh | 59 | # Check if system root is installed and remove | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | build.py | 19 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | scripts/env.py | 13 | __all__ = [ | CODE |