Android Studio无法调试C++代码,提示Dual(Java+Native)(15971)(反汇编)
第三方库反调试防护排查与解决方法

怀疑接入的第三方库存在安全防护措施阻止应用调试,有没有开发者遇到过类似情况?
环境信息
Android Studio Giraffe | 2022.3.1 Patch 2 java version "11.0.20" 2023-07-18 LTS
相关配置文件
CMakeList.txt
cmake_minimum_required(VERSION 3.4.1) SET(TARGET native-lib) file(GLOB src "jni/*.cpp" "jni/benchmark/*.cpp" "jni/MallocTest.cpp") add_library( # Specifies the name of the library. ${TARGET} # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). ${src} ) find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log ) TARGET_INCLUDE_DIRECTORIES( ${TARGET} PRIVATE ${EXT_DEP}/include ) target_link_libraries( # Specifies the target library. ${TARGET} # Links the target library to the log library # included in the NDK. PRIVATE ${log-lib} )
build.gradle
android { compileSdkVersion rootProject.ext.android["compileSdkVersion"] buildToolsVersion rootProject.ext.android["buildToolsVersion"] useLibrary 'org.apache.http.legacy' defaultConfig { applicationId "" minSdkVersion rootProject.ext.android["minSdkVersion"] targetSdkVersion rootProject.ext.android["targetSdkVersion"] versionCode rootProject.ext.android["versionCode"] versionName rootProject.ext.android["versionName"] // Enabling multidex support. multiDexEnabled true multiDexKeepProguard file('maindexlist.pro') ndk { abiFilters 'arm64-v8a' } packagingOptions { pickFirst 'lib/arm64-v8a/*.so' pickFirst 'lib/armeabi-v7a/*.so' exclude '**/x86/*.so' exclude '**/x86_64/*.so' exclude '**/armeabi/*.so' exclude '**/mips/*.so' exclude '**/mips64/*.so' } resConfigs "zh-rCN" vectorDrawables.generatedDensities = ['hdpi'] // 华为支付 resConfigs "en", "zh-rCN" //ARouter start javaCompileOptions { annotationProcessorOptions { arguments = [AROUTER_MODULE_NAME: project.getName(), AROUTER_GENERATE_DOC: "enable"] } } buildConfigField "String", "GIT_HASH", "\"${gitHash}\"" buildConfigField "String", "GIT_BRANCH", "\"${gitBranch}\"" buildConfigField "boolean", "dependSongStudio", "${rootProject.ext.dependSongStudio}" //ARouter end vectorDrawables.useSupportLibrary = true javaCompileOptions { annotationProcessorOptions { arguments += [ "room.schemaLocation" : "$projectDir/schemas".toString(), "room.incremental" : "true", "room.expandProjection": "true"] } } manifestPlaceholders = [ ZX_APPID: "xxx" ] } sourceSets { main { jniLibs.srcDirs = ['libs'] } } signingConfigs { debug { storeFile file("") storePassword "" keyAlias "" keyPassword "" } release { storeFile file("") storePassword "" keyAlias "" keyPassword "" } } buildTypes { debug { debuggable true minifyEnabled false zipAlignEnabled false shrinkResources false signingConfig signingConfigs.debug } release { zipAlignEnabled true shrinkResources true minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.cfg' signingConfig signingConfigs.release } } dexOptions { maxProcessCount 6 jumboMode true javaMaxHeapSize "6g" incremental true preDexLibraries true } lintOptions { checkReleaseBuilds false abortOnError false } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } productFlavors { } android.buildFeatures.dataBinding = true aaptOptions { File publicTxtFile = project.rootProject.file('public.txt') if (publicTxtFile.exists()) { additionalParameters "--stable-ids", "${project.rootProject.file('public.txt').absolutePath}" } else { additionalParameters "--emit-ids", "${project.rootProject.file('public.txt').absolutePath}" } } if (project.hasProperty('devBuild')) { aaptOptions.cruncherEnabled = false } repositories { flatDir { dirs project(':livenessLib').file('libs') } } }
排查与解决思路
- 定位问题库:先单独调试不含第三方库的基础工程,确认基础调试流程正常后,逐个引入第三方库,找到触发反调试的具体库。从配置看,
livenessLib这类活体检测库大概率带有反调试逻辑。 - 查官方文档:多数带安全防护的第三方库会提供开发调试开关,比如支付、风控类库,直接查对应库的集成文档,找关闭反调试的配置或方法。
- Hook绕过检测:如果官方没提供调试开关,用Frida注入脚本Hook反调试相关函数,比如
ptrace、getppid:if (Process.arch === 'arm64') { const ptrace = new NativeFunction(Module.findExportByName(null, 'ptrace'), 'int', ['int', 'int', 'int', 'int']); Interceptor.replace(ptrace, new NativeCallback((request, pid, addr, data) => { if (request === 0x1 /* PTRACE_TRACEME */) { return 0; } return ptrace(request, pid, addr, data); }, 'int', ['int', 'int', 'int', 'int'])); } - 调整构建配置:确认
debug构建的debuggable true已开启(你的配置已设置),部分库会校验签名或构建类型,尝试用release签名打包debug包,或修改buildConfig字段欺骗库的环境检测。 - 静态分析patch:用IDA/Ghidra反编译目标
.so文件,定位反调试代码段(比如查找ptrace系统调用),直接patch掉检测逻辑。
内容的提问来源于stack exchange,提问作者hu baoyu
相关产品推荐
相关产品推荐

