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

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

  •  
  •   s82kd92l · 2018-07-10 18:57:31 +08:00 · 17074 次点击
    这是一个创建于 2358 天前的主题,其中的信息可能已经有所发展或是发生改变。
    开放 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 条附言  ·  2018-07-11 12:21:08 +08:00
    @pual
    @tempdban
    理解在实际中确实有移植 c 代码的需求,或许能这样折衷一下: 允许 app 创造全新的纯 native 进程。这种进程的资源管理与生命周期用另一套单独的框架管理,可参照 ios 做法。native 进程可以用 pipe/unix socket/shared memory/binder 之类的与 java vm 通信,但绝不允许 native code 用裸指针的方式染指 java 层。
    60 条回复    2018-07-27 10:27:43 +08:00
    xingda920813
        1
    xingda920813  
       2018-07-10 19:12:57 +08:00
    偏激了. 那 iOS 开发怎么讲?
    gam2046
        2
    gam2046  
       2018-07-10 19:26:31 +08:00   ❤️ 9
    其实不能这么说。当初 Android 能火起来,依靠的也是其开放性。现在倒打一耙说过于开放导致现在的境遇就不是很合理了。

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

    从技术层面解决你说的应用问题是不存在的,人家 ios 还可以越狱乱调私有接口。但正规的应用不敢这样做。
    zj299792458
        40
    zj299792458  
       2018-07-11 12:47:56 +08:00 via iPhone
    @jdgui 怎么唤醒?
    cxl008
        41
    cxl008  
       2018-07-11 13:44:45 +08:00
    @nicevar 正解
    VYSE
        42
    VYSE  
       2018-07-11 14:36:45 +08:00
    @s82kd92l #36 Runtime.getRuntime().exec()
    and ptrace is a syscall
    s82kd92l
        43
    s82kd92l  
    OP
       2018-07-11 16:23:26 +08:00
    @VYSE 你可能对 exec()和 syscall 有误解...

    exec()是执行命令行程序。syscall 是指 open/fork/ioctl 这种.这年头就算是 NDK 程序也没有随便用 syscall 的本事,会被 seccomp 挡住。
    VYSE
        44
    VYSE  
       2018-07-11 16:33:13 +08:00   ❤️ 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 封过, 见市面多数加壳方案.
    s82kd92l
        45
    s82kd92l  
    OP
       2018-07-11 18:12:46 +08:00
    @VYSE ptrace 自己进程和 ptrace 其他进程两码事,普通 linux 发行版都有 yama 防止随便 attach 其他进程,何况 android 这种久经考验的
    VYSE
        46
    VYSE  
       2018-07-11 18:21:29 +08:00
    @s82kd92l #45 我原话"ptrace hook 上去也可以实现 JNI 提供的功能", 你怎么非要脑洞到 ptrace 其他 UID 的进程, 我是说通过 ptrace 可以实现很多 JNI 调用, 比如 VirtualApp 里用到的 Substrate.
    s82kd92l
        47
    s82kd92l  
    OP
       2018-07-11 18:28:39 +08:00
    @VYSE 不是限制 ptrace 其他 UID,而是其他 PID
    VYSE
        48
    VYSE  
       2018-07-11 18:30:39 +08:00
    @s82kd92l #47 .......你自己再查查试试
    youxiachai
        49
    youxiachai  
       2018-07-11 18:31:32 +08:00
    我感觉...早期.android 不开放 NDK..早就 GG 了...毕竟远古时代...手机硬件性能那么差

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

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

    lz 显然陷入一种因咽废食的状态..
    s82kd92l
        50
    s82kd92l  
    OP
       2018-07-11 23:45:01 +08:00 via Android   ❤️ 1
    @VYSE 嗯,你是对的。我在 termux 里能够对其他 pid 做 strace, 看来目前 Android 是允许同一个 uid 下的进程相互调试的
    tempdban
        51
    tempdban  
       2018-07-12 00:49:39 +08:00 via Android
    你还是不明白啊,谷歌要是想做,他有一百万种方法限制你,你附言里提到的方法已经是很麻烦的办法了。
    国产手机系统就限制的不错,方案也成熟,谷歌拿去直接用呗。
    他为啥不做?就是不想得罪开发者。
    还有兄弟,等到你要实现一个需求,但是因为系统限制实在无法实现的时候,你就知道愁了,让马儿跑又不让马儿吃草的例子多了去了,用户才不管怎么解释,他就是要,WP 就是活生生的例子,多少 WP 软件作者被喷到不行,更新纪录里写着爱用不用。
    hook/hotpatch 修改 Java VM 那也只是改了我这个进程的内存页,别的进程影响不到啊。
    各种 native 层的进程保活,长连接保活,访问私有 API。
    兄弟你 ps 都能看出来的东西,系统真的看不出来么,API 不存在私有不私有兄弟。能用隐藏的 API 那是本事,API 没用做他干嘛。
    别用户的思维来搞产品,懂得 app 背后机制的人还是少数。
    有很多事是我们不得不妥协的
    tempdban
        52
    tempdban  
       2018-07-12 01:02:11 +08:00 via Android
    还有兄弟,你正文中每个英文单词,都是要仔细打磨你才能明确的知道他究竟在干些什么。
    tempdban
        53
    tempdban  
       2018-07-12 01:13:24 +08:00 via Android
    @VYSE 正想抽空看一眼 VirtualApp 到底是怎么一个黑科技,原来还是 ptrace 啊,感谢送上。
    另外请教一下 android 的 linker 和平时用的 gold 有啥区别,不都是读 ELF 吗?
    VYSE
        54
    VYSE  
       2018-07-12 03:13:19 +08:00
    @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 随便用
    VYSE
        55
    VYSE  
       2018-07-12 03:55:03 +08:00
    @tempdban #53 搞错了一点 VirtualApp 并没有用 ptrace 把 substrate so inject 进去, 而是自己代码直接 load library 的. Frida, ADBI 这种会用 ptrace.
    qsjh898
        56
    qsjh898  
       2018-07-12 11:06:35 +08:00
    要是没有 NDK,你还用个鸡毛微信
    codehz
        57
    codehz  
       2018-07-13 12:47:54 +08:00
    @VYSE #54 用 hybris 这个库还是可以加载 android 上的 so 文件的,不过由于自己实现了链接的逻辑,所以 gdb 调试就没法用了
    VYSE
        58
    VYSE  
       2018-07-13 14:53:15 +08:00
    @codehz #57 这个库不错, 做了不少 compat 补丁, 不过要是能封装一整套做 glue 的 libc, linker 直接跑已编译好的 ELF 就更好了
    tempdban
        59
    tempdban  
       2018-07-27 01:54:00 +08:00 via Android
    @VYSE 我其实对这类黑科技很感兴趣,纯靠自己研究太慢了,请问可否留个联系方式,以后讨教
    VYSE
        60
    VYSE  
       2018-07-27 10:27:43 +08:00 via Android
    @tempdban twitter @VYSEa
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3256 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 12:28 · PVG 20:28 · LAX 04:28 · JFK 07:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.