本發明涉及軟件版權保護技術,特別涉及一種增強軟件保護易用性的方法。
背景技術:軟件作為一種特殊的產品,由于其純數字化的特征,從問世起就一直遭受盜版的困擾。盜版的存在不僅給軟件開發者造成了巨大的損失,也極大阻礙了整個軟件行業的發展。因此,幾乎所有的軟件都采取了相應的技術措施來避免軟件遭受破解和盜版,其中最為有效的就是基于硬件的軟件保護裝置。現有的軟件保護方法中涉及到軟件保護裝置,也稱為軟件加密鎖或者軟件加密狗,其中涉及到安全處理芯片、內部控制電路、存儲電路等硬件結構。軟件保護裝置是一種通過計算機接口(包括但不限于并口或者USB接口)連接到計算機主機上的硬件設備。該設備內部具有非易失性存儲空間可供讀寫,通常還具有單片機或者微處理控制芯片等計算處理單元。軟件開發者可以通過接口函數和軟件保護裝置進行數據交換(即對軟件保護裝置進行讀寫),來檢查軟件保護裝置是否插在接口上;或者直接用軟件保護裝置附帶的工具進行加密。這樣,軟件開發者可以在軟件中設置多處軟件鎖,利用軟件保護裝置作為鑰匙來打開這些鎖;如果沒插軟件保護裝置或軟件保護裝置不對應,軟件將不能正常執行。此外,軟件保護裝置內部包含特定的功能,例如一部分存儲空間、一些密碼算法或者一些用戶自定義的算法或者功能。在軟件發行之前,軟件開發者修改自己的軟件代碼,使得軟件在運行過程中需要使用到軟件保護裝置內部的一些功能,這樣軟件離開軟件保護裝置之后就會無法運行,而軟件保護裝置作為一種硬件設備復制的難度較大,從而起到防止盜版軟件非法傳播的作用。當前市場上主要的軟件保護裝置包括:美國SafeNet公司的SentinelSuperpro、以色列Aladdin公司的HaspHL、中國北京深思洛克軟件股份有限公司的精銳系列、德國Wi-Bu公司的WIBU-Key等。所有這些軟件保護裝置都提供了內置的存儲空間、私有或公開的密碼算法,當軟件運行過程中可以調用這些功能來檢驗是否屬于正版。這些軟件保護裝置采用了智能卡芯片作為硬件的基礎,而且支持用戶將自己定義的功能寫入到軟件保護裝置內部,甚至可以直接將軟件的部分功能移植到軟件保護裝置內部完成,從而大大提高了軟件被盜版的難度,通常稱這種將自己定義的功能或者軟件的部分功能移植到軟件保護裝置內部的技術為代碼移植。本發明人現在對應網站為http://www.sense.com.cn/,其中詳細公開了本發明人開發的軟件保護裝置的具體參數性能和工作原理。現有的通過軟件保護裝置進行軟件保護的一種有效的方法是“代碼移植”:將軟件中部分代碼經過編譯,移植到加密鎖硬件內部,使得主機端中的軟件中沒有該段代碼的副本。該方法中,將待保護的應用軟件的關鍵代碼和數據都移植到加密鎖的硬件中保護起來。在主機端中的需要使用該應用軟件時,應用軟件可以向加密鎖發送指令使其運行關鍵代碼并接收返回結果,從而可以完成整個軟件的全部功能。由于這些代碼和數據在PC主機端中的是不存在的,因此解密者無從猜測算法或竊取數據,從而極大程度的保證了整個軟件系統的安全性。這種加密鎖的使用較為繁瑣,要求程序員針對被保護代碼專門編制程序,一方面要編寫加密鎖程序,該加密鎖程序在加密鎖中運行,一方面要編寫調用加密鎖的程序,該調用加密鎖的程序是應用軟件的一部分,通過與加密鎖的通信,命令加密鎖執行加密鎖程序并返回結果。當前沒有一種簡單易行的方法和工具來簡化這些工作。
技術實現要素:有鑒于此,本發明提供了一種提高加密鎖軟件保護方式的易用性的方法及系統,根據置于加密鎖中運行的程序的源代碼中的函數(下稱其為目標函數)格式,構造應用軟件編譯環境下的源文件;構造加密鎖軟件編譯環境下的源文件,包括:1.分析源程序函數聲明格式;2.構造應用軟件編譯環境(本發明所指編譯應用軟件所需的環境,包括但不限于的VisualStudio集成開發工具)下的源文件;3.構造加密鎖軟件編譯環境(指編譯成加密鎖內運行的程序所需的環境,如北京深思洛克軟件股份有限公司的精銳系列加密鎖需要在KeilC下將源文件編譯為8051系列單片機的可執行程序,其內容參見http://www.sense.com.cn/product_1.html,以及該公司在先申請并已經公開的多項專利文獻,其內容均引入本發明的說明書中,不再贅述)下的源文件。KeilC的具體內容參見http://www.keil.com/其中,構造應用軟件編譯環境下的源文件可進一步包括:1)添加頭文件;2)構造目標函數,進一步包括:a)構造目標函數聲明;b)構造變量聲明及初始化;c)構造輸入參數處理程序,其功能是將目標函數的輸入參數處理為連續存儲的數據流;d)構造向加密鎖發送指令和數據的程序,其功能是將輸入數據發送給加密鎖,并接收加密鎖返回的數據;e)構造輸出參數處理的程序,其功能是將加密鎖返回的數據賦給目標函數的輸出參數;其中,構造加密鎖軟件編譯環境下的源文件可進一步包括:1)添加頭文件;2)構造目標函數聲明;3)構造主函數;a)構造變量聲明及初始化;b)構造輸入參數處理程序,其功能是將輸入數據(連續存儲的數據流)轉換為目標函數所需的參數;c)構造調用目標函數的程序;d)構造向主機發送數據的程序,其功能是將輸出參數送回主機。與現有技術相比,本發明具有以下有益效果:本方法生成軟件開發環境和加密鎖程序編譯環境下的源文件,用戶無需關心保護程序后加密鎖相關的種種細節(包括參數處理、加密鎖API、與加密鎖的通信等),只需要加密鎖程序編譯環境下的核心代碼,可以用使用函數的方法直接調用被保護代碼,即用戶調用一個被保護的函數時和調用未被保護的函數或類方法相同,無需做額外處理,增強加密鎖保護方法的易用性。附圖說明圖1為本發明方法的過程示意圖。圖2為應用軟件編譯環境下構造目標函數的示意圖。圖3為加密鎖軟件編譯環境下構造主函數的示意圖。具體實施方式下面結合附圖對本發明的實施例進行詳細說明。以一個簡單的C++語言應用程序為例,其主程序代碼如示例代碼1所示。示例代碼1,應用程序主程序:#include<stdlib.h>#include<stdio.h>//對數字進行排序voidsort(unsignedchar*p,intlen);voidmain(){unsignedchartest[]={4,3,8,2,9,7,1,5,0,6};intlen=sizeof(test);inti;sort(test,len);printf("result:\n");for(i=0;i<len;i++){printf("%d",test[i]);}system("pause");}該主程序的作用是對一個數組進行排序,其核心算法sort函數可作為被保護函數放入加密鎖執行。sort函數代碼如示例代碼2所示。示例代碼2,核心算法sort函數://對數字進行排序voidsort(unsignedchar*p,intlen){inti,j;unsignedchartmp;for(i=0;i<len-1;i++){for(j=0;j<len-i-1;j++){if(p[j]<p[j+1]){tmp=p[j];p[j]=p[j+1];p[j+1]=tmp;}}}}其中,所述實例的軟件運行環境為32位x86平臺,操作系統為32位windowsxp。當然,這里的運行環境和操作系統僅僅是示例。本領域的技術人員完全能夠理解在不進行創造性的勞動的情況下,將這些實例改寫以適應于其它運行環境和操作系統,無需再在本發明中贅述。C/C++語言中,指針參數與數據長度參數只存在邏輯上的關系,而不能自動識別指針的長度由哪個參數指定,對于指針參數,應做特殊處理。故而定義了一個Pointer的數據結構,目標函數的參數凡是指針類型,都需用該類型替代,指針之外的其他類型則無需特殊處理。Pointer結構及其相關函數如示例代碼3所示。示例代碼3,Pointer結構定義:typedefintvint;typedefstruct_Pointer{char*pointer;//數據指針vintused;//指針已使用的大小vintsize;//指針最大長度vintmalloc;//是否為malloc分配的指針vintelementsize;//數據元素的大小}Pointer;其中,char*pointer表示數據指針,vintused定義指針已使用的大小,vintsize定義指針最大長度,vintmalloc定義是否為malloc分配的指針,vintelementsize定義數據元素的大小。Sort函數的參數包含指針,因此應稍加改進,用Pointer代替指針。改后代碼如示例代碼4所示。示例代碼4,改進后的sort函數://對數字進行排序voidsort(Pointer*pp){inti,j;unsignedchar*p=pp->pointer;vintlen=pp->used;unsignedchartmp;for(i=0;i<len-1;i++){for(j=0;j<len-i-1;j++){if(p[j]<p[j+1]){tmp=p[j];p[j]=p[j+1];p[j+1]=tmp;}}}}此外,根據本發明的一個實施例,本發明所提供的方法包括如下步驟及示例代碼:1.分析源程序函數聲明格式。如示例代碼6所示,用VmFuntion表示函數,其成員包括函數名(即stringname),返回值類型(即stringret)和各參數的類型(即vector<VmVar>pars),其它成員與函數格式無關,將在下文說明。由于分析源程序函數聲明格式為基于編譯原理的技術常識,本說明書不再贅述其實現方式。示例代碼6,VmFunction類定義:classVmFuntion{public:stringGetHostCode();stringGetGuestCode();public:stringname;//函數名stringret;//返回值類型vector<VmVar>pars;//函數參數private:voidinit();voidaddInitCode();voidaddDestroyCode();voiddeclare(conststring&type,conststring&name,constchar*init="");voidpushTo(constchar*bufname);voidgetFrom(constchar*bufname);stringfuncDelare();stringfuncCall();stringaddHostBody();stringmainFuncDelare();voidaddGuestBody();private:stringcode;vector<string>vartypes;vector<string>varnames;vector<string>varvalues;};2.構造應用軟件編譯環境下的源文件,下述示例代碼7中的VmFunction::GetHostCode函數的返回值即為計算后得出的源文件的內容。本步驟示例代碼如示例代碼7所示。示例代碼7,應用軟件編譯環境下的代碼的構造方法:classTypeService{typedefmap<string,VmType>TypeMap;TypeMaptypemap;public:TypeService(){makeTypeMap("");}//解析源文件,構造類型表voidmakeTypeMap(stringfilename);voidpush(constVmType&type){typemap[type.name]=type;}//根據名字查找類型VmTypefind(conststring&name);//根據變量名和類型構造輸入參數處理代碼stringmakePushCode(constchar*bufname,conststring&_typename,conststring&varname);//根據變量名和類型構造輸出參數處理代碼stringmakePullCode(constchar*bufname,conststring&_typename,conststring&varname);};externTypeServicetypemap;//構造主機(應用軟件編譯環境)下的源代碼stringVmFuntion::GetHostCode(){init();code+="#include\"LibHostPointer.h\"\n\n";code+=funcDelare()+"\n{\n";addHostBody();code+="}\n";returncode;}//構造從機(加密鎖軟件編譯環境)下的源代碼stringVmFuntion::GetGuestCode(){init();code+="#include\"ses_v3.h\"\n\n""#include\"VmPointer.h\"\n\n""#include<stdlib.h>\n\n"+funcDelare()+";\n\n""voidmain()\n""{\n";addGuestBody();code+="}\n";returncode;}//初始化各成員變量voidVmFuntion::init(){code="";varnames.clear();varvalues.clear();vartypes.clear();}//在成員變量code中添加目標函數的聲明stringVmFuntion::funcDelare(){stringcode;code+=ret;//voidcode+="";//''code+=name;//namecode+="(";//(for(inti=0;i<(int)pars.size();++i){if(i>0){code+=",";}constVmVar&var=pars[i];code+=var.type;code+="";code+=var.name;}code+=")";returncode;}//在成員變量code中添加主機(應用軟件編譯環境)下的目標函數的函數體;函數體中定義一個Pointer類型的數據,將目標函數的各參數按順序寫入其中,并通過LibHostCall調用加密鎖,將加密鎖傳回得數據解析并寫入到目標函數的各參數和返回值。stringVmFuntion::addHostBody(){declare("Pointer","buf","mallocPointer(1,0)");declare("vint","ret","0");//聲明offset,用于從流數據中提取數據declare("vint","offset","0");//聲明的變量初始化addInitCode();pushTo("buf");code+="
ret=LibHostCall(&buf);\n";code+="\n
//重新初始化Pointer類型參數\n";for(inti=0;i<(int)pars.size();++i){if(pars[i].type=="Pointer"){code+="
"+pars[i].name+".used=0;\n";}elseif(pars[i].type=="Pointer*"){code+="
"+pars[i].name+"->used=0;\n";}}getFrom("buf");returncode;}//生成一段聲明變量的源代碼,并存儲初始化該變量的初始化字符串,以備在所有變量聲明后生成初始化這些變量的源代碼voidVmFuntion::declare(conststring&type,conststring&name,constchar*init){code+="
"+type+""+name+";\n";vartypes.push_back(type);varnames.push_back(name);varvalues.push_back(init);}//生成初始化變量的源代碼voidVmFuntion::addInitCode(){for(inti=0;i<(int)varnames.size();++i){if(varvalues[i].length()>0){code+="
"+varnames[i]+"="+varvalues[i]+";\n";}}}//生成將目標函數各參數依次寫入到存儲變量的源代碼,bufname為存儲變量的變量名voidVmFuntion::pushTo(constchar*bufname){stringstr;for(inti=0;i<(int)pars.size();++i){constVmVar&var=pars[i];str=typemap.makePushCode(bufname,var.type,var.name);if(str.size()>0){code+="\n";code+=str;}else{//return"";}}if(ret!="void"){code+=typemap.makePushCode(bufname,ret,"ret");}}//生成調用目標函數的源代碼stringVmFuntion::funcCall(){stringcode;charstr[len];//調用函數if(ret!="void"){sprintf_s(str,len,"
ret=%s(",name.c_str());code+=str;}else{code+="
";code+=name;code+="(";}for(inti=0;i<(int)pars.size();++i){constVmVar&var=pars[i];if(i>0){code+=",";}code+=var.name;}code+=");\n";returncode;}//生成從存儲變量依次讀取目標函數各參數的源代碼,bufname為存儲變量的變量名voidVmFuntion::getFrom(constchar*bufname){stringstr;for(inti=0;i<(int)pars.size();++i){constVmVar&var=pars[i];str=typemap.makePullCode(bufname,var.type,var.name);if(str.size()>0){code+="\n";code+=str;}else{//return"";}}if(ret!="void"){code+=typemap.makePullCode(bufname,ret,"ret");}}//生成釋放內存的源代碼,并清理VmFuntion::declare存儲的初始化變量voidVmFuntion::addDestroyCode(){for(inti=0;i<(int)varnames.size();++i){if(vartypes[i]=="Pointer"||vartypes[i]=="Pointer*"){code+="
destroyPointer(&"+varnames[i]+");\n";}else{code+="
destroyPointer("+varnames[i]+");\n";}}varvalues.clear();varnames.clear();vartypes.clear();}本步驟包括以下子步驟:1)添加頭文件,示例代碼8中為LibPointer.h,包括連續數據保存結構Pointer、將數據寫入Pointer的函數(示例代碼中為pushBackData、pushBackPointer、pushBackString)、從Pointer讀取數據的函數、加密鎖API調用函數(LibHostCall)。各函數可以源文件或以庫的形式加入到應用軟件。"LibPointer.h"頭文件內容如示例代碼8所示。示例代碼8,"LibPointer.h"頭文件:#if!defined_LIB_HOST_POINTER_H_#define_LIB_HOST_POINTER_H_#ifdef__cplusplusextern"C"{#endif#ifdefWIN32typedefshortvint;staticconstchar*pointerTypeString="Pointer";#elsetypedefintvint;#endiftypedefstruct_Pointer{char*pointer;//數據指針vintused;//指針已使用的大小vintsize;//指針最大長度vintmalloc;//是否為malloc分配的指針vintelementsize;//數據元素的大小}Pointer;//構造Pointer結構,并為count個size大小的變量動態分配內存PointermallocPointer(vintsize,vintcount);//構造Pointer結構,并將指針、數據大小和數量參數賦給pointer、size和count成員PointerconstPointer(void*vpointer,vintsize,vintcount);//復制Pointer結構PointercopyPointer(Pointerp);//調整內存大小Pointer*resizePointer(Pointer*p,vintcount);//將vpointer指向的size長度的數據復制到pPointer*pushBackData(Pointer*p,constvoid*vpointer,vintsize);//將src包含的數據復制到pPointer*pushBackPointer(Pointer*p,constPointer*src);//從p中指針加上offset的位置開始,將大小為size的數據復制到vpointerPointer*getData(Pointer*p,vint*offset,void*vpointer,vintsize);//從p中指針加上offset的位置開始,將大小為src->size的數據復制到srcPointer*getPointer(Pointer*p,vint*offset,Pointer*dst);//從p中指針加上offset的位置開始,將大小為size的數據復制到srcPointer*getString(Pointer*p,vint*offset,char*str);//將p保存的數據釋放掉,并將各成員置為零voiddestroyPointer(Pointer*p);#ifdefWIN32intLibHostCall(Pointer*p);voidprintPointer(Pointer*p);#endif#ifdef__cplusplus}//endofextern"C"{#endif#endif示例代碼9,LibHostCall函數實現:#include"stdafx.h"#include"stdlib.h"#include"stdio.h"#include"LibPointer.h"#include"sense4.h"#defineFAIL1#defineSECCEED0intLibHostConnectLock(SENSE4_CONTEXT*pctx,char*fid,Pointer*p);intLibHostExecute(SENSE4_CONTEXT*pctx,char*fid,Pointer*p);//連接加密鎖,將參數p指向的數據傳給加密鎖,命令加密鎖執行程序intLibHostCall(Pointer*p){char*fid="0001";SENSE4_CONTEXTctx={0};intret;ret=LibHostConnectLock(&ctx,fid,p);if(ret!=S4_SUCCESS){returnret;}ret=LibHostExecute(&ctx,fid,p);if(ret!=S4_SUCCESS){returnret;}S4Close(&ctx);returnS4_SUCCESS;}//調用加密鎖API,完成與加密鎖的連接intLibHostConnectLock(SENSE4_CONTEXT*pctx,char*fid,Pointer*p){SENSE4_CONTEXT*pctxEnum=NULL;unsignedlongsize=0;unsignedlongret=0;S4Enum(pctxEnum,&size);if(size==0){printf("EliteIVnotfound!\n");returnFAIL;}pctxEnum=(SENSE4_CONTEXT*)malloc(size);if(pctxEnum==NULL){printf("Notenoughmemory!\n");returnFAIL;}ret=S4Enum(pctxEnum,&size);if(ret!=S4_SUCCESS){printf("EnumerateEliteIVerror!\n");free(pctxEnum);returnFAIL;}memcpy(pctx,pctxEnum,sizeof(SENSE4_CONTEXT));free(pctxEnum);pctxEnum=NULL;ret=S4Open(pctx);if(ret!=S4_SUCCESS){printf("OpenEliteIVfailed!\n");returnFAIL;}ret=S4ChangeDir(pctx,"\\");if(ret!=S4_SUCCESS){printf("Norootdirectoryfound!\n");S4Close(pctx);returnFAIL;}ret=S4VerifyPin(pctx,(BYTE*)"12345678",8,S4_USER_PIN);if(ret!=S4_SUCCESS){printf("VerifyuserPINfailed!\n");S4Close(pctx);returnFAIL;}returnS4_SUCCESS;}//向加密鎖發送數據(參數p),令加密鎖執行指定的程序intLibHostExecute(SENSE4_CONTEXT*pctx,char*fid,Pointer*p){DWORDsize;intret=S4Execute(pctx,fid,p->pointer,p->used,p->pointer,p->size,&size);if(ret!=S4_SUCCESS){printf("ExecuteEliteIVexefailed!\n");S4Close(pctx);returnFAIL;}returnS4_SUCCESS;}示例代碼10,Pointer相關函數實現:#include<stdlib.h>#include<stdio.h>#include<string.h>#include<assert.h>#include"LibPointer.h"http://以字節為單位,顛倒數據的順序,解決應用軟件和加密鎖軟件字節序不同的問題voidSwapByteOrderRef(void*pp,vintsize){char*p=(char*)pp;charc;vinti;for(i=0;i<size/2;++i){c=p[i];p[i]=p[size-i-1];p[size-i-1]=c;}}//構造Pointer結構,并為count個size大小的變量動態分配內存PointermallocPointer(vintsize,vintcount){Pointerret;intmemsize=size*count;if(count>0){ret.pointer=(char*)malloc(memsize);}else{ret.pointer=NULL;}ret.malloc=1;ret.used=0;ret.size=memsize;ret.elementsize=size;returnret;}//構造Pointer結構,并將指針、數據大小和數量參數賦給pointer、size和count成員PointerconstPointer(void*vpointer,vintsize,vintcount){Pointerret;intmemsize=size*count;ret.pointer=(char*)vpointer;ret.malloc=0;ret.used=memsize;ret.size=memsize;ret.elementsize=size;returnret;}//調整內存大小Pointer*resizePointer(Pointer*p,vintcount){intmemsize=p->elementsize*count;intnewused=p->used<memsize?p->used:memsize;void*newp=malloc(memsize);if(p->used>0){memcpy(newp,p->pointer,newused);}if(p->malloc){free(p->pointer);}p->malloc=1;p->pointer=(char*)newp;p->used=newused;p->size=memsize;returnp;}//將vpointer指向的size長度的數據復制到pPointer*pushBackData(Pointer*p,constvoid*vpointer,vintsize){char*pp;if(p->used+size>p->size){p=resizePointer(p,(p->used+size)*2);}pp=(char*)p->pointer+p->used;memcpy(pp,vpointer,size);if(size>1){SwapByteOrderRef(pp,size);}p->used+=size;returnp;}//將src包含的數據復制到pPointer*pushBackPointer(Pointer*p,constPointer*src){p=pushBackData(p,&src->used,sizeof(src->used));p=pushBackData(p,&src->size,sizeof(src->size));p=pushBackData(p,&src->malloc,sizeof(src->malloc));p=pushBackData(p,&src->elementsize,sizeof(src->elementsize));{intcount=src->used/src->elementsize;inti;assert(count*src->elementsize==src->used);for(i=0;i<count;++i){p=pushBackData(p,src->pointer+i*src->elementsize,src->elementsize);}}returnp;}//從p中指針加上offset的位置開始,將大小為size的數據復制到vpointerPointer*getData(Pointer*p,vint*offset,void*vpointer,vintsize){memcpy(vpointer,(char*)p->pointer+*offset,size);if(size>1){SwapByteOrderRef(vpointer,size);}*offset+=size;returnp;}//從p中指針加上offset的位置開始,將大小為src->size的數據復制到srcPointer*getPointer(Pointer*p,vint*offset,Pointer*dst){staticvintused,size,malloc,element;inti=0;p=getData(p,offset,&used,sizeof(used));p=getData(p,offset,&size,sizeof(size));p=getData(p,offset,&malloc,sizeof(malloc));p=getData(p,offset,&element,sizeof(element));dst=resizePointer(dst,size);for(i=0;i<used/element;++i){p=getData(p,offset,dst->pointer+i*element,element);}dst->used=used;returnp;}//將p保存的數據釋放掉,并將各成員置為零voiddestroyPointer(Pointer*p){if(p->malloc){free(p->pointer);}p->pointer=NULL;p->used=0;p->size=0;p->elementsize=0;}2)構造目標函數,包括:a.構造變量聲明及初始化,參考示例代碼7中的VmFuntion::declare(生成聲明變量的源代碼,并存儲初始化該變量的初始化字符串,以備在所有變量聲明后生成初始化這些變量的源代碼)和VmFuntion::addInitCode(生成初始化變量的源代碼);b.構造輸入參數處理程序,其功能是將目標函數的輸入參數處理為連續存儲的數據流,參考示例代碼7中的VmFuntion::pushTo(生成將目標函數各參數依次寫入到存儲變量的源代碼)和TypeService::makePushCode(根據變量名和類型構造輸入參數處理代碼);c.構造向加密鎖發送指令和數據的程序,其功能是將輸入數據發送給加密鎖,并接收加密鎖返回的數據;參考示例代碼9中的LibHostCall;d.構造輸出參數處理的程序,其功能是將加密鎖返回的數據賦給目標函數的輸出參數,參考示例代碼7中的VmFuntion::getFrom(生成從存儲變量依次讀取目標函數各參數的源代碼生成從存儲變量依次讀取目標函數各參數的源代碼)和TypeService::makePullCode(根據變量名和類型構造輸出參數處理代碼)。3.構造加密鎖軟件編譯環境下的源文件。該步驟下包括如下進一步的步驟:1)添加頭文件,本例需要添加的頭文件為LibPointer.h、ses_v3.h(加密鎖相關的頭文件)、stdlib.h。其中ses_v3.h為加密鎖SDK中給出的頭文件,聲明了一些與加密鎖緊密相關的變量和函數,如緩沖區數據指針、發送數據函數和退出函數等。2)構造目標函數聲明,示例代碼11中的VmFuntion::mainFuncDelare(生成添加頭文件及聲明目標函數的源程序)3)構造主函數:a.構造變量聲明及初始化,參考示例代碼7中的VmFuntion::declare(生成聲明變量的源代碼,并存儲初始化該變量的初始化字符串,以備在所有變量聲明后生成初始化這些變量的源代碼)和VmFuntion::addInitCode(生成初始化變量的源代碼);b.構造輸入參數處理程序,其功能是將輸入數據(連續存儲的數據流)轉換為目標函數所需的參數,參考示例代碼7中的VmFuntion::pushTo(生成將目標函數各參數依次寫入到存儲變量的源代碼)和TypeService::makePushCode(根據變量名和類型構造輸入參數處理代碼);c.構造調用目標函數(即sort函數)的程序;參考示例代碼11中的VmFuntion::addGuestBody(在成員變量code中添加加密鎖編譯環境下的主函數的函數體);d.構造向主機發送數據的程序,其功能是將輸出參數送回主機。示例代碼如下所示:示例代碼11,構造加密鎖軟件編譯環境下源程序的方法://生成添加頭文件及聲明目標函數的源程序stringVmFuntion::mainFuncDelare(){return"#include\"ses_v3.h\"\n\n""#include\"VmPointer.h\"\n\n"+funcDelare()+";\n\n";}//在成員變量code中添加加密鎖編譯環境下的主函數的函數體;函數體中,從來自主機的數據提取目標函數參數、調用目標參數、將各參數和返回值依次寫入一段內存并發送給主機。voidVmFuntion::addGuestBody(){//聲明rec:接收來自主機的數據declare("staticchar","mem[512]");//聲明rec:接收來自主機的數據declare("Pointer","buf","constPointer(pbInBuff,1,bInLen)");//聲明offset,用于從流數據中提取數據declare("vint","offset","0");//聲明返回值if(ret!="void"){declare(ret,"ret","0");}//聲明各參數for(inti=0;i<(int)pars.size();++i){constVmVar&var=pars[i];if(var.type=="Pointer"){declare(var.type,var.name,"mallocPointer(0,0)");}elseif(var.type=="Pointer*"){declare("Pointer",var.name+"Local","mallocPointer(0,0)");declare("Pointer*",var.name,("&"+var.name+"Local").c_str());}else{declare(var.type,var.name);}}//聲明的變量初始化addInitCode();code+="
init_mempool(mem,512);\n";getFrom("buf");code+="\n";code+="
//調用函數\n";code+=funcCall();//addDestroyCode();code+="
destroyPointer(&buf);\n";pushTo("buf");//發送函數參數//...code+="
_set_response(buf.used,buf.pointer);\n";code+="
_exit();\n";}應用本方法生成的應用軟件編譯環境下的源程序如示例代碼12所示,加密鎖軟件編譯環境下源程序如示例代碼13所示。示例代碼12:采用本方法生成的應用軟件編譯環境下的源程序:#include"LibPointer.h"voidsort(Pointer*array){Pointerbuf;vintret;vintoffset;buf=mallocPointer(1,0);ret=0;offset=0;//Pointer*arraypushBackPointer(&buf,array);ret=LibHostCall(&buf);//重新初始化Pointer類型參數array->used=0;//Pointer*arraygetPointer(&buf,&offset,array);}示例代碼13:利用本方法生成的加密鎖軟件編譯環境下的源程序:#include"ses_v3.h"#include"LibPointer.h"#include<stdlib.h>voidsort(Pointer*array);voidmain(){staticcharmem[512];Pointerbuf;vintoffset;PointerarrayLocal;Pointer*array;buf=constPointer(pbInBuff,1,bInLen);offset=0;arrayLocal=mallocPointer(0,0);array=&arrayLocal;init_mempool(mem,512);//Pointer*arraygetPointer(&buf,&offset,array);//調用函數sort(array);destroyPointer(&buf);//Pointer*arraypushBackPointer(&buf,array);_set_response(buf.used,buf.pointer);_exit();}在KeilC下將源文件編譯為可執行程序,利用SDK中的開發測試工具將之寫入到加密鎖,即可為應用軟件所用,應用軟件調用目標函數時即會與加密鎖通信,傳遞參數,取回結果。以上示例性的程序代碼只是一種示例,其完全可以采用其它的編程語言來實現或者進行改變,不用于限制本發明的具體實現手段。本發明的保護范圍由權利要求書限定。本領域技術人員可以在本發明的實質和保護范圍內,對本發明做出各種修改或等同替換,這種修改或等同替換也應視為落在本發明的保護范圍內。本領域內的技術人員應明白,本發明的實施例可提供為方法、系統、或計算機程序產品。因此,本發明可采用完全硬件實施例、完全軟件實施例、或結合軟件和硬件方面的實施例的形式。而且,本發明可采用在一個或多個其中包含有計算機可用程序代碼的計算機可用存儲介質(包括但不限于磁盤存儲器和光學存儲器等)上實施的計算機程序產品的形式。本發明是參照根據本發明實施例的方法、設備(系統)、和計算機程序產品的流程圖和/或方框圖來描述的。應理解可由計算機程序指令實現流程圖和/或方框圖中的每一流程和/或方框、以及流程圖和/或方框圖中的流程和/或方框的結合。可提供這些計算機程序指令到通用計算機、專用計算機、嵌入式處理機或其他可編程數據處理設備的處理器以產生一個機器,使得通過計算機或其他可編程數據處理設備的處理器執行的指令產生用于實現在流程圖一個流程或多個流程和/或方框圖一個方框或多個方框中指定的功能的裝置。這些計算機程序指令也可存儲在能引導計算機或其他可編程數據處理設備以特定方式工作的計算機可讀存儲器中,使得存儲在該計算機可讀存儲器中的指令產生包括指令裝置的制造品,該指令裝置實現在流程圖一個流程或多個流程和/或方框圖一個方框或多個方框中指定的功能。這些計算機程序指令也可裝載到計算機或其他可編程數據處理設備上,使得在計算機或其他可編程設備上執行一系列操作步驟以產生計算機實現的處理,從而在計算機或其他可編程設備上執行的指令提供用于實現在流程圖一個流程或多個流程和/或方框圖一個方框或多個方框中指定的功能的步驟。顯然,本領域的技術人員可以對本發明進行各種改動和變型而不脫離本發明的精神和范圍。這樣,倘若本發明的這些修改和變型屬于本發明權利要求及其等同技術的范圍之內,則本發明也意圖包含這些改動和變型在內。雖然本發明已以優選實例公開如上,然而所公開實例并非用以限制本發明的范圍。可以理解:在不脫離本發明的精神的情況下,在此可以產生各種附加、修改和替換。本領域普通技術人員很清楚:在不脫離本發明的精神或本質特性的情況下,可以以其他特殊形式、結構、布置、比例、以及利用其他元件、材料和部件來實現本發明。本領域的技術人員將意識到:本發明可以使用發明實際中使用的結構、布置、比例、材料以及部件和其他的許多修改,這些修改在不脫離本發明的原理的情況下而特別適應于特殊環境和操作需求。因此,當前公開的實施例在所有方面應被理解為說明性的而非對其請求保護的范圍的限制。