天天看點

在Android Native層中建立Java虛拟機執行個體

<a href="http://jaq.alibaba.com/community/art/show?articleid=848">在android native層中建立java虛拟機執行個體</a>

前言

android應用中jni代碼,是作為本地方法運作的。而大部分情況下,這些jni方法均需要傳遞dalvik虛拟機執行個體作為第一個參數。例如,你需要用虛拟機執行個體來建立jstring和其他的java對象、查找類或成員變量等。大部分情況下,在你用jni接口從java層調用native層中的代碼時,你并不需要在native代碼中自己初始化一個dalvik虛拟機執行個體。但是,如果你在搞逆向或者寫exp,你總是需要鑽研各種非正常的情況。

最近,我在逆向時需要在native代碼中手動建立虛拟機執行個體用于在jni接口函數中傳遞java對象。在本文中,我将分享我是如何實作這種方法的。

在Android Native層中建立Java虛拟機執行個體

如果你嘗試編譯調用上述截圖中函數的代碼,你可能會得到下面的錯誤:

在Android Native層中建立Java虛拟機執行個體

官方文檔中介紹的如何建立jvm的方法在這裡可以用來了解上述的api函數和它們的選項和參數的用途。如果你想在android中使用這些方法,你必須顯示從so庫中調用這些方法。

官方文檔中介紹的如何初始化虛拟機的類路徑,在此處是非常有用的。其内容如下:

在Android Native層中建立Java虛拟機執行個體

上面的配置,設定目前的類路徑為目前目錄(.)。如果你想要虛拟機通路系統或者app的類,這是必須設定的。實驗表明,将該值設定為一個目錄并不會起作用。我嘗試将其設定為/data/local/tmp,同時在該目錄下放置了一個dex檔案、含有dex檔案的jar包和apk檔案。隻有在設定jar包、dex檔案或apk檔案的全路徑時,上述選項才起作用。奇怪的是,當類路徑中沒有一個合法的檔案時,系統類(例如java.lang.string)都不能通路。換句話說,除非類路徑中至少有一個檔案,否則語句(*env)-&gt;findclass(env, "java.lang.string")傳回0,甚至java.lang.string這樣定義在架構中的類都無法通路。

為了測試,下面将一個apk檔案push到模拟器或真機裝置中。

在Android Native層中建立Java虛拟機執行個體

javavmoption的使用如下:

在Android Native層中建立Java虛拟機執行個體

creates a java vm

use the vm to get reference to com.android.internal.telephony.itelephony$stub class

get the transaction_sendoemrilrequestraw field value

destroy the vm

return field value

該方法是通過在庫檔案libnativehelper.so或者libdvm.so中加載建立虛拟機相關的方法。但是,下面幾行代碼看起來很奇怪:代碼看起來像是根據成員值判斷目前裝置是否已經解鎖或者是解鎖方法是否成功。反正我是不很确定,不過我也就想抽取其中建立虛拟機的代碼而已。

在Android Native層中建立Java虛拟機執行個體

任何地方都無法找到這幾個方法的文檔說明。不過,發現這些方法調用的人相當聰明。如果不調用這些方法,你就會得到下面奇怪的錯誤資訊:

在Android Native層中建立Java虛拟機執行個體

除了這幾個奇怪的方法,這種方式建立虛拟機對我很好使。但是,我想知道_zn13jniinvocationc1ev方法都做了什麼,在不同版本間的android系統中是否可移植。我的直覺告訴我,寫死的方法名可能會導緻在不同的裝置或者android版本間的不相容性。

同時,感興趣的是建立虛拟機的選項:

在Android Native層中建立Java虛拟機執行個體
在Android Native層中建立Java虛拟機執行個體

最後,我使用上面的方式來建立虛拟機,因為它來自谷歌,具有很好的健壯性和相容性。

下面就是最終的建立虛拟機的代碼:

在Android Native層中建立Java虛拟機執行個體

下面是其使用方法:

在Android Native層中建立Java虛拟機執行個體

阿裡聚安全

本文來自合作夥伴“阿裡聚安全”,發表于2017年04月13日 13:35.

繼續閱讀