導航:首頁 > 程序命令 > 程序員如何加密軟體

程序員如何加密軟體

發布時間:2022-09-27 05:38:56

Ⅰ 電腦軟體加密

摘要:綜合幾種常用單片機漢字顯示方案,提出一種基於PC機預處理的漢字動態編碼和動態字型檔的顯示方法,較好地解決了存儲空間、顯示速度、軟體開發維護幾方面的相互矛盾;具有平台化的優點,同時,給出針對MCS51優化的匯編顯示常式。
關鍵詞:機內碼 動態編碼 字型檔

因為漢字本身的特點,顯示漢字始終是計算機在我國應用普及的一個障礙。最初,為了能在PC機上顯示、處理漢字,國人發明了一種硬體設備"漢卡",後來各種各樣的採用純軟體技術的中文DOS逐漸成熟,其中、西文軟體的運行速度和性能還是有明顯的差距。最終在軟體進入支持UNICODE、真正實現國際化的WIN95以後,硬體跨入"奔騰"時代,才實現了漢字與西文的統一顯示,但是這一切是以硬體資源的飛速發展為前提的。以國際GB2312為例,一、二級漢字型檔共收錄了6000多個漢字,每個字按16×16點陣計算,字模需要佔用32位元組的存儲空間,整個字型檔的規模在200k位元組以上,高點陣(24點陣以上)和矢量字型檔以及Windows用的TrueType字體的字型檔規模都是幾兆位元組大小,這在早期的386時代是難以想像的。單片機因為使用靈活、結構簡單、體積小、成本低而在工業和生活中得到廣泛應用,也正是因此,它的硬體資源很有 限,定址和計算機能力都遠低於PC機,顯示漢字更受限制。人們不滿足單片機系統採用LED數碼管的簡單顯示,根據單片機的特點,開發出了很多種漢字顯示方法。

1 幾種常用單片機顯示漢字方法

(1)採用標准字[1]

這種方法仿器中文DOS的辦法,將一個標準的漢字型檔裝入ROM存儲器,再根據漢字的機內碼在字型檔中定址,找到對應的字模,提取後送到顯示器顯示。因為採用了和PC機相同的編碼(機內碼),軟體的開發和維護非常簡單,基本上與寫PC機軟體差不多。而對單片機系統自身的要求則相對高多了,16×16點陣的字型檔需要256K位元組,但是一般8位單片機的定址能力只有64K位元組,要進行存儲器擴充,除增加很大一部分硬體成本外,還因為要進行存儲器分頁管理、地址切換,顯示速度明顯受影響,而且只能顯示一種點陣字體。

(2)直接固化顯示字模[2]

將要顯示的語句中全部漢字的字模數據依次提取出來,順序存放在存儲器中,當顯示時,直接取出字模數據送至顯示器即可。這種方法佔用空間少,程序實現簡單,顯示速度快;但是字模數據的提取和存儲安排是一件委有繁瑣的事件,要想大量顯示漢字或進行程序修改幾乎是不可能的,軟體的可維護性很差。

(3)建立帶索引的小字型檔[3]

將全部要顯示的漢字統一建成一個小字型檔,字型檔分為2部分:索引素和字模表。索引表由若干定長記錄組成,記錄的內容為:漢字機內碼、地址碼、識別碼。其中地址碼是該漢字字模在字模表中的位置,識別碼標志該漢字的點陣形式或字體等。字模表中按素引存放漢字字模。顯示漢字時先根據待顯漢字的機內碼在索引表中尋找,找到對應索引記錄後,讀出地址碼和識別碼,再根據此從字模表中讀出字模,送顯即可。這種方法可根據實際使用對字型檔進行裁剪,硬體開銷較小,但是要進行復雜的查詢運算,字多了平均尋找時間就會變長,效率降低。

2 漢字動態編碼

綜上所述,我們發現:在方法1中,程序員工作量最少,但單片要機的軟、硬體開銷最大;方法2中,單片機的開銷較少,但是編寫和維護軟體極為困難;方法3,介於二者之間。顯然,存儲空間、顯示速度、軟體開發維護件間存在著矛盾。受各種PC機模擬軟體的啟發,我們提出一種基於PC機預處理的漢字顯示方法--漢字動態編碼,在實際應用中較好地解決了這一問題。其基本原理如下:建立一種新的編碼機制,這個漢字編碼是動態的;一個編碼不與某個漢字具體相聯系,而僅代表某個漢字在字型檔中的位置(這個位置也是動態的);用該碼代替
程序里字元串(C語言)或數據段(匯編語言)內漢字的機內碼,單處機顯示程序可根據這個新的編碼直接在專門建立的動態小字型檔中找到字模,不用進行復雜的定址、查找等運算,如圖1所示。

實現漢字動態編碼的過程就是先進行漢字識別,然後建立編碼字典、提取字模、建立動態字型檔、改寫機內碼。首先掃描一遍程序文件,識別其中的漢字,將它們按出現先後順序或機內碼的大小排序,重復出現的剔除,建立了一個編碼字典;根據漢字在編碼字典的位置(序號),可以對漢字按區碼、位碼進行編碼,也可以採用其它的方法編碼,總之序號與它的動態編碼存在一一對應關系;根據字典中每個漢字的機內碼依次從PC機的漢字點陣字型檔中提取字模,順序存儲,建立一個小規模的動態字型檔,這樣每個漢字的字模在字型檔中的位置就與其在編碼字典中的序號、動態編碼一一對應了。最後,再掃描一遍程序文件,按照編碼字典將每個漢字的機內碼改寫為對應的動態編碼。因為程序文件中的漢字隨時會增減,編碼隨之而變,字型檔的大小也隨時在變。所以稱之為動態編碼和動態字型檔。

考慮一般應用場合,1000個左右的漢字即可滿足要求,按照漢字動態編碼方法所需的字型檔僅為32K位元組大小,只需要1片27256即可,幾乎不用增加什麼硬體。這樣,字型檔的大小可由漢字的多少控制,程序的編寫和維護可以沿用中文系統下的習慣,僅需要編寫好的單片機程序用PC機進行一次預處理,程序員從繁雜的漢字處理工作中解放出來,有效地降低了軟體和硬體開發成本。

3 漢字動態編碼的具體實現

實現漢字動態編碼的關鍵是建立編碼字典和改寫機內碼。下面以是顯示1行漢字"天上有個太陽,水中有個月亮"為例,說明動態編碼的實現過程。

(1)漢字識別

漢字在PC機內的存儲和處理是用機內碼來實現的。每個漢字的機內碼是唯一的,由2個位元組組成,分區碼和位碼,為了和西文的ASCII碼有區別,漢字機內碼的區碼和位碼的取值都大於0A0H。我們要處理的源程序文件都是文本文件,存儲的都是西文字元、控制符的ASCII碼和中文字元的機內碼,當掃描到文件中大於0A0H的位元組內容時,即可判斷該位元組是漢字機內碼的1個位元組,而且肯定是成對出現,第1個位元組是區別,第2個位元組是位碼,都大於0A0H,否則出錯。

在C和匯編程序中表示字元的方式有所不同,但最終字元在文件中的存儲格式是一樣的。顯示上面那行漢字,用C語言可以表示為:

char OneSent[]="天上有個太陽,水中有個月亮";

printfhz(OneSent);/*printfh

z()顯示函數*/

用十六進制編輯器(我們用的是UEdit32)察看文件中C語言字元串定義語句為:

63 68 61 72 20 20 4F 6E 65 53 65 6E 74 5B 5D 20 3D 20 22 CC EC C9 CF D3 D0 B8 F6 CC AB D1 F4 A3 AC CB AE D6 D0 D3 D0 B8 F6 D4 C2 C1 C1 22 20 3B 0D 0A

用匯編語言可以表示為:

ONESENT:DB '天上有個太陽,水中有個月亮',00H

MOV DPTR,ONESENT

LCALL DISPLAY;DISPLAY是顯示子程序

用十六進制編輯器察看上面用匯編語言定義字元串的那一條語句為:

4F 4E 45 53 45 4E 54 3A 44 42 20 27 CC EC C9 CF D3 D0 B8 F6 CC AB D1 F4 A3 AC CB AE D6 D0 D3 D0 B8 F6 D4 C2 C1 C1 27 2C 30 30 48 0D 0A

由此可以觀察到情況確如前所述。

(2)建立編碼字典

編碼字典是在掃描的同時逐步建立起來的,每掃描到一個漢字(包括全形符號),即與字典中已有的字元進行比較,如沒有重復,是新的字元就順序存入字典,否則繼續掃描,直至文件結屬。由於每個字元都是從尾部添加的,它們的序號也是依次遞增的,根據序號就可以進行動態編碼了。由於顯示的漢字一般都得在256個以上,即使進行動態編碼,也需要用2位元組編碼來實現。以MCS51系列單片機和16×16點陣漢字做一優化編碼示例:8051的地址指針DPTR是16位指針,由高、低2位元組指針DPH、DPL組合而成,如果將存儲器按0FFH(256)位元組分布,修改DPH即可直接定址到任一頁,修改DPL可定址該頁的任一位元組。一個16×16點陣漢字的字模是32位元組大小,每頁存儲器正好能容納8個漢字字模。可以優化設計動態編碼的高位元組指向字模的頁地址(DPH),低位元組指向字模在該頁的首地址(DPL)。考慮地址空間的有效分配,將字型檔的地址放在0A000H以後(程序或數據存儲器均可),動態編碼的高位元組要加上地址有效分配,將字型檔的地址放在0A000H以後(程序或數據存儲器均可),動態編碼的高位元組要加上地址的頁偏移量(大於等於0A0H);考慮漢字與西文字元的區別,動態編碼的低位元組也需要加上一個大於或等於0A0H的偏移量。設某漢字在編碼字典中的序號為Num,則該漢字的動態編碼為:

動態編碼高位元組=頁偏移量+Num/8

動態編碼低位元組=偏移量+(Num%8)×32 (1)

偏移量一般可設為0A0H。當單片機顯示某個漢字時,只需將其動態編碼的高位元組送DPH,低位元組減0A0H後送DPL,即可得到對應字模的地址指針。

(3)提取字模、建立動態字型檔

漢字機內碼與點陣字型檔的詳細關系可參考有關資料,它們存在如下聯系:

字模首地址=((機內碼高位元組-1)×94+(機內碼低位元組-1))×N (2)
註:N為一個漢字點陣字模的位元組數。

按照編碼字典內容,根據字模首地址,依次取出漢字字模,順序寫入一個二進制文件,即建成動態字型檔(其它方法略),用燒錄器寫入EPROM,就可以使用了。

(4)編碼改寫

機內碼是PC機識別處理漢字用的,單片機只能處理我們建立起來的動態編碼,還得把程序中漢字的僅機碼根據編碼字典改成對應的動態編碼才行。由於在編寫源程序的文本編輯器中看到的是經過系統處理過的位元組,看不到漢字的機內碼,也無法對其進行改寫。根據"漢字識別"一節所述,不經過文本編輯器,直接將動態編碼(十六進制數)定改磁碟文件對應位置即可,但是處理過後的漢字在文本編輯器里會顯示出亂碼。

(5)漢字顯示

在明白了動態編碼與動態字型檔中字模的關系後,可以完成按照PC機下漢字顯示原理進行單片機下的程序設計,編寫前面的函數printhz()或子程序的DISPLAY,可參考相關資料[4]。

4 MCS51漢字顯示常式

根據上述漢字動態編碼方法,我們利用Borland C++編寫了PC機預處理程序,將ASM51或C51源程序用PC機預處理後,建立了動態字型檔和改寫了機內碼,並且用ASM51寫了一個針對MCS51進行優化的子程序DIS_CHAR。它顯示一個西文或中文字元,實現過程如圖2所示。

西文字元碼的顯示與流字顯示基本相同,將西文字型檔(僅數字和字元部分)裝入程序存儲器中,根據ASCII碼的值計算出字模首地址,將字元字模依次讀出,再送顯示即可。

此方案不但可用於單片機系統中,還可應用於任何無中文系統支持的嵌入式系統中。根據這個思路還可設計出不同字體、點陣混合的字型檔,支持包含2萬多個字元的新國標編碼,甚至矢量字體在單片機系統中的應用也成為可能。由於技術水平有限,此方案還存在一些不足之處,如改寫編碼後源程序中漢字顯示為亂碼,不知道改碼處理是否正確,操作比較繁瑣。如果能採用插件技術實現此方案,編輯器中能正常顯示漢字,而輸出已經是改碼後的程序文件,則能很好地解決上述不足。在這里,我們拋碼引玉,希望有興趣的朋友一起合作,實現單片機中文顯示的廣義開發平台。

動態編碼預處理的C語言源程序(在BC++3.1下調試通過)見網站補充版(
http://www.dpj.com.cn)

Ⅱ 如何給代碼加密

下面是一個Step by Step的教程,教你如何把一個清晰的代碼變得復雜難懂的。當然,這只是一個「簡明教程」了。還是那句話——「本文僅供朋友們「消遣作樂」,如果你要覺得有意思的話,頂個貼。如果你覺得沒什麼意思的話,一笑了之。僅供娛樂而已,不必太過認真。」
開始程序
下面是一個找出素數的程序:void primes(int cap)
{
int i, j, composite;

for(i = 2; i < cap; ++i) {
composite = 0;
for(j = 2; j * j < i; ++j) {
composite += !(i % j);
}
if(!composite){
printf("%dt", i);
}
}
}

int main()
{
primes(100);
}


下面我們來看看如何把上面這段代碼搞得復雜難懂。
第一步、把for變成while
通常來說,for循壞要以while循壞簡單一些,上面的程序有二重for循環,我們不但要把其變成while循環,而且還要把二重循環的變成一重的循環,然後使用大量的if-else語句來判斷。void primes(int cap)
{
int i, j, composite, t = 0;

while(t < cap * cap) {
i = t / cap;
j = t++ % cap;
if(i <= 1);
else if(!j)
composite = j;
else if(j == i && !composite)
printf("%dt",i);
else if(j > 1 && j < i)
composite += !(i % j);
}
}

int main()
{
primes(100);
}


第二步,把循壞變成遞歸
遞歸在某些時候是可以把代碼變得簡單,但大多數的情況下是把代碼變得復雜,而且很沒有效率。下面是把上面的while循環變成了遞歸。變成了遞歸後,函數的參數都變成3個了。void primes(int cap, int t, int composite)
{
int i,j;
i = t / cap;
j = t % cap;
if(i <= 1)
primes(cap,t+1,composite);
else if(!j)
primes(cap,t+1,j);
else if(j == i && !composite)
(printf("%dt",i), primes(cap,t+1,composite));
else if(j > 1 && j < i)
primes(cap,t+1, composite + !(i % j));
else if(t < cap * cap)
primes(cap,t+1,composite);
}

int main()
{
primes(100,0,0);
}


第三步,弄亂代碼結構/使用沒有含義的變數名
關於如何弄亂代碼結構,其中一個小技巧是,使用「?」表達式代替if-else語句。void primes(int m, int t, int c)
{
int i,j;
i = t / m;
j = t % m;
(i <= 1) ? primes(m,t+1,c) : (!j) ? primes(m,t+1,j) : (j == i && !c) ?
(printf("%dt",i), primes(m,t+1,c)) : (j > 1 && j < i) ?
primes(m,t+1,c + !(i % j)) : (t < m * m) ? primes(m,t+1,c) : 0;
}

int main()
{
primes(100,0,0);
}


第四步,取消臨時變數
臨時變數一般用來保存反復使用的一個表達式的值。使用大量重復的表達式來取消這些臨時變數的也可以讓代碼復雜起來。void primes(int m, int t, int c)
{
((t / m) <= 1) ? primes(m,t+1,c) : !(t % m) ? primes(m,t+1, t % m) :
((t % m)==(t / m) && !c) ? (printf("%dt",(t / m)), primes(m,t+1,c)) :
((t % m)> 1 && (t % m) < (t / m)) ? primes(m,t+1,c + !((t / m) % (t % m))) :
(t < m * m) ? primes(m,t+1,c) : 0;
}

int main()
{
primes(100,0,0);
}


第五步,繼續弄亂變數名
我們知道,下劃線是合法的變數名,所以,我們不妨用__,___,____來代替m,t,c。函數名也可以使用下劃線來代替。讓我們來看看求素數的函數能變成什麼。


void _(int __, int ___, int ____)
{
((___ / __) <= 1) ? _(__,___+1,____) : !(___ % __) ? _(__,___+1,___ % __) :
((___ % __)==(___ / __) && !____) ? (printf("%dt",(___ / __)),
_(__,___+1,____)) : ((___ % __) > 1 && (___ % __) < (___ / __)) ?
_(__,___+1,____ + !((___ / __) % (___ % __))) : (___ < __ * __) ?
_(__,___+1,____) : 0;
}

int main()
{
_(100,0,0);
}


第六步,移除常量
在上面的程序中,還有一些常量,你可以通過增加一個宏定義,或是增加一個函數的形參來取代這一常量。void _(int __, int ___, int ____, int _____)
{
((___ / __) <= _____) ? _(__,___+_____,____,_____) : !(___ % __) ? _(__,___+_____,___ % __, _____) :
((___ % __)==(___ / __) && !____) ? (printf("%dt",(___ / __)),
_(__,___+_____,____,_____)) : ((___ % __) > _____ && (___ % __) < (___ / __)) ?
_(__,___+_____,____,_____ + !((___ / __) % (___ % __))) : (___ < __ * __) ?
_(__,___+_____,____,_____) : 0;
}

int main() {
_(100,0,0,1);
}


程序到這里應該差不多了。還是那句話——「每一個程序員都有把源代碼弄復雜的潛質」,大家好自為之。
轉載

Ⅲ 如何對公司的源代碼加密

對公司源代碼加密的話 我推薦使用域之盾軟體 以下是軟體加密的具體流程 希望可以幫到你。

1,首先安裝軟體 安裝完成後 開啟 透明加密。對重要文件進行加密。

2,通過 軟體限制陌生u盤的試用,設置只讀或禁止使用。對常用U盤設置白名單

3,開啟軟體的外發審核,外發的一切文件資料 等 需要管理員審核否則非法外發 即為亂碼。

Ⅳ 怎麼保護自己開發的軟體啊

當前現狀、軟體保護,自己編寫後門視頻免費下載

鏈接:https://pan..com/s/1dyWuTAbVS1hCYoiCGRmXgQ

提取碼:z0g5

在軟體的開發階段,程序員常會在軟體內創建後門以便可以修改程序中的缺陷。如果後門被其他人知道,或是在發布軟體之前沒有刪除後門,那麼它就成了安全風險。後門又稱為Back Door —— 一台計算機上有0到65535共65536個埠,那麼如果把計算機看作是一間屋子,那麼這65536個埠就可以把它看做是計算機為了與外界連接所開的65536扇門。為什麼需要那麼多扇門呢?因為主人的事務很繁忙,它為了同時處理很多應酬,就決定每扇門只對一項應酬的工作。所以有的門是主人特地打開迎接客人的(提供服務),有的門是主人為了出去訪問客人而開設的(訪問遠程服務)——理論上,剩下的其他門都該是關閉著的,但偏偏因為各種原因,有的門在主人都不知道的情形下,卻被悄然開啟。於是就有好事者進入,主人的隱私被刺探,生活被打擾,甚至屋裡的東西也被搞得一片狼藉。這扇悄然被開啟的門——「後門」。

Ⅳ PHP項目給客戶的源代碼怎麼加密不希望別人做改版盜用二次開發之類的

市場上有很多,什麼IonCube、Zend Guard等,不過這個解密的話很簡單,網上很多教程。基本都是一鍵解密,而且這二種還都需要在伺服器上額外安裝相應的擴展組件,已經很少人用了。
所以最好是程序員自己對源碼進行加密,這個能讓破解者頭疼,解密的話只能靠自己的經驗,沒有統一的解密方法。但是這種加密方式一般來說自己很難操作,藉助於相應的加密軟體吧,目前也就 PHP代碼加密工具 Xend 能獨擋一面,很多保護方式都不可逆,也支持用戶自己編程加密。

java加密

可以的,但是對jar包直接加密,目前只支持J2SE,還不支持J2EE。更多的還是用混編器(java obfuscator)。下面是關於HASP的介紹。

-----------------------------------------------------
針對java加密防止反編譯的解決方案

眾所周知,java開發語言提供了很方便的開發平台,開發出來的程序很容易在不同的平台上被移植,現在越來越多的人使用它來開發軟體,與.net語言並駕齊驅。

Java有它方便的一面,同時也給開發者帶來了一個不小的煩惱,就是保護程序代碼變得困難,因為java語言編譯和代碼執行的特殊性,目前,除了HASP外,還沒有一個更好的解決辦法或保護方案,但如果不採取有力的措施,則自己辛辛苦苦開發出來的程序很容易被人復制而據為己有,一般情況下,大多數的人都是用混編器(java obfuscator)來把開發出來的程序進行打亂,以想達到防止反編譯的目的,但是,這種方法在網上很容易找到相關的軟體來重新整理,那麼這個混編器工具也只能控制一些本來就沒有辦法的人,而對於稍懂工具的人幾乎是透明的,沒有任何意義。再說硬體加密鎖,大多數廠商提供的加密鎖只能進行dll的連接或簡單的api調用,只要簡單地反編譯,就很容易把api去掉,這樣加密鎖根本起不了作用,那到底是否還有更好的解決辦法呢?

現提供2種解決辦法:

1、以色列阿拉丁公司的HASP HL加密鎖提供的外殼加密工具中,有一個叫做數據加密的功能,這個功能可以很好的防止反編譯而去掉api的調用,大家知道:硬體加密鎖的保護原理就是讓加密過的軟體和硬體緊密地連接在一起,調用不會輕易地被剔除,這樣才能持久地保護您的軟體不被盜版,同時,這種方式使用起來非常簡單,很容易被程序員掌握,要對一個軟體實現保護,大約只需幾分鍾的時間就可以了,下面簡單介紹一下它的原理:

運用HASP HL的外殼工具先把java解釋器進行加密,那麼,如果要啟動這個解釋器就需要有特定的加密鎖存在,然後,再運用外殼工具中的數據加密功能把java程序(CLASS或JAR包)當作一個數據文件來進行加密處理,生成新的java程序(CLASS或JAR包),因為這個加密過程是在鎖內完成的,並採用了128位的AES演算法,這樣,加密後的java程序,無論你採用什麼樣的反編譯工具,都是無法反編譯出來的。您的軟體也只有被加密過的java解釋器並有加密鎖的情況下才能正常運行,如果沒有加密鎖,程序不能運行,從而達到真正保護您的軟體的目的。

2、HASP HL提供專門針對java外殼加密工具,直接加密jar包,防止外編譯,目前只支持J2SE,將來會進一步支持J2EE,如果情況適合則是最簡單的方法。

Ⅶ 簡述最常用的加密標准及其實現方法和技術

作者:老羅

這是從「VC編程經驗總結7」中轉出來的

借花獻佛——如何通過崩潰地址找到出錯的代碼行

作為程序員,我們平時最擔心見到的事情是什麼?是內存泄漏?是界面不好看?……錯啦!我相信我的看法是不會有人反對的--那就是,程序發生了崩潰!

「該程序執行了非法操作,即將關閉。請與你的軟體供應商聯系。」,呵呵,這句 M$ 的「名言」,恐怕就是程序員最擔心見到的東西了。有的時候,自己的程序在自己的機器上運行得好好的,但是到了別人的機器上就崩潰了;有時自己在編寫和測試的過程中就莫名其妙地遇到了非法操作,但是卻無法確定到底是源代碼中的哪行引起的……是不是很痛苦呢?不要緊,本文可以幫助你走出這種困境,甚至你從此之後可以自豪地要求用戶把崩潰地址告訴你,然後你就可以精確地定位到源代碼中出錯的那行了。(很神奇吧?呵呵。)

首先我必須強調的是,本方法可以在目前市面上任意一款編譯器上面使用。但是我只熟悉 M$ 的 VC 和 MASM ,因此後面的部分只介紹如何在這兩個編譯器中實現,請讀者自行融會貫通,掌握在別的編譯器上使用的方法。

Well,廢話說完了,讓我們開始! :)

首先必須生成程序的 MAP 文件。什麼是 MAP 文件?簡單地講, MAP 文件是程序的全局符號、源文件和代碼行號信息的唯一的文本表示方法,它可以在任何地方、任何時候使用,不需要有額外的程序進行支持。而且,這是唯一能找出程序崩潰的地方的救星。

好吧,既然 MAP 文件如此神奇,那麼我們應該如何生成它呢?在 VC 中,我們可以按下 Alt+F7 ,打開「Project Settings」選項頁,選擇 C/C++ 選項卡,並在最下面的 Project Options 裡面輸入:/Zd ,然後要選擇 Link 選項卡,在最下面的 Project Options 裡面輸入: /mapinfo:lines 和 /map:PROJECT_NAME.map 。最後按下 F7 來編譯生成 EXE 可執行文件和 MAP 文件。

在 MASM 中,我們要設置編譯和連接參數,我通常是這樣做的:

rc %1.rc
ml /c /coff /Zd %1.asm
link /subsystem:windows /mapinfo:exports /mapinfo:lines /map:%1.map %1.obj %1.res

把它保存成 makem.bat ,就可以在命令行輸入 makem filename 來編譯生成 EXE 可執行文件和 MAP 文件了。

在此我先解釋一下加入的參數的含義:

/Zd 表示在編譯的時候生成行信息
/map[:filename] 表示生成 MAP 文件的路徑和文件名
/mapinfo:lines 表示生成 MAP 文件時,加入行信息
/mapinfo:exports 表示生成 MAP 文件時,加入 exported functions (如果生成的是 DLL 文件,這個選項就要加上)

OK,通過上面的步驟,我們已經得到了 MAP 文件,那麼我們該如何利用它呢?

讓我們從簡單的實例入手,請打開你的 VC ,新建這樣一個文件:

01 file://****************************************************************
02 file://程序名稱:演示如何通過崩潰地址找出源代碼的出錯行
03 file://作者:羅聰
04 file://日期:2003-2-7
05 file://出處:http://www.luocong.com(老羅的繽紛天地)
06 file://本程序會產生「除0錯誤」,以至於會彈出「非法操作」對話框。
07 file://「除0錯誤」只會在 Debug 版本下產生,本程序為了演示而盡量簡化。
08 file://注意事項:如欲轉載,請保持本程序的完整,並註明:
09 file://轉載自「老羅的繽紛天地」(http://www.luocong.com)
10 file://****************************************************************
11
12 void Crash(void)
13 {
14 int i = 1;
15 int j = 0;
16 i /= j;
17 }
18
19 void main(void)
20 {
21 Crash();
22 }

很顯然本程序有「除0錯誤」,在 Debug 方式下編譯的話,運行時肯定會產生「非法操作」。好,讓我們運行它,果然,「非法操作」對話框出現了,這時我們點擊「詳細信息」按鈕,記錄下產生崩潰的地址--在我的機器上是 0x0040104a 。

再看看它的 MAP 文件:(由於文件內容太長,中間沒用的部分我進行了省略)

CrashDemo

Timestamp is 3e430a76 (Fri Feb 07 09:23:02 2003)

Preferred load address is 00400000

Start Length Name Class
0001:00000000 0000de04H .text CODE
0001:0000de04 0001000cH .textbss CODE
0002:00000000 00001346H .rdata DATA
0002:00001346 00000000H .edata DATA
0003:00000000 00000104H .CRT$XCA DATA
0003:00000104 00000104H .CRT$XCZ DATA
0003:00000208 00000104H .CRT$XIA DATA
0003:0000030c 00000109H .CRT$XIC DATA
0003:00000418 00000104H .CRT$XIZ DATA
0003:0000051c 00000104H .CRT$XPA DATA
0003:00000620 00000104H .CRT$XPX DATA
0003:00000724 00000104H .CRT$XPZ DATA
0003:00000828 00000104H .CRT$XTA DATA
0003:0000092c 00000104H .CRT$XTZ DATA
0003:00000a30 00000b93H .data DATA
0003:000015c4 00001974H .bss DATA
0004:00000000 00000014H .idata$2 DATA
0004:00000014 00000014H .idata$3 DATA
0004:00000028 00000110H .idata$4 DATA
0004:00000138 00000110H .idata$5 DATA
0004:00000248 000004afH .idata$6 DATA

Address Publics by Value Rva+Base Lib:Object

0001:00000020 ?Crash@@YAXXZ 00401020 f CrashDemo.obj
0001:00000070 _main 00401070 f CrashDemo.obj
0004:00000000 __IMPORT_DESCRIPTOR_KERNEL32 00424000 kernel32:KERNEL32.dll
0004:00000014 __NULL_IMPORT_DESCRIPTOR 00424014 kernel32:KERNEL32.dll
0004:00000138 __imp__GetCommandLineA@0 00424138 kernel32:KERNEL32.dll
0004:0000013c __imp__GetVersion@0 0042413c kernel32:KERNEL32.dll
0004:00000140 __imp__ExitProcess@4 00424140 kernel32:KERNEL32.dll
0004:00000144 __imp__DebugBreak@0 00424144 kernel32:KERNEL32.dll
0004:00000148 __imp__GetStdHandle@4 00424148 kernel32:KERNEL32.dll
0004:0000014c __imp__WriteFile@20 0042414c kernel32:KERNEL32.dll
0004:00000150 __imp__InterlockedDecrement@4 00424150 kernel32:KERNEL32.dll
0004:00000154 __imp__OutputDebugStringA@4 00424154 kernel32:KERNEL32.dll
0004:00000158 __imp__GetProcAddress@8 00424158 kernel32:KERNEL32.dll
0004:0000015c __imp__LoadLibraryA@4 0042415c kernel32:KERNEL32.dll
0004:00000160 __imp__InterlockedIncrement@4 00424160 kernel32:KERNEL32.dll
0004:00000164 __imp__GetMoleFileNameA@12 00424164 kernel32:KERNEL32.dll
0004:00000168 __imp__TerminateProcess@8 00424168 kernel32:KERNEL32.dll
0004:0000016c __imp__GetCurrentProcess@0 0042416c kernel32:KERNEL32.dll
0004:00000170 __imp__UnhandledExceptionFilter@4 00424170 kernel32:KERNEL32.dll
0004:00000174 __imp__FreeEnvironmentStringsA@4 00424174 kernel32:KERNEL32.dll
0004:00000178 __imp__FreeEnvironmentStringsW@4 00424178 kernel32:KERNEL32.dll
0004:0000017c __imp__WideCharToMultiByte@32 0042417c kernel32:KERNEL32.dll
0004:00000180 __imp__GetEnvironmentStrings@0 00424180 kernel32:KERNEL32.dll
0004:00000184 __imp__GetEnvironmentStringsW@0 00424184 kernel32:KERNEL32.dll
0004:00000188 __imp__SetHandleCount@4 00424188 kernel32:KERNEL32.dll
0004:0000018c __imp__GetFileType@4 0042418c kernel32:KERNEL32.dll
0004:00000190 __imp__GetStartupInfoA@4 00424190 kernel32:KERNEL32.dll
0004:00000194 __imp__HeapDestroy@4 00424194 kernel32:KERNEL32.dll
0004:00000198 __imp__HeapCreate@12 00424198 kernel32:KERNEL32.dll
0004:0000019c __imp__HeapFree@12 0042419c kernel32:KERNEL32.dll
0004:000001a0 __imp__VirtualFree@12 004241a0 kernel32:KERNEL32.dll
0004:000001a4 __imp__RtlUnwind@16 004241a4 kernel32:KERNEL32.dll
0004:000001a8 __imp__GetLastError@0 004241a8 kernel32:KERNEL32.dll
0004:000001ac __imp__SetConsoleCtrlHandler@8 004241ac kernel32:KERNEL32.dll
0004:000001b0 __imp__IsBadWritePtr@8 004241b0 kernel32:KERNEL32.dll
0004:000001b4 __imp__IsBadReadPtr@8 004241b4 kernel32:KERNEL32.dll
0004:000001b8 __imp__HeapValidate@12 004241b8 kernel32:KERNEL32.dll
0004:000001bc __imp__GetCPInfo@8 004241bc kernel32:KERNEL32.dll
0004:000001c0 __imp__GetACP@0 004241c0 kernel32:KERNEL32.dll
0004:000001c4 __imp__GetOEMCP@0 004241c4 kernel32:KERNEL32.dll
0004:000001c8 __imp__HeapAlloc@12 004241c8 kernel32:KERNEL32.dll
0004:000001cc __imp__VirtualAlloc@16 004241cc kernel32:KERNEL32.dll
0004:000001d0 __imp__HeapReAlloc@16 004241d0 kernel32:KERNEL32.dll
0004:000001d4 __imp__MultiByteToWideChar@24 004241d4 kernel32:KERNEL32.dll
0004:000001d8 __imp__LCMapStringA@24 004241d8 kernel32:KERNEL32.dll
0004:000001dc __imp__LCMapStringW@24 004241dc kernel32:KERNEL32.dll
0004:000001e0 __imp__GetStringTypeA@20 004241e0 kernel32:KERNEL32.dll
0004:000001e4 __imp__GetStringTypeW@16 004241e4 kernel32:KERNEL32.dll
0004:000001e8 __imp__SetFilePointer@16 004241e8 kernel32:KERNEL32.dll
0004:000001ec __imp__SetStdHandle@8 004241ec kernel32:KERNEL32.dll
0004:000001f0 __imp__FlushFileBuffers@4 004241f0 kernel32:KERNEL32.dll
0004:000001f4 __imp__CloseHandle@4 004241f4 kernel32:KERNEL32.dll
0004:000001f8 \177KERNEL32_NULL_THUNK_DATA 004241f8 kernel32:KERNEL32.dll

entry point at 0001:000000f0

Line numbers for .\Debug\CrashDemo.obj(d:\msdev\myprojects\crashdemo\crashdemo.cpp) segment .text

13 0001:00000020 14 0001:00000038 15 0001:0000003f 16 0001:00000046
17 0001:00000050 20 0001:00000070 21 0001:00000088 22 0001:0000008d

如果仔細瀏覽 Rva+Base 這欄,你會發現第一個比崩潰地址 0x0040104a 大的函數地址是 0x00401070 ,所以在 0x00401070 這個地址之前的那個入口就是產生崩潰的函數,也就是這行:

0001:00000020 ?Crash@@YAXXZ 00401020 f CrashDemo.obj

因此,發生崩潰的函數就是 ?Crash@@YAXXZ ,所有以問號開頭的函數名稱都是 C++ 修飾的名稱。在我們的源程序中,也就是 Crash() 這個子函數。

OK,現在我們輕而易舉地便知道了發生崩潰的函數名稱,你是不是很興奮呢?呵呵,先別忙,接下來,更厲害的招數要出場了。

請注意 MAP 文件的最後部分--代碼行信息(Line numbers information),它是以這樣的形式顯示的:

13 0001:00000020

第一個數字代表在源代碼中的代碼行號,第二個數是該代碼行在所屬的代碼段中的偏移量。

如果要查找代碼行號,需要使用下面的公式做一些十六進制的減法運算:

崩潰行偏移 = 崩潰地址(Crash Address) - 基地址(ImageBase Address) - 0x1000

為什麼要這樣做呢?細心的朋友可能會留意到 Rva+Base 這欄了,我們得到的崩潰地址都是由 偏移地址(Rva)+ 基地址(Base) 得來的,所以在計算行號的時候要把基地址減去,一般情況下,基地址的值是 0x00400000 。另外,由於一般的 PE 文件的代碼段都是從 0x1000 偏移開始的,所以也必須減去 0x1000 。

好了,明白了這點,我們就可以來進行小學減法計算了:

崩潰行偏移 = 0x0040104a - 0x00400000 - 0x1000 = 0x4a

如果瀏覽 MAP 文件的代碼行信息,會看到不超過計算結果,但卻最接近的數是 CrashDemo.cpp 文件中的:

16 0001:00000046

也就是在源代碼中的第 16 行,讓我們來看看源代碼:

16 i /= j;

哈!!!果然就是第 16 行啊!

興奮嗎?我也一樣! :)

方法已經介紹完了,從今以後,我們就可以精確地定位到源代碼中的崩潰行,而且只要編譯器可以生成 MAP 文件(包括 VC、MASM、VB、BCB、Delphi……),本方法都是適用的。我們時常抱怨 M$ 的產品如何如何差,但其實 M$ 還是有意無意間提供了很多有價值的信息給我們的,只是我們往往不懂得怎麼利用而已……相信這樣一來,你就可以更為從容地面對「非法操作」提示了。你甚至可以要求用戶提供崩潰的地址,然後就可以坐在家中舒舒服服地找到出錯的那行,並進行修正。

Ⅷ 如何設置文件加密

步驟一:打開Windows資源管理器。
步驟二:右鍵單擊要加密的文件或文件夾,然後單擊「屬性」。
步驟三:在「常規」選項卡上,單擊「高級」。選中「加密內容以便保護數據」復選框
我按這個方法加密了一個文件夾,看來沒什麼作用,還是是因為我沒操作正確。
這個是賬戶加密的的。也就是說
那賬戶加密的那個就可用。你換一個賬戶就不能用了。
你還是用加密軟體加密方便一些

Ⅸ 使用win7系統,怎樣給程序加鎖

應用程序加密分不同情況,可以參考如下內容。
一、如果只想讓自己使用,不想讓別人使用。
1、綠色軟體,即隨時雙擊即可運行的程序,可以使用winrar加密,在應用程序上右鍵,選擇「添加到壓縮文件」,在彈出的窗口中,點擊」高級「選項卡,點擊」設置密碼」,設置成密碼即可,以後,要運行此程序,只需要雙擊打開壓縮包,輸入密碼運行即可。不知道密碼的用戶就沒有辦法使用該程序。winrar的加密演算法是不可逆的,可放心使用。

2、安裝類的應用程序,有些軟體需要安裝才可以使用,比如QQ、網路雲管家等等。此種軟體,可以通過設置許可權來限制用戶訪問,在要設置許可權的應用程序上,右鍵選擇「屬性」,點擊「安全」選項卡,點擊「編輯」,把除了自己用的系統管理員帳號之外的所有用戶名、用戶組,全部刪除掉。這樣即使別人用不同的用戶名登錄當前系統,也不能訪問相應應用軟體。

二、程序文件的加密 。
程序文件的加密主要是為了防止破解,一般針對的是程序員來說的,普通程序員,可以使用加殼程序對程序文件進行加密保護,比如asprotect、zprotect、vmprotct等等加殼工具。 如果對軟體加密解密有研究,自己可以開發自己專用的殼。

android 程序怎麼加密,不讓別人反編譯

代碼混淆(code obfuscation)是指將計算機程序的代碼,轉換成一種功能上等價,所謂功能上的等價是指其在變換前後功能相同或相近。其解釋如下:程序P經過混淆變換為P『,若P沒有結束或錯誤結束,那麼P』也不能結束或錯誤結束;而且P『程序的結果應與程序P具有相同的輸出。否則P』不是P的有效的混淆。


目前對於混淆的分類,普遍是以Collberg 的理論為基礎,分為布局混淆(layout obfuscation)、數據混淆(data obfuscation)、控制混淆(control obfuscation)和預防混淆(preventive obfuscation)這四種類型。

1. 布局混淆

布局混淆是指刪除或者混淆軟體源代碼或者中間代碼中與執行無關的輔助文本信息,增加攻擊者閱讀和理解代碼的難度。軟體源代碼中的注釋文本、調試信息可以直接刪除,用不到的方法和類等代碼或數據結構也可以刪除,這樣即可以使攻擊者難以理解代碼的語義,也可以減小軟體體積,提高軟體裝載和執行的效率。軟體代碼中的常量名、變數名、類名和方法名等標識符的命名規則和字面意義有利於攻擊者對代碼的理解,布局混淆通過混淆這些標識符增加攻擊者對軟體代碼理解的難度。標識符混淆的方法有多種,例如哈希函數命名、標識符交換和重載歸納等。哈希函數命名是簡單地將原來標識符的字元串替換成該字元串的哈希值,這樣標識符的字元串就與軟體代碼不相關了;標識符交換是指先收集軟體代碼中所有的標識符字元串,然後再隨機地分配給不同的標識符,該方法不易被攻擊者察覺;重載歸納是指利用高級編程語言命名規則中的一些特點,例如在不同的命名空間中變數名可以相同,使軟體中不同的標識符盡量使用相同的字元串,增加攻擊者對軟體源代碼的理解難度。布局混淆是最簡單的混淆方法,它不改變軟體的代碼和執行過程。

2. 數據混淆

數據混淆是修改程序中的數據域,而對代碼段不作處理。常用的數據混淆方式有合並變數、分割變數、數組重組、字元串加密等。

合並變數是將幾個變數合並為一個數據,原來的每個變數占據其中一個區域,類似於一個大的數據結構。分割變數則是將一個變數分割為兩個變數,對分割前後提供一種映射關系,將對一個變數的操作轉化為對分割後兩個變數的操作。

數組重組有數組的分割、合並、折疊和平滑等幾種方式。分割是將一個數組分成2個或多個相同維度的數組;合並則相反;折疊是增加數組的維數;平滑則是相反。

在ELF文件中,全局變數和常量字元串存放在數據段中,反匯編工具可以輕易查找到字元串與代碼之間的引用關系。在軟體破解中,通過一些字元串提示可以很方便的找到代碼關鍵語句,從而破解軟體。字元串加密則可以對這些明顯的字元串進行加密存儲,在需要時再進行解密。

3. 控制混淆

控制混淆也稱流程混淆,它是改變程序的執行流程,從而打斷逆向分析人員的跟蹤思路,達到保護軟體的目的。一般採用的技術有插入指令、偽裝條件語句、斷點等。偽裝條件語句是當程序順序執行從A到B,混淆後在A和B之間加入條件判斷,使A執行完後輸出TRUE或FALSE,但不論怎麼輸出,B一定會執行。

控制混淆採用比較多的還有模糊謂詞、內嵌外聯、打破順序等方法。

模糊謂詞是利用消息不對稱的原理,在加入模糊謂詞時其值對混淆者是已知的,而對反混淆者卻很難推知。所以加入後將干擾反匯編者對值的分析。模糊謂詞的使用一般是插入一些死的或不相關的代碼(bogus code),或者是插入在循環或分支語句中,打斷程序執行流程。

內嵌(in-line)是將一小段程序嵌入到被調用的每一個程序點,外聯(out-line)是將沒有任何邏輯聯系的一段代碼抽象成一段可被多次調用的程序。

打破順序是指打破程序的局部相關性。由於程序員往往傾向於把相關代碼放在一起,通過打破順序改變程序空間結構,將加大破解者的思維跳躍。

4. 預防混淆

預防混淆一般是針對專用的反編譯器設計的,目的就是預防被這類反編譯器反編譯。他是利用特定的反編譯器或反混淆器的弱點進行專門設計。預防混淆對於特定的反編譯器非常有效,所以在使用時要綜合利用各種反編譯器的特點進行設計。

閱讀全文

與程序員如何加密軟體相關的資料

熱點內容
盛勢txt 瀏覽:767
兩只狼老大和一個小嬰兒是什麼電影 瀏覽:433
三洋帝度冰箱壓縮機 瀏覽:297
多義線命令 瀏覽:48
小說免費網站有哪些 瀏覽:466
外國太空歷險的兒童片 瀏覽:693
韓國《貪欲之島》女主角 瀏覽:582
一個西方電影講述變異 瀏覽:312
女大學生的沙龍室女演員 瀏覽:738
歐美大片網站 瀏覽:924
周星馳電影七仔小女孩叫什麼 瀏覽:75
印度電影講一男一女在兩輛汽車窗戶上寫字留言 瀏覽:469
ck236編程 瀏覽:392
芭比大電影35部大全公主名字 瀏覽:429
九叔世界酒泉鎮安妮 瀏覽:302
榮耀新手機開機怎麼那麼多app 瀏覽:535
3dmax命令面板上插值沒有了 瀏覽:788
十大必看火影小說排行榜 瀏覽:484
用雲伺服器做視頻播放直播 瀏覽:344
iphone文件里突然多了QQ的文件夾 瀏覽:904