2016-07-13 72 views
0

我剛剛創建了我的第一個使用JNI和NDK的Android應用程序,簡單的Hello-JNI來說話。用一個返回字符串的獨特函數。 我簽名APK解壓縮,如果我看到.so文件似乎不是本機編譯的。我期待一個二進制代碼。我讀了函數和字符串的名稱。 我的目標是使用SDK編寫本機代碼來隱藏未被proguard覆蓋的字符串。 我使用過Android Studio 2.1.2Android NDK JNI二進制代碼?

的build.gradle項目

buildscript { 
repositories { 
    jcenter() 
} 
dependencies { 
    //classpath 'com.android.tools.build:gradle:2.1.2' 
    classpath 'com.android.tools.build:gradle-experimental:0.7.2' 
    // NOTE: Do not place your application dependencies here; they belong 
    // in the individual module build.gradle files 
} 
} 

allprojects { 
    repositories { 
     jcenter() 
} 
} 

task clean(type: Delete) { 
    delete rootProject.buildDir 
} 

的build.gradle應用

apply plugin: 'com.android.model.application' 

model { 
android { 
    compileSdkVersion 23 
    buildToolsVersion "23.0.3" 

    defaultConfig { 
     applicationId "com.danielezampieri.jniapp" 
     minSdkVersion.apiLevel 18 
     targetSdkVersion.apiLevel 23 
     versionCode 1 
     versionName "1.0" 
    } 
    buildTypes { 
     release { 
      minifyEnabled false 
      proguardFiles.add(file('proguard-android.txt')) 
     } 
    } 
    ndk { 
     moduleName "jniapp" 
    } 
} 
} 
dependencies { 
compile fileTree(dir: 'libs', include: ['*.jar']) 
testCompile 'junit:junit:4.12' 
compile 'com.android.support:appcompat-v7:23.0.0' 
compile 'com.android.support:design:23.0.0' 
} 

gradle-wrapper.properties

#Mon Dec 28 10:00:20 PST 2015 
distributionBase=GRADLE_USER_HOME 
distributionPath=wrapper/dists 
zipStoreBase=GRADLE_USER_HOME 
zipStorePath=wrapper/dists 
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip 

local.properties

ndk.dir=P\:\\Android\\sdk\\ndk-bundle 
sdk.dir=P\:\\Android\\sdk 
+0

我能幫到你嗎,你打開.so文件,只看到純文本,而不是十六進制命令?順便說一句,我建議你嘗試android studio 2.2 preview 5.它支持不同的構建系統(CMake,Android.mk makefile,ndk-build)。自2.1以來固定的許多錯誤 –

+0

我等待2.2產品發佈,我懷疑也有很多改變。 – Daniele

回答

1

如果您的字符串在C/C++等來定義:

char *mySecretString = "some secret"; 

然後,當然它是可讀.so,而它是本地編譯。編譯不是混淆,而是將代碼翻譯成目標平臺的機器代碼。該字符串不是代碼,但是數據和ASCII字符串數據的二進制形式是完全相同的ASCII字符串。

函數名不會有.so可見,除非:

  • 他們是全球/ EXTERN(那麼他們必須是可見的,因此加載共享庫的應用程序可以通過搜索內存中的功能他們的名字 - 在裝載圖書館期間)。
  • .so你的.so文件包括一些調試信息,使用發佈模式,並根據需要strip(我相信NDK在發佈模式剝離.so文件足夠,但我從來沒有親自檢查過,所以他們甚至可以留下一些調試信息發佈?)。

所以,如果你想使用本機庫混淆:

對於功能:使用晦澀的外部函數的名稱,或添加的所謂槽外部(可見)函數名本地功能的另一個層,並確保所有調試信息被剝離,所以不包括本地符號。

對於字符串:通過某種加密對數據進行加密,將加密的數據包含在.so文件中,然後在解密例程使用之前將字符串解密到內存中。

請注意,任何人手動拆卸你的代碼將仍然能夠找到所有的東西,如果他投入足夠的精力。

+0

謝謝,你已經澄清了這種情況。我只是想確定一下。所以文件本身編譯以防止它們被反彙編爲.dex。爲了編譯多平臺,需要一些特殊的設備,或者Android Studio在使用NDK時需要注意一切。 – Daniele

+0

@Daniele NDK包含所有支持平臺的交叉編譯器,您可以在主機平臺(桌面)下構建所有'.so'版本。 '.so'文件也可以反彙編,但它將本地機器代碼分解爲ASM/C源代碼。如果機器代碼已經過優化(-O2或-O3),則將其轉換爲易於閱讀的源代碼要困難得多。反彙編dex/class產生更多可讀結果,因爲那些包含二進制java操作碼,經常「反駁」反彙編生成它們的源指令是什麼(因爲Java比沒有複雜功能的C/C++更簡單)。 – Ped7g

+0

非常感謝@Ped7g,你已經很好地闡明瞭,現在要學習如何管理所有這些信息。我不認爲Android Studio在這種情況下會有很多幫助,在我的情況下需要遵循良好的文檔和示例? – Daniele