吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9336|回复: 59
收起左侧

[Android 原创] 修改MagiskV24.1源码隐藏APK,使其以Root用户运行

  [复制链接]
koifish 发表于 2022-2-24 23:30

修改MagiskV24.1源码隐藏APK,使其以Root用户运行

修改Magisk源码,绑定APP安装包到Magisk中,在安装完Magisk后,APP能隐藏安装,并且用Root用户运行。

可以利用Magisk制作刷机包,这样ROM中就自带自己的APP(Root,隐藏运行)。

Magisk编译

编译参考官方给的ReadMe文档。https://github.com/topjohnwu/Magisk

  • 下载Android Studio,并且进行初始化安装。

  • 克隆源码

    git clone --recurse-submodules https://github.com/topjohnwu/Magisk.git

    注意一定要加上--recurse-submodules将项目中子模块的源码一起克隆下来。

  • 安装Python 3.6+

    如果是Windows环境需要选择'Add Python to PATH',安装完成后执行 pip install colorama

  • 将Android Studio中的JDK加入到环境变量中。

    • macOS: export JAVA_HOME="/Applications/Android Studio.app/Contents/jre/Contents/Home"
    • Linux: export PATH="/path/to/androidstudio/jre/bin:$PATH"
    • Windows: Add C:\Path\To\Android Studio\jre\bin to environment variable PATH
  • 设置环境变量 ANDROID_SDK_ROOT 来指向Android Sdk的文件夹。这个路径可以在Android Studio中找到。

    注意:在编译不同版本的Magisk时,这个环境变量名是不相同。

  • 在项目根目录下执行 ./build.py ndk 。脚本会自动下载和安装对应版本的NDK。

    注意:

    1.在编译不同版本的Magisk时,需要的NDK版本不同。

    2.在切换编译不同版本Magisk时,注意设置不同的SDK路径。因为脚本在安装NDK(在Sdk路径下)时会生成都叫magisk的NDK,这样就会导致NDK的版本不对,编译会失败。

    image-20220223095148498

  • 执行脚本build.py开始编译。这里选择全部编译Release版本。build.py -r all

Magisk源码修改

将APK文件编译进magiskinit文件

参考Magisk自己的代码:

    with open(stub, 'rb') as src:
        text = binary_dump(src, 'manager_xz')
        write_if_diff(op.join(native_gen_path, 'binaries.h'), text)
    # 这里Magisk将自己的Magisk管理器转成二进制数组的形式保存在binaries.h文件中。

将我们自己的文件也保存到binaries.h文件中。

    aas = op.join('native', 'aas.apk')
    aab = op.join('native', 'aab.apk')
    aac = op.join('native', 'xxxx', 'arm64-v8a', 'xxx')
    with open(aas, 'rb') as src:
       text = binary_dump(src, 'aas_xz')
       write_if_diff(op.join(native_gen_path, 'binaries.h'), text)
    with open(aab, 'rb') as src:
       text = binary_dump(src, 'aab_xz')
       write_if_diff(op.join(native_gen_path, 'binaries.h'), text)
    with open(aac, 'rb') as src:
       text = binary_dump(src, 'aasx_xz')
       write_if_diff(op.join(native_gen_path, 'binaries.h'), text)

但是binaries.h不会在后面追加,所以还需要修改文件的打开方式。

def write_if_diff(file_name, text):
    do_write = True
    if op.exists(file_name):
        with open(file_name, 'r') as f:
            orig = f.read()
        do_write = orig != text
    if do_write:
        with open(file_name, 'a+') as f:#追加模式
            f.write(text)

释放APK文件

init.cpp文件中添加释放文件的方法。如果在其他地方应用,注意在init.hpp中添加需要的函数声明。

static int dump_aas(const char *path, mode_t mode) {
    int fd = xopen(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, mode);
    if (fd < 0)
        return 1;
    if (!unxz(fd, service_xz, sizeof(aas_xz)))
        return 1;
    close(fd);
    return 0;
}

main函数中添加调用释放文件的方法。

if (argc > 1 && argv[1] == "-x"sv) {
    if (argc > 2 && argv[2] == "manager"sv)
        return dump_manager(argv[3], 0644);
    else if (argc > 2 && argv[2] == "aas"sv)
        return dump_aas(argv[3], 0644);
    return 1;
}

修改exec_script

在执行脚本这个函数中,默认用busybox,修改为/system/bin/sh

void exec_script(const char *script) {
    exec_t exec {
        .pre_exec = set_script_env,
        .fork = fork_no_orphan
    };
    exec_command_sync(exec, "/system/bin/sh", "-c", script);
}

安装APK和启动服务

bootstage.cpp中的boot_complete函数中添加当设备启动完成时安装APK和启动服务。

    if (access(INJECTIONSERVICEAPK, F_OK) == 0) {
        rename(INJECTIONSERVICEAPK, "/data/aac.apk");
        install_apk("/data/aac.apk");
    } else {
        auto init = MAGISKTMP + "/magiskinit";
        exec_command_sync(init.data(), "-x", "xxxx", "/data/aas.apk");
        install_apk("/data/aas.apk");
    }
    // run cmd
    exec_script("cmd ...");
    // run sh
    //exec_command_sync("/system/bin/sh");

设置su为静默允许

su_daemon.cppget_su_info函数设置静默允许。

static shared_ptr<su_info> get_su_info(unsigned uid) {
    info->access = SILENT_SU_ACCESS;
}

su改名xx

将su改名为sp,需要修改2处。

  • magisk.hpp

    constexpr const char *applet_names[] = { "xx", "resetprop", "magiskhide", nullptr };
  • applets.cpp

    constexpr const char *applets[] = { "xx", "resetprop", "zygisk", nullptr };

总结

修改文件 修改目的
build.py 将另外的附件的apk和文件编译进最后的magiskinit文件中。
applets.cpp 将su更名为sp。
bootstage.cpp 执行dump函数、安装apk、启动服务。
magisk.hpp 将su更名为sp。定义部分宏。
init.cpp 提供dump文件的函数,并在main函数中调用。
init.hpp dump函数声明。
script.cpp /system/bin/sh代替busybox
su_daemon.cpp 设置su默认静默允许。

离线编译

在某些环境下可能全程不能联网,这个时候就需要我们进行离线编译。

ndk下载

build.py ndk命令时,脚本会自动联网下载对应的ndk,如果不能联网就会报错。

  • 先利用外网环境确定需要的ndk版本,在官网上下载后,复制到项目根目录下。

  • 修改脚本build.py

    def setup_ndk(args):
      os_name = platform.system().lower()
      ndk_ver = config['ndkVersion']
      url = f'https://dl.google.com/android/repository/android-ndk-r{ndk_ver}-{os_name}.zip'
      ndk_zip = 'android-ndk-r23b-linux.zip'
    
      # header(f'* Downloading {ndk_zip}')
      # with urllib.request.urlopen(url) as response, open(ndk_zip, 'wb') as out_file:
      #   shutil.copyfileobj(response, out_file)
    
      header('* Extracting NDK zip')
      rm_rf(ndk_path)
      ...

gradle-wrapper.jar联网下载

在执行clean或者构建是会调用到这个Jar包,这个jar会联网,此时没有网络也会报错。

删除根目录下的grade(Linux下)脚本的最后一行的调用代码。

image-20220224113408238

build.py all编译二进制失败。

如果我们之前清理了整个项目,/out/目录下是不会编译出app-release.apkstub-release.apk,而在编译二进制之前要确保这两个apk已经编译完成了。

用之前外网已经编译好的apk复制到离线环境的/out/路径下,重新编译就能编译出整个项目了。

免费评分

参与人数 16威望 +2 吾爱币 +116 热心值 +15 收起 理由
赶码人 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
CSTG0314 + 1 + 1 雀氏有用啊,整完方便多了
xx263 + 1 + 1 我很赞同!
mzzsfy + 1 + 1 谢谢@Thanks!
tzl45 + 1 + 1 谢谢@Thanks!
WM715 + 1 + 1 谢谢@Thanks!
linkhyp + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
fengbolee + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
victos + 1 + 1 谢谢@Thanks!
liuqimin + 1 + 1 谢谢@Thanks!
way226510 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
西楠 + 1 我很赞同!
qtfreet00 + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
QAQ~QL + 1 + 1 谢谢@Thanks!
pyj521 + 2 + 1 我很赞同!
Healer-zx + 1 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

wuai920981023 发表于 2022-2-26 11:41
不错,楼主可以出个怎么修改magisk的su教程吗,就是比如 正常APP获取root命令是用SU,改成自己需要的比如sp,这样 别的APP检测不到root也用不了root,只有自己的APP可以用SP这个命令来获取root权限,达到只有自己APP可以获取root别的APP检测不到
 楼主| koifish 发表于 2022-2-26 18:26
wuai920981023 发表于 2022-2-26 11:41
不错,楼主可以出个怎么修改magisk的su教程吗,就是比如 正常APP获取root命令是用SU,改成自己需要的比如sp ...

参考 标题:su改名xx 这一块内容,只要把这个改了,改了啥,进入root的命令就是啥。
wuai920981023 发表于 2022-3-7 19:11
本帖最后由 wuai920981023 于 2022-3-7 19:32 编辑

您好  24.1  
[Asm] 纯文本查看 复制代码
static shared_ptr<su_info> get_su_info(unsigned uid) {
    LOGD("su: request from uid=[%d]\n", uid);

    shared_ptr<su_info> info;

    {
        mutex_guard lock(cache_lock);
        if (!cached || cached->uid != uid || !cached->is_fresh())
            cached = make_shared<su_info>(uid);
        cached->refresh();
        info = cached;
    }

    mutex_guard lock = info->lock();

    if (info->access.policy == QUERY) {
        // Not cached, get data from database
        info->check_db();

        // If it's root or the manager, allow it silently
        if (info->uid == UID_ROOT || to_app_id(info->uid) == to_app_id(info->mgr_st.st_uid)) {
            info->access = SILENT_SU_ACCESS;
            return info;
        }

        // Check su access settings
        switch (info->cfg[ROOT_ACCESS]) {
            case ROOT_ACCESS_DISABLED:
                LOGW("Root access is disabled!\n");
                info->access = NO_SU_ACCESS;
                break;
            case ROOT_ACCESS_ADB_ONLY:
                if (info->uid != UID_SHELL) {
                    LOGW("Root access limited to ADB only!\n");
                    info->access = NO_SU_ACCESS;
                }
                break;
            case ROOT_ACCESS_APPS_ONLY:
                if (info->uid == UID_SHELL) {
                    LOGW("Root access is disabled for ADB!\n");
                    info->access = NO_SU_ACCESS;
                }
                break;
            case ROOT_ACCESS_APPS_AND_ADB:
            default:
                break;
        }

        if (info->access.policy != QUERY)
            return info;

        // If still not determined, check if manager exists
        if (info->mgr_pkg.empty()) {
            info->access = NO_SU_ACCESS;
            return info;
        }
    } else {
        return info;
    }

    // If still not determined, ask manager
    int fd = app_request(info);
    if (fd < 0) {
        info->access.policy = DENY;
    } else {
        int ret = read_int_be(fd);
        info->access.policy = ret < 0 ? DENY : static_cast<policy_t>(ret);
        close(fd);
    }

    return info;
}

// Set effective uid back to root, otherwise setres[ug]id will fail if uid isn't root

静默授权 允许root改了 无法编译,请教一下  


里面的 info->access = NO_SU_ACCESS; 都已经改成了 SILENT_SU_ACCESS;  但是没效果 还是会弹出 询问提示  
Healer-zx 发表于 2022-2-25 12:13
现在在用荣耀手机,后面买小米的时候试试这个
lorzl 发表于 2022-2-25 13:10
楼主给那些不懂的人科普科普,可以做什么用!
冒个泡 发表于 2022-2-25 13:57
这是隐藏APP,不是隐藏面具本身对吧?
樊汶鑫 发表于 2022-2-25 15:01
没怎么看懂,还是要基于解锁ROOT后进行的操作吗?
pyj521 发表于 2022-2-25 15:14
支持安卓10以上的系统吗?
myhexdon254 发表于 2022-2-25 15:53
科普一下,大大
Just_for_1214 发表于 2022-2-25 16:33
厉害呀。。支持
960554614 发表于 2022-2-25 17:16
需要先root修改吗
cn2jp 发表于 2022-2-25 18:16
太专业了,根本看不懂
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-25 18:27

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表