本發(fā)明涉及計(jì)算機(jī)安全領(lǐng)域,具體涉及一種加固安卓安裝包的動(dòng)態(tài)鏈接庫(kù)SO文件的方法和裝置。
背景技術(shù):
如果安卓安裝包未經(jīng)加固處理,則通過(guò)對(duì)該安卓安裝包的反向處理就可以對(duì)安卓安裝包進(jìn)行修改,損害開發(fā)者的利益。例如,針對(duì)安卓安裝包的動(dòng)態(tài)鏈接庫(kù)SO文件的加固,現(xiàn)有技術(shù)中提供了基于填充數(shù)據(jù)(Shellcode)和壓縮可執(zhí)行文件等解決方案。但是這樣也產(chǎn)生了其他問(wèn)題:未對(duì)SO文件進(jìn)行加固時(shí),SO文件可以被安卓系統(tǒng)加載,但是對(duì)SO文件進(jìn)行加固后,安卓系統(tǒng)就無(wú)法直接對(duì)原來(lái)的SO文件進(jìn)行操作了。
技術(shù)實(shí)現(xiàn)要素:
鑒于上述問(wèn)題,提出了本發(fā)明以便提供一種克服上述問(wèn)題或者至少部分地解決上述問(wèn)題的加固安卓安裝包的動(dòng)態(tài)鏈接庫(kù)SO文件的方法和裝置。
依據(jù)本發(fā)明的一個(gè)方面,提供了一種加固安卓安裝包的動(dòng)態(tài)鏈接庫(kù)SO文件的方法,包括:
對(duì)安卓安裝包的原SO文件增加外殼,得到加固的SO文件;
在所述加固的SO文件的初始化代碼中寫入所述原SO文件的內(nèi)存加載邏輯,以使安卓系統(tǒng)在加載所述加固的SO文件時(shí),根據(jù)所述內(nèi)存加載邏輯,將所述原SO文件加載到內(nèi)存中。
可選地,所述對(duì)安卓安裝包的原SO文件增加外殼包括:
將所述原SO文件轉(zhuǎn)換為二進(jìn)制形式,將得到的二進(jìn)制形式的原SO文件添加到所述外殼中。
可選地,該方法還包括:
在所述加固的SO文件的初始化代碼中,將所述加固的SO文件中的至少一個(gè)指定函數(shù)指向該函數(shù)在所述原SO文件中對(duì)應(yīng)的指定函數(shù),以使安卓系統(tǒng)在調(diào)用所述加固的SO文件中的指定函數(shù)時(shí),調(diào)用原SO文件中對(duì)應(yīng)的指定函數(shù)。
可選地,所述加固的SO文件中的指定函數(shù)與所述原SO文件中對(duì)應(yīng)的指定函數(shù)為同類型的函數(shù)。
可選地,所述加固的SO文件中的指定函數(shù)與所述原SO文件中對(duì)應(yīng)的指定函數(shù)均為JNI_Onload函數(shù)。
可選地,該方法還包括:
在所述加固的SO文件的初始化代碼中為所述原SO文件預(yù)留加載空間;
所述內(nèi)存加載邏輯包括:將所述原SO文件加載到安卓系統(tǒng)為所述預(yù)留加載空間分配的內(nèi)存空間中。
可選地,所述在所述加固的SO文件的初始化代碼中為所述原SO文件預(yù)留加載空間包括:
在所述加固的SO文件的初始化代碼的用于存儲(chǔ)未初始化的全局變量的指定代碼段中為所述原SO文件預(yù)留加載空間。
可選地,所述用于存儲(chǔ)未初始化的全局變量的指定代碼段為.bss節(jié)。
可選地,所述在所述加固的SO文件的初始化代碼中為所述原SO文件預(yù)留加載空間包括:
在所述用于存儲(chǔ)未初始化的全局變量的指定代碼段中設(shè)置與所述原SO文件對(duì)應(yīng)的指定數(shù)組;
根據(jù)所述原SO文件的大小,確定所述原SO文件在內(nèi)存中占用的空間的數(shù)值,將該數(shù)值存儲(chǔ)至所述指定數(shù)組中,以使安卓系統(tǒng)在加載所述加固的SO文件時(shí),根據(jù)該指定數(shù)值中存儲(chǔ)的數(shù)值為所述預(yù)留加載空間分配內(nèi)存空間。
可選地,該方法在所有步驟前進(jìn)一步包括:
對(duì)安卓安裝包進(jìn)行解包,得到安卓安裝包的至少一個(gè)原SO文件。
可選地,該方法還包括:
將所述加固的SO文件打包到對(duì)應(yīng)的安卓安裝包中,以使所述安卓安裝包被安裝后,每次啟動(dòng)對(duì)應(yīng)的應(yīng)用時(shí),由安卓系統(tǒng)加載所述加固后的SO文件。
依據(jù)本發(fā)明的另一方面,提供了一種加固安卓安裝包的動(dòng)態(tài)鏈接庫(kù)SO文件的裝置,包括:
加殼單元,適于對(duì)安卓安裝包的原SO文件增加外殼,得到加固的SO文件;
編輯單元,適于在所述加固的SO文件的初始化代碼中寫入所述原SO文件的內(nèi)存加載邏輯,以使安卓系統(tǒng)在加載所述加固的SO文件時(shí),根據(jù)所述內(nèi)存加載邏輯,將所述原SO文件加載到內(nèi)存中。
可選地,所述加殼單元,適于將所述原SO文件轉(zhuǎn)換為二進(jìn)制形式,將得到的二進(jìn)制形式的原SO文件添加到所述外殼中。
可選地,所述編輯單元,還適于在所述加固的SO文件的初始化代碼中,將所述加固的SO文件中的至少一個(gè)指定函數(shù)指向該函數(shù)在所述原SO文件中對(duì)應(yīng)的指定函數(shù),以使安卓系統(tǒng)在調(diào)用所述加固的SO文件中的指定函數(shù)時(shí),調(diào)用原SO文件中對(duì)應(yīng)的指定函數(shù)。
可選地,所述加固的SO文件中的指定函數(shù)與所述原SO文件中對(duì)應(yīng)的指定函數(shù)為同類型的函數(shù)。
可選地,所述加固的SO文件中的指定函數(shù)與所述原SO文件中對(duì)應(yīng)的指定函數(shù)均為JNI_Onload函數(shù)。
可選地,所述編輯單元,還適于在所述加固的SO文件的初始化代碼中為所述原SO文件預(yù)留加載空間;所述內(nèi)存加載邏輯包括:將所述原SO文件加載到安卓系統(tǒng)為所述預(yù)留加載空間分配的內(nèi)存空間中。
可選地,所述編輯單元,適于在所述加固的SO文件的初始化代碼的用于存儲(chǔ)未初始化的全局變量的指定代碼段中為所述原SO文件預(yù)留加載空間。
可選地,所述用于存儲(chǔ)未初始化的全局變量的指定代碼段為.bss節(jié)。
可選地,所述編輯單元,適于在所述用于存儲(chǔ)未初始化的全局變量的指定代碼段中設(shè)置與所述原SO文件對(duì)應(yīng)的指定數(shù)組;根據(jù)所述原SO文件的大小,確定所述原SO文件在內(nèi)存中占用的空間的數(shù)值,將該數(shù)值存儲(chǔ)至所述指定數(shù)組中,以使安卓系統(tǒng)在加載所述加固的SO文件時(shí),根據(jù)該指定數(shù)值中存儲(chǔ)的數(shù)值為所述預(yù)留加載空間分配內(nèi)存空間。
可選地,該裝置還包括:
解包單元,適于對(duì)安卓安裝包進(jìn)行解包,得到安卓安裝包的至少一個(gè)原SO文件。
可選地,打包單元,適于將所述加固的SO文件打包到對(duì)應(yīng)的安卓安裝包中,以使所述安卓安裝包被安裝后,每次啟動(dòng)對(duì)應(yīng)的應(yīng)用時(shí),由安卓系統(tǒng)加載所述加固后的SO文件。
由上述可知,本發(fā)明的技術(shù)方案,在對(duì)安卓安裝包的原SO文件增加外殼,得到加固的SO文件后,向加固的SO文件的初始化代碼中寫入原SO文件的內(nèi)存加載邏輯,以使安卓系統(tǒng)在加載所述加固的SO文件時(shí),根據(jù)所述內(nèi)存加載邏輯,將所述原SO文件加載到內(nèi)存中。該技術(shù)方案利用了初始化代碼在SO文件在加載時(shí)可以自動(dòng)運(yùn)行的特點(diǎn),使得安卓系統(tǒng)在加載加固的SO文件時(shí)可以直接運(yùn)行原SO文件的內(nèi)存加載邏輯,從而實(shí)現(xiàn)了原SO文件的加載,不需要系統(tǒng)直接對(duì)原SO文件進(jìn)行操作,簡(jiǎn)單方便。
上述說(shuō)明僅是本發(fā)明技術(shù)方案的概述,為了能夠更清楚了解本發(fā)明的技術(shù)手段,而可依照說(shuō)明書的內(nèi)容予以實(shí)施,并且為了讓本發(fā)明的上述和其它目的、特征和優(yōu)點(diǎn)能夠更明顯易懂,以下特舉本發(fā)明的具體實(shí)施方式。
附圖說(shuō)明
通過(guò)閱讀下文優(yōu)選實(shí)施方式的詳細(xì)描述,各種其他的優(yōu)點(diǎn)和益處對(duì)于本領(lǐng)域普通技術(shù)人員將變得清楚明了。附圖僅用于示出優(yōu)選實(shí)施方式的目的,而并不認(rèn)為是對(duì)本發(fā)明的限制。而且在整個(gè)附圖中,用相同的參考符號(hào)表示相同的部件。在附圖中:
圖1示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的加固安卓安裝包的動(dòng)態(tài)鏈接庫(kù)SO文件的方法的流程示意圖;
圖2示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的加固安卓安裝包的動(dòng)態(tài)鏈接庫(kù)SO文件的裝置的結(jié)構(gòu)示意圖。
具體實(shí)施方式
下面將參照附圖更詳細(xì)地描述本公開的示例性實(shí)施例。雖然附圖中顯示了本公開的示例性實(shí)施例,然而應(yīng)當(dāng)理解,可以以各種形式實(shí)現(xiàn)本公開而不應(yīng)被這里闡述的實(shí)施例所限制。相反,提供這些實(shí)施例是為了能夠更透徹地理解本公開,并且能夠?qū)⒈竟_的范圍完整的傳達(dá)給本領(lǐng)域的技術(shù)人員。
圖1示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的一種加固安卓安裝包的動(dòng)態(tài)鏈接庫(kù)SO文件的方法的流程示意圖,如圖1所示,該方法包括:
步驟S110,對(duì)安卓安裝包的原SO文件增加外殼,得到加固的SO文件。
步驟S120,在加固的SO文件的初始化代碼中寫入原SO文件的內(nèi)存加載邏輯,以使安卓系統(tǒng)在加載加固的SO文件時(shí),根據(jù)內(nèi)存加載邏輯,將原SO文件加載到內(nèi)存中。
可見,圖1所示的方法,在對(duì)安卓安裝包的原SO文件增加外殼,得到加固的SO文件后,向加固的SO文件的初始化代碼中寫入原SO文件的內(nèi)存加載邏輯,以使安卓系統(tǒng)在加載加固的SO文件時(shí),根據(jù)內(nèi)存加載邏輯,將原SO文件加載到內(nèi)存中。該技術(shù)方案利用了初始化代碼在SO文件在加載時(shí)可以自動(dòng)運(yùn)行的特點(diǎn),使得安卓系統(tǒng)在加載加固的SO文件時(shí)可以直接運(yùn)行原SO文件的內(nèi)存加載邏輯,從而實(shí)現(xiàn)了原SO文件的加載,不需要系統(tǒng)直接對(duì)原SO文件進(jìn)行操作,簡(jiǎn)單方便。
在本發(fā)明的一個(gè)實(shí)施例中,圖1所示的方法中,對(duì)安卓安裝包的原SO文件增加外殼包括:將原SO文件轉(zhuǎn)換為二進(jìn)制形式,將得到的二進(jìn)制形式的原SO文件添加到外殼中。
在對(duì)原SO文件進(jìn)行加固的過(guò)程中,還會(huì)涉及對(duì)函數(shù)的加密、添加解密邏輯等其他內(nèi)容,由于不是本發(fā)明的重點(diǎn),在此不做過(guò)多介紹。在本實(shí)施例中,將原SO文件轉(zhuǎn)換為二進(jìn)制形式,將其添加到外殼中(例如寫入.data節(jié)),形成了加固的SO文件。加固的SO文件的文件名與原SO文件名可以是相同的,這樣在加載過(guò)程中,系統(tǒng)實(shí)際是把加固后的SO文件當(dāng)作原SO文件進(jìn)行加載。也正因如此,由于加固的SO文件并不等同于原SO文件,許多函數(shù)的調(diào)用就會(huì)產(chǎn)生問(wèn)題,例如:
SO文件并非是通過(guò)JAVA代碼編寫的,需要安卓系統(tǒng)利用JAVA的跨平臺(tái)機(jī)制,即通過(guò)JNI(Java Native Interface,JAVA本地接口)來(lái)使用SO文件,即實(shí)現(xiàn)JAVA層與本地層(Native層)的通信。具體地,在未對(duì)SO文件進(jìn)行加固的情況下,JAVA層可以直接調(diào)用SO文件中的JNI函數(shù)來(lái)實(shí)現(xiàn)對(duì)SO文件的使用,但是在對(duì)SO文件增加外殼的情況下,JAVA層定位到的是加固后的SO文件中JNI函數(shù)的函數(shù)地址,而并非原SO文件的函數(shù)地址,從而產(chǎn)生崩潰。
因此,在本發(fā)明的一個(gè)實(shí)施例中,圖1所示的方法還包括:在加固的SO文件的初始化代碼中,將加固的SO文件中的至少一個(gè)指定函數(shù)指向該函數(shù)在原SO文件中對(duì)應(yīng)的指定函數(shù),以使安卓系統(tǒng)在調(diào)用加固的SO文件中的指定函數(shù)時(shí),調(diào)用原SO文件中對(duì)應(yīng)的指定函數(shù)。具體地,加固的SO文件中的指定函數(shù)與原SO文件中對(duì)應(yīng)的指定函數(shù)為同類型的函數(shù),例如函數(shù)名相同的函數(shù)。
在本發(fā)明的一個(gè)實(shí)施例中,上述方法中,加固的SO文件中的指定函數(shù)與原SO文件中對(duì)應(yīng)的指定函數(shù)均為JNI_Onload函數(shù)。
試看下例:原SO文件liba.so通過(guò)增加外殼,得到了加固的SO文件libshell.so。但由于libshell.so仍然為命名為liba.so,安卓系統(tǒng)通過(guò)System.loadLibrary(“l(fā)iba.so”)加載到的實(shí)際上是libshell.so。在加載libshell.so時(shí),運(yùn)行l(wèi)ibshell.so的初始化代碼,在這個(gè)過(guò)程中就完成了將liba.so的加載。安卓系統(tǒng)在調(diào)用其所認(rèn)為的liba.so的JNI_Onload函數(shù)時(shí),如果未對(duì)libshell.so中的JNI_Onload函數(shù)進(jìn)行修改,那么系統(tǒng)實(shí)際上調(diào)用的是libshell.so中的JNI_Onload函數(shù)。而在本實(shí)施例中,libshell.so中的JNI_Onload函數(shù)被指向了liba.so中的JNI_Onload函數(shù),那么安卓系統(tǒng)在調(diào)用其所認(rèn)為的liba.so的JNI_Onload函數(shù)時(shí),也就恰好可以正確地調(diào)用到liba.so的JNI_Onload函數(shù),不會(huì)再出錯(cuò)。對(duì)于安卓系統(tǒng)希望調(diào)用的liba.so中的其他函數(shù),也可以進(jìn)行類似的處理。
在本發(fā)明的一個(gè)實(shí)施例中,圖1所示的方法還包括:在加固的SO文件的初始化代碼中為原SO文件預(yù)留加載空間;內(nèi)存加載邏輯包括:將原SO文件加載到安卓系統(tǒng)為預(yù)留加載空間分配的內(nèi)存空間中。
現(xiàn)有技術(shù)中,安卓系統(tǒng)在加載SO文件到內(nèi)存中時(shí),會(huì)通過(guò)mmap函數(shù)在調(diào)用該SO文件的應(yīng)用的進(jìn)程空間中為其隨機(jī)分配一段內(nèi)存,在本實(shí)施例中,也可以通過(guò)這種方式為加固的SO文件分配內(nèi)存。但是由于原SO文件并不是作為一個(gè)獨(dú)立SO文件而存在的,這種方法就會(huì)存在一個(gè)問(wèn)題:當(dāng)原SO文件使用完畢后,需要釋放掉為原SO文件分配的內(nèi)存空間,而在上述實(shí)施例中,原SO文件是作為加固后的SO文件中的一部分,很難掌握到使用完原SO文件的時(shí)機(jī),而如果不釋放掉為原SO文件分配的內(nèi)存空間,就會(huì)產(chǎn)生內(nèi)存泄漏的問(wèn)題。
在本實(shí)施例中,將原SO文件加載到安卓系統(tǒng)為預(yù)留加載空間分配的內(nèi)存空間中。而這部分預(yù)留加載空間實(shí)際上是加固后的SO文件所占用的內(nèi)存空間的一部分。顯然,當(dāng)加固后的SO文件使用完畢后,原SO文件一定也已使用完畢,這時(shí)候如果釋放掉加固后的SO文件所占用的內(nèi)存空間,不僅不會(huì)影響原SO文件的正常使用(因?yàn)樵璖O文件已經(jīng)使用完了),還可以一并釋放掉原SO文件所占用的內(nèi)存空間。
在本發(fā)明的一個(gè)實(shí)施例中,上述方法中,在加固的SO文件的初始化代碼中為原SO文件預(yù)留加載空間包括:在加固的SO文件的初始化代碼的用于存儲(chǔ)未初始化的全局變量的指定代碼段中為原SO文件預(yù)留加載空間。具體地,用于存儲(chǔ)未初始化的全局變量的指定代碼段為.bss節(jié)。
如果對(duì)全局變量進(jìn)行初始化,那么就不能夠保留已賦予全局變量的值,也就會(huì)無(wú)法確定原SO文件會(huì)占用多大的內(nèi)存空間,而.bss節(jié)則是常見的用于存儲(chǔ)未初始化的全局變量的代碼段。
在本發(fā)明的一個(gè)實(shí)施例中,上述方法中,在加固的SO文件的初始化代碼中為原SO文件預(yù)留加載空間包括:在用于存儲(chǔ)未初始化的全局變量的指定代碼段中設(shè)置與原SO文件對(duì)應(yīng)的指定數(shù)組;根據(jù)原SO文件的大小,確定原SO文件在內(nèi)存中占用的空間的數(shù)值,將該數(shù)值存儲(chǔ)至指定數(shù)組中,以使安卓系統(tǒng)在加載加固的SO文件時(shí),根據(jù)該指定數(shù)值中存儲(chǔ)的數(shù)值為預(yù)留加載空間分配內(nèi)存空間。
例如,計(jì)算出原SO文件會(huì)占用10234kb的內(nèi)存空間,那么就在加固的SO文件的.bss節(jié)中設(shè)置一個(gè)存儲(chǔ)該值的數(shù)組。安卓系統(tǒng)在加載加固的SO文件時(shí),會(huì)為.bss節(jié)分配內(nèi)存空間,這時(shí)就會(huì)為原SO文件分配出10234kb的內(nèi)存空間。當(dāng)加載原SO文件時(shí),就可以將原SO文件加載到該內(nèi)存空間中。而在.bss節(jié)中增加這樣一個(gè)數(shù)組,幾乎不會(huì)影響加固后的SO文件的大小。
在本發(fā)明的一個(gè)實(shí)施例中,上述方法在所有步驟前進(jìn)一步包括:對(duì)安卓安裝包進(jìn)行解包,得到安卓安裝包的至少一個(gè)原SO文件。
在本發(fā)明的一個(gè)實(shí)施例中,上述方法還包括:
將加固的SO文件打包到對(duì)應(yīng)的安卓安裝包中,以使安卓安裝包被安裝后,每次啟動(dòng)對(duì)應(yīng)的應(yīng)用時(shí),由安卓系統(tǒng)加載加固后的SO文件。
在上述實(shí)施例中由于對(duì)原SO文件進(jìn)行了加固處理,還需進(jìn)一步將其與安卓安裝包的其他文件,例如安卓資源文件、安卓配置文件等一同打包為完整的安卓安裝包。其中,SO文件、安卓資源文件等可以是開發(fā)者分別提供的,例如在一個(gè)開發(fā)團(tuán)隊(duì)內(nèi)部,由不同的項(xiàng)目組提供不同類別的文件,最后由安全組對(duì)SO文件進(jìn)行加密和全部文件的打包;也可以由專門的安全服務(wù)提供方對(duì)開發(fā)者提供的未加固安卓安裝包進(jìn)行解包處理,對(duì)其中的SO文件進(jìn)行加固后重新進(jìn)行打包。安卓系統(tǒng)加載加固后的SO文件可以是通過(guò)Linker(安卓系統(tǒng)的動(dòng)態(tài)庫(kù)加載器)來(lái)加載的。
圖2示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的一種加固安卓安裝包的動(dòng)態(tài)鏈接庫(kù)SO文件的裝置的結(jié)構(gòu)示意圖,如圖2所示,加固安卓安裝包的動(dòng)態(tài)鏈接庫(kù)SO文件的裝置200包括:
加殼單元210,適于對(duì)安卓安裝包的原SO文件增加外殼,得到加固的SO文件。
編輯單元220,適于在加固的SO文件的初始化代碼中寫入原SO文件的內(nèi)存加載邏輯,以使安卓系統(tǒng)在加載加固的SO文件時(shí),根據(jù)內(nèi)存加載邏輯,將原SO文件加載到內(nèi)存中。
可見,圖2所示的裝置,在對(duì)安卓安裝包的原SO文件增加外殼,得到加固的SO文件后,向加固的SO文件的初始化代碼中寫入原SO文件的內(nèi)存加載邏輯,以使安卓系統(tǒng)在加載加固的SO文件時(shí),根據(jù)內(nèi)存加載邏輯,將原SO文件加載到內(nèi)存中。該技術(shù)方案利用了初始化代碼在SO文件在加載時(shí)可以自動(dòng)運(yùn)行的特點(diǎn),使得安卓系統(tǒng)在加載加固的SO文件時(shí)可以直接運(yùn)行原SO文件的內(nèi)存加載邏輯,從而實(shí)現(xiàn)了原SO文件的加載,不需要系統(tǒng)直接對(duì)原SO文件進(jìn)行操作,簡(jiǎn)單方便。
在本發(fā)明的一個(gè)實(shí)施例中,上述裝置中,加殼單元210,適于將原SO文件轉(zhuǎn)換為二進(jìn)制形式,將得到的二進(jìn)制形式的原SO文件添加到外殼中。
在對(duì)原SO文件進(jìn)行加固的過(guò)程中,還會(huì)涉及對(duì)函數(shù)的加密、添加解密邏輯等其他內(nèi)容,由于不是本發(fā)明的重點(diǎn),在此不做過(guò)多介紹。在本實(shí)施例中,將原SO文件轉(zhuǎn)換為二進(jìn)制形式,將其添加到外殼中(例如寫入.data節(jié)),形成了加固的SO文件。加固的SO文件的文件名與原SO文件名可以是相同的,這樣在加載過(guò)程中,系統(tǒng)實(shí)際是把加固后的SO文件當(dāng)作原SO文件進(jìn)行加載。也正因如此,由于加固的SO文件并不等同于原SO文件,許多函數(shù)的調(diào)用就會(huì)產(chǎn)生問(wèn)題,例如:
SO文件并非是通過(guò)JAVA代碼編寫的,需要安卓系統(tǒng)利用JAVA的跨平臺(tái)機(jī)制,即通過(guò)JNI(Java Native Interface,JAVA本地接口)來(lái)使用SO文件,即實(shí)現(xiàn)JAVA層與本地層(Native層)的通信。具體地,在未對(duì)SO文件進(jìn)行加固的情況下,JAVA層可以直接調(diào)用SO文件中的JNI函數(shù)來(lái)實(shí)現(xiàn)對(duì)SO文件的使用,但是在對(duì)SO文件增加外殼的情況下,JAVA層定位到的是加固后的SO文件中JNI函數(shù)的函數(shù)地址,而并非原SO文件的函數(shù)地址,從而產(chǎn)生崩潰。
因此,在本發(fā)明的一個(gè)實(shí)施例中,上述裝置中,編輯單元220,還適于在加固的SO文件的初始化代碼中,將加固的SO文件中的至少一個(gè)指定函數(shù)指向該函數(shù)在原SO文件中對(duì)應(yīng)的指定函數(shù),以使安卓系統(tǒng)在調(diào)用加固的SO文件中的指定函數(shù)時(shí),調(diào)用原SO文件中對(duì)應(yīng)的指定函數(shù)。
在本發(fā)明的一個(gè)實(shí)施例中,上述裝置中,加固的SO文件中的指定函數(shù)與原SO文件中對(duì)應(yīng)的指定函數(shù)為同類型的函數(shù)。
在本發(fā)明的一個(gè)實(shí)施例中,上述裝置中,加固的SO文件中的指定函數(shù)與原SO文件中對(duì)應(yīng)的指定函數(shù)均為JNI_Onload函數(shù)。
試看下例:原SO文件liba.so通過(guò)增加外殼,得到了加固的SO文件libshell.so。但由于libshell.so仍然為命名為liba.so,安卓系統(tǒng)通過(guò)System.loadLibrary(“l(fā)iba.so”)加載到的實(shí)際上是libshell.so。在加載libshell.so時(shí),運(yùn)行l(wèi)ibshell.so的初始化代碼,在這個(gè)過(guò)程中就完成了將liba.so的加載。安卓系統(tǒng)在調(diào)用其所認(rèn)為的liba.so的JNI_Onload函數(shù)時(shí),如果未對(duì)libshell.so中的JNI_Onload函數(shù)進(jìn)行修改,那么系統(tǒng)實(shí)際上調(diào)用的是libshell.so中的JNI_Onload函數(shù)。而在本實(shí)施例中,libshell.so中的JNI_Onload函數(shù)被指向了liba.so中的JNI_Onload函數(shù),那么安卓系統(tǒng)在調(diào)用其所認(rèn)為的liba.so的JNI_Onload函數(shù)時(shí),也就恰好可以正確地調(diào)用到liba.so的JNI_Onload函數(shù),不會(huì)再出錯(cuò)。對(duì)于安卓系統(tǒng)希望調(diào)用的liba.so中的其他函數(shù),也可以進(jìn)行類似的處理。
在本發(fā)明的一個(gè)實(shí)施例中,上述裝置中,編輯單元220,還適于在加固的SO文件的初始化代碼中為原SO文件預(yù)留加載空間;內(nèi)存加載邏輯包括:將原SO文件加載到安卓系統(tǒng)為預(yù)留加載空間分配的內(nèi)存空間中。
現(xiàn)有技術(shù)中,安卓系統(tǒng)在加載SO文件到內(nèi)存中時(shí),會(huì)通過(guò)mmap函數(shù)在調(diào)用該SO文件的應(yīng)用的進(jìn)程空間中為其隨機(jī)分配一段內(nèi)存,在本實(shí)施例中,也可以通過(guò)這種方式為加固的SO文件分配內(nèi)存。但是由于原SO文件并不是作為一個(gè)獨(dú)立SO文件而存在的,這種方法就會(huì)存在一個(gè)問(wèn)題:當(dāng)原SO文件使用完畢后,需要釋放掉為原SO文件分配的內(nèi)存空間,而在上述實(shí)施例中,原SO文件是作為加固后的SO文件中的一部分,很難掌握到使用完原SO文件的時(shí)機(jī),而如果不釋放掉為原SO文件分配的內(nèi)存空間,就會(huì)產(chǎn)生內(nèi)存泄漏的問(wèn)題。
在本實(shí)施例中,將原SO文件加載到安卓系統(tǒng)為預(yù)留加載空間分配的內(nèi)存空間中。而這部分預(yù)留加載空間實(shí)際上是加固后的SO文件所占用的內(nèi)存空間的一部分。顯然,當(dāng)加固后的SO文件使用完畢后,原SO文件一定也已使用完畢,這時(shí)候如果釋放掉加固后的SO文件所占用的內(nèi)存空間,不僅不會(huì)影響原SO文件的正常使用(因?yàn)樵璖O文件已經(jīng)使用完了),還可以一并釋放掉原SO文件所占用的內(nèi)存空間。
在本發(fā)明的一個(gè)實(shí)施例中,上述裝置中,編輯單元220,適于在加固的SO文件的初始化代碼的用于存儲(chǔ)未初始化的全局變量的指定代碼段中為原SO文件預(yù)留加載空間。
在本發(fā)明的一個(gè)實(shí)施例中,上述裝置中,用于存儲(chǔ)未初始化的全局變量的指定代碼段為.bss節(jié)。
如果對(duì)全局變量進(jìn)行初始化,那么就不能夠保留已賦予全局變量的值,也就會(huì)無(wú)法確定原SO文件會(huì)占用多大的內(nèi)存空間,而.bss節(jié)則是常見的用于存儲(chǔ)未初始化的全局變量的代碼段。
在本發(fā)明的一個(gè)實(shí)施例中,上述裝置中,編輯單元220,適于在用于存儲(chǔ)未初始化的全局變量的指定代碼段中設(shè)置與原SO文件對(duì)應(yīng)的指定數(shù)組;根據(jù)原SO文件的大小,確定原SO文件在內(nèi)存中占用的空間的數(shù)值,將該數(shù)值存儲(chǔ)至指定數(shù)組中,以使安卓系統(tǒng)在加載加固的SO文件時(shí),根據(jù)該指定數(shù)值中存儲(chǔ)的數(shù)值為預(yù)留加載空間分配內(nèi)存空間。
例如,計(jì)算出原SO文件會(huì)占用10234kb的內(nèi)存空間,那么就在加固的SO文件的.bss節(jié)中設(shè)置一個(gè)存儲(chǔ)該值的數(shù)組。安卓系統(tǒng)在加載加固的SO文件時(shí),會(huì)為.bss節(jié)分配內(nèi)存空間,這時(shí)就會(huì)為原SO文件分配出10234kb的內(nèi)存空間。當(dāng)加載原SO文件時(shí),就可以將原SO文件加載到該內(nèi)存空間中。而在.bss節(jié)中增加這樣一個(gè)數(shù)組,幾乎不會(huì)影響加固后的SO文件的大小。
在本發(fā)明的一個(gè)實(shí)施例中,上述裝置還包括:解包單元(圖未示),適于對(duì)安卓安裝包進(jìn)行解包,得到安卓安裝包的至少一個(gè)原SO文件。
在本發(fā)明的一個(gè)實(shí)施例中,上述裝置還包括:打包單元(圖未示),適于將加固的SO文件打包到對(duì)應(yīng)的安卓安裝包中,以使安卓安裝包被安裝后,每次啟動(dòng)對(duì)應(yīng)的應(yīng)用時(shí),由安卓系統(tǒng)加載加固后的SO文件。
在上述實(shí)施例中由于對(duì)原SO文件進(jìn)行了加固處理,還需進(jìn)一步將其與安卓安裝包的其他文件,例如安卓資源文件、安卓配置文件等一同打包為完整的安卓安裝包。其中,SO文件、安卓資源文件等可以是開發(fā)者分別提供的,例如在一個(gè)開發(fā)團(tuán)隊(duì)內(nèi)部,由不同的項(xiàng)目組提供不同類別的文件,最后由安全組對(duì)SO文件進(jìn)行加密和全部文件的打包;也可以由專門的安全服務(wù)提供方對(duì)開發(fā)者提供的未加固安卓安裝包進(jìn)行解包處理,對(duì)其中的SO文件進(jìn)行加固后重新進(jìn)行打包。安卓系統(tǒng)加載加固后的SO文件可以是通過(guò)Linker(安卓系統(tǒng)的動(dòng)態(tài)庫(kù)加載器)來(lái)加載的。
綜上所述,本發(fā)明的技術(shù)方案,在對(duì)安卓安裝包的原SO文件增加外殼,得到加固的SO文件后,向加固的SO文件的初始化代碼中寫入原SO文件的內(nèi)存加載邏輯,以使安卓系統(tǒng)在加載所述加固的SO文件時(shí),根據(jù)所述內(nèi)存加載邏輯,將所述原SO文件加載到內(nèi)存中。該技術(shù)方案利用了初始化代碼在SO文件在加載時(shí)可以自動(dòng)運(yùn)行的特點(diǎn),使得安卓系統(tǒng)在加載加固的SO文件時(shí)可以直接運(yùn)行原SO文件的內(nèi)存加載邏輯,從而實(shí)現(xiàn)了原SO文件的加載,不需要系統(tǒng)直接對(duì)原SO文件進(jìn)行操作,簡(jiǎn)單方便。
需要說(shuō)明的是:
在此提供的算法和顯示不與任何特定計(jì)算機(jī)、虛擬裝置或者其它設(shè)備固有相關(guān)。各種通用裝置也可以與基于在此的示教一起使用。根據(jù)上面的描述,構(gòu)造這類裝置所要求的結(jié)構(gòu)是顯而易見的。此外,本發(fā)明也不針對(duì)任何特定編程語(yǔ)言。應(yīng)當(dāng)明白,可以利用各種編程語(yǔ)言實(shí)現(xiàn)在此描述的本發(fā)明的內(nèi)容,并且上面對(duì)特定語(yǔ)言所做的描述是為了披露本發(fā)明的最佳實(shí)施方式。
在此處所提供的說(shuō)明書中,說(shuō)明了大量具體細(xì)節(jié)。然而,能夠理解,本發(fā)明的實(shí)施例可以在沒(méi)有這些具體細(xì)節(jié)的情況下實(shí)踐。在一些實(shí)例中,并未詳細(xì)示出公知的方法、結(jié)構(gòu)和技術(shù),以便不模糊對(duì)本說(shuō)明書的理解。
類似地,應(yīng)當(dāng)理解,為了精簡(jiǎn)本公開并幫助理解各個(gè)發(fā)明方面中的一個(gè)或多個(gè),在上面對(duì)本發(fā)明的示例性實(shí)施例的描述中,本發(fā)明的各個(gè)特征有時(shí)被一起分組到單個(gè)實(shí)施例、圖、或者對(duì)其的描述中。然而,并不應(yīng)將該公開的方法解釋成反映如下意圖:即所要求保護(hù)的本發(fā)明要求比在每個(gè)權(quán)利要求中所明確記載的特征更多的特征。更確切地說(shuō),如下面的權(quán)利要求書所反映的那樣,發(fā)明方面在于少于前面公開的單個(gè)實(shí)施例的所有特征。因此,遵循具體實(shí)施方式的權(quán)利要求書由此明確地并入該具體實(shí)施方式,其中每個(gè)權(quán)利要求本身都作為本發(fā)明的單獨(dú)實(shí)施例。
本領(lǐng)域那些技術(shù)人員可以理解,可以對(duì)實(shí)施例中的設(shè)備中的模塊進(jìn)行自適應(yīng)性地改變并且把它們?cè)O(shè)置在與該實(shí)施例不同的一個(gè)或多個(gè)設(shè)備中??梢园褜?shí)施例中的模塊或單元或組件組合成一個(gè)模塊或單元或組件,以及此外可以把它們分成多個(gè)子模塊或子單元或子組件。除了這樣的特征和/或過(guò)程或者單元中的至少一些是相互排斥之外,可以采用任何組合對(duì)本說(shuō)明書(包括伴隨的權(quán)利要求、摘要和附圖)中公開的所有特征以及如此公開的任何方法或者設(shè)備的所有過(guò)程或單元進(jìn)行組合。除非另外明確陳述,本說(shuō)明書(包括伴隨的權(quán)利要求、摘要和附圖)中公開的每個(gè)特征可以由提供相同、等同或相似目的的替代特征來(lái)代替。
此外,本領(lǐng)域的技術(shù)人員能夠理解,盡管在此所述的一些實(shí)施例包括其它實(shí)施例中所包括的某些特征而不是其它特征,但是不同實(shí)施例的特征的組合意味著處于本發(fā)明的范圍之內(nèi)并且形成不同的實(shí)施例。例如,在下面的權(quán)利要求書中,所要求保護(hù)的實(shí)施例的任意之一都可以以任意的組合方式來(lái)使用。
本發(fā)明的各個(gè)部件實(shí)施例可以以硬件實(shí)現(xiàn),或者以在一個(gè)或者多個(gè)處理器上運(yùn)行的軟件模塊實(shí)現(xiàn),或者以它們的組合實(shí)現(xiàn)。本領(lǐng)域的技術(shù)人員應(yīng)當(dāng)理解,可以在實(shí)踐中使用微處理器或者數(shù)字信號(hào)處理器(DSP)來(lái)實(shí)現(xiàn)根據(jù)本發(fā)明實(shí)施例的加固安卓安裝包的動(dòng)態(tài)鏈接庫(kù)SO文件的裝置中的一些或者全部部件的一些或者全部功能。本發(fā)明還可以實(shí)現(xiàn)為用于執(zhí)行這里所描述的方法的一部分或者全部的設(shè)備或者裝置程序(例如,計(jì)算機(jī)程序和計(jì)算機(jī)程序產(chǎn)品)。這樣的實(shí)現(xiàn)本發(fā)明的程序可以存儲(chǔ)在計(jì)算機(jī)可讀介質(zhì)上,或者可以具有一個(gè)或者多個(gè)信號(hào)的形式。這樣的信號(hào)可以從因特網(wǎng)網(wǎng)站上下載得到,或者在載體信號(hào)上提供,或者以任何其他形式提供。
應(yīng)該注意的是上述實(shí)施例對(duì)本發(fā)明進(jìn)行說(shuō)明而不是對(duì)本發(fā)明進(jìn)行限制,并且本領(lǐng)域技術(shù)人員在不脫離所附權(quán)利要求的范圍的情況下可設(shè)計(jì)出替換實(shí)施例。在權(quán)利要求中,不應(yīng)將位于括號(hào)之間的任何參考符號(hào)構(gòu)造成對(duì)權(quán)利要求的限制。單詞“包含”不排除存在未列在權(quán)利要求中的元件或步驟。位于元件之前的單詞“一”或“一個(gè)”不排除存在多個(gè)這樣的元件。本發(fā)明可以借助于包括有若干不同元件的硬件以及借助于適當(dāng)編程的計(jì)算機(jī)來(lái)實(shí)現(xiàn)。在列舉了若干裝置的單元權(quán)利要求中,這些裝置中的若干個(gè)可以是通過(guò)同一個(gè)硬件項(xiàng)來(lái)具體體現(xiàn)。單詞第一、第二、以及第三等的使用不表示任何順序??蓪⑦@些單詞解釋為名稱。
本發(fā)明的實(shí)施例公開了A1、一種加固安卓安裝包的動(dòng)態(tài)鏈接庫(kù)SO文件的方法,其中,該方法包括:
對(duì)安卓安裝包的原SO文件增加外殼,得到加固的SO文件;
在所述加固的SO文件的初始化代碼中寫入所述原SO文件的內(nèi)存加載邏輯,以使安卓系統(tǒng)在加載所述加固的SO文件時(shí),根據(jù)所述內(nèi)存加載邏輯,將所述原SO文件加載到內(nèi)存中。
A2、如A1所述的方法,其中,所述對(duì)安卓安裝包的原SO文件增加外殼包括:
將所述原SO文件轉(zhuǎn)換為二進(jìn)制形式,將得到的二進(jìn)制形式的原SO文件添加到所述外殼中。
A3、如A1所述的方法,其中,該方法還包括:
在所述加固的SO文件的初始化代碼中,將所述加固的SO文件中的至少一個(gè)指定函數(shù)指向該函數(shù)在所述原SO文件中對(duì)應(yīng)的指定函數(shù),以使安卓系統(tǒng)在調(diào)用所述加固的SO文件中的指定函數(shù)時(shí),調(diào)用原SO文件中對(duì)應(yīng)的指定函數(shù)。
A4、如A3所述的方法,其中,所述加固的SO文件中的指定函數(shù)與所述原SO文件中對(duì)應(yīng)的指定函數(shù)為同類型的函數(shù)。
A5、如A3所述的方法,其中,所述加固的SO文件中的指定函數(shù)與所述原SO文件中對(duì)應(yīng)的指定函數(shù)均為JNI_Onload函數(shù)。
A6、如A1所述的方法,其中,該方法還包括:
在所述加固的SO文件的初始化代碼中為所述原SO文件預(yù)留加載空間;
所述內(nèi)存加載邏輯包括:將所述原SO文件加載到安卓系統(tǒng)為所述預(yù)留加載空間分配的內(nèi)存空間中。
A7、如A6所述的方法,其中,所述在所述加固的SO文件的初始化代碼中為所述原SO文件預(yù)留加載空間包括:
在所述加固的SO文件的初始化代碼的用于存儲(chǔ)未初始化的全局變量的指定代碼段中為所述原SO文件預(yù)留加載空間。
A8、如A7所述的方法,其中,所述用于存儲(chǔ)未初始化的全局變量的指定代碼段為.bss節(jié)。
A9、如A7所述的方法,其中,所述在所述加固的SO文件的初始化代碼中為所述原SO文件預(yù)留加載空間包括:
在所述用于存儲(chǔ)未初始化的全局變量的指定代碼段中設(shè)置與所述原SO文件對(duì)應(yīng)的指定數(shù)組;
根據(jù)所述原SO文件的大小,確定所述原SO文件在內(nèi)存中占用的空間的數(shù)值,將該數(shù)值存儲(chǔ)至所述指定數(shù)組中,以使安卓系統(tǒng)在加載所述加固的SO文件時(shí),根據(jù)該指定數(shù)值中存儲(chǔ)的數(shù)值為所述預(yù)留加載空間分配內(nèi)存空間。
A10、如A1-A9中任一項(xiàng)所述的方法,其中,該方法在所有步驟前進(jìn)一步包括:
對(duì)安卓安裝包進(jìn)行解包,得到安卓安裝包的至少一個(gè)原SO文件。
A11、如A10所述的方法,其中,該方法還包括:
將所述加固的SO文件打包到對(duì)應(yīng)的安卓安裝包中,以使所述安卓安裝包被安裝后,每次啟動(dòng)對(duì)應(yīng)的應(yīng)用時(shí),由安卓系統(tǒng)加載所述加固后的SO文件。
本發(fā)明的實(shí)施例還公開了B12、一種加固安卓安裝包的動(dòng)態(tài)鏈接庫(kù)SO文件的裝置,其中,該裝置包括:
加殼單元,適于對(duì)安卓安裝包的原SO文件增加外殼,得到加固的SO文件;
編輯單元,適于在所述加固的SO文件的初始化代碼中寫入所述原SO文件的內(nèi)存加載邏輯,以使安卓系統(tǒng)在加載所述加固的SO文件時(shí),根據(jù)所述內(nèi)存加載邏輯,將所述原SO文件加載到內(nèi)存中。
B13、如B12所述的裝置,其中,
所述加殼單元,適于將所述原SO文件轉(zhuǎn)換為二進(jìn)制形式,將得到的二進(jìn)制形式的原SO文件添加到所述外殼中。
B14、如B12所述的裝置,其中,
所述編輯單元,還適于在所述加固的SO文件的初始化代碼中,將所述加固的SO文件中的至少一個(gè)指定函數(shù)指向該函數(shù)在所述原SO文件中對(duì)應(yīng)的指定函數(shù),以使安卓系統(tǒng)在調(diào)用所述加固的SO文件中的指定函數(shù)時(shí),調(diào)用原SO文件中對(duì)應(yīng)的指定函數(shù)。
B15、如B14所述的裝置,其中,所述加固的SO文件中的指定函數(shù)與所述原SO文件中對(duì)應(yīng)的指定函數(shù)為同類型的函數(shù)。
B16、如B14所述的裝置,其中,所述加固的SO文件中的指定函數(shù)與所述原SO文件中對(duì)應(yīng)的指定函數(shù)均為JNI_Onload函數(shù)。
B17、如B12所述的裝置,其中,
所述編輯單元,還適于在所述加固的SO文件的初始化代碼中為所述原SO文件預(yù)留加載空間;所述內(nèi)存加載邏輯包括:將所述原SO文件加載到安卓系統(tǒng)為所述預(yù)留加載空間分配的內(nèi)存空間中。
B18、如B17所述的裝置,其中,
所述編輯單元,適于在所述加固的SO文件的初始化代碼的用于存儲(chǔ)未初始化的全局變量的指定代碼段中為所述原SO文件預(yù)留加載空間。
B19、如B18所述的裝置,其中,所述用于存儲(chǔ)未初始化的全局變量的指定代碼段為.bss節(jié)。
B20、如B18所述的裝置,其中,
所述編輯單元,適于在所述用于存儲(chǔ)未初始化的全局變量的指定代碼段中設(shè)置與所述原SO文件對(duì)應(yīng)的指定數(shù)組;根據(jù)所述原SO文件的大小,確定所述原SO文件在內(nèi)存中占用的空間的數(shù)值,將該數(shù)值存儲(chǔ)至所述指定數(shù)組中,以使安卓系統(tǒng)在加載所述加固的SO文件時(shí),根據(jù)該指定數(shù)值中存儲(chǔ)的數(shù)值為所述預(yù)留加載空間分配內(nèi)存空間。
B21、如B12-B20中任一項(xiàng)所述的裝置,其中,該裝置還包括:
解包單元,適于對(duì)安卓安裝包進(jìn)行解包,得到安卓安裝包的至少一個(gè)原SO文件。
B22、如B21所述的裝置,其中,該裝置還包括:
打包單元,適于將所述加固的SO文件打包到對(duì)應(yīng)的安卓安裝包中,以使所述安卓安裝包被安裝后,每次啟動(dòng)對(duì)應(yīng)的應(yīng)用時(shí),由安卓系統(tǒng)加載所述加固后的SO文件。