【问题标题】:How to prevent NDK from dumping stack trace to android logcat?如何防止 NDK 将堆栈跟踪转储到 android logcat?
【发布时间】:2017-10-06 16:25:06
【问题描述】:

我们正在努力添加一个 NDK 组件,以便为我们的 Android 应用提供额外的安全性。我们希望这个组件的逻辑是私有的,因此不希望在 android studio logcat 中转储堆栈跟踪。我已经尝试了 CMake 构建配置的几个标志,但似乎都没有帮助。

    externalNativeBuild {
        cmake {
            cppFlags "-lz -std=c++11 -s"
            arguments "-DAPP_OPTIM=release", "-DCMAKE_BUILD_TYPE=Release"
        }
    }

另外,是否有任何类似 Proguard 的工具可用于 NDK 以便混淆代码?

【问题讨论】:

    标签: android c++ cmake android-ndk


    【解决方案1】:

    你在问一个有点奇怪的事情。如果您只想使逆向工程更难 - 那么最好只混淆代码并且不要试图隐藏您的崩溃,至少因为它:

    • 使得在开发过程中调试应用程序变得更加困难
    • 无法通过 Google Play 控制台从最终用户那里获取崩溃报告
    • 以不可预知的方式干扰系统范围的故障报告机制和应用程序框架

    如果你还想尝试一下 - 试试这个 sn-p:

    #include <signal.h>
    #include <stddef.h>
    #include <unistd.h>
    #include <sys/syscall.h>
    
    void makeCrashesSilent() {
        struct sigaction sa;
        sa.sa_flags = SA_SIGINFO;
        sa.sa_sigaction = [] (int signo, siginfo_t*, void*) {
            _exit(1);
        };
        int signals[] = {
                SIGSEGV,
                SIGBUS,
                SIGFPE,
                SIGABRT,
                SIGILL,
                SIGINT,
        };
        for (size_t i = 0; i < sizeof signals / sizeof signals[0]; i++) {
            syscall(__NR_sigaction, signals[i], &sa, nullptr);
        }
    }
    

    此函数为所有 UNIX 信号安装自定义处理程序,这些信号在通常情况下会导致本机崩溃和 logcat 中的相关转储。调用此函数一次以抑制 logcat 中的调试输出。但尽管如此,logcat 中的少量消息仍然可以检测到每次崩溃:

    10-06 21:24:01.214 945-2236/? I/ActivityManager: Process com.example.sergik.test2 (pid 7682) has died: fore TOP 
    10-06 21:24:01.214 632-632/? I/Zygote: Process 7682 exited cleanly (1)
    

    仅此而已。没有崩溃转储,没有额外的信息。请注意,系统可能会立即重新启动您的应用程序,因为它看不到发生崩溃,最好推迟重新启动,直到用户明确请求。同样正如我之前所说的 - 这很可能会混淆 android 运行时,尤其是在现代系统上,ART 为某些信号安装了自己的处理程序链。

    所以最好专注于混淆。 AFAIK 有一些基于 LLVM 的混淆器可能适合您的需求。但是您甚至可以在没有任何额外工具的情况下开始 - 作为第一步,您可以从二进制文件中隐藏所有不必要的符号信息,只留下 JNI 所需的导出,例如通过每个 .so 文件的版本脚本:

    {
      global:
        JNI_OnLoad; Java_*;
    
      local:
        *;
    };
    

    这样的脚本将隐藏所有导出,除了在 Java 领域使用您的代码所需的导出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-02
      • 1970-01-01
      • 1970-01-01
      • 2014-05-15
      • 2013-10-06
      • 1970-01-01
      • 2015-06-15
      相关资源
      最近更新 更多