如何防止NDK将堆栈跟踪转储到android logcat?

时间:2017-10-06 16:25:06

标签: android c++ cmake android-ndk

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

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

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

1 个答案:

答案 0 :(得分:2)

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

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

如果您仍想尝试使用它 - 请尝试以下代码段:

#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 land中的代码的导出。