Android NDK 编译 so 文件 抹除导出符号 反逆向

版权归作者所有,如有转发,请注明文章出处:cyrus-studio.github.io/blog/

前言

NDK 编译 so 默认情况下,所有 public 函数 都会导出,通过 IDA、GHIDRA 可以看到函数名

但除了必须导出的 JNI 函数外,其余 C/C++ 函数符号不导出其实也完全没影响,编译器/链接器内部可以调用,运行时照样可以正常执行。

必须导出的 JNI 函数

函数名 是否必须导出 说明
JNI_OnLoad ✅ 是(总是) 系统通过 dlsym() 查找,初始化用
Java_... ✅ 是(如果用静态注册) Java 层方法通过名称匹配
JNI_OnUnload ❌ 否(可选) 卸载时调用,不导出也不会出错
JNI_OnLoad_LibName(非标准) ❌ 否(特殊系统扩展) Android 未使用
JNI_GetCreatedJavaVMs、JNI_CreateJavaVM ❌ 否 仅在 native 启动 JVM 时使用(一般用不到)

使用 linker version script 精细控制导出

Linker Version Script 是 GNU 链接器(ld)提供的一种机制,用来控制 .so 或 .a 文件中哪些符号可以导出、哪些必须隐藏。

创建 hide.map 文件(仅导出所有 JNI_ 和 Java_ 开头的 JNI 方法)

ini 复制代码
{
    global:
        JNI_*;
        Java_*;

    local:
        *;
};

解释

  • global: 表示这些符号会被导出,可供外部(如 ART)通过 dlsym() 使用。

  • Java_* 会匹配所有以 Java_ 开头的方法 ------ 即静态注册 JNI 方法。

  • local: *; 表示其余全部符号(如内部 C 函数、C++ mangled 符号、加密算法、字符串处理等)一律隐藏,无法通过 IDA 等工具直接查看函数名。

在你的 CMakeLists.txt 中这样写:

bash 复制代码
# 抹除符号
set_target_properties(native-lib PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_SOURCE_DIR}/hide.map")

参考:android-docs.cn/ndk/guides/...

测试

重新编译运行,使用 IDA Pro 打开 so ,可以看到只导出了 JNI 相关函数

只控制导出符号,不影响内部调用,程序运行时不会出错。

除了增加逆向难度,同时还能减少 so 文件的体积

动态注册 JNI 方法,JNI 方法反跟踪

Android 的 ART 虚拟机会用 dlsym() 查找你导出的 JNI 方法(如Java_com_example_native_NativeUtils_secretMethod),所以这些你不能隐藏,否则会导致运行时崩溃。

如果你用 RegisterNatives 动态注册 JNI 方法,就可以完全避免导出 Java_com_xxx 的方法名:

c 复制代码
#include <jni.h>

// 定义方法签名
static JNINativeMethod methods[] = {
    {"secretMethod", "()V", (void *)secretMethod},
};

// JNI_OnLoad 动态注册方法
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
    JNIEnv* env = nullptr;
    vm->GetEnv((void**)&env, JNI_VERSION_1_6);

    jclass clazz = env->FindClass("com/example/native/NativeUtils");
    env->RegisterNatives(clazz, methods, sizeof(methods)/sizeof(methods[0]));

    return JNI_VERSION_1_6;
}

函数名字可以自定义:

javascript 复制代码
void secretMethod(JNIEnv *env, jobject obj) {
    // your native code
}

此时 .so 中不需要导出 Java_com_example_xxx 符号,IDA 也就看不到!

完整源码

开源地址:github.com/CYRUS-STUDI...

相关文章:

相关推荐
用户962377954488 小时前
DVWA 靶场实验报告 (High Level)
安全
火柴就是我8 小时前
让我们实现一个更好看的内部阴影按钮
android·flutter
数据智能老司机11 小时前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机11 小时前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
用户9623779544813 小时前
DVWA 靶场实验报告 (Medium Level)
安全
red1giant_star13 小时前
S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞
安全
砖厂小工15 小时前
用 GLM + OpenClaw 打造你的 AI PR Review Agent — 让龙虾帮你审代码
android·github
张拭心15 小时前
春节后,有些公司明确要求 AI 经验了
android·前端·人工智能
张拭心16 小时前
Android 17 来了!新特性介绍与适配建议
android·前端
用户9623779544816 小时前
DVWA Weak Session IDs High 的 Cookie dvwaSession 为什么刷新不出来?
安全