Android逆向筆記之AndroidStudio生成so並調用native方法


AndroidStudio版本: 4.0.1


使用AndroidStudio進行ndk開發很簡單,我們的目標是生成一個so文件,里面有一個getSign方法,在Java層調用so文件中的getSign方法獲取。

先創建一個NDK項目,創建的時候拉到最下面選擇Native C++,然后Next:

1

然后輸入項目的名字:

1

這一步保持默認即可(反正我也不懂C++...):

1

創建完項目之后糟糕紅色嘆號了,有這么個提示:

1

這是因為創建的項目沒有配置NDK,NDK需要單獨下載,可以去這個頁面選擇自己平台對應的NDK下載:

https://developer.android.com/ndk/downloads?hl=zh-cn

下載完解壓到本地即可,注意解壓后的路徑名中盡量不要包含中文以免無謂踩坑。

然后回到AndroidStudio,為項目設置上剛剛下載的這個NDK,菜單選擇File-->Project Structure:

1

切換到SDK Location,然后在Android NDK Location那一項選擇剛剛下載的NDK解壓到的目錄,OK之后項目就會自動開始sync。

1

sync完之后就不會報錯了,還顯示了個小對號:

1

切換到Project視圖看下生成的項目結構:

1

先看MainActivity自動生成的內容:

package cc11001100.android.ndk_study_003;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
}

自動加載了一個native-lab的so文件,然后還自動聲明了一個stringFromJNI的native方法,然后再來看cpp下自動生成的這個native-lib.cpp文件:

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_cc11001100_android_ndk_1study_1003_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

看起來跟我們想要的結果已經差不多了,不行,名字不一樣,接下來就是修改名字為getSign,先改Java層的MainActivity,注意修改的時候使用重構重命名,Shift+6,改完之后:

package cc11001100.android.ndk_study_003;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        tv.setText(getSign());
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String getSign();
}

會發現native-lib.cpp的名字也自動修改了,都不用我們手動干預,很方便:

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_cc11001100_android_ndk_1study_1003_MainActivity_getSign(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

然后Run一下看看安裝效果:

1

OK,接下來打包成apk,然后反編譯觀察一下這種方式打包的效果是怎樣的:

1

選擇打包成apk:

1

key可以創建一個新的也可以用老的:

1

構建release包,簽名版本為V2,然后“Finish”等一段時間:

1

如果打包成功的話,在app下會多出一個release文件夾,下面有個app-release.apk文件,這就是本次打包成功的apk文件:

1

然后啟動jeb,把打包好的apk文件拖到jeb中看下,項目結構是這樣的:

1

反編譯MainActivity看下:

1

然后到lib下,把so文件拿出來:

1

然后拖到IDA64中,在Function name窗口中輸入Java搜索我們的JNI方法,因為我們是靜態注冊的,所以這里是能搜到的,然后雙擊搜索到的函數名,查看其匯編代碼:

1

然后分析這段匯編的代碼就能還原原本邏輯了,其實arm匯編我也沒整太明白,就趕緊結束以免露餡,本篇文章到此為止吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM