2016-07-13 5 views
0

私はJNIとNDKを使った最初のAndroidアプリケーションを作成しました。単純なHello-JNIが話しています。文字列を返すユニークな関数。 アンパックされたAPKに署名し、ネイティブでコンパイルされていないような.soファイルが表示された場合。私はバイナリコードを期待していました。私は関数と文字列の名前を読んだ。 私の目標は、Proguardによって混乱していない文字列を隠すためにSDKを使用してネイティブコードを書くことです。 は、私は、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を使用

あなたの文字列がC/C++のように定義されている場合
ndk.dir=P\:\\Android\\sdk\\ndk-bundle 
sdk.dir=P\:\\Android\\sdk 
+0

あなたは正しく.soファイルを開き、16進コマンドではなくプレーンテキストだけを表示しますか? btw、私はあなたにアンドロイドスタジオ2.2プレビューを試してみることをお勧めします5.それは別のビルドシステム(CMake、Android.mkメイクファイル、ndkビルド)をサポートしています。 2.1以降に修正された多くのバグ –

+0

私は2.2リリースを待っていますが、私は多くの変更もあると思います。 – Daniele

答えて

1

:それはネイティブにコンパイルありながら

char *mySecretString = "some secret"; 

は、その後のもちろん は、.soで読めるです。 コンパイルは難読化ではなく、ターゲットプラットフォームのマシンコードへのコードの変換です。文字列はコードではありませんが、データとASCII文字列データのバイナリ形式は全く同じASCII文字列です。ない限り

関数名は、.soに表示されている必要はありません。彼らはグローバルである

  • /のextern(共有ライブラリをロードするアプリケーションをすることによって、メモリ内の関数を検索することができるように、彼らは、表示されている必要があり彼らの名前 - ライブラリの読み込み中)。
  • あなたの.soファイルには、必要に応じていくつかのデバッグ情報、リリースモード、およびstripが含まれています(リリースモードの.soファイルは十分に削除されていますが、個人的に調べなかったので、リリース?)。機能については

    :不可解な外部関数名を使用、またはトラフ外部(可視)関数名と呼ばれる地元の機能の別の層を追加し、すべてのことを確認してくださいあなたは難読化のためのネイティブライブラリを使用したい場合は

デバッグ情報は削除されるので、ローカルシンボルは含まれません。

文字列の場合:暗号化によってデータを暗号化し、暗号化されたデータを.soファイルに含めてから、暗号化されたデータを復号化ルーチンで使用する前にメモリに格納します。

あなたのコードを手動で逆アセンブルする人は、十分な努力をしても、そのすべてのものを見つけることができます。

+0

ありがとうございます、あなたは状況を明らかにしました。私はちょうどそのことを確かめたかったのです。ファイルは.dexとして逆アセンブルされないようにネイティブにコンパイルされていました。マルチプラットフォームをコンパイルするには、NDKを使用する際に特別なデバイスが必要です。あるいは、Android Studioがすべてを処理しますか? – Daniele

+0

@Daniele NDKにはすべてのサポートされているプラ​​ットフォームのクロスコンパイラが含まれているので、ホストプラットフォーム(デスクトップ)の下にすべての '.so'バージョンをビルドすることができます。 '.so'ファイルも逆アセンブルできますが、ネイティブマシンコードをASM/Cソースに逆アセンブルしています。マシンコードが最適化されている場合(-O2または-O3)、読みやすいソースに戻すことはずっと困難です。複雑な機能を持たないC/C++よりもJavaが単純な言語であるため、dex/classを逆アセンブルするとバイナリjava opcodeが含まれているので、より多くの読みやすい結果が得られます。 – Ped7g

+0

ありがとう@Pad7g、あなたは非常によく分かりましたが、ここでこの情報をすべて管理する方法を学ぶことがポイントです。私はこのケースではAndroid Studioが大いに役立つとは思いません。私の場合は、適切なドキュメントと例を参考にしてください。 – Daniele