本發(fā)明涉及軟件代碼保護技術領域,具體地說是一種基于單表代替密碼與Playfair密碼的虛擬機操作碼替換與合并的Python腳本程序防逆轉方法。
背景技術:
Python腳本程序是使用Python腳本語言開發(fā)的應用程序。使用python腳本語言開發(fā)的應用程序(app.py)首先要通過Python腳本編譯器將其編譯為具有特定結構的字節(jié)碼文件(app.pyc),讓后將字節(jié)碼文件(app.pyc)發(fā)布給客戶運行。
使用Python腳本語言開發(fā)的應用編譯生成的字節(jié)碼(.pyc)文件,不是針對特定處理器和系統(tǒng)的二進制文件,而是針對Python虛擬機(Python Virtual Machine)的具有特定的結構和特征的文件,其保留了Python源碼文件中的全部信息。
而目前使用Python腳本語言開發(fā)的應用程序容易被攻擊者反編譯為源碼文件,對開發(fā)者和用戶造成損失,這些都字節(jié)碼文件的組織格式有關。字節(jié)碼文件中最重要的一個屬性域就是操作碼序列,其中包含了對程序執(zhí)行邏輯的控制,和對程序中各個參數(shù)的執(zhí)行的操作等信息,因此對操作碼序列的保護顯得尤為重要。
技術實現(xiàn)要素:
本發(fā)明是為了克服現(xiàn)有Python程序防逆轉技術存在的不足之處,提供一種基于操作碼替換與合并的Python腳本程序防逆轉方法,以期能為字節(jié)碼文件提供安全性高的保護措施,并提升Python應用程序的運行效率。
本發(fā)明為達到上述發(fā)明目的,采用如下技術方案:
本發(fā)明一種基于操作碼替換與合并的Python腳本程序防逆轉方法,是應用于Python源碼文件中,所述Python源碼文件中包含opcode.h文件、peephole.c文件和ceval.c文件:所述操作碼為所述opcode.h文件中的n個自然數(shù);所述n個自然數(shù)分別對應于n個虛擬機操作;
定義所述n個虛擬機操作的集合為:OP={op1,op2,…,opi,…,opn},opi表示第i個虛擬機操作;
定義所述n個操作碼的集合為CODE={code1,code2,…,codei,…,coden},codei表示第i個操作碼,且第i個虛擬機操作opi對應于第i個操作碼codei;所述n個操作碼分為帶參數(shù)的操作碼和不帶參數(shù)的操作碼,假設所有不帶參數(shù)的操作碼為前a個操作碼,即{code1,code2,…,codea};所有帶參數(shù)的操作碼為剩余n-a個操作碼,即{codea+1,codea+2,…,coden},1≤i≤n;
定義操作碼序列S是一串由m個操作碼和k個參數(shù)組成的序列;
定義基本塊為所述操作碼序列S中若干個順序執(zhí)行的操作碼所構成的子序列;
定義所述操作碼序列S的基本塊信息BS是一個長度為m的序列;所述基本塊信息BS中的每個元素與所述操作碼序列S中的m個操作碼一一對應,所述基本塊信息BS中的每個元素值為其對應的操作碼在所述操作碼序列S中的基本塊序號;其特點是,所述Python腳本程序防逆轉方法是按如下步驟進行:
步驟1、替換操作;
步驟1.1、在所述前a個操作碼{code1,code2,…,codea}中去除和“SLICE”相關的操作碼后,將剩余的操作碼的順序進行隨機交換,得到所有不帶參數(shù)的操作碼的新子集sub1;
步驟1.2、在所述剩余n-a個帶參數(shù)的操作碼{codea+1,codea+2,…,coden}中去除和“FUNCTION”相關的操作碼后,將剩余的操作碼的順序進行隨機交換,得到所有帶參數(shù)的操作碼的新子集sub2;
步驟1.3、由所有不帶參數(shù)的操作碼的新子集sub1和所有帶參數(shù)的操作碼的新子集sub2構成操作碼替換的集合,記為CODE′={code′1,code′2,…,code′i,…,code′n},code′i表示第i個操作的替換碼,所述操作碼替換的集合CODE′中至少存在一個元素不屬于所述n個操作碼的集合CODE;
步驟1.4、在所述opcode.h文件中利用所述操作碼替換的集合CODE′替換所述n個操作碼的集合CODE;
步驟2、合并操作
步驟2.1、從字節(jié)碼文件中提取所述操作碼序列S和基本塊信息BS并進行分析,得到操作碼對在所述字節(jié)碼文件中出現(xiàn)頻率的降序排序;
步驟2.2、選取排序為前W個的操作碼對,將前W個的操作碼對中每一個操作碼對(codei,codej)進行合,形成一個新的操作碼codei+j;1≤i≠j≤n;
步驟2.2.1、在所述opcode.h文件添加所述前W個的操作碼對的定義和語義信息;
步驟2.2.2、在所述peephole.c文件中添加對所述前W個的操作碼的合并過程;
步驟2.2.3、在所述ceval.c文件中添加對所述前W個的操作碼的解釋過程;
步驟3、利用gcc重新編譯經上述步驟1-步驟2形成的新的Python源碼文件,生成新的Python腳本運行環(huán)境new_python,作為Python腳本程序的防逆轉環(huán)境。
與已有技術相比,本發(fā)明有益效果體現(xiàn)在:
1、一種基于單表代替密碼的虛擬機操作碼替換的Python腳本程序防逆轉方法,在不影響Python應用的運行結果的前提下,使用新的操作碼CODE′對來的操作的語義信息進行隱藏,防止他人進行反編譯,為Python腳本程序提供較強的安全保障。
2、本發(fā)明提出的Python應用程序防逆轉方法,將同在一個基本塊中的操作碼序列進行合并,使得用一個新操作碼就可以蘊含原來多個操作碼的語義信息,不但對操作碼序列中的語義信息進行了隱藏,而且有效減少了操作碼序中操作碼的個數(shù),從而縮短了操作碼序列的長度,改變了操作碼序列的內容和結構,大大增加了字節(jié)碼文件的安全性,并且使得Python應用程序執(zhí)行效率增加了%5左右、應用大小減少了1.5%左右。
附圖說明
圖1為本發(fā)明操作碼替換示意圖;
圖2為本發(fā)明操作碼序列經操作碼替換前后示意圖;
圖3為本發(fā)明操作碼合并過程示意圖;
圖4為本發(fā)明操作碼序列經操作碼合并前后示意圖;
圖5為本發(fā)明操作碼序列經操作碼替換與合并前后示意圖。
具體實施方式
下面結合附圖通過具體實施例對本發(fā)明基于單表代替密碼和Playfair密碼的虛擬機操作碼替換與合并的Python腳本程序防逆轉方法做進一步的詳細說明。
本實施例中,一種基于操作碼替換與合并的Python腳本程序防逆轉方法,是應用于Python源碼文件中,這些Python源碼文件中包含操作碼映射opcode.h文件、窺孔優(yōu)化peephole.c文件和虛擬機ceval.c文件;操作碼為opcode.h文件中定義的n個自然數(shù);這n個自然數(shù)分別對應于ceval.c文件中涉及到的n個虛擬機操作;
定義n個虛擬機操作的集合為:OP={op1,op2,…,opi,…,opn},opi表示第i個虛擬機操作,為LOAD_CONST、STORE_NAME等具有特定語義信息的操作;
定義n個操作碼的集合為CODE={code1,code2,…,codei,…,coden},codei表示第i個操作碼,且第i個虛擬機操作opi對應于第i個操作碼codei;1≤i≤n;n個操作碼分為帶參數(shù)的操作碼和不帶參數(shù)的操作碼,假設所有不帶參數(shù)的操作碼為前a個操作碼,即{code1,code2,…,codea};所有帶參數(shù)的操作碼為剩余n-a個操作碼,即{codea+1,codea+2,…,coden},具體的說,在Python-2.7.9中,如果codei<90,則codei為不帶參數(shù)的操作碼,如果90≤codei≤147,則codei為帶參數(shù)的操作碼,1≤i≤n;
定義第i個虛擬機操作opi到第i個操作碼codei的映射關系為:map(opi)=codei;
定義操作碼序列S是一串由m個操作碼和k個參數(shù)組成的一個型如下面所示的序列;
其中為的兩個參數(shù),可以為空,1≤j≤m;
定義基本塊為操作碼序列S中若干個順序執(zhí)行的操作碼所構成的子序列,即由JUMP_FORWARD、CONTINUE_LOOP等跳轉、循環(huán)控制操作碼鏈接的操做不屬于同一基本塊中;
定義操作碼序列S的基本塊信息BS是一個形如下面所示的長度為m的序列;基本塊信息BS中的每個元素valj與在操作碼序列S中的m個操作碼一一對應,基本塊信息BS中的每個元素valj的值為其對應的操作碼在操作碼序列S中的基本塊的序號;
BS=[val1,val2,...,valj,...,valm]
本實施例中的Python腳本程序防逆轉方法是按如下步驟進行:
步驟1、替換操作;
步驟1.1、在前a個操作碼{code1,code2,…,codea}中去除和“SLICE”相關的操作碼后,具體有SLICE、STORE_SLICE、DELETE_SLICE對應的操作碼值,將剩余的操作碼的順序進行隨機交換,得到所有不帶參數(shù)的操作碼的新子集sub1;
步驟1.2、在剩余n-a個帶參數(shù)的操作碼{codea+1,codea+2,…,coden}中去除和“FUNCTION”相關的操作碼后,具體有CALL_FUNCTION、MAKE_FUNCTION、CALL_FUNCTION_VAR、CALL_FUNCTION_KW、CALL_FUNCTION_VAR_KW對應的操作碼值,將剩余的操作碼的順序進行隨機交換,得到所有帶參數(shù)的操作碼的新子集sub2;
步驟1.3、由所有不帶參數(shù)的操作碼的新子集sub1和所有帶參數(shù)的操作碼的新子集sub2構成操作碼替換的集合,記為CODE′={code1′,code′2,…,code′i,…,code′n},codei′表示第i個操作的替換碼,操作碼替換的集合CODE′中至少存在一個元素不屬于n個操作碼的集合CODE;
步驟1.4、如圖1所示,在opcode.h文件中利用操作碼替換的集合CODE′替換操作碼的集合CODE,即可完成圖2所示的S到S'的轉換;
步驟2、合并操作
步驟2.1、按圖3所示的流程,從大量的字節(jié)碼文件中提取操作碼序列S和基本塊信息BS并進行分析,尋找BS中能使valr=valr+1的r,能使vals=vals+1的s…,即尋找S中可以合并的操作碼對(opr,opr+1),(ops,ops+1)…,并按這些(opr,opr+1),(ops,ops+1)…出現(xiàn)的頻率進行降序排序,得到操作碼對在字節(jié)碼文件中出現(xiàn)頻率的降序排序;
步驟2.2、選取排序為前W個的操作碼對,將前W個的操作碼對中任意每一個操作碼對(codei,codej)進行合,形成一個新的操作碼codei+j,如圖4所示,從而完成將操作碼序列S到S″的轉換,1≤i≠j≤n;
步驟2.2.1、在opcode.h文件添加前W個的操作碼對的定義和語義信息;
步驟2.2.2、在peephole.c文件中添加對前W個的操作碼的合并過程;
步驟2.2.3、在ceval.c文件中添加對前W個的操作碼的解釋過程;
步驟3、利用gcc重新編譯經上述步驟1-步驟2形成的新的Python源碼文件,生成新的Python腳本運行環(huán)境new_python,作為Python腳本程序的防逆轉環(huán)境,防逆轉環(huán)境new_python編譯腳本文件(app.py),最終生成包含如圖5中S″'所示的操作碼序列的字節(jié)碼文件(app.pyc),字節(jié)碼文件(app.pyc)能夠被new_python正確解釋執(zhí)行,且現(xiàn)有的反編譯工具不能反編譯出字節(jié)碼文件(app.pyc)中的源代碼的。