本發(fā)明涉及應(yīng)用程序的調(diào)試領(lǐng)域,尤其涉及一種應(yīng)用程序的反調(diào)試方法和系統(tǒng)。
背景技術(shù):
隨著計算機(jī)技術(shù)應(yīng)用日益普及,Android智能終端的快速發(fā)展,Android軟件產(chǎn)業(yè)得以飛速發(fā)展,與此同時,攻擊者利用Android軟件逆向技術(shù)對軟件的各種攻擊和未授權(quán)使用以及盜版復(fù)制等行為也越來越多。
Android逆向分析技術(shù)可以被用來在不知道應(yīng)用程序源代碼的情況下分析應(yīng)用程序的功能流程、篡改應(yīng)用程序的數(shù)據(jù)代碼等,逆向分析技術(shù)如果被不加限制的惡意使用,利用者可以分析獲取應(yīng)用程序的核心技術(shù),也可以篡改應(yīng)用程序的簽名和作者信息,還可以將惡意代碼注入到已有的應(yīng)用程序中并通過二次打包進(jìn)行偽裝,這些行為都極大的危害了應(yīng)用程序開發(fā)者的利益,嚴(yán)重?fù)p害了廣大用戶的隱私安全。
在Android軟件逆向技術(shù)中,Android調(diào)試技術(shù)是一個非常重要的組成部分。通過進(jìn)行Android應(yīng)用的調(diào)試,可以得到Android應(yīng)用的運(yùn)行流程,推斷出Android應(yīng)用的基本原理,通??梢苑浅m樌铱焖俚乩@過一些登陸限制或功能限制,獲取到一些用戶私密信息,具有較大的危害。例如,可以分析清楚Android程序中使用的數(shù)據(jù)加解密方法、如分析清楚應(yīng)用收費(fèi)功能的判斷邏輯,從而可以繞過是否付費(fèi)的檢查,從而可以不繳費(fèi)的情況下使用收費(fèi)功能等、如對于游戲應(yīng)用可以去開發(fā)出相應(yīng)的“游戲外掛”等。而軟件逆向的第一步則是能夠?qū)Τ绦蜻M(jìn)行調(diào)試,如果沒有反調(diào)試技術(shù),則相當(dāng)于程序被“裸露”在黑客面前。目前比較重要的程序都希望能夠加入反調(diào)試功能,防止黑客進(jìn)行調(diào)試,從而不讓別人分析程序的實(shí)現(xiàn)原理,極大的提高了程序被破解的門檻,如何進(jìn)行應(yīng)用程序的反調(diào)試已成為急需解決的問題。
技術(shù)實(shí)現(xiàn)要素:
本發(fā)明的目的在于提供一種反調(diào)試方法和系統(tǒng),通過創(chuàng)建一個用于調(diào)試應(yīng)用程序進(jìn)程的子進(jìn)程,從而完全杜絕了應(yīng)用程序被黑客攻擊的可能性,實(shí)現(xiàn)了對應(yīng)用程序的反調(diào)試。
本發(fā)明所采用的技術(shù)方案如下:
一種反調(diào)試方法,其特征在于,該方法包括:
步驟S101,將需要反調(diào)試的進(jìn)程設(shè)置為調(diào)試狀態(tài);
步驟S102,在需要反調(diào)試的進(jìn)程中創(chuàng)建子進(jìn)程;
步驟S103,將所創(chuàng)建的子進(jìn)程附加到需要反調(diào)試的進(jìn)程中;
步驟S104,子進(jìn)程接收需要反調(diào)試的進(jìn)程發(fā)送的反饋消息,并對該反饋消息進(jìn)行處理。
將需要反調(diào)試的進(jìn)程設(shè)置為調(diào)試狀態(tài)包括:
通過調(diào)用Android系統(tǒng)接口函數(shù)prctl(option,arg2,arg3,arg4,arg5)來將需要反調(diào)試的進(jìn)程設(shè)置為調(diào)試狀態(tài),其中參數(shù)option是PR_SET_DUMPABLE,參數(shù)arg2的值是1, 參數(shù)arg3的值是0, 參數(shù)arg4的值是0, 參數(shù)arg5的值是0。
在需要反調(diào)試的進(jìn)程中創(chuàng)建子進(jìn)程包括:
通過調(diào)用Android系統(tǒng)函數(shù)fork來完成子進(jìn)程的創(chuàng)建。
將所創(chuàng)建的子進(jìn)程附加到需要反調(diào)試的進(jìn)程中包括:
通過調(diào)用Android系統(tǒng)函數(shù)getppid來獲取到需要反調(diào)試的進(jìn)程的進(jìn)程ID,將所創(chuàng)建的子進(jìn)程附加到需要反調(diào)試的進(jìn)程中。
將所創(chuàng)建的子進(jìn)程附加到需要反調(diào)試的進(jìn)程中包括:
調(diào)用Android系統(tǒng)函數(shù)ptrace(PTRACE_ATTACH, ppid, NULL, NULL)來執(zhí)行附加操作,其中參數(shù)PTRACE_ATTACH表明是附加操作,參數(shù)ppid是獲取到的需要反調(diào)試的進(jìn)程的進(jìn)程ID,表示將所創(chuàng)建的子進(jìn)程附加到該需要反調(diào)試的進(jìn)程的進(jìn)程ID所指示的進(jìn)程中,NULL代表空缺。
子進(jìn)程接收需要反調(diào)試的進(jìn)程發(fā)送的反饋消息,并對該反饋消息進(jìn)行處理包括:
通過調(diào)用Android系統(tǒng)函數(shù)WSTOPSIG(status)來獲取需要反調(diào)試的進(jìn)程的反饋消息,其中變量status用于存放變量信號值,
判斷該status的值是否等于以下四個信號中的任意一個,四個信號包括:停止該反調(diào)試的進(jìn)程的執(zhí)行信號SIGSTOP、停止該反調(diào)試的進(jìn)程的運(yùn)行信號SIGTSTP、當(dāng)后臺作業(yè)要從用戶終端讀數(shù)據(jù)時的信號SIGTTIN、在寫終端或修改終端模式時收到的信號SIGTTOU,如果上述判斷不成立,則不對所述的反饋消息進(jìn)行任何處理,如果上述判斷成立,則設(shè)置需要反調(diào)試的進(jìn)程刪除所述反饋消息。
通過調(diào)用Android系統(tǒng)函數(shù)ptrace(PTRACE_CONT, ppid, 0, 0) 來實(shí)現(xiàn)刪除操作,其中,參數(shù)PTRACE_CONT用于指示需要反調(diào)試的進(jìn)程繼續(xù)執(zhí)行系統(tǒng)調(diào)用過程,參數(shù)ppid是需要反調(diào)試的進(jìn)程的進(jìn)程ID值,參數(shù)0指示需要反調(diào)試的進(jìn)程刪除所述的反饋消息。
一種反調(diào)試系統(tǒng),該系統(tǒng)包括設(shè)置模塊、創(chuàng)建模塊、調(diào)試模塊以及處理模塊,其特征在于:
設(shè)置模塊,用于將需要反調(diào)試的進(jìn)程設(shè)置為調(diào)試狀態(tài);
創(chuàng)建模塊,用于在需要反調(diào)試的進(jìn)程中創(chuàng)建子進(jìn)程;
調(diào)試模塊,用于將所創(chuàng)建的子進(jìn)程附加到需要反調(diào)試的進(jìn)程中;
處理模塊,用于子進(jìn)程等待需要反調(diào)試的進(jìn)程的消息,并對消息進(jìn)行處理。
設(shè)置模塊中包括:
調(diào)用單元:
用于通過調(diào)用Android系統(tǒng)接口函數(shù)prctl(option,arg2,arg3,arg4,arg5)來設(shè)置當(dāng)前進(jìn)程可以被調(diào)試, 其中參數(shù)option是PR_SET_DUMPABLE,參數(shù)arg2的值是1, 參數(shù)arg3的值是0, 參數(shù)arg4的值是0, 參數(shù)arg5的值是0;
創(chuàng)建模塊中包括:
建立單元,用于通過調(diào)用系統(tǒng)函數(shù)fork來完成新進(jìn)程的創(chuàng)建;
將所創(chuàng)建的子進(jìn)程附加到需要反調(diào)試的進(jìn)程中包括:
通過調(diào)用函數(shù)getppid來獲取到需要反調(diào)試的進(jìn)程的進(jìn)程ID,將所創(chuàng)建的子進(jìn)程附加到需要反調(diào)試的進(jìn)程中;
子進(jìn)程等待需要反調(diào)試的進(jìn)程的消息,并對消息進(jìn)行處理包括:
通過調(diào)用Android系統(tǒng)函數(shù)WSTOPSIG(status)來獲取需要反調(diào)試的進(jìn)程的反饋消息,其中變量status用于存放變量信號值,
判斷該status的值是否等于以下四個信號中的任意一個,四個信號包括:停止該反調(diào)試的進(jìn)程的執(zhí)行信號SIGSTOP、停止該反調(diào)試的進(jìn)程的運(yùn)行信號SIGTSTP、當(dāng)后臺作業(yè)要從用戶終端讀數(shù)據(jù)時的信號SIGTTIN、在寫終端或修改終端模式時收到的信號SIGTTOU,如果上述判斷不成立,則不對所述的反饋消息進(jìn)行任何處理,如果上述判斷成立,則設(shè)置需要反調(diào)試的進(jìn)程刪除所述反饋消息。
將所創(chuàng)建的子進(jìn)程附加到需要反調(diào)試的進(jìn)程中包括:
調(diào)用函數(shù)ptrace(PTRACE_ATTACH, ppid, NULL, NULL)來執(zhí)行附加操作,其中參數(shù)request填入PTRACE_ATTACH,參數(shù)ppid是獲取到的需要反調(diào)試的進(jìn)程的進(jìn)程ID,表示將所創(chuàng)建的子進(jìn)程附加到該需要反調(diào)試的進(jìn)程的進(jìn)程ID所指示的進(jìn)程中,NULL代表空缺。
本發(fā)明的技術(shù)方案所能獲得的有益效果包括,通過消耗較少的系統(tǒng)資源,簡單、方便的防止了其他進(jìn)程調(diào)試被保護(hù)的進(jìn)程。
附圖說明
圖1為該反調(diào)試方法的流程示意圖;
圖2為該反調(diào)試系統(tǒng)的功能模塊示意圖。
具體實(shí)施方式
為了更好的說明本發(fā)明,現(xiàn)結(jié)合具體實(shí)施例以及說明書附圖對技術(shù)方案作進(jìn)一步的說明。雖然實(shí)施例中記載了這些具體的實(shí)施方式,然其并非用以限定本發(fā)明,任何所屬技術(shù)領(lǐng)域中具有通常知識者,在不脫離本發(fā)明的精神和范圍內(nèi),當(dāng)可作些許的更動與潤飾,故本發(fā)明的保護(hù)范圍當(dāng)視權(quán)利要求書所界定者為準(zhǔn)。
該應(yīng)用程序的反調(diào)試方法的流程示意圖如圖1所示。該反調(diào)試方法首先會在被反調(diào)試的進(jìn)程中,即應(yīng)用程序進(jìn)程,設(shè)置當(dāng)前進(jìn)程可以被附加,然后再創(chuàng)建一個子進(jìn)程,子進(jìn)程則會附加到反調(diào)試進(jìn)程中執(zhí)行調(diào)試任務(wù),然后子進(jìn)程進(jìn)入消息循環(huán),來處理父進(jìn)程發(fā)送過來的消息。該反調(diào)試方法具體包括如下步驟:
1)步驟S101:將反調(diào)試的進(jìn)程設(shè)置為調(diào)試狀態(tài);
通過調(diào)用Android系統(tǒng)接口函數(shù)prctl(int option,unsigned long arg2,unsigned long arg3,unsigned long arg4,unsigned long arg5)來設(shè)置當(dāng)前進(jìn)程可以被調(diào)試,此函數(shù)的關(guān)鍵點(diǎn)在于參數(shù)option。
在該反調(diào)試方法中的具體調(diào)用是prctl(PR_SET_DUMPABLE, 1, 0, 0, 0),其中參數(shù)option是PR_SET_DUMPABLE,參數(shù)arg2的值是1。
2)步驟S102:在反調(diào)試的進(jìn)程中創(chuàng)建子進(jìn)程;
在Android系統(tǒng)中創(chuàng)建一個新進(jìn)程,通過調(diào)用系統(tǒng)函數(shù)fork()來完成新進(jìn)程的創(chuàng)建,由fork創(chuàng)建的新進(jìn)程被稱為子進(jìn)程(child process),調(diào)用fork函數(shù)將會有返回值,如果返回值為0,則表示創(chuàng)建的是子進(jìn)程,如果返回值大于0,則表示創(chuàng)建的是父進(jìn)程,對于父進(jìn)程,其返回值是新進(jìn)程的進(jìn)程ID,該進(jìn)程ID是進(jìn)程的唯一編號,子進(jìn)程可以通過調(diào)用系統(tǒng)函數(shù)getpid以獲得其父進(jìn)程的進(jìn)程ID,具體實(shí)現(xiàn)如下:
pid_tpid = fork();
如果pid 的值為0則說明當(dāng)前進(jìn)程是子進(jìn)程。
3)步驟S103:所創(chuàng)建的子進(jìn)程對反調(diào)試的進(jìn)程進(jìn)行調(diào)試;
在步驟S102中創(chuàng)建的子進(jìn)程,通過調(diào)用函數(shù)getpid來獲取到父進(jìn)程,即反調(diào)試的進(jìn)程的進(jìn)程ID,將子進(jìn)程附加到父進(jìn)程,即將子進(jìn)程附加到反調(diào)試的進(jìn)程中,子進(jìn)程對反調(diào)試的進(jìn)程進(jìn)行調(diào)試。具體實(shí)現(xiàn)如下:
a. 獲取父進(jìn)程ID
pid_tppid =getppid();
其中,pid_t是進(jìn)程ID的類型,getppid()是Android系統(tǒng)提供的獲取進(jìn)程ID的函數(shù),ppid是父進(jìn)程的ID,即進(jìn)程的唯一編號。
b.附加到父進(jìn)程中
調(diào)用Android系統(tǒng)提供的ptrace()函數(shù)來執(zhí)行附加操作,long ptrace(int request, pid_tppid, void * addr, void * data) ,其中參數(shù)request填入類型PTRACE_ATTACH則說明是附加操作。具體實(shí)現(xiàn)如下:
long err = ptrace(PTRACE_ATTACH, ppid, NULL, NULL);
其中參數(shù)request填入的是PTRACE_ATTACH則說明是附加操作,參數(shù)ppid則是步驟S102中獲取到的父進(jìn)程的ID,指明附加到哪個進(jìn)程。
通過步驟S103則可以讓子進(jìn)程來調(diào)試父進(jìn)程,但是這個調(diào)試并不是真正的調(diào)試,而只是附加到父進(jìn)程,這樣可以防止其他進(jìn)程來附加父進(jìn)程,可以起到“占坑”的目的,同時最重要的是子進(jìn)程需要處理好父進(jìn)程的暫停信號,避免父進(jìn)程崩潰,所以下面需要處理暫停信號。
4)步驟S104:子進(jìn)程等待反調(diào)試的進(jìn)程的消息,并對消息進(jìn)行處理;
子進(jìn)程需要處理好父進(jìn)程的信號,從而避免父進(jìn)程進(jìn)入group-stop狀態(tài),從而避免程序崩潰異常。
程序總共有4種信號SIGSTOP(停止進(jìn)程的執(zhí)行信號)、SIGTSTP(停止進(jìn)程的運(yùn)行信號)、SIGTTIN(當(dāng)后臺作業(yè)要從用戶終端讀數(shù)據(jù)時的信號)、SIGTTOU(在寫終端或修改終端模式時收到的信號)會導(dǎo)致進(jìn)程陷入到group-stop狀態(tài)。所以需要處理好這4種信號。
通過調(diào)用系統(tǒng)函數(shù)WSTOPSIG()來獲取父進(jìn)程暫停的信號。調(diào)用WSTOPSIG(status)來從status變量中獲取到父進(jìn)程的暫停信號,其中status是一個變量存放信號值,判斷status的值是不是上述的4個信號值,即SIGSTOP、SIGTSTP、SIGTTIN、SIGTTOU這4種,判斷stauts的值是否等于上述4個信號值中的任意一個,如果不是,則可以忽略,如果是,則需要設(shè)置父進(jìn)程丟掉此信號,不需要進(jìn)行處理。其中,丟掉此信號的操作是通過調(diào)用系統(tǒng)函數(shù)ptrace()來實(shí)現(xiàn)的。具體實(shí)現(xiàn)如下:
ptrace(PTRACE_CONT, ppid, 0, 0);
其中,參數(shù)PTRACE_CONT指示父進(jìn)程繼續(xù)執(zhí)行系統(tǒng)調(diào)用過程,參數(shù)ppid是父進(jìn)程的進(jìn)程ID值,參數(shù)0指示父進(jìn)程忽略引起的暫停信號,丟棄這個信號不進(jìn)行處理。
通過對這個暫停信號的處理,就處理了父進(jìn)程被子進(jìn)程調(diào)試會出現(xiàn)程序崩潰的情況,所以把最關(guān)鍵的一步處理好了,那么父進(jìn)程和子進(jìn)程就可以一直存在,并且不會產(chǎn)生異常。同時由于父進(jìn)程被子進(jìn)程調(diào)試了,所以其他的Hack想調(diào)試這個進(jìn)程則已經(jīng)是不可能的了(Android系統(tǒng)的一個進(jìn)程只允許一個進(jìn)程調(diào)試)。
該反調(diào)試系統(tǒng)的功能模塊示意圖如圖2所示,該反調(diào)試系統(tǒng)包括設(shè)置模塊201、創(chuàng)建模塊202、調(diào)試模塊203以及處理模塊204。其中,設(shè)置模塊,用于將反調(diào)試的進(jìn)程設(shè)置為調(diào)試狀態(tài);創(chuàng)建模塊,用于在反調(diào)試的進(jìn)程中創(chuàng)建子進(jìn)程;調(diào)試模塊,用于所創(chuàng)建的子進(jìn)程對反調(diào)試的進(jìn)程進(jìn)行調(diào)試;處理模塊,用于子進(jìn)程等待反調(diào)試的進(jìn)程的消息,并對消息進(jìn)行處理。
設(shè)置模塊中具體包括:調(diào)用單元,用于通過調(diào)用Android系統(tǒng)接口函數(shù)prctl(option,arg2,arg3,arg4,arg5)來設(shè)置當(dāng)前進(jìn)程可以被調(diào)試,其中參數(shù)option是PR_SET_DUMPABLE,參數(shù)arg2的值是1。創(chuàng)建模塊中具體包括:建立單元,用于通過調(diào)用系統(tǒng)函數(shù)fork來完成新進(jìn)程的創(chuàng)建。
本領(lǐng)域內(nèi)的技術(shù)人員應(yīng)明白,本發(fā)明的實(shí)施例可提供為方法、系統(tǒng)、或計算機(jī)程序產(chǎn)品。因此,本發(fā)明可采用完全硬件實(shí)施例、完全軟件實(shí)施例、或結(jié)合軟件和硬件方面的實(shí)施例的形式。而且,本發(fā)明可采用在一個或多個其中包含有計算機(jī)可用程序代碼的計算機(jī)可用存儲介質(zhì)(包括但不限于磁盤存儲器、CD-ROM、光學(xué)存儲器等)上實(shí)施的計算機(jī)程序產(chǎn)品的形式。
本發(fā)明是參照根據(jù)本發(fā)明實(shí)施例的方法、設(shè)備(系統(tǒng))、和計算機(jī)程序產(chǎn)品的流程圖和/或方框圖來描述的。應(yīng)理解可由計算機(jī)程序指令實(shí)現(xiàn)流程圖和/或方框圖中的每一流程和/或方框、以及流程圖和/或方框圖中的流程和/或方框的結(jié)合??商峁┻@些計算機(jī)程序指令到通用計算機(jī)、專用計算機(jī)、嵌入式處理機(jī)或其他可編程數(shù)據(jù)處理設(shè)備的處理器以產(chǎn)生一個機(jī)器,使得通過計算機(jī)或其他可編程數(shù)據(jù)處理設(shè)備的處理器執(zhí)行的指令產(chǎn)生用于實(shí)現(xiàn)在流程圖一個流程或多個流程和/或方框圖一個方框或多個方框中指定的功能的裝置。
這些計算機(jī)程序指令也可存儲在能引導(dǎo)計算機(jī)或其他可編程數(shù)據(jù)處理設(shè)備以特定方式工作的計算機(jī)可讀存儲器中,使得存儲在該計算機(jī)可讀存儲器中的指令產(chǎn)生包括指令裝置的制造品,該指令裝置實(shí)現(xiàn)在流程圖一個流程或多個流程和/或方框圖一個方框或多個方框中指定的功能。
這些計算機(jī)程序指令也可裝載到計算機(jī)或其他可編程數(shù)據(jù)處理設(shè)備上,使得在計算機(jī)或其他可編程設(shè)備上執(zhí)行一系列操作步驟以產(chǎn)生計算機(jī)實(shí)現(xiàn)的處理,從而在計算機(jī)或其他可編程設(shè)備上執(zhí)行的指令提供用于實(shí)現(xiàn)在流程圖一個流程或多個流程和/或方框圖一個方框或多個方框中指定的功能的步驟。
顯然,本領(lǐng)域的技術(shù)人員可以對本發(fā)明進(jìn)行各種改動和變型而不脫離本發(fā)明的精神和范圍。這樣,倘若本發(fā)明的這些修改和變型屬于本發(fā)明權(quán)利要求及其等同技術(shù)的范圍之內(nèi),則本發(fā)明也意圖包含這些改動和變型在內(nèi)。