㈠ playframework1.x怎麼實現分頁的
首先Play有兩個分支, 1.x和2.x
1.x使用java開發, 只支持Java項目.
2.x使用Scala開發, 同時支持Java和Scala項目.
1.x我沒用過, Play2用過一段時間. 說說Play2的閃光點.
1. Play2的模板引擎.
Play2的模板是很強大並且容易上手的. 相對於Java領域其他模板引擎(Freemarker, Velocity, JSP, Groovy, etc), 主要有三個特點.
1) 簡單易上手, 沒有JSP裡面繁雜的內置對象和指令, 所有功能都通過方法調用完成.
2) 主流IDE中都支持Play模板的靜態類型檢查, 類似JSP.
3) 支持反向路由.
沒代碼我說個XX
舉個例子, 一般系統都會有一個固定的頁面布局, 比如分出 頁頭頁尾.如果用JSP或者Velocity之類的模板, 一般都是通過sitemesh+filter或者在每個頁面include來完成布局. 使用Play模板, 完成這個功能非常容易.
首先定義一個main頁面,
@(title: String = "默認標題")(staticFile: Html = Html(""))(content: Html)
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="utf-8" />
<title>@title</title>
</head>
<body>
@header() <-- 頁頭 -->
@navigator() <!-- 導航 -->
@content
<script src="@routes.Assets.versioned("js/jquery-1.11.2.min.js")"></script>
@staticFile
聲明了三個參數:
title標題, 有默認值
staticFile為html代碼塊, 可以傳js等
content為頁面內容
因為main頁面最後會被編譯成一個方法(准確地說是一個Scala object), 所以其他頁面
可以直接調用這個方法, 傳入自己自定義的內容.比如
@main() {
<script type="text/javascript">
FG.user.login();
</script>
} {
<div class="login width1200">
<!-- login -->
</div>
}
這樣就完成了頁面布局, 沒有隨處可見的include, 也沒有暗箱操作的filter, 所有的一切都是方法調用, 是不是很簡單清晰?
靜態類型檢查就不說了, 本來Java的一大優點(缺點)就是類型檢查 所以在Java里用Freemarker或者Velocity這種模板的做法值得商榷.
反向路由的意思是, 在Play中, 所有的Controller url都配置在一個routes文件中, 例如
GET /register @controllers.user.LoginController.registerPage
之後無論是在Controller里還是模板中, 都不用硬編碼url. 而是使用routes文件.
例如在Controller中: redirect(routes.LoginController.registerPage())就能實現重定向
而在模板中: <a href="@controllers.routes.LoginController.registerPage()">
使用反向路由的好處就是入口清晰, 項目里的所有url統一配置在一個文件里, 方便組織和維護.routes這種風格類似於REST里的URI模板, 其實Play是Java領域里最適合開發REST項目的框架之一.
2. 熱部署, 這個應該都知道了. 現在的Java Web框架沒這個功能都不好意思拿出來說.
雖然Scala代碼編譯很慢, 但是如果只是修改幾個類, sbt的增量編譯速度還是很快的. 基本上改代碼再刷新頁面就能看到結果.
3. 內置dev/prod環境隔離, 內置部署腳本.
平
常開發的時候使用run啟動Play, 是跑在dev模式. Play會定時掃描源碼目錄進行熱更新, 並且類都是訪問的時候再載入, 提高啟動速度.
使用start啟動項目就運行在prod模式.Play內置dist命令, 可以把所有的文件打包成一個zip,
解壓之後直接運行bin目錄下的可執行文件即可啟動項目, 除了JDK之外無須任何其他外部依賴.
4. 使用Play開發的Server大部分能做到Stateless.
Play
拋棄了Servlet/JSP里session, context等概念,
內置沒有提供方法將對象與伺服器實例進行綁定(你要使用HashMap存的話Play也沒辦法). 推薦的做法是使用外部緩存, 比如Redis,
Memcached等. 可能你覺得這是Play的一個缺點, 但是只要你開發過流量稍微大一點的應用, 你就會理解這點.
5. 好用的配置庫.
如果你之前開發過Java項目, 肯定寫過**.properties或者管理一大堆的xml..
Java
內置庫對properties文件的處理是很弱的, 你不得不自己寫一些工具類去進行處理.而且properties文件還不支持更復雜的語法.
Play的配置文件使用HOCON格式, 默認配置文件為application.conf.你能很容易讀取裡面的配置,
並且你也可以把自己的配置寫在裡面.所以基本上就用不到properties或者xml文件了.
6. Play插件.
Play有比較多的官方和第三方插件可以使用. 比如發郵件, 授權和驗證, 第三方登錄等等.自己寫一個插件也很簡單.
7. 優秀的測試支持(以下的例子為Play Java版本)
因為Play誕生的時候TDD已經很火熱, 所以Play對測試的支持非常好.
通過Helpers.fakeApplication()一行代碼就能模擬出一個Application(Play中的Application你可以理解為類似於Spring的Context).
FakeRequest request = new FakeRequest(POST, routes.LoginController.requestPhoneCode(phone).url());
Result result = route(request);
assertThat(status(result), is(OK));
三行代碼就能對Controller進行測試.
通過要測試完整的Http請求, 可以通過fakeServer在測試中啟動一個Play應用, 通過請求這個Play應用來完成測試.
Play還內置了對 Selenium WebDriver的支持, 可以模擬瀏覽器進行測試.以下是官方的例子:
@Test
public void runInBrowser() {
running(testServer(3333), HTMLUNIT, browser -> {
browser.goTo("");
assertThat(browser.$("#title").getText()).isEqualTo("Hello Guest");
browser.$("a").click();
assertThat(browser.url()).isEqualTo("/login");
});
}
以上說的都是優點. 當然坑也有一些.
不過用了Play2之後, 如果讓我在Java里再做技術選型, 我會不猶豫的選Play.
㈡ 什麼是科研平台
平台的意義很廣泛,不同人從事不同行業甚至在同一行業從事不同的方向對平台的認識和理解可能都會不同.但總體來說,平台也是有共性的,通常的理解是指一種基礎的可用於衍生其他產品的環境.這種環境可能只用於產生其他的產品,也有可能在產生其他產品的之後還會是這些衍生產品生存的環境.
比如說,在汽車行業,對於某一種類型的生產線,會稱之為一個平台.使用這種類型生產線生產出來的汽車都會具有一些相似的特徵,如標志的307和206,它們就是同一個平台的產物.
而計算機行業所說的windows平台及linux平台就是指一些軟體的運行環境.通常也是指這些軟體產生的環境.
但平台與平台之間不是絕對隔離的,因此,並不是所有產生於windows的軟體就不能運行於linux平台,這還要看使用什麼樣的編譯環境.從編譯的角度來看,平台就又有了新的定義,如使用C編譯器的編譯環境,我們就叫它C平台,使用其他的編譯語言,也可以叫相應的平台.這些都是編譯平台.但這樣的叫法比較奇怪,還是叫編譯環境的比較多.
所以,平台真的是一種很抽象的東西,它的定義可以很廣泛,也可以很狹隘,關鍵是要看如何方便我們實際生活工作中的溝通和對事物的理解.
至於如何去建立平台,那就要根據各個行業的不同具體去確定 ,如搞科研的平台叫科研平台。
如:分子生物學研究平台就擁有高效液相色譜、凝膠成像系統、高速與超速冷凍離心機、分子雜交儀、溫度梯度PCR儀、熒光顯微鏡等一批國際先進、搭配比較合理的分子生物學研究的硬體設施,可開展生物大分子提取與純化、基因克隆與功能分析、特異性蛋白的分離與鑒定、功能基因組學、等研究。
㈢ 怎樣對ssh框架結構的編譯之後的.class進行混淆處理,防止反編譯。
下面是我從論壇上靠過來的 希望對你有幫助
常用的保護技術
由於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 題庫管理模塊和其它部分的交互過程圖
㈣ net framework 2.0 是什麼
.NET Framework是支持生成和運行下一代應用程序和 XML Web services 的內部 Windows 組件。
.NET Framework現主要由以下幾部分組成:
(1).包括五種正式的語言編譯器(C#,Visual Basic,託管 C++,J#和Jscript 腳本語言等).
(2).框架類庫(Framework Class Library,FCL)由很多相關互聯的類庫組成,支持Windows應用程序.Web應用程序.Web服務和數據訪問等的開發.
(3).公共語言運行庫(Common Language Runtime,CLR)是處於,NET核心Framework的面向對象的引擎,其將各種語言編譯器生成的中間代碼編譯為執行應用程序所需要的原生碼(native code).
NET Framework主要包含一個非常大的代碼庫,可以在客戶語言(如C#)中通過面向對象編程技術(OOP)來使用這些代碼。
目的是,不同的操作系統可以根據自己的特性,支持其中的部分或全部模塊。例如,PDA支持所有的核心.NET功能,但不需要某些更深奧的模塊。
㈤ 如何有效的防止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程序的重要技術。
㈥ 如何做好生產環境和開發環境的隔離
如何做好生產環境和開發環境的隔離
src/main目錄下原來有 java, resources, 我新建幾個目錄: resources-dev, resources-test, resources-prod.
resources --- 一些共享的配置文件, 一般不需要修改的
resources-dev --- 開發環境下用的配置文件, 和resources目錄下文件沒有重合.
resources-prod --- 生產環境下用的配置文件, 和resources目錄下文件沒有重合.
本機開發的時候設置源碼目錄為 java, resources, resources-dev, 可以直接開發調試.
編譯的時候希望maven根據不同環境, 打包不同的目錄下的文件, 我們利用maven的profile和build-helper-maven-plugin插件就可以實現.
㈦ 如何保護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 題庫管理模塊和其它部分的交互過程圖
㈧ 我的c語言作業編譯後總是被360當作木馬給隔離刪除了怎麼辦!都是些非常簡單的程序啊
切記,運行程序時,360有認為有攻擊。需要人工選擇「始終允許執行該程序」
勿忘!
㈨ 用C語言編譯6度隔離理論
我不明白 六度隔離 理論,請在 補充回答 里說明。
比如一共30人,分別是1到30號。
而且,1號只認識2號,2號只認識3號……
那麼,1號認識30號就需要28個人了。
所以,六度隔離 理論是不是有什麼具體說明和限制,請說明,謝謝。
--------------------------------我來補充回答了--------------------------------
對不起,請不要復制網上的理論!
那個我在當初回答你的問題時就看過了,而且比你復制的全多了。
我有些不理解這個理論,具體不理解的地方也寫在上面了。
所以希望你可以給我解釋,然後我才能幫你編程,明白?