首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  Android

回头再看,感觉 android 对所有 app 开放 NDK 是大败笔

  •  
  •   s82kd92l · 9 天前 · 5680 次点击
    开放 NDK 初衷应该是为了应对很少场景下的高性能要求,比如直接处理音频 /视频编码。而随着 Java vm 优化越来越好,NDK 作为高性能替代品的作用也越来越小了。最需要性能的游戏其实也可能绕过 NDK,用 java+shader+renderscript/opencl/vulkan 做到不错的效果。

    相反,NDK 的大门一开,却使得无数不务正业的黑科技成为可能:各种 hook/hotpatch 修改 Java VM 本身,各种 native 层的进程保活,长连接保活,访问私有 API,甚至利用 linux 内核漏洞 root。现在稍微大一点的项目,不再 native 层做反 hook 加壳都不好意思跟人打招呼,而且 hook 这些本来就是猫捉老鼠的游戏,甚至可以说是军备竞赛,战场是在用户的手机上,武器就是双方程序员的时间和精力,受伤的是 cpu 和电池。Google 这么多年在 android 安全上的投入,包括 selinux,seccomp 也都是主要针对来自第三方 NDK 代码的威胁。

    所以我觉得 NDK 应该做成高危权限,没有明确的理由禁止使用,这样 android 的生态会清净得多。
    第 1 条附言  ·  9 天前
    @pual
    @tempdban
    理解在实际中确实有移植 c 代码的需求,或许能这样折衷一下: 允许 app 创造全新的纯 native 进程。这种进程的资源管理与生命周期用另一套单独的框架管理,可参照 ios 做法。native 进程可以用 pipe/unix socket/shared memory/binder 之类的与 java vm 通信,但绝不允许 native code 用裸指针的方式染指 java 层。
    58 回复  |  直到 2018-07-13 14:53:15 +08:00
        1
    xingda920813   9 天前
    偏激了. 那 iOS 开发怎么讲?
        2
    gam2046   9 天前   ♥ 9
    其实不能这么说。当初 Android 能火起来,依靠的也是其开放性。现在倒打一耙说过于开放导致现在的境遇就不是很合理了。

    比较客观的说法,当初 Android 依靠开放性,吸引了一批奇技淫巧者,弄出了许多新奇的东西。但是随着蛋糕越来越大,自然也开始慢慢有人惦记了,总会有苍蝇臭虫飞回来。这不是开放的原罪。
        3
    981340936lxm   9 天前 via Android
    不太同意,那有没有考虑好的一面呢?
        4
    tetora   9 天前 via Android
    我觉得挺好的,起码这方面的知识多起来了,都安分守己的话,不就少了很多岗位了吗
        5
    lonelinsky   9 天前
        6
    sampeng   9 天前
    安全你没考虑到啊。。不提供 ndk。。私密的逻辑怎么搞? java 真的就是在裸奔啊。。
        7
    s82kd92l   9 天前 via Android
    @xingda920813 iOS 从一开始就是 native 层,所有的文档都是 native,沙盒安全边界也是 native。Android 文档绝大部分是在 Java 层,所以这些 hook 之类的是 undocumented behaviour,所以才叫“黑科技”。
        8
    s82kd92l   9 天前 via Android
    @sampeng
    @981340936lxm java 字节码一样可以做混淆。就保护代码本身而言不觉得比机器汇编码差哪去。
        9
    nicevar   9 天前
    不开放 NDK 的话 android 很难有今天,光游戏这块就发展不起来,你说的那一套有人用才行,别人其他平台有现成的代码光移植就成大问题,另外机顶盒这块也很难发展起来,2.x 版本的时候没有 ndk 很多东西都没法做,连个最简单的获取本地网卡的 mac 地址都不行
        10
    s82kd92l   9 天前 via Android
    @nicevar 机顶盒里都是厂商自带 app,权限高用 ndk 没问题啊
        11
    codehz   9 天前
    @lonelinsky #5 已经有方法 native 层 patch vm 绕过了
        12
    hjc4869   9 天前
    WP7 当年就不让第三方 app 用 native code,所有代码全部运行在 CLR 上。结果系统自带 native apps 无比流畅,第三方 app 却都卡的没法用。
        13
    SonicY   9 天前 via Android
    WP7 那是仅限于首页滑动流畅……
        14
    s82kd92l   9 天前
    @hjc4869 现在的纯 java app 在 android 上也可以无比流畅的
        15
    yhzwy   9 天前
    身为程序员当然是能玩的东西越多越好。
    不然都限制死了还玩什么
        16
    jdgui   9 天前 via Android
    @s82kd92l 混淆没啥用吧。我们都是看 smail 看程序逻辑的
        17
    s82kd92l   9 天前   ♥ 1
    @jdgui 真要用心混淆的话看 smail 看不出的。随便想想就有很多种方法让 smail 逻辑隐藏,当然会需要一个整体性的混淆框架:
    1. 自动把代码逻辑分成很多小的 class。复杂的逻辑可能被分成成百上千的 class。人肉看这种 smail 代码会疯掉的。
    2. 实现一个 userspace coroutine/thread 之类的框架,然后就可以做 non-deterministic execution.可能执行 10 个 smail 指令就跳到另一个 thread 上了,下次跳回来也不知道是什么时候。这种逻辑必须执行时才能确定路径,无法静态分析。
        18
    pual   9 天前 via Android
    Java 虚拟机堆内存太少,有时需要加载动画 webp 之类的需要 ndk 分配进程的堆内存
        19
    pual   9 天前 via Android
    另利用 jni 与 java 层调用很多优秀的开源库,ss 的 Android 版本就是一个很不错的栗子
        20
    tempdban   9 天前 via Android   ♥ 1
    我 c 语言写的框架到你安卓里还必须要 Java 重写一遍?我现成的加密库到你安卓再移植一年?移植的万一有 bug 谁维护?
    初期安卓软件少的时候怎么上量?
    不弄的方便一点谁给你写?
    你把 app 耍流氓的锅扔给 ndk 谁能服?
    源码就在那给你看,还是不是该耍的流氓还要耍 就算没有 ndk 没有 jni,是不是套路层出不穷?
    WP 那个 API 给的少的可怜 逼死多少 app。
    谷歌是没撕破脸皮,直接搞一 cgroup 限制死你,管你是啥语言都没用。
    因噎废食
        21
    tempdban   9 天前 via Android
    还有你说文档大多只告诉 Java 层怎么用,咱先不管是不是这样,源码就摆在那,公开的科技他还叫黑科技?
    还扯到 Root … 有多少 rootkit 是内核直接提权,有多少是利用系统服务提权。
    你说 selinux 针对来自第三方 NDK 代码的威胁,兄弟,你怕是来引战的。
        22
    janus77   9 天前   ♥ 1
    四个字,因噎废食
        23
    wweir   9 天前 via Android
    “ NDK 应该做成高危权限”
    回波血,同意 lz 的观点,既然 ndk 能做到很多无法预见的事情,那把 ndk 标注为高危特殊权限就没毛病
        24
    opengps   9 天前 via Android
    选择空间越大,创新能力越强,题主喜欢规范统一没问题,只是容易错失一些创新
        25
    lolizeppelin   9 天前 via Android
    游戏还做不做了 没 ndk 你现在都能在安卓上玩些啥游戏。 安卓都 tm 没了好不
        26
    liprais   9 天前   ♥ 1
    ndk 没问题,app 不审核才是最大的问题
        27
    randyzhao   9 天前   ♥ 1
    这事应该应用市场去做
        28
    missdeer   9 天前
    偏激了,我们用 NDK 主要是为了代码跨平台
        29
    cxl008   9 天前
    安全层面考虑,最后代码必然下沉,越来越往下,java 那裸奔的感觉,反编译后随意修改。。。只能说你的看法比较片面
        30
    zj299792458   9 天前 via iPhone
    会安卓会 java 会 C 会 ndk 表示不知道你们在讲什么,ndk 和保活是啥关系?
        31
    Mutoo   9 天前
    游戏用 java 写的话,移植性就差了,这也是为什么 cocos2d-x 能干掉 cocos2d-java 和 cocos2d-objc 的原因。
        32
    flyingghost   9 天前
    开放本身没有错,开放是吸引力,开放是创新之源,开放是避免同质化的途径之一。
    但窗户打开,难免就会有苍蝇进来。关窗吗?自绝之路。正确的做法是完善从线下到线上的安全体系、监测体系、事后惩戒体系。
    windows 占了你说的多少个优点?开放、一堆 Undocumented、蛋糕足够大。win 的生态也确实足够糟糕的。那怎么办呢?
        33
    nicevar   9 天前
    @s82kd92l 还有很多第三方合作 app 的,没有推广渠道,盒子卖不了几个
    另外 java 的混淆在怎么折腾防护能力也高不到哪去,还是 smali,静态分析动态分析不是什么问题,你想一下 windows 安全对抗发展那么多年,什么加密加壳虚拟机自己写 loader 都还被击破,我不知道你有没有听过安全发展那个笑话,一个 10G 的程序运行了一个小时后打印出了 hello world
        34
    VYSE   9 天前
    其实禁用 NDK 没啥用, 你得禁 ELF 执行, 不然 ptrace hook 上去也可以实现 JNI 提供的功能, 现有 Android 不现实, 只能通过 secommp 这些再进行些 API 管控
        35
    s82kd92l   9 天前
    @nicevar 你的论据正好说明了 java 与 native 的防护能力是五十步笑百步,windows 第三方大都是 c/c++写的也没好到哪去。能真正保证不被盗的只有一条铁律:不在客户端保存敏感代码,尽量不在客户端运行敏感代码。 @cxl008
        36
    s82kd92l   9 天前
    @VYSE 不让你用 NDK 你哪来的 ptrace?
        37
    jdgui   9 天前
    @zj299792458 之前版本的,liunx 运行个 c 进程去唤醒 app
        38
    nicevar   9 天前   ♥ 1
    @s82kd92l 你错了,不是五十步笑百步,是五十步笑千步,如果 java 混淆能挡住 5%的人,那封装成 so 稍作处理就可能挡住 80%的人,差距是巨大的,软件根本不可能保证不被盗,只能阻止一部分人,这个值当然越大越好了
    另外其实我想说即使没有 NDK,也会有一整套的东西出来,你没见过 iPhone 出来的时候不能开发软件没有 sdk,那开发链接工具是怎么来的了?除非你 android 连 rom 都不让人摸到
        39
    cxh116   9 天前 via Android
    如果 android 像 ios 只有一个应用市场,乱搞直接封帐号,就不会有这么多问题了。

    从技术层面解决你说的应用问题是不存在的,人家 ios 还可以越狱乱调私有接口。但正规的应用不敢这样做。
        40
    zj299792458   9 天前 via iPhone
    @jdgui 怎么唤醒?
        41
    cxl008   9 天前
    @nicevar 正解
        42
    VYSE   9 天前
    @s82kd92l #36 Runtime.getRuntime().exec()
    and ptrace is a syscall
        43
    s82kd92l   8 天前
    @VYSE 你可能对 exec()和 syscall 有误解...

    exec()是执行命令行程序。syscall 是指 open/fork/ioctl 这种.这年头就算是 NDK 程序也没有随便用 syscall 的本事,会被 seccomp 挡住。
        44
    VYSE   8 天前   ♥ 1
    @s82kd92l #43 你可能有误解, 我说 exec 是说不需要 NDK, ELF 始终是可以执行的, 甚至可以用 Linux arm toolchain 静态编译出不依赖 Android linker 的 ELF.

    第二 ptrace 的确是 syscall, 见 bionic 代码
    unsigned int __fastcall _ptrace(enum __ptrace_request a1, void *a2, void *a3)
    {
    unsigned int result; // r0

    result = linux_eabi_syscall(__NR_ptrace, a1, a2, a3);
    if ( result > 0xFFFFF000 )
    result = j___set_errno_internal(-result);
    return result;
    }

    第三 ptrace 自己进程来做 code modify 从来没有被 seccomp 封过, 见市面多数加壳方案.
        45
    s82kd92l   8 天前
    @VYSE ptrace 自己进程和 ptrace 其他进程两码事,普通 linux 发行版都有 yama 防止随便 attach 其他进程,何况 android 这种久经考验的
        46
    VYSE   8 天前
    @s82kd92l #45 我原话"ptrace hook 上去也可以实现 JNI 提供的功能", 你怎么非要脑洞到 ptrace 其他 UID 的进程, 我是说通过 ptrace 可以实现很多 JNI 调用, 比如 VirtualApp 里用到的 Substrate.
        47
    s82kd92l   8 天前
    @VYSE 不是限制 ptrace 其他 UID,而是其他 PID
        48
    VYSE   8 天前
    @s82kd92l #47 .......你自己再查查试试
        49
    youxiachai   8 天前
    我感觉...早期.android 不开放 NDK..早就 GG 了...毕竟远古时代...手机硬件性能那么差

    说败笔..其实,你说的缺点,其实大部分都不是事...起码对于一个生态来说...

    不能因为有黑暗的存在..就不能用光明的手段啊...

    lz 显然陷入一种因咽废食的状态..
        50
    s82kd92l   8 天前 via Android   ♥ 1
    @VYSE 嗯,你是对的。我在 termux 里能够对其他 pid 做 strace, 看来目前 Android 是允许同一个 uid 下的进程相互调试的
        51
    tempdban   8 天前 via Android
    你还是不明白啊,谷歌要是想做,他有一百万种方法限制你,你附言里提到的方法已经是很麻烦的办法了。
    国产手机系统就限制的不错,方案也成熟,谷歌拿去直接用呗。
    他为啥不做?就是不想得罪开发者。
    还有兄弟,等到你要实现一个需求,但是因为系统限制实在无法实现的时候,你就知道愁了,让马儿跑又不让马儿吃草的例子多了去了,用户才不管怎么解释,他就是要,WP 就是活生生的例子,多少 WP 软件作者被喷到不行,更新纪录里写着爱用不用。
    hook/hotpatch 修改 Java VM 那也只是改了我这个进程的内存页,别的进程影响不到啊。
    各种 native 层的进程保活,长连接保活,访问私有 API。
    兄弟你 ps 都能看出来的东西,系统真的看不出来么,API 不存在私有不私有兄弟。能用隐藏的 API 那是本事,API 没用做他干嘛。
    别用户的思维来搞产品,懂得 app 背后机制的人还是少数。
    有很多事是我们不得不妥协的
        52
    tempdban   8 天前 via Android
    还有兄弟,你正文中每个英文单词,都是要仔细打磨你才能明确的知道他究竟在干些什么。
        53
    tempdban   8 天前 via Android
    @VYSE 正想抽空看一眼 VirtualApp 到底是怎么一个黑科技,原来还是 ptrace 啊,感谢送上。
    另外请教一下 android 的 linker 和平时用的 gold 有啥区别,不都是读 ELF 吗?
        54
    VYSE   8 天前
    @tempdban #53 linker 本质是负责加载 so, 最初两者只是实现细节上的区别, 比如之前研究一般情况可以替换:
    https://v-e-o.blogspot.com/2017/12/run-arm-executables-on-linux-x86-with.html

    不过最新的 Android linker 已经加入 PIE only, namespace, ZIP LD_LIBRARY_PATH 等一堆 feature, 现在已经没法直接移植到 Linux 平台
    我司也有产品直接在 LXC 里跑 Android, 两套 linker 随便用
        55
    VYSE   8 天前
    @tempdban #53 搞错了一点 VirtualApp 并没有用 ptrace 把 substrate so inject 进去, 而是自己代码直接 load library 的. Frida, ADBI 这种会用 ptrace.
        56
    qsjh898   8 天前
    要是没有 NDK,你还用个鸡毛微信
        57
    codehz   7 天前
    @VYSE #54 用 hybris 这个库还是可以加载 android 上的 so 文件的,不过由于自己实现了链接的逻辑,所以 gdb 调试就没法用了
        58
    VYSE   6 天前
    @codehz #57 这个库不错, 做了不少 compat 补丁, 不过要是能封装一整套做 glue 的 libc, linker 直接跑已编译好的 ELF 就更好了
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   鸣谢   ·   实用小工具   ·   2834 人在线   最高记录 3541   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.1 · 24ms · UTC 06:48 · PVG 14:48 · LAX 23:48 · JFK 02:48
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1