導航:首頁 > 源碼編譯 > 如何保護程序不讓別人反編譯

如何保護程序不讓別人反編譯

發布時間:2022-07-31 10:39:45

1. C#如何防止被別人反編譯

C#
編寫的代碼通過VS編譯器生成
dll

exe
,很容易被一些反編譯工具查看到源碼或對源碼進行修改。
為防止代碼被反編譯或被篡改,我們可以進行一定的防範措施。但不能杜絕,因為DotNet編寫代碼運行必須編譯成IL
中間語言,IL是很規則,同時也很好反編譯。
反編譯防範措施:
設置項目代碼反匯編屬性
混淆
方法一:防止
Ildasm.exe(MSIL
反匯編程序)
反匯編程序集
方法很簡單在項目文件AssemblyInfo.cs中增加SuppressIldasm屬性。
當項目中增加SuppressIldasm屬性後在使用ildasm.exe反編譯代碼,會提示:"受保護的模塊
--
無法進行反匯編"
ildasm.exe
讀取項目中包含
SuppressIldasm
屬性就不對此程序集進行反編譯。但ILSyp,Reflector等反編譯工具針對程序集設置SuppressIldasm屬性置之不理,一樣可以反編譯源碼。
缺點:
可見SuppressIldasm
屬性只針對ildasm.exe工具起效果,同時也能刪除ildasm.exe工具的此項限制。參考:《去掉ILDasm的SuppressIldasmAttribute限制》
方法二:混淆
混淆原理:將VS編譯出的文件(exe

dll)通過ildasm對文件進行重命名,字元串加密,移動等方式將原始代碼打亂。這種方式比較常見。
VS2013
自帶混淆工具:工具-->PreEmptive
Dotfuscator
and
Analytics
但VS2013自帶Dotfuscator
5.5
需購買激活才能使用全部功能。目前網路提供
DotfuscatorPro
4.9
破解版版本下載。
打開
DotfuscatorPro
4.9
主界面
Settings->Global
Options
全局配置
常用功能配置:Disable
String
Encryption=NO
啟用字元串加密
選擇需混淆C#編譯代碼(dll

exe)
其中Library不要勾選,否則有些類、變數等等不會混淆;
Rename
重命名配置
常用功能配置:
勾選
=
use
enhanced
overload
inction
使用增強模式
重命名方案
Renaming
Scheme
=
Unprintable
(不可列印字元,即亂碼),也可以選擇其他如小寫字母、大寫字元、數字的方式。
String
Encryption
字元串加密
勾選需要加密字元串文件(exe

dll)
可根據各自需求可進行其他相關配置。(如:control
flow,Output,Setting
->Build
Settings,Settings
-->
Project
Properties等)
最後生成混淆文件
Build
Project。
Build
Project
生成混淆項目錯誤:
Could
not
find
a
compatible
version
of
ildasm
to
run
on
assembly
C:Users***.exe.??This
assembly
was
originally
built
with
.NET
Framework
v4.0.30319.
Build
Error.
處理方法:
ILASM_v4.0.30319
=
C:WindowsMicrosoft.NETFrameworkv4.0.30319ilasm.exe
ILDASM_v4.0.30319
=
C:Program
Files
(x86)Microsoft
SDKsWindowsv8.1AinNETFX
4.5.1
Toolsildasm.exe
[安裝VS版本不同對應目錄會有所變化]
混淆代碼對比
未使用混淆工具,反編譯出的源碼:
使用混淆工具,反編譯出的源碼:
效果很明顯,很難看出反編譯代碼所寫的真正邏輯。
缺點:
C#代碼通過混淆工具生成後,增加了很多轉換過程。這使得反編譯工具無法很直觀看到源碼真正邏輯。但源碼代碼過多轉換會使軟體本身運行效率降低,甚至會出現報錯情況。

2. 如何防止代碼被反編譯

由於apk是android虛擬機載入的,它有一定的規范,加密apk後Dalvik無法識別apk了。完全避免是不可能的,總有人能夠破解你的代碼。但是有幾種方式來提高被反編譯取代碼的難度。
1 關鍵代碼使用jni調用本地代碼,用c或者c++編寫,因此相對比較難於反編譯

2 混淆java代碼。混淆是不改變代碼邏輯的情況下,增加無用代碼,或者重命名,使反編譯後的源代碼難於看懂。 網上開源的java代碼混淆工具較多,一般是用ant的方式來編譯的。

1 . 在工程文件project.properties中加入下proguard.config=proguard.cfg , 如下所示:
target=android-8
proguard.config=proguard.cfg
Eclipse會通過此配置在工程目錄生成proguard.cfg文件

2 . 生成keystore (如已有可直接利用)
按照下面的命令行 在D:\Program Files\Java\jdk1.6.0_07\bin>目錄下,輸入keytool -genkey -alias android.keystore -keyalg RSA -validity 100000 -keystore android.keystore
參數意義:-validity主要是證書的有效期,寫100000天;空格,退格鍵 都算密碼。
命令執行後會在D:\Program Files\Java\jdk1.6.0_07\bin>目錄下生成 android.keystore文件。

3. 在Eclipce的操作
File -> Export -> Export Android Application -> Select project -> Using the existing keystore , and input password -> select the destination APK file

經過混淆後的源代碼,原先的類名和方法名會被類似a,b,c。。。的字元所替換,混淆的原理其實也就是類名和方法名的映射。
但4大組件並沒有混淆(所有在清單文件定義的組件不能被混淆),因為系統需要通過清單文件來查找和運行應用程序。

proguard.cfg 文件代碼解讀
-optimizationpasses 5 ->設置混淆的壓縮比率 0 ~ 7
-dontusemixedcaseclassnames -> Aa aA
- ->如果應用程序引入的有jar包,並且想混淆jar包裡面的class
-dontpreverify
-verbose ->混淆後生產映射文件 map 類名->轉化後類名的映射

-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* ->混淆採用的演算法.

-keep public class * extends android.app.Activity ->所有activity的子類不要去混淆
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

-keepclasseswithmembernames class * {
native <methods>; -> 所有native的方法不能去混淆.
}

-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
-->某些構造方法不能去混淆
}

-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}

-keepclassmembers enum * { -> 枚舉類不能去混淆.
public static **[] values();
public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable { -> aidl文件不能去混淆.
public static final android.os.Parcelable$Creator *;
}

3. .net如何防反編譯

.net是中間語言十分容易被反編譯,通常都使用混淆作為一種加密手段。不過混淆不是真正防反編譯,只不過反編譯後代碼難讀懂而已,並且現在破解混淆的方式也比較多。所以真正要防反編譯還是需要通過加密代碼的方式。比如德國威步他們提供一種對.NET代碼完全加密保護的方式來防止反編譯的,曾經測試過用Reflector(.net反編譯工具)反編譯他們加密軟體加密的.NET程序,的確完全無法看到源代碼了。

4. 怎麼防止開發出來的程序被別人反編譯

1.本地數據加密
iOS應用防反編譯加密技術之一:對NSUserDefaults,sqlite存儲文件數據加密,保護帳號和關鍵信息
2.URL編碼加密
iOS應用防反編譯加密技術之二:對程序中出現的URL進行編碼加密,防止URL被靜態分析
3.網路傳輸數據加密
iOS應用防反編譯加密技術之三:對客戶端傳輸數據提供加密方案,有效防止通過網路介面的攔截獲取數據
4.方法體,方法名高級混淆
iOS應用防反編譯加密技術之四:對應用程序的方法名和方法體進行混淆,保證源碼被逆向後無法解析代碼
5.程序結構混排加密
iOS應用防反編譯加密技術之五:對應用程序邏輯結構進行打亂混排,保證源碼可讀性降到最低

5. 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. 預防混淆

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

6. 如何讓C++寫的dll不被反編譯

簡單回答:
1、理論上不能保證程序不被反編譯。
2、一些加殼軟體可以做到加大被反編譯的難度,迫使操作者先解殼才能做反編譯,但同時會降低程序的運行效率。
3、當前的技術條件下,一般而言,反編譯出的「源代碼」一般而言並不能作學習,參考的源代碼,多數情況下只能用於分析區部片斷分析,主要用於破解或小范圍類修改。
4、一些簡單的加殼軟體:ASPACK、UPX、PECompact等,如果想嘗試,自個去搜索下載後試試。加殼後的軟體還有可能被某些殺軟當成惡意軟體。
5、這也正是很多對安全要求高的系統使用「三層架構」(類似訪問網頁/網站)的原因。因為在三層架構中,核心軟體、數據不被用戶直接接觸。

************以下是相關知識,有耐心可看看************
一、關於反編譯與破解。
1、以當前的技術來說,理論上,所有的程序都存在被反編譯的可能。
2、但是反編譯出來的代碼並不一定能被技術不高的人看懂,因為反編譯出來的「源代碼」與編寫者寫出的原代碼在80%以上是不同的。這是因為反編譯的原理是根據機器碼(或中間碼),讓機算機進行反向生成高級語言,而不是找出編寫者原有的代碼,找出原有的代碼是不可能的。反編譯出來的代碼在可理解性、可閱讀性上,一般而言是非常差的。
3、但是,這並不代碼反編譯出來的「源代碼」沒有價值,對於內行來說,分析反編譯出來的代碼中的某些特定片段,就可以對程序進行破解,找出程序的關鍵點、口令、數據來源等等。因為破壞總是比建設要容易,分析局部比規劃全局要容易得多。
4、如果考慮到被反編譯將關鍵代碼進行特殊處理的話,可能加大相關的難度,比如將特定的字元串分成多個字串在程序中存儲,或是進行加密後存儲,在使用時合成/生成,不用時即時在內存中清除等等……。
5、反編譯後對關鍵部分的定位往往是根據字元串來進行的,比如在用戶沒有注冊時,跳出一行對話,告訴用戶「請注冊後再使用」,破解者就會在反編譯後追查這個字串所在,然後查到這個字串對應的變數與地址,再追查調用這個變數或地址的代碼,然後再延伸查到什麼情況下調用「調用這個變數或地址的代碼」,最後,設定跳過語句。這就是最典型的破解注冊的方法。破解完再將修改了的「源代碼」進行編譯,或是根據「源代碼」直接修正程序中對應的代碼,OK,破解版正式完成。
二、關於加殼。
1、理論上,同樣,沒有破解不了的殼。
2、但是有些加殼軟體使用了一些特別的方法,使得破解殼的難度變得非常難,技術不夠的朋友很難下手,比如將原程序代碼拆分、變型、植入自校驗等等技術。
3、但加殼軟體同樣是程序,它自身就存在被反編的可能,加了殼可以類比成,在一個木箱外面再加個保險櫃。但千萬別以為保險櫃就一定是保險的,面對各種技術開鎖、暴力開箱,再強的保險櫃也只能是加大難度而已。
4、越復雜的加殼,就會使得程序運行時效率降得越低,這是必然的,因為原本只關注目標任務的程序現在還要時時提防著被提取、被監測。

7. 如何保護Java程序 防止Java反編譯

Java是一種跨平台的、解釋型語言。Java 源代碼編譯中間「位元組碼」存儲於class文件中。Class文件是一種位元組碼形式的中間代碼,該位元組碼中包括了很多源代碼的信息,例如變數名、方法名等。因此,Java中間代碼的反編譯就變得非常容易。目前市場上有許多免費的、商用的反編譯軟體,都能夠生成高質量的反編譯後的源代碼。所以,對開發人員來說,如何保護Java程序就變成了一個非常重要的挑戰。本文首先討論了保護Java程序的基本方法,然後對代碼混淆問題進行深入研究,最後結合一個實際的應用程序,分析如何在實踐中保護Java程序。 反編譯成為保護Java程序的最大挑戰 通常C、C++等編程語言開發的程序都被編譯成目標代碼,這些目標代碼都是本機器的二進制可執行代碼。通常所有的源文件被編譯、鏈接成一個可執行文件。在這些可執行文件中,編譯器刪除了程序中的變數名稱、方法名稱等信息,這些信息往往是由內存地址表示,例如如果需要使用一個變數,往往是通過這個變數的地址來訪問的。因此,反編譯這些本地的目標代碼就是非常困難的。 Java語言的出現,使得反編譯變得非常容易而有效。原因如下:1.由於跨平台的需求,Java的指令集比較簡單而通用,較容易得出程序的語義信息;2.Java編譯器將每一個類編譯成一個單獨的文件,這也簡化了反編譯的工作;3.Java 的Class文件中,仍然保留所有的方法名稱、變數名稱,並且通過這些名稱來訪問變數和方法,這些符號往往帶有許多語義信息。由於Java程序自身的特點,對於不經過處理的Java程序反編譯的效果非常好。 目前,市場上有許多Java的反編譯工具,有免費的,也有商業使用的,還有的是開放源代碼的。這些工具的反編譯速度和效果都非常不錯。好的反編譯軟體,能夠反編譯出非常接近源代碼的程序。因此,通過反編譯器,黑客能夠對這些程序進行更改,或者復用其中的程序。因此,如何保護Java程序不被反編譯,是非常重要的一個問題。 常用的保護技術 由於Java位元組碼的抽象級別較高,因此它們較容易被反編譯。本節介紹了幾種常用的方法,用於保護Java位元組碼不被反編譯。通常,這些方法不能夠絕對防止程序被反編譯,而是加大反編譯的難度而已,因為這些方法都有自己的使用環境和弱點。 隔離Java程序 最簡單的方法就是讓用戶不能夠訪問到Java Class程序,這種方法是最根本的方法,具體實現有多種方式。例如,開發人員可以將關鍵的Java Class放在伺服器端,客戶端通過訪問伺服器的相關介面來獲得服務,而不是直接訪問Class文件。這樣黑客就沒有辦法反編譯Class文件。目前,通過介面提供服務的標准和協議也越來越多,例如 HTTP、Web Service、RPC等。但是有很多應用都不適合這種保護方式,例如對於單機運行的程序就無法隔離Java程序。這種保護方式見圖1所示。 圖1隔離Java程序示意圖 對Class文件進行加密 為了防止Class文件被直接反編譯,許多開發人員將一些關鍵的Class文件進行加密,例如對注冊碼、序列號管理相關的類等。在使用這些被加密的類之前,程序首先需要對這些類進行解密,而後再將這些類裝載到JVM當中。這些類的解密可以由硬體完成,也可以使用軟體完成。 在實現時,開發人員往往通過自定義ClassLoader類來完成加密類的裝載(注意由於安全性的原因,Applet不能夠支持自定義的ClassLoader)。自定義的ClassLoader首先找到加密的類,而後進行解密,最後將解密後的類裝載到JVM當中。在這種保護方式中,自定義的ClassLoader是非常關鍵的類。由於它本身不是被加密的,因此它可能成為黑客最先攻擊的目標。如果相關的解密密鑰和演算法被攻克,那麼被加密的類也很容易被解密。這種保護方式示意圖見圖2。 圖2 對Class文件進行加密示意圖 轉換成本地代碼 將程序轉換成本地代碼也是一種防止反編譯的有效方法。因為本地代碼往往難以被反編譯。開發人員可以選擇將整個應用程序轉換成本地代碼,也可以選擇關鍵模塊轉換。如果僅僅轉換關鍵部分模塊,Java程序在使用這些模塊時,需要使用JNI技術進行調用。 當然,在使用這種技術保護Java程序的同時,也犧牲了Java的跨平台特性。對於不同的平台,我們需要維護不同版本的本地代碼,這將加重軟體支持和維護的工作。不過對於一些關鍵的模塊,有時這種方案往往是必要的。 為了保證這些本地代碼不被修改和替代,通常需要對這些代碼進行數字簽名。在使用這些本地代碼之前,往往需要對這些本地代碼進行認證,確保這些代碼沒有被黑客更改。如果簽名檢查通過,則調用相關JNI方法。這種保護方式示意圖見圖3。 代碼混淆
圖3 轉換成本地代碼示意圖 代碼混淆是對Class文件進行重新組織和處理,使得處理後的代碼與處理前代碼完成相同的功能(語義)。但是混淆後的代碼很難被反編譯,即反編譯後得出的代碼是非常難懂、晦澀的,因此反編譯人員很難得出程序的真正語義。從理論上來說,黑客如果有足夠的時間,被混淆的代碼仍然可能被破解,甚至目前有些人正在研製反混淆的工具。但是從實際情況來看,由於混淆技術的多元化發展,混淆理論的成熟,經過混淆的Java代碼還是能夠很好地防止反編譯。下面我們會詳細介紹混淆技術,因為混淆是一種保護Java程序的重要技術。圖4是代碼混淆的示意圖。
圖4 代碼混淆示意圖 幾種技術的總結 以上幾種技術都有不同的應用環境,各自都有自己的弱點,表1是相關特點的比較。 混淆技術介紹 表1 不同保護技術比較表
到目前為止,對於Java程序的保護,混淆技術還是最基本的保護方法。Java混淆工具也非常多,包括商業的、免費的、開放源代碼的。Sun公司也提供了自己的混淆工具。它們大多都是對Class文件進行混淆處理,也有少量工具首先對源代碼進行處理,然後再對Class進行處理,這樣加大了混淆處理的力度。目前,商業上比較成功的混淆工具包括JProof公司的1stBarrier系列、Eastridge公司的JShrink和4thpass.com的SourceGuard等。主要的混淆技術按照混淆目標可以進行如下分類,它們分別為符號混淆(Lexical Obfuscation)、數據混淆(Data Obfuscation)、控制混淆(Control Obfuscation)、預防性混淆(Prevent Transformation)。 符號混淆 在Class中存在許多與程序執行本身無關的信息,例如方法名稱、變數名稱,這些符號的名稱往往帶有一定的含義。例如某個方法名為getKeyLength(),那麼這個方法很可能就是用來返回Key的長度。符號混淆就是將這些信息打亂,把這些信息變成無任何意義的表示,例如將所有的變數從vairant_001開始編號;對於所有的方法從method_001開始編號。這將對反編譯帶來一定的困難。對於私有函數、局部變數,通常可以改變它們的符號,而不影響程序的運行。但是對於一些介面名稱、公有函數、成員變數,如果有其它外部模塊需要引用這些符號,我們往往需要保留這些名稱,否則外部模塊找不到這些名稱的方法和變數。因此,多數的混淆工具對於符號混淆,都提供了豐富的選項,讓用戶選擇是否、如何進行符號混淆。 數據混淆 圖5 改變數據訪問 數據混淆是對程序使用的數據進行混淆。混淆的方法也有多種,主要可以分為改變數據存儲及編碼(Store and Encode Transform)、改變數據訪問(Access Transform)。 改變數據存儲和編碼可以打亂程序使用的數據存儲方式。例如將一個有10個成員的數組,拆開為10個變數,並且打亂這些變數的名字;將一個兩維數組轉化為一個一維數組等。對於一些復雜的數據結構,我們將打亂它的數據結構,例如用多個類代替一個復雜的類等。 另外一種方式是改變數據訪問。例如訪問數組的下標時,我們可以進行一定的計算,圖5就是一個例子。 在實踐混淆處理中,這兩種方法通常是綜合使用的,在打亂數據存儲的同時,也打亂數據訪問的方式。經過對數據混淆,程序的語義變得復雜了,這樣增大了反編譯的難度。 控制混淆 控制混淆就是對程序的控制流進行混淆,使得程序的控制流更加難以反編譯,通常控制流的改變需要增加一些額外的計算和控制流,因此在性能上會給程序帶來一定的負面影響。有時,需要在程序的性能和混淆程度之間進行權衡。控制混淆的技術最為復雜,技巧也最多。這些技術可以分為如下幾類: 增加混淆控制 通過增加額外的、復雜的控制流,可以將程序原來的語義隱藏起來。例如,對於按次序執行的兩個語句A、B,我們可以增加一個控制條件,以決定B的執行。通過這種方式加大反匯編的難度。但是所有的干擾控制都不應該影響B的執行。圖6就給出三種方式,為這個例子增加混淆控制。 圖6 增加混淆控制的三種方式 控制流重組 重組控制流也是重要的混淆方法。例如,程序調用一個方法,在混淆後,可以將該方法代碼嵌入到調用程序當中。反過來,程序中的一段代碼也可以轉變為一個函數調用。另外,對於一個循環的控制流,為可以拆分多個循環的控制流,或者將循環轉化成一個遞歸過程。這種方法最為復雜,研究的人員也非常多。 預防性混淆 這種混淆通常是針對一些專用的反編譯器而設計的,一般來說,這些技術利用反編譯器的弱點或者Bug來設計混淆方案。例如,有些反編譯器對於Return後面的指令不進行反編譯,而有些混淆方案恰恰將代碼放在Return語句後面。這種混淆的有效性對於不同反編譯器的作用也不太相同的。一個好的混淆工具,通常會綜合使用這些混淆技術。 案例分析 在實踐當中,保護一個大型Java程序經常需要綜合使用這些方法,而不是單一使用某一種方法。這是因為每種方法都有其弱點和應用環境。綜合使用這些方法使得Java程序的保護更加有效。另外,我們經常還需要使用其它的相關安全技術,例如安全認證、數字簽名、PKI等。 本文給出的例子是一個Java應用程序,它是一個SCJP(Sun Certificate Java Programmer)的模擬考試軟體。該應用程序帶有大量的模擬題目,所有的題目都被加密後存儲在文件中。由於它所帶的題庫是該軟體的核心部分,所以關於題庫的存取和訪問就成為非常核心的類。一旦這些相關的類被反編譯,則所有的題庫將被破解。現在,我們來考慮如何保護這些題庫及相關的類。 在這個例子中,我們考慮使用綜合保護技術,其中包括本地代碼和混淆技術。因為該軟體主要發布在Windows上,因此轉換成本地代碼後,僅僅需要維護一個版本的本地代碼。另外,混淆對Java程序也是非常有效的,適用於這種獨立發布的應用系統。 在具體的方案中,我們將程序分為兩個部分,一個是由本地代碼編寫的題庫訪問的模塊,另外一個是由Java開發的其它模塊。這樣可以更高程度地保護題目管理模塊不被反編譯。對於Java開發的模塊,我們仍然要使用混淆技術。該方案的示意圖參見圖7。 圖7 SCJP保護技術方案圖 對於題目管理模塊,由於程序主要在Windows下使用,所以使用C++開發題庫訪問模塊,並且提供了一定的訪問介面。為了保護題庫訪問的介面,我們還增加了一個初始化介面,用於每次使用題庫訪問介面之前的初始化工作。它的介面主要分為兩類: 1. 初始化介面 在使用題庫模塊之前,我們必須先調用初始化介面。在調用該介面時,客戶端需要提供一個隨機數作為參數。題庫管理模塊和客戶端通過這個隨機數,按一定的演算法同時生成相同的SessionKey,用於加密以後輸入和輸出的所有數據。通過這種方式,只有授權(有效)的客戶端才能夠連接正確的連接,生成正確的SessionKey,用於訪問題庫信息。非法的客戶很難生成正確的SessionKey,因此無法獲得題庫的信息。如果需要建立更高的保密級別,也可以採用雙向認證技術。 2. 數據訪問介面 認證完成之後,客戶端就可以正常的訪問題庫數據。但是,輸入和輸出的數據都是由SessionKey所加密的數據。因此,只有正確的題庫管理模塊才能夠使用題庫管理模塊。圖8時序圖表示了題庫管理模塊和其它部分的交互過程。 圖8 題庫管理模塊和其它部分的交互過程圖

8. C#怎樣防止反編譯

我使用的方法是利用加殼工具:virboxProtectorStandalone。直接進行加殼。高級混淆、虛擬化代碼、智能壓縮等加密策略。如果要授權控制,可使用許可版本的virboxProtector。

未經加殼保護的 ILspy 反編譯效果如下:

public int add(int a, int b){
return a + b;}public int div(int a, int b){
return a / b;}public int mul(int a, int b){
return a * b;}public int sub(int a, int b){
return a - b;}

解決方案:

深思自主研發了為 C# .net 語言做保護的外殼(Virbox Protector)。將C# .net 編譯成的執行程序(.exe),動態庫(.dll)直接拖入加殼工具即可完成保護操作,十分方便。並且在效果上已經完全看不到源碼中的邏輯。

加密後的效果

public int add(int a, int b){
return (int)dm.dynamic_method((object)this, System.Reflection.MethodBase.GetCurrentMethod(), 16416u, 21, 16384u, 32u, 31516u, 5).Invoke(this, new object[]
{
this,
a,
b
});}
public int div(int a, int b){
return (int)dm.dynamic_method((object)this, System.Reflection.MethodBase.GetCurrentMethod(), 16956u, 21, 16924u, 32u, 31516u, 2).Invoke(this, new object[]
{
this,
a,
b
});}
public int mul(int a, int b){
return (int)dm.dynamic_method((object)this, System.Reflection.MethodBase.GetCurrentMethod(), 16776u, 21, 16744u, 32u, 31516u, 3).Invoke(this, new object[]
{
this,
a,
b
});}
public int sub(int a, int b){
return (int)dm.dynamic_method((object)this, System.Reflection.MethodBase.GetCurrentMethod(), 16596u, 21, 16564u, 32u, 31516u, 4).Invoke(this, new object[]
{
this,
a,
b
});}

架構支持

IIS 服務架構的後台邏輯 DLL 文件

windows PC 應用程序 EXE 文件

windows PC 應用程序動態庫 DLL 文件

UG等第三方繪圖工具使用的 DLL 文件

Unity3d 編譯使用的 DLL 文件

9. 怎樣才能讓c#寫的程序不被反編譯

對於.NET程序常用的保護措施有混淆、加密、加殼,但對應的有脫殼、解密、反混淆,雖然混淆是個不可逆的過程,但可以反混成盡量可讀的代碼。由於il與.net語言的round-tripping,所以反編譯在理論上是完全可行的,只是難度問題。我們現在能做的就是提高反編譯的難度!所以想「讓c#寫的程序不被反編譯」,期待VS2015的native。

10. 如何有效的防止Java程序被反編譯和破解

由於Java位元組碼的抽象級別較高,因此它們較容易被反編譯。下面介紹了幾種常用的方法,用於保護Java位元組碼不被反編譯。通常,這些方法不能夠絕對防止程序被反編譯,而是加大反編譯的難度而已,因為這些方法都有自己的使用環境和弱點。
1.隔離Java程序
最簡單的方法就是讓用戶不能夠訪問到Java Class程序,這種方法是最根本的方法,具體實現有多種方式。例如,開發人員可以將關鍵的Java Class放在伺服器端,客戶端通過訪問伺服器的相關介面來獲得服務,而不是直接訪問Class文件。這樣黑客就沒有辦法反編譯Class文件。目前,通過介面提供服務的標准和協議也越來越多,例如 HTTP、Web Service、RPC等。但是有很多應用都不適合這種保護方式,例如對於單機運行的程序就無法隔離Java程序。
2.對Class文件進行加密
為了防止Class文件被直接反編譯,許多開發人員將一些關鍵的Class文件進行加密,例如對注冊碼、序列號管理相關的類等。在使用這些被加密的類之前,程序首先需要對這些類進行解密,而後再將這些類裝載到JVM當中。這些類的解密可以由硬體完成,也可以使用軟體完成。
在實現時,開發人員往往通過自定義ClassLoader類來完成加密類的裝載(注意由於安全性的原因,Applet不能夠支持自定義的ClassLoader)。自定義的ClassLoader首先找到加密的類,而後進行解密,最後將解密後的類裝載到JVM當中。在這種保護方式中,自定義的ClassLoader是非常關鍵的類。由於它本身不是被加密的,因此它可能成為黑客最先攻擊的目標。如果相關的解密密鑰和演算法被攻克,那麼被加密的類也很容易被解密。
3.轉換成本地代碼
將程序轉換成本地代碼也是一種防止反編譯的有效方法。因為本地代碼往往難以被反編譯。開發人員可以選擇將整個應用程序轉換成本地代碼,也可以選擇關鍵模塊轉換。如果僅僅轉換關鍵部分模塊,Java程序在使用這些模塊時,需要使用JNI技術進行調用。當然,在使用這種技術保護Java程序的同時,也犧牲了Java的跨平台特性。對於不同的平台,我們需要維護不同版本的本地代碼,這將加重軟體支持和維護的工作。不過對於一些關鍵的模塊,有時這種方案往往是必要的。為了保證這些本地代碼不被修改和替代,通常需要對這些代碼進行數字簽名。在使用這些本地代碼之前,往往需要對這些本地代碼進行認證,確保這些代碼沒有被黑客更改。如果簽名檢查通過,則調用相關JNI方法。
4.代碼混淆
代碼混淆是對Class文件進行重新組織和處理,使得處理後的代碼與處理前代碼完成相同的功能(語義)。但是混淆後的代碼很難被反編譯,即反編譯後得出的代碼是非常難懂、晦澀的,因此反編譯人員很難得出程序的真正語義。從理論上來說,黑客如果有足夠的時間,被混淆的代碼仍然可能被破解,甚至目前有些人正在研製反混淆的工具。但是從實際情況來看,由於混淆技術的多元化發展,混淆理論的成熟,經過混淆的Java代碼還是能夠很好地防止反編譯。下面我們會詳細介紹混淆技術,因為混淆是一種保護Java程序的重要技術。

閱讀全文

與如何保護程序不讓別人反編譯相關的資料

熱點內容
價格便宜的雲伺服器 瀏覽:551
寶馬n52電腦怎麼編程 瀏覽:350
安卓平板android如何降級 瀏覽:124
蘋果怎麼下載整理文字軟體app 瀏覽:130
怎麼刪除一個app下載任務 瀏覽:713
python執行bat命令 瀏覽:471
什麼吉他調音器app最好 瀏覽:33
php程序員招聘試題 瀏覽:14
程序員升職記第九關最優解 瀏覽:317
三星安卓11怎麼訪問data文件夾 瀏覽:817
華三伺服器怎麼設置開機自啟 瀏覽:711
釘郵登錄伺服器地址 瀏覽:644
起源編譯器適配第二款應用 瀏覽:433
cad弄斷線條命令 瀏覽:463
怎麼恢復手機app的安裝包 瀏覽:300
idea重啟項目不編譯 瀏覽:495
程序員那麼可愛演員表陸漓媽媽 瀏覽:127
linuxgadget驅動 瀏覽:594
華三調用acl的命令 瀏覽:9
資金流pdf 瀏覽:931