本文將簡要介紹Sentinel SuperPro軟件加密鎖的編程開發(fā)知識,可供需要進行軟件加密鎖開發(fā)的軟件開發(fā)商快速學習掌握這種類型的加密鎖的編程開發(fā),快速保護自己的軟件不受侵害,防止加密狗被破解。本文資源來源于Sentinel SuperPro加密鎖開發(fā)套件中的開發(fā)手冊,僅供大家學習,文字版權屬于Sentinel SuperPro所有。
一、加密鎖簡介 Sentinel SuperPro加密鎖是一個硬件/軟件保護系統(tǒng),功能主要是保護軟件,即防止未經(jīng)允許非法使用開發(fā)商的軟件。如未把正確的加密鎖與計算機連接,則被保護的應用程序?qū)o法實現(xiàn)全部功能。因此,只有合法用戶才能使用開發(fā)商的產(chǎn)品。 使用SuperPro軟件保護鎖完成軟件保護,就是將軟件開發(fā)商的未被保護的應用程序與SuperPro軟件保護鎖加密算法相綁定過程。最終實現(xiàn)綁定后的應用程序沒有軟件保護鎖不能單獨運行,只有插入軟件開發(fā)商自己定義算法的軟件保護鎖,應用程序才能正常運行。當軟件開發(fā)商的軟件銷售給最終用戶后,軟件即使被非法復制,而沒有軟件開發(fā)商提供的軟件保護鎖軟件不能被使用。這樣一來,從技術上防止盜版起到軟件保護的作用。 應用程序和Sentinel Superpro軟件保護鎖加密算法的綁定,是通過API函數(shù)調(diào)用來校驗軟件保護鎖是否存在來實現(xiàn)的。API函數(shù)驗證分由三部分組成: 1)詢問部分:開發(fā)商的應用程序通過API調(diào)用向軟件保護鎖的驅(qū)動程序發(fā)出的“查詢串”, 驅(qū)動程序自動將“查詢串”傳給并口或USB口上的SuperPro軟件保護鎖上的算法單元。 2)運算部分:加密鎖通過內(nèi)部的算法芯片計算“查詢串”,并將運算結果“響應串”返回給驅(qū)動程序。 3)程序鑒定、行動部分:驅(qū)動程序?qū)?#8220;響應串”返回給應用程序中的API函數(shù)調(diào)用。應用程序?qū)Ψ祷刂怠?#8220;響應串”進行比較判斷,判斷與預知運算結果是否相等,根據(jù)判斷的結果進行相應的行動。 如果返回值—“響應串”與預知運算結果相等,則說明保護應用程序的軟件保護鎖存在,使用程序的用戶為合法用戶。不相等則說明保護應用程序的軟件保護鎖不存在,用戶為非法用戶,應用程序?qū)⒔K止被使用。 SentinelSuperPro 系統(tǒng)一個主要優(yōu)點是可對一個加密鎖編程,以提供多種驅(qū)動程序類型,包括固定響應和可變響應。這樣,所創(chuàng)建的軟件鎖具有非常多的類型。 例如,可用單元存儲固定數(shù)據(jù)(如序列號、用戶名稱)或存儲控制功能詢問的代碼。然后,可簡單地讀取這些數(shù)據(jù),以檢驗是否附加了加密鎖。也可使用存儲的數(shù)據(jù)控制程序流程或應用程序的函數(shù)。數(shù)據(jù)字組可以定義為只讀的(鎖定)或可讀/寫的。 每個加密鎖的前 8 個單元為系統(tǒng)信息保留。除了某些限制外,可以任意方式使用其它 56 個單元。 二、加密鎖編程接口 下面以VB語言為例,說明使用SuperPro軟件保護鎖時,有關API調(diào)用的數(shù)據(jù)結構、函數(shù)以及必要的步驟。 1.基本信息 DEVELOPER ID:用戶ID為加密編號,為固定數(shù)字,沒有它就不能使用加密鎖。 地址:SuperPro 的地址從00H到3FH,以十六進制數(shù)表示。 訪問權限:SuperPro的每一個存儲單元可以單獨設置成不同的操作權限。 1- 可讀/寫數(shù)據(jù);2- 只讀數(shù)據(jù);3- 計數(shù)器;4- 算法 2.數(shù)據(jù)結構 APIPACKET Type APIPACKET data(4096) As Byte End Type 除了sproInitialize, 所有的函數(shù)都使用APIPACKET數(shù)據(jù)結構,該結構在調(diào)用sproFindFirstUnit 時被初始化,在調(diào)用sproFindNextUnit的時候會根據(jù)下一個加密鎖的信息進行必要修改。當函數(shù)正常返回時,APIPACKET中存放必要的返回信息。 SuperPro驅(qū)動程序使用該結構中的信息與加密鎖進行通訊。開發(fā)者不要自行修改其中的數(shù)據(jù)。SuperPro驅(qū)動程序不負責分配APIPACKET數(shù)據(jù)單元,開發(fā)者在程序中必須分配APIPACKET結構變量,并且把指針傳遞給不同的函數(shù)。 3.API函數(shù) ● RNBOsproFindFirstUnit() RNBOsproFindFirstUnit() 函數(shù)定位具有指定的開發(fā)者ID的SentinelSuperPro 加密鎖。在調(diào)用 RNBOsproInitialize() 之后,使用其他調(diào)用之前,必須首先調(diào)用該函數(shù)。如果找到了加密鎖,訊息包或UNITINFO 記錄中將包含有效的數(shù)據(jù),如果未找到加密鎖,訊息包或 UNITINFO 記錄將被標記為無效的。 RNBOsproFindFirstUnit() 將搜索所有連接在并行端口上的所有級聯(lián)單位。如果存在多個加密鎖具有相同的開發(fā)者 ID,RNBOsproFindFirstUnit() 存取找到的第一個加密鎖。在需要的時候,可以使用 RNBOsproFindNextUnit()查找具有相同開發(fā)者 ID 的其他加密鎖。 參數(shù) RNBOsproFindFirstUnit() 調(diào)用需要以下參數(shù): ■由 Rainbow Technologies 或者其他發(fā)布者為您指定的開發(fā)者 ID。 ■指向訊息包記錄或者 UNITINFO 結構的指針。 返回值 如果執(zhí)行成功,函數(shù)返回成功。如果發(fā)生了錯誤,函數(shù)將返回附錄中所列的狀態(tài)碼。 ● RNBOsproFindNextUnit() RNBOsproFindNextUnit() 函數(shù)搜索具有給定開發(fā)者 ID 的下一個加密鎖。 開發(fā)者ID是由第一次調(diào)用的 RNBOsproFindFirstUnit() 指定的。(要找到具有不同的開發(fā)者ID的加密鎖,需要再 次調(diào)用RNBOsproFindFirstUnit()。) 如果 RNBOsproFindNextUnit() 成功了,訊息包或者 UNITINFO 記錄將包含下一個加密鎖的數(shù)據(jù)。如果未成功,訊息包或者 UNITINFO 記錄將被標記為無效的。要重新對訊息包或 UNITINFO 記錄初始化,需要再次使用 RNBOsproFindFirstUnit() 以及 RNBOsproFindNextUnit()。 RNBOsproFindNextUnit() 將搜索連接到任何并行端口上的所有級聯(lián)單位。如果同時連接了幾個加密鎖,應用程序可 以多次調(diào)用RNBOsproFindNextUnit()。 參數(shù) RNBOsproFindNextUnit()函數(shù)需要一個參數(shù):指向訊息包記錄或者UNITINFO 結構的指針。 返回值 如果執(zhí)行成功,函數(shù)返回成功。如果發(fā)生了錯誤,函數(shù)將返回附錄中所列的狀態(tài)碼。 ● RNBOsproFormatPacket() RNBOsproFormatPacket() 函數(shù)檢驗訊息包記錄大小的有效性,并且初始化它的缺省值。該調(diào)用必須在調(diào)用其他 API 函數(shù)之前進行,否則將返回錯誤碼 2 (INVALID PACKET)。 參數(shù) RNBOsproFormatPacket() 需要下列參數(shù): ■指向訊息包記錄 (RBP_RNBOspro_APIPACKET) 的指針。 ■PacketLen 的值是一個整數(shù), 包含了訊息包的長度 (1028 個字節(jié)) 。 返回值 所有的函數(shù)都返回一個無符號的 16 位的值。值為 0 表示操作成功了,其他的值都表明發(fā)生了錯誤。如果發(fā)生了錯誤,函數(shù)將返回附錄中列出的狀態(tài)碼之一。如果返回的狀態(tài)碼為非 0 的值,那么函數(shù)返回的其他數(shù)據(jù)將是無意義的。 ● RNBOsproGetVersion() RNBOsproGetVersion() 函數(shù)返回與 SentinelSuperPro 驅(qū)動程序有關的信息,應用程序可以使用該信息。 參數(shù) RNBOsproGetVersion() 函數(shù)需要下列參數(shù): ■指向訊息包記錄或者 UNITINFO 結構的指針。 ■指向用來返回主版本號的位置的指針。 ■指向用來返回次版本號的位置的指針。 ■指向用來返回修訂版本號的位置的指針。 ■指向用來返回驅(qū)動程序類型標識符的位置的指針。 返回值 如果執(zhí)行成功,函數(shù)返回成功。如果發(fā)生了錯誤,函數(shù)將返回附錄中所列的狀態(tài)碼。 ● RNBOsproInitialize() RNBOsproInitialize() 函數(shù)使驅(qū)動程序執(zhí)行所需的初始化操作。在調(diào)用任何其他的 API 之前,應用程序必須首先調(diào)用 RNBOsproInitialize() 一次。 參數(shù) RNBOsproInitialize() 函數(shù)不需要任何參數(shù)。 返回值 如果執(zhí)行成功,函數(shù)返回成功。如果發(fā)生了錯誤,函數(shù)將返回附錄中所列的狀態(tài)碼。 ● RNBOsproOverwrite() RNBOsproOverwrite() 函數(shù)使應用程序能夠改變字組的值與存取碼,但是被限制的單元(0 到 7)除外。在使用該函數(shù)的時候,需要同時提供寫密碼和重寫密碼。 注意重寫密碼的能力是相當強大的。它的使用應該僅限于工作室中,而不應該在正式發(fā)布的應用程序中出現(xiàn)。如果您的保護方案不需要在應用程序中使用重寫密碼,Rainbow 可以通過編程使您的每一個加密鎖具有一個“隨機重寫密碼”。每個加密鎖中將包含不同的重寫加密鎖密碼,并且不能在最終用戶實際使用中進行修改。 參數(shù) RNBOsproOverwrite() 函數(shù)需要下列參數(shù): ■指向訊息包記錄或者 UNITINFO 結構的指針。 ■您的寫密碼。 ■您的兩個字組長的重寫密碼。 ■需要寫入的定址。 ■賦予該字組的存取碼:0 (可讀/寫數(shù)據(jù))、1 (只讀數(shù)據(jù))、2 (計數(shù)器)、3 (算法/隱藏的)。 ■希望寫到該定址上的值。 返回值 如果執(zhí)行成功,函數(shù)返回成功。如果發(fā)生了錯誤,函數(shù)將返回附錄中所列的狀態(tài)碼。 ● RNBOsproQuery() 利用RNBOsproQuery() 函數(shù),應用程序可以發(fā)送詢問字串到SentinelSuperPro 加密鎖。應用程序還可以指定用來對字串進行轉換的算法描述符。 加密鎖將使用自己的算法和指定的算法描述符中儲存的信息對輸入字串進行轉換。然后加密鎖將轉換之后的字串返回到應用程序。應用程序?qū)⒎祷氐淖执c希望得到的字串相比較,即可知道所需要的加密鎖是否仍連接在并行端口上。 在軟件開發(fā)階段,高級編程序的鑒定 API:詢問選項可以用來確認加密鎖的算法描述符對給定的輸入字串進行轉換的結果。 參數(shù) RNBOsproQuery() 函數(shù)需要下列參數(shù): ■指向訊息包記錄或者 UNITINFO 結構的指針。 ■詢問字串中的字節(jié)個數(shù)(最大值 56)。 ■指向包含詢問字串的緩沖區(qū)的指針(偏移量在前,段定址在后)。 ■指向用來供驅(qū)動程序返回結果字串的緩沖區(qū)的指針。該緩沖區(qū)需要足夠大,以便容納整個的結果字串。另外一種可取的辦法是,將某個位置的指針傳遞給驅(qū)動程序,但驅(qū)動程序僅返回結果字串的最后 32 個位。 ■詢問中使用的算法描述符的首(較低的)字組的定址。該定址必須是偶數(shù)。一般來說,較長的詢問字串能夠提供更好的保護。推薦的詢問字串長度至少為 8 個十六進制字符(32 個位)。驅(qū)動程序允許的最長的詢問字串的長度為 56 個字節(jié)。如果發(fā)送的字串長度小于 32 位,驅(qū)動程序?qū)⒃谔砑右环N已知的模式之后再將其發(fā)送出去。 返回值 如果執(zhí)行成功,函數(shù)返回成功。如果發(fā)生了錯誤,函數(shù)將返回附錄中所列的狀態(tài)碼。 ● RNBOsproRead() 應用程序可以使用 RNBOsproRead() 函數(shù)讀取非隱藏的記憶體字組的值。非隱藏的字組的存取碼為 0 (可讀/寫數(shù)據(jù))、1 (只讀數(shù)據(jù))或 2(計數(shù)器)。算法/隱藏的字組的存取碼為 3,它是不能被讀取的。如果試圖讀取一個隱藏的字組,驅(qū)動程序?qū)⒎祷鼐芙^存取。通過檢查該狀態(tài)即可判斷字組是不是算法字組。RNBOsproRead() 返回字組的值,而不是其存取碼。要獲得字組的存取碼,可以使用 RNBOsproExtendedRead()。 參數(shù) RNBOsproRead() 函數(shù)需要下列參數(shù): ■指向訊息包記錄或者 UNITINFO 結構的指針。 ■被讀取的定址。 ■一個指針,在調(diào)用成功的時候,該指針指向驅(qū)動程序返回的指定字組的內(nèi)容。 返回值 如果執(zhí)行成功,函數(shù)返回成功。如果發(fā)生了錯誤,函數(shù)將返回附錄中所列的狀態(tài)碼。 ● RNBOsproDecrement() RNBOsproDecrement() 函數(shù)將可讀/寫的數(shù)據(jù)字組(存取碼為 0)或者計數(shù)器字組(存取碼為 2)的值減量 1。在使用該函數(shù)時需要提供寫密碼。如果試圖對被鎖定或者隱藏的字組減量,驅(qū)動程序?qū)⒎祷鼐芙^存取。如果字組中的值已歸零,驅(qū)動程序?qū)⒎祷匾褮w零。對這兩種狀態(tài)碼應用程序都需要進行檢查。RNBOsproDecrement() 可以用來限制演示程序能夠被執(zhí)行的次數(shù)。首先將一個計數(shù)器與一個算法描述符聯(lián)系起來,然后在每次程序執(zhí)行的時候?qū)⒂嫈?shù)器減一。當計數(shù)器為 0 時,算法將自動被去激活。以后的詢問將返回無效的響應。 參數(shù) RNBOsproDecrement() 函數(shù)需要下列參數(shù): ■指向訊息包記錄或者 UNITINFO 結構的指針。 ■您的寫密碼。 ■需要被減量的數(shù)據(jù)字組或計數(shù)器的定址。 返回值 如果執(zhí)行成功,函數(shù)返回成功。如果發(fā)生了錯誤,函數(shù)將返回附錄中所列的狀態(tài)碼。 ● RNBOsproExtendedRead() RNBOsproExtendedRead() 函數(shù)讀取非隱藏的記憶體字組的值和存取碼。未隱藏的字組的存取碼為 0 (可讀/寫數(shù)據(jù))、(只讀數(shù)據(jù))或 2 (計數(shù)器)。算法/隱藏字組的存取碼為 3,它們是不可讀的。如果試圖讀取一個隱藏的字組,驅(qū)動程序返回拒絕存取。通過檢查該狀態(tài),能夠確認一個字組是否是算法字組。 參數(shù) RNBOsproExtendedRead() 函數(shù)需要下列參數(shù): ■指向訊息包記錄或者 UNITINFO 結構的指針。 ■要讀取的定址。 ■指向指定字組的內(nèi)容的指針,在調(diào)用成功時由驅(qū)動程序返回內(nèi)容。 ■指向指定字組的存取碼的指針,在調(diào)用成功時由驅(qū)動程序返回存取碼。存取碼可能是 0 (可讀/寫數(shù)據(jù))、1 (只讀數(shù)據(jù))或 2 (計數(shù)器)。調(diào)用不可能返回存取碼 3 (算法/隱藏的)。 返回值 如果執(zhí)行成功,函數(shù)返回成功。如果發(fā)生了錯誤,函數(shù)將返回附錄中所列的狀態(tài)碼。 4.必要的初始化步驟 在調(diào)用API函數(shù)進行加密工作以前,必須在應用程序中完成以下有關加密的初始化工作。 分配APIPACKET數(shù)據(jù)結構 調(diào)用RNBOsproFormatPacket初始化結構(僅Win32程序使用) 調(diào)用RNBOsproInitialize函數(shù) 調(diào)用RNBOsproFindFirstUnit函數(shù)找到軟件保護鎖 以上工作完成以后,開發(fā)者可以根據(jù)各自的需要在程序的任何部分進行讀寫、查詢等工作。所有函數(shù)沒有必然的前后順序。 當利用查詢響應對,調(diào)用RNBOSproQuery進行查詢時,需要對查詢響應對進行適當轉換。 三、備注 如果想了解更多有關軟件保護鎖的信息,請參閱加密鎖手冊SentinelSuperPro Developer Guide。 附錄.API狀態(tài)碼返回數(shù)值 0 success - 調(diào)用順利地完成。 1 invalid function code - 指定了一個無效功能碼。對于有效的 API 功能碼,請查看您所使用的語言的包含檔案(例如:SUPERPRO.H )。如果使用 Rainbow 提供的接口程序與驅(qū)動程序通訊,通常不應該產(chǎn)生該錯誤。 2 invalid packet - 在命令訊息包中檢測到核對和錯誤,該錯誤表明內(nèi)部不一致。因是訊息包記錄或 UNITINFO 結構還沒有被初始化,或者可能已被篡改了。如果使用Rainbow 提供的接口程序與驅(qū)動程序通訊,通常不應該產(chǎn)生該錯誤。 3 unit not found - 或者 RNBOsproFindFirstUnit(),或者 RNBOsproFindNextUnit() 無法找到指定的 SentinelSuperPro 加密鎖。請確信發(fā)送了正確的開發(fā)者 ID。如果該加密鎖消失(也就是說,已?被取消),該錯誤是其它函數(shù)返回的。 4 access denied - 企圖對字組執(zhí)行非法操作。例如,您可能試圖從算法/隱藏字組中讀取、向鎖定的字組中寫入,或者將不是計數(shù)器字組或者數(shù)據(jù)字組的字組減量。 5 invalid memory address - 指定了無效的 SentinelSuperPro 記憶體定址。有效的定址是十進制的 0-63(十六進制的 0-3F)。對于許多操作,單元 0-7 是無效的。必須使用第一個(偶數(shù))定址引用算法描述符。 6 invalid access code - 指定了一個無效的存取碼。存取碼必須是 0(讀/寫數(shù)據(jù))、1(只讀數(shù)據(jù))、2 (計數(shù)器)或者 3(算法/隱藏)。 7 port is busy - 因為端口被占用,所以請求的操作不能完成。導致的原因可能是有大量的打印任務,或者該端口上的某個單位正在執(zhí)行寫操作并阻塞了該端口。請再試一次該函數(shù)。 8 write not ready - 由于暫時缺少足夠的能力,不能執(zhí)行寫入或者減量操作。請再試一次該操作。 9 no port installed - 在工作站上沒有發(fā)現(xiàn)并行端口。 10 already zero - 試圖將已?包含 0 的計數(shù)器字組或者數(shù)據(jù)字組減量。如果使用該計數(shù)器控制演示程序執(zhí)行,當對應的算法描述符被起動密碼重新激活之后,可能會出現(xiàn)這種情況。 12 driver not installed - 沒有安裝或者沒有檢測到系統(tǒng)設備驅(qū)動程序。不可能與該單位通訊。請驗證設備驅(qū)動程序的加載是否正確。 13 communications error - 系統(tǒng)設備驅(qū)動程序與該單位通訊時碰到問題。請驗證設備驅(qū)動程序的安裝是否正確。 18 version not supported - 當前的系統(tǒng)設備驅(qū)動程序過期。請更新驅(qū)動程序。 19 OS environment not supported - 客戶程序庫不支持該操作系統(tǒng)或者環(huán)境。請與技術支持聯(lián)系。 20 query too long - 發(fā)送的詢問字串超過 56 個字符。請發(fā)送較短的字串。 30 driver is busy - 系統(tǒng)驅(qū)動程序繁忙。請再試一次該操作。 31 port allocation failure - 通過操作系統(tǒng)的并行端口爭用處理器來分配并行端口時失敗。 32 port release failure - 通過操作系統(tǒng)的并行端口爭用處理器來釋放先前分配的并行端口時失敗。 39 acquire port timeout - 在規(guī)定的超時時間內(nèi)請求使用并行端口失敗。 42 signal not supported - 特定的機器不支持信號線。例如,企圖在一臺 NEC 9800 計算機上使用 ACK 線。 57 init not called - 沒有初始化加密鎖。在調(diào)用產(chǎn)生該錯誤的函數(shù)之前,請先調(diào)用RNBOsproInitialize() 函數(shù)。 58 driver type not supported - 對于定義的操作系統(tǒng)和客戶程序庫,不支持驅(qū)動程序的存取類型。該驅(qū)動程序的存取類型無論是直接 I/O,還是系統(tǒng)驅(qū)動程序。 59 fail on driver comm - 客戶程序庫與 Rainbow 的系統(tǒng)驅(qū)動程序通訊失敗。 60 API status unavailable - 擴充的 API 狀態(tài)函數(shù)不可用。 255 invalid status - 返回的狀態(tài)碼無效。 注:本文部分內(nèi)容來源于SafeNet(原彩虹天地)加密鎖產(chǎn)品Sentinel SuperPro的使用說明文檔以及相關技術文檔整理而成。 |
|