新版magisk(v24.0+)使用magiskhide

时间:2025-01-29 08:07:05

新版的Magisk没有MagiskHide了,于是我把旧版(v23.0)的MagiskHide抄了过来.

hide_unmount

最简单的检测magisk就是查看/proc/%d/mounts文件.代码如下

char line[1024];
char path[PATH_MAX];
FILE* fp;

sprintf(path,"/proc/%d/mounts",getpid());
fp = fopen(path, "r");
if (fp) {
    while (fgets(line, 1024, fp)) {
        LOGD("%s",line);
    }
    fclose(fp);
}
......
2022-07-30 17:45:31.015 13650-13650/ D/Shocker: /dev/Y1U/.magisk/block/system_root /system/lib64/ erofs ro,seclabel,relatime,user_xattr,acl,cache_strategy=readaround 0 0
2022-07-30 17:45:31.015 13650-13650/ D/Shocker: /dev/Y1U/.magisk/block/system_root /system/lib64/libvm_control. erofs ro,seclabel,relatime,user_xattr,acl,cache_strategy=readaround 0 0
2022-07-30 17:45:31.015 13650-13650/ D/Shocker: /dev/Y1U/.magisk/block/system_root /system/lib64/libvsim_auth.so erofs ro,seclabel,relatime,user_xattr,acl,cache_strategy=readaround 0 0
2022-07-30 17:45:31.015 13650-13650/ D/Shocker: /dev/Y1U/.magisk/block/system_root /system/lib64/ erofs ro,seclabel,relatime,user_xattr,acl,cache_strategy=readaround 0 0
2022-07-30 17:45:31.015 13650-13650/ D/Shocker: /dev/Y1U/.magisk/block/system_root /system/lib64/libwebviewchromium_loader.so erofs ro,seclabel,relatime,user_xattr,acl,cache_strategy=readaround 0 0
2022-07-30 17:45:31.015 13650-13650/ D/Shocker: /dev/Y1U/.magisk/block/system_root /system/lib64/ erofs ro,seclabel,relatime,user_xattr,acl,cache_strategy=readaround 0 0
2022-07-30 17:45:31.016 13650-13650/ D/Shocker: /dev/Y1U/.magisk/block/system_root /system/lib64/ erofs ro,seclabel,relatime,user_xattr,acl,cache_strategy=readaround 0 0
2022-07-30 17:45:31.016 13650-13650/ D/Shocker: /dev/Y1U/.magisk/block/system_root /system/lib64/@1. erofs ro,seclabel,relatime,user_xattr,acl,cache_strategy=readaround 0 0
2022-07-30 17:45:31.016 13650-13650/ D/Shocker: /dev/Y1U/.magisk/block/system_root /system/lib64/-V3-ndk_platform.so erofs ro,seclabel,relatime,user_xattr,acl,cache_strategy=readaround 0 0
2022-07-30 17:45:31.016 13650-13650/ D/Shocker: /dev/Y1U/.magisk/block/system_root /system/lib64/-V4-ndk_platform.so erofs ro,seclabel,relatime,user_xattr,acl,cache_strategy=readaround 0 0
2022-07-30 17:45:31.016 13650-13650/ D/Shocker: /dev/Y1U/.magisk/block/system_root /system/lib64/@1. erofs ro,seclabel,relatime,user_xattr,acl,cache_strategy=readaround 0 0
2022-07-30 17:45:31.016 13650-13650/ D/Shocker: /dev/Y1U/.magisk/block/system_root /system/lib64/@1. erofs ro,seclabel,relatime,user_xattr,acl,cache_strategy=readaround 0 0

可以看到,有很多/dev/Y1U/.magisk/block/system_root.

在MagiskHide里,这些信息都会被magisk daemon给unmount掉.

void hide_unmount(int pid) {
    if (pid > 0 && switch_mnt_ns(pid))//切换的目标进程的namespace
        return;

    LOGD("hide: handling PID=[%d]\n", pid);

    char val;
    int fd = xopen(SELINUX_ENFORCE, O_RDONLY);
    xxread(fd, &val, sizeof(val));
    close(fd);
    // Permissive
    if (val == '0') {
        chmod(SELINUX_ENFORCE, 0640);
        chmod(SELINUX_POLICY, 0440);
    }

    vector<string> targets;

    // Unmount dummy skeletons and /sbin links
    targets.push_back(MAGISKTMP);
    parse_mnt("/proc/self/mounts", [&](mntent *mentry) {
        if (TMPFS_MNT(system) || TMPFS_MNT(vendor) || TMPFS_MNT(product) || TMPFS_MNT(system_ext))
            targets.emplace_back(mentry->mnt_dir);
        return true;
    });

    for (auto &s : reversed(targets))
        lazy_unmount(s.data());
    targets.clear();

    // Unmount all Magisk created mounts
    parse_mnt("/proc/self/mounts", [&](mntent *mentry) {
        if (strstr(mentry->mnt_fsname, BLOCKDIR))
            targets.emplace_back(mentry->mnt_dir);
        return true;
    });

    for (auto &s : reversed(targets))
        lazy_unmount(s.data());
}
static void lazy_unmount(const char* mountpoint) {
    if (umount2(mountpoint, MNT_DETACH) != -1)
        LOGD("hide: Unmounted (%s)\n", mountpoint);
}

在zygisk里需要改进下.

static void companion_handler(int i)
{
    int pid;
    read(i, &pid, sizeof(pid));

    unshare(CLONE_NEWNS);
    mount(nullptr, "/", nullptr, MS_PRIVATE | MS_REC, nullptr);
    LOGD("do_hide start pid:%d\n",pid);
    do_hide(pid);
    return;
}

加载模块后,查看效果

......
2022-07-30 19:03:32.597 6774-6774/ D/Shocker: /dev/block/dm-15 /storage/emulated/0/Android/data f2fs rw,lazytime,seclabel,nosuid,nodev,noatime,background_gc=on,discard,no_heap,user_xattr,inline_xattr,acl,inline_data,inline_dentry,flush_merge,extent_cache,mode=adaptive,active_logs=6,reserve_root=32768,resuid=0,resgid=1065,inlinecrypt,alloc_mode=default,checkpoint_merge,fsync_mode=nobarrier 0 0
2022-07-30 19:03:32.597 6774-6774/ D/Shocker: /dev/block/dm-15 /storage/emulated/0/Android/obb f2fs rw,lazytime,seclabel,nosuid,nodev,noatime,background_gc=on,discard,no_heap,user_xattr,inline_xattr,acl,inline_data,inline_dentry,flush_merge,extent_cache,mode=adaptive,active_logs=6,reserve_root=32768,resuid=0,resgid=1065,inlinecrypt,alloc_mode=default,checkpoint_merge,fsync_mode=nobarrier 0 0
2022-07-30 19:03:32.597 6774-6774/ D/Shocker: tmpfs /data/data tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,mode=751 0 0
2022-07-30 19:03:32.597 6774-6774/ D/Shocker: tmpfs /data/user tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,mode=751 0 0
2022-07-30 19:03:32.597 6774-6774/ D/Shocker: tmpfs /data/user_de tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,mode=751 0 0
2022-07-30 19:03:32.597 6774-6774/ D/Shocker: /dev/block/dm-15 /data/user_de/0/ f2fs rw,lazytime,seclabel,nosuid,nodev,noatime,background_gc=on,discard,no_heap,user_xattr,inline_xattr,acl,inline_data,inline_dentry,flush_merge,extent_cache,mode=adaptive,active_logs=6,reserve_root=32768,resuid=0,resgid=1065,inlinecrypt,alloc_mode=default,checkpoint_merge,fsync_mode=nobarrier 0 0
2022-07-30 19:03:32.597 6774-6774/ D/Shocker: /dev/block/dm-15 /data/data/ f2fs rw,lazytime,seclabel,nosuid,nodev,noatime,background_gc=on,discard,no_heap,user_xattr,inline_xattr,acl,inline_data,inline_dentry,flush_merge,extent_cache,mode=adaptive,active_logs=6,reserve_root=32768,resuid=0,resgid=1065,inlinecrypt,alloc_mode=default,checkpoint_merge,fsync_mode=nobarrier 0 0
2022-07-30 19:03:32.597 6774-6774/ D/Shocker: /dev/block/dm-15 /data/user_de/0/ f2fs rw,lazytime,seclabel,nosuid,nodev,noatime,background_gc=on,discard,no_heap,user_xattr,inline_xattr,acl,inline_data,inline_dentry,flush_merge,extent_cache,mode=adaptive,active_logs=6,reserve_root=32768,resuid=0,resgid=1065,inlinecrypt,alloc_mode=default,checkpoint_merge,fsync_mode=nobarrier 0 0
2022-07-30 19:03:32.597 6774-6774/ D/Shocker: /dev/block/dm-15 /data/data/ f2fs rw,lazytime,seclabel,nosuid,nodev,noatime,background_gc=on,discard,no_heap,user_xattr,inline_xattr,acl,inline_data,inline_dentry,flush_merge,extent_cache,mode=adaptive,active_logs=6,reserve_root=32768,resuid=0,resgid=1065,inlinecrypt,alloc_mode=default,checkpoint_merge,fsync_mode=nobarrier 0 0
2022-07-30 19:03:32.597 6774-6774/ D/Shocker: tmpfs /data/misc/profiles/cur tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,mode=751 0 0
2022-07-30 19:03:32.597 6774-6774/ D/Shocker: tmpfs /data/misc/profiles/ref tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,mode=751 0 0
2022-07-30 19:03:32.597 6774-6774/ D/Shocker: /dev/block/dm-15 /data/misc/profiles/cur/0/ f2fs rw,lazytime,seclabel,nosuid,nodev,noatime,background_gc=on,discard,no_heap,user_xattr,inline_xattr,acl,inline_data,inline_dentry,flush_merge,extent_cache,mode=adaptive,active_logs=6,reserve_root=32768,resuid=0,resgid=1065,inlinecrypt,alloc_mode=default,checkpoint_merge,fsync_mode=nobarrier 0 0
2022-07-30 19:03:32.597 6774-6774/ D/Shocker: /dev/block/dm-15 /data/misc/profiles/ref/ f2fs rw,lazytime,seclabel,nosuid,nodev,noatime,background_gc=on,discard,no_heap,user_xattr,inline_xattr,acl,inline_data,inline_dentry,flush_merge,extent_cache,mode=adaptive,active_logs=6,reserve_root=32768,resuid=0,resgid=1065,inlinecrypt,alloc_mode=default,checkpoint_merge,fsync_mode=nobarrier 0 0

hide_sensitive_props

修改系统敏感属性,例如.device_state``````等等.
其原理是找到/dev/__properties__/properties_serial在进程中的内存,然后在内存中解析和修改
也可以参考这篇文章.
Android Property 实现解析与黑魔法
部分代码如下

bool ContextsSerialized::MapSerialPropertyArea(bool access_rw, bool* fsetxattr_failed) {
  char filename[PROP_FILENAME_MAX];// filename:/dev/__properties__/properties_serial
  int len = async_safe_format_buffer(filename, sizeof(filename), "%s/properties_serial", filename_);
  if (len < 0 || len >= PROP_FILENAME_MAX) {
    serial_prop_area_ = nullptr;
    return false;
  }

  if (access_rw) {
    serial_prop_area_ =
        prop_area::map_prop_area_rw(filename, "u:object_r:properties_serial:s0", fsetxattr_failed);//mmap映射到内存
  } else {
    serial_prop_area_ = prop_area::map_prop_area(filename);//mmap映射到内存
  }
  return serial_prop_area_;// serial_prop_area_就是 /dev/__properties__/properties_serial 在内存的映射地址
}

移植的resetprop代码如下.

static const char *prop_key[] =
    {".device_state", "", "",
     "", ".warranty_bit", "ro.warranty_bit",
     "", "", "", "",
     ".warranty_bit", ".warranty_bit",
     ".device_state", nullptr};

static const char *prop_val[] =
    {"locked", "green", "1",
     "enforcing", "0", "0",
     "0", "1", "user", "release-keys",
     "0", "0",
     "locked", nullptr};


void hide_sensitive_props()
{
    LOGD("hide: Hiding sensitive props\n");

    for (int i = 0; prop_key[i]; ++i)
    {
        char buf[256];
        getprop(prop_key[i], buf);
        string value = buf;
        if (!value.empty())
        {
            LOGD("set %s:%s", prop_key[i], prop_val[i]);
            setprop(prop_key[i], prop_val[i]);
        }
    }
}

日志输出如下

2022-08-01 14:12:11.035 2948-2949/? D/Shocker: set .device_state:locked
2022-08-01 14:12:11.035 2948-2949/? D/Shocker: set :green
2022-08-01 14:12:11.035 2948-2949/? D/Shocker: set :1
2022-08-01 14:12:11.035 2948-2949/? D/Shocker: set :enforcing
2022-08-01 14:12:11.035 2948-2949/? D/Shocker: set :0
2022-08-01 14:12:11.035 2948-2949/? D/Shocker: set :1
2022-08-01 14:12:11.035 2948-2949/? D/Shocker: set :user
2022-08-01 14:12:11.035 2948-2949/? D/Shocker: set :release-keys
adb shell getprop .device_state
locked

最后

GitHub地址:
/PShocker/Zygisk-MagiskHide

也可以来我的博客看看
/