Android安全与逆向之Java虚拟机和Dalvik虚拟机的区别
很多人認為Dalvik虛擬機是一個Java虛擬機,因為Android的編程語言恰恰就是Java語言。但是這種說法并不準確,因為Dalvik虛擬機并不是按照Java虛擬機的規(guī)范來實現(xiàn)的,兩者并不兼容;同時還要兩個明顯的不同:
Java虛擬機運行的是Java字節(jié)碼,生成的字節(jié)碼文件也就是class文件(class文件:二進制處理過的文件),然后再由java虛擬機去執(zhí)行編譯運行過程。而Dalvik虛擬機運行的則是其專有的文件格式DEX(Dalvik Executable)。
在Java SE程序中的Java類會被編譯成一個或者多個字節(jié)碼文件(.class)然后打包到JAR文件,而后Java虛擬機會從相應(yīng)的CLASS文件和JAR文 件中獲取相應(yīng)的字節(jié)碼;Android應(yīng)用雖然也是使用Java語言進行編程,但是在編譯成CLASS文件后,還會通過一個工具(dx)將應(yīng)用所有的 CLASS文件轉(zhuǎn)換成一個.dex文件(dex文件是壓縮成zip文件,這樣可以減少占用空間),而后Dalvik虛擬機會從其中讀取指令和數(shù)據(jù)。
Dalvik和Android系統(tǒng)Android作為新一代的基于Linux的開源手機操作系統(tǒng),其系統(tǒng)架構(gòu)由下而上可以分為以下幾部分:
1)Linux內(nèi)核
2)本地庫
3)Android運行庫
4)應(yīng)用框架
5)應(yīng)用 ? ?
Dalvik VM (Android虛擬機),它可以支持已轉(zhuǎn)換為.dex(即Dalvik Exacutable)格式的java應(yīng)用程序。.dex格式是專為Dalvik設(shè)計的一種壓縮格式,適合內(nèi)存和處理器速度有限的系統(tǒng)。
每一個Android應(yīng)用都運行在一個Dalvik VM實例里,而每一個虛擬機實例都是一個獨立的進程空間。虛擬機的線程機制、內(nèi)存分配和管理、Mutex等都是依賴底層操作系統(tǒng)實現(xiàn)的。所有Android應(yīng)用的線程都對應(yīng)一個Linux線程,虛擬機因而可以更多依賴操作的線程調(diào)度和管理機制。
? ?
?
?java虛擬機: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? java虛擬機 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? java虛擬機基于棧。 ? ? ? ? ? ? ? ? ? ?
? java虛擬機運行的是java字節(jié)碼。(java類會被編譯成一個或多個字節(jié)碼.class文件,打包到.jar文件中,java虛擬機從相應(yīng)的.class文件和.jar文件中獲取相應(yīng)的字節(jié)碼)
?
Dalvik虛擬機:
基于棧的機器必須使用指令來載入和操作棧上數(shù)據(jù),所需指令更多更多 dalvik虛擬機是基于寄存器的
? 常量池已被修改為只使用32位的索引,以 簡化解釋器。dalvik的堆和棧的參數(shù)可以通過-Xms和-Xmx更改
? 一個應(yīng)用,一個虛擬機實例,一個進程(所有android應(yīng)用的線程都是對應(yīng)一個linux線程,都運行在自己的沙盒中,不同的應(yīng)用在不同的進程中運行。每個android dalvik應(yīng)用程序都被賦予了一個獨立的linux PID(app_*))
?
?
Dalvik和標準Java虛擬機(JVM)之間的首要差別之一,就是Dalvik基于寄存器,而JVM基于棧。Dalvik基于寄存器指令體大,但是指令不多。JVM指令體小,但是指令多。
Dalvik和Java之間的另外一大區(qū)別就是運行環(huán)境——Dalvik經(jīng)過優(yōu)化,允許在有限的內(nèi)存中同時運行多個虛擬機的實例,并且每一個 Dalvik應(yīng)用作為一個獨立的Linux進程執(zhí)行。
(1)虛擬機很小,使用的空間也小;
(2)Dalvik沒有JIT編譯器;
(3)常量池已被修改為只使用32位的索引,以簡化解釋器;
(4)它使用自己的字節(jié)碼,而非Java字節(jié)碼。
?備注:
JIT編譯器,英文寫作Just-In-Time Compiler,中文意思是即時編譯器。
JIT編譯器能夠?qū)SIL編譯成為各種不同的機器代碼,以適應(yīng)對應(yīng)的系統(tǒng)平臺,最終使得程序在目標系統(tǒng)中得到順利地運行。
Dalvik虛擬機架構(gòu):
? ? ?在android源碼中,Dalvik虛擬機的實現(xiàn)位于“dalvik/”目錄下,其中“dalvik/vm”是虛擬機的實現(xiàn)部分,將會編譯成libdvm.so;而"dalvik/libdex"將會編譯成libdex.a靜態(tài)庫作為dex工具;“dalvik/dexdump”是.dex文件的反編譯工具;虛擬機的可執(zhí)行程序位于“dalvik/dalvikvm”中,將會編譯成dalvikvm可執(zhí)行文件。
? dalvik虛擬機架構(gòu):
?Dalvik進程管理:
? ? ? ? ?dalvik進程管理是依賴于linux的進程體系結(jié)構(gòu)的,如要為應(yīng)用程序創(chuàng)建一個進程,它會使用linux的fork機制來復制一個進程(復制進程往往比創(chuàng)建進程效率更高)。
? ? ? ? ?Zygote是一個虛擬機進程,同時也是一個虛擬機實例的孵化器,它通過init進程啟動。首先會孵化出System_Server(android絕大多系統(tǒng)服務(wù)的守護進程,它會監(jiān)聽socket等待請求命令,當有一個應(yīng)用程序啟動時,就會向它發(fā)出請求,zygote就會FORK出一個新的應(yīng)用程序進程).每當系統(tǒng)要求執(zhí)行一個android應(yīng)用程序時,Zygote就會運用linux的FORK進制產(chǎn)生一個子進程來執(zhí)行該應(yīng)用程序。
? ? ? ? 每當執(zhí)行一個Android應(yīng)用程序,Zygote就會孵化一個子線程去執(zhí)行該應(yīng)用程序(系統(tǒng)內(nèi)部執(zhí)行dvz指令完成的)。這樣做的好處是顯而易見的,Zygote進程是在系統(tǒng)啟動時產(chǎn)生的,它會完成虛擬機的初始化,庫的加載,預(yù)置類庫的加載和初始化等操作,而在系統(tǒng)需要一個新的虛擬機實例時,Zygote通過復制自身,最快速地提供一個系統(tǒng)。另外,對于一些只讀的系統(tǒng)庫,所有虛擬機實例都和Zygote共享一塊內(nèi)存區(qū)域,這樣可以大大節(jié)省內(nèi)存開銷。
? ? ? ?相對于基于堆棧的虛擬機實現(xiàn),基于寄存器的虛擬機實現(xiàn)雖然在硬件通用性上要差一些,但是它在代碼的執(zhí)行效率卻更勝一籌。在基于寄存器的虛擬機中,可以更加有效地減少多余指令的分發(fā)和減少內(nèi)存的讀寫訪問。
?
?
?JVM和Dalvik進程管理:
? ? ? ? linux中進程間通信的方式有很多,但是dalvik使用的是信號方式來完成進程間通信。
?
Android的初始化流程:
總結(jié)
以上是生活随笔為你收集整理的Android安全与逆向之Java虚拟机和Dalvik虚拟机的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux之软连接和硬链接
- 下一篇: Android安全与逆向之Dex动态加载