Android查看.so文件中的JNI方法詳解
引言:為何需要分析.so文件?
在Android開發(fā)或Linux系統(tǒng)編程中,動(dòng)態(tài)鏈接庫(kù)(.so文件)承載著核心的本地代碼實(shí)現(xiàn)。特別是使用JNI(Java Native Interface)技術(shù)時(shí),我們經(jīng)常需要確認(rèn):
- 庫(kù)中導(dǎo)出了哪些可供Java/Kotlin調(diào)用的本地方法?
- 方法簽名是否正確?
- 是否存在符號(hào)沖突或缺失?
本文將以實(shí)戰(zhàn)角度,介紹多種查看.so文件中方法的工具和技巧。
一、三大核心工具對(duì)比
- objdump - 全能分析器
# 查看動(dòng)態(tài)符號(hào)表(推薦) objdump -T libnative.so # 反匯編查看代碼邏輯 objdump -d libnative.so # 組合使用:快速定位JNI方法 objdump -T libnative.so | grep "Java_"
特點(diǎn):
- 功能最全面,可查看符號(hào)表、反匯編、段信息
- 系統(tǒng)自帶,無(wú)需額外安裝
- 輸出信息詳細(xì)但可能較冗長(zhǎng)
- nm - 簡(jiǎn)潔符號(hào)查看器
# 查看動(dòng)態(tài)符號(hào) nm -D libnative.so # 顯示所有符號(hào)(包括未導(dǎo)出) nm libnative.so # 按類型過(guò)濾(T=代碼段,U=未定義) nm -D libnative.so | grep " T "
特點(diǎn):
- 輸出簡(jiǎn)潔直觀
- 快速過(guò)濾符號(hào)類型
- 適合腳本處理
- readelf - ELF專業(yè)分析器
# 詳細(xì)符號(hào)表信息 readelf -Ws libnative.so # 查看動(dòng)態(tài)段信息 readelf -d libnative.so
特點(diǎn):
- 專門解析ELF格式,信息最權(quán)威
- 顯示符號(hào)的綁定類型、可見性等詳細(xì)信息
- 適合深度分析
二、實(shí)戰(zhàn):定位JNI方法的四種姿勢(shì)
場(chǎng)景:分析 libnative-lib.so 中的JNI方法
方法1:直接過(guò)濾法(最常用)
# 使用任何工具配合grep過(guò)濾"Java_"前綴 objdump -T libnative-lib.so | grep "Java_" # 輸出示例: # 000000000001234 g DF .text 00068 Base Java_com_example_app_MainActivity_stringFromJNI
方法2:格式化輸出法
# 按列格式化輸出,便于閱讀
readelf -Ws libnative-lib.so | awk '/Java_/ {printf "%-40s %-20s\n", $8, $4}'
方法3:完整分析腳本
#!/bin/bash
# analyze_jni.sh
LIB=$1
echo "=== JNI Methods in $LIB ==="
echo "Tool | Count | Sample Method"
echo "----------|-------|--------------"
# 使用objdump
COUNT1=$(objdump -T "$LIB" | grep -c "Java_")
SAMPLE1=$(objdump -T "$LIB" | grep "Java_" | head -1 | awk '{print $NF}')
echo "objdump | $COUNT1 | $SAMPLE1"
# 使用nm
COUNT2=$(nm -D "$LIB" | grep -c "Java_")
SAMPLE2=$(nm -D "$LIB" | grep "Java_" | head -1 | awk '{print $3}')
echo "nm | $COUNT2 | $SAMPLE2"
# 使用readelf
COUNT3=$(readelf -Ws "$LIB" | grep -c "Java_")
SAMPLE3=$(readelf -Ws "$LIB" | grep "Java_" | head -1 | awk '{print $8}')
echo "readelf | $COUNT3 | $SAMPLE3"
方法4:Android NDK工具鏈版
# 使用NDK提供的交叉編譯版本(Android專屬) $NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-objdump -T libnative-lib.so
三、進(jìn)階:處理特殊場(chǎng)景
- 符號(hào)被剝離的情況
如果.so發(fā)布時(shí)被strip處理過(guò):
# 嘗試反匯編尋找JNI模式 objdump -d stripped_lib.so | less # 搜索JNIEnv指針使用模式(如x0寄存器傳遞)
- C++符號(hào)修飾問題
# 查看修飾后的符號(hào) nm libnative.so | grep "_Z" # 使用c++filt還原可讀名稱 nm libnative.so | c++filt | grep "Java_"
- 批量分析多個(gè)庫(kù)
# 批量檢查當(dāng)前目錄所有.so文件的JNI方法
for lib in *.so; do
echo "=== $lib ==="
nm -D "$lib" | grep "Java_" | wc -l
done
四、技巧與避坑指南
技巧1:理解JNI命名規(guī)則
Java_包名_類名_方法名 ↓ Java_com_example_app_MainActivity_onCreate │ │ │ │ 固定 包名 類名 方法名 (點(diǎn)替換為下劃線)
技巧2:查看方法簽名
如果庫(kù)包含調(diào)試信息,可以查看詳細(xì)簽名:
# 使用objdump查看重定位信息 objdump -R libnative.so | grep Java_
技巧3:驗(yàn)證方法是否存在
在Java/Kotlin端驗(yàn)證:
// 加載前檢查
static {
try {
System.loadLibrary("native-lib");
Log.d("JNI", "Library loaded successfully");
} catch (UnsatisfiedLinkError e) {
Log.e("JNI", "Method not found: " + e.getMessage());
}
}
五、工具選擇決策樹
需要分析.so文件?
├── 只需快速查看JNI方法 → `nm -D lib.so | grep "Java_"`
├── 需要詳細(xì)反匯編信息 → `objdump -d lib.so`
├── 分析ELF結(jié)構(gòu)細(xì)節(jié) → `readelf -Ws lib.so`
└── 處理Android庫(kù) → 使用NDK交叉編譯版objdump
總結(jié)
掌握.so文件分析方法,能幫助開發(fā)者:
- 快速定位JNI方法,解決UnsatisfiedLinkError
- 驗(yàn)證符號(hào)導(dǎo)出,確??缯Z(yǔ)言調(diào)用正常
- 調(diào)試Native崩潰,理解底層調(diào)用棧
- 優(yōu)化庫(kù)體積,識(shí)別未使用的導(dǎo)出符號(hào)
無(wú)論是日常開發(fā)還是性能優(yōu)化,這些技能都是Native開發(fā)者的必備利器。
到此這篇關(guān)于Android查看.so文件中的JNI方法詳解的文章就介紹到這了,更多相關(guān)Android查看.so文件JNI方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android 實(shí)現(xiàn)一個(gè)隱私彈窗功能
這篇文章主要介紹了Android 實(shí)現(xiàn)一個(gè)隱私彈窗功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2025-05-05
Android studio 2020中的Android SDK 下載教程
這篇文章主要介紹了Android studio 2020中的Android SDK 下載教程,本文圖文并茂給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03
android利用消息機(jī)制獲取網(wǎng)絡(luò)圖片
這篇文章主要為大家詳細(xì)介紹了android利用消息機(jī)制獲取網(wǎng)絡(luò)圖片的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
Android APK應(yīng)用安裝原理解析之AndroidManifest使用PackageParser.parserPac
這篇文章主要介紹了Android APK應(yīng)用安裝原理解析之AndroidManifest使用PackageParser.parserPackage原理,結(jié)合實(shí)例形式分析了PackageManagerService調(diào)用PackageParser.parserPackage方法解析APK清單相關(guān)原理與操作技巧,需要的朋友可以參考下2017-12-12
android 自定義圓角button效果的實(shí)例代碼(自定義view Demo)
這篇文章主要介紹了android 自定義圓角button(自定義View Demo),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
Android Parcelable與Serializable詳解及區(qū)別
這篇文章主要介紹了Android Parcelable與Serializable詳解及區(qū)別的相關(guān)資料,需要的朋友可以參考下2017-01-01

