<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 14,  comments - 37,  trackbacks - 0

    一、前言

    1.1 什么是Jocky?

       我們知道,Java是一種跨平臺(tái)的編程語(yǔ)言,其源碼(.java文件)被編譯成與平臺(tái)無(wú)關(guān)的字節(jié)碼(.class文件),然后在運(yùn)行期動(dòng)態(tài)鏈接。這樣,編譯后的類文件中將包含有符號(hào)表,從而使得Java程序很容易被反編譯。相信每一個(gè)Java開(kāi)發(fā)人員,都曾經(jīng)用過(guò)諸如Jad之類的反編譯器,對(duì)Java的class 文件進(jìn)行反編譯,從而觀察程序的結(jié)構(gòu)與實(shí)現(xiàn)細(xì)節(jié)。如此一來(lái),對(duì)于那些需要嚴(yán)格進(jìn)行知識(shí)產(chǎn)權(quán)保護(hù)的Java應(yīng)用,如何有效的保護(hù)客戶的商業(yè)投資,是開(kāi)發(fā)人員經(jīng)常需要面對(duì)的問(wèn)題。
       于是就出現(xiàn)了Java混淆編譯器,它的作用是打亂class文件中的符號(hào)信息,從而使反向工程變得非常困難。
       Jocky就是這樣一款優(yōu)秀的Java混淆編譯器。

    1.2 為什么需要Jocky?

       目前業(yè)界有不少商業(yè)的甚或是開(kāi)源的混淆編譯器,但它們普遍存在一些這樣或者那樣的問(wèn)題。一般而言,現(xiàn)有的混淆器都是對(duì)編譯好的 class文件進(jìn)行混淆,這樣就需要編譯和混淆兩個(gè)步驟。而事實(shí)上,并不是所有的符號(hào)都需要混淆。如果你開(kāi)發(fā)的是一個(gè)類庫(kù),或者某些類需要?jiǎng)討B(tài)裝載,那些公共API(或者說(shuō):那些被publish出來(lái)的API)就必須保留符號(hào)不變,只有這樣,別人才能使用你的類庫(kù)。現(xiàn)有的混淆器提供了GUI或腳本的方式來(lái)對(duì)那些需要保留的符號(hào)名稱進(jìn)行配置,但如果程序較大時(shí),配置工作將變得很復(fù)雜,而程序一旦修改,配置工作又要重新進(jìn)行。某些混淆器能夠調(diào)整字節(jié)碼的順序,使反編譯更加困難,但筆者經(jīng)歷過(guò)混淆之后的程序運(yùn)行出錯(cuò)的情況。
       而Jocky與其它混淆編譯器最大的不同之處在于:它是直接從源碼上做文章,也就是說(shuō)編譯過(guò)程本身就是一個(gè)混淆過(guò)程。

    1.3 Jocky是如何工作的?

       Jocky混淆編譯器是在Sun JDK中提供的Java編譯器(javac)的基礎(chǔ)上完成的,修改了其中的代碼生成過(guò)程,對(duì)編譯器生成的中間代碼進(jìn)行混淆,最后再生成class文件,這樣編譯和混淆只需要一個(gè)步驟就可以完成。另外可以在源程序中插入 符號(hào)保留指令 來(lái)控制哪些符號(hào)需要保留,將混淆過(guò)程與開(kāi)發(fā)過(guò)程融合在一起,不需要單獨(dú)的配置。

    1.4 Jocky的作用

    1.4.1代碼混淆

       如前文所述,混淆編譯是Jocky的首要用途。我們舉一個(gè)最簡(jiǎn)單的例子,下面的SimpleBean是未經(jīng)混淆的class文件通過(guò)Jad反編譯以后獲得的源文件:

     1public class SimpleBean implements Serializable {
     2  
     3  private String name = "myname";
     4  
     5  private List myList = null;
     6  
     7  public void SimpleBean() {
     8    myList = new ArrayList(10);
     9  }

    10
    11  public void foo1() {
    12    myList.add("name");
    13  }

    14  
    15  private void foo2() {    
    16  }

    17  
    18  private void writeObject(java.io.ObjectOutputStream out)
    19      throws IOException {
    20    
    21  }

    22
    23}
     
    <未混淆的類文件反編譯后的效果>

       下面是經(jīng)Jocky混淆過(guò)的類文件,通過(guò)Jad反編譯后產(chǎn)生的源文件:

     1public class SimpleBean implements Serializable {
     2
     3  private String _$2;
     4
     5  private List _$1;
     6
     7  public SimpleBean()     {
     8        _$2 = "myname";
     9        this;
    10        JVM INSTR new #4   <Class ArrayList>;
    11        JVM INSTR dup ;
    12        JVM INSTR swap ;
    13        10;
    14        ArrayList();
    15        _$1;
    16    }
      
    17  public void foo1() {
    18    _$1.add("name");
    19  }

    20
    21  private void _$1() {
    22  }

    23
    24  private void writeObject(ObjectOutputStream objectoutputstream){
    25      throws IOException {
    26  }

    27}
     
    <Jocky混淆過(guò)的類文件反編譯的效果>

    1.4.2 支持將JDK 5.0的語(yǔ)法編譯成能夠在JDK 1.4上運(yùn)行的類文件

       JDK 5.0在語(yǔ)法層面上有許多新增特色,能夠?yàn)楹?jiǎn)化應(yīng)用的開(kāi)發(fā)帶來(lái)一些便利。譬如Generics、Enhanced for Loop以及 Autoboxing/Unboxing等。但另人遺憾的是,倘若利用這些新的語(yǔ)法開(kāi)發(fā)應(yīng)用,就意味著不能夠在JDK 1.4上運(yùn)行,而JDK 1.4畢竟是目前最為普及的VM版本。幸運(yùn)是,Jocky的另一個(gè)特色就是:通過(guò)參數(shù)配置,能夠把用JDK 5.0語(yǔ)法編寫(xiě)的應(yīng)用編譯成JDK 1.4上的類文件版本。我們可以把經(jīng)過(guò) Jocky編譯的類文件以UltraEdit打開(kāi),可以發(fā)現(xiàn)在第8個(gè)字節(jié)上(類文件的major version)的數(shù)值是0x30,即十進(jìn)制的48,這是JDK 1.4所能夠理解的類文件版本(JDK 5.0默認(rèn)編譯的類文件版本是49)。前提是:應(yīng)用中不能夠使用JDK 1.4中所沒(méi)有的一些API。

    二、Jocky的用法

    2.1 常規(guī)用法

       使用Jocky非常簡(jiǎn)單,獲得jocky.jar以后,只需要運(yùn)行java -jar jocky.jar就可以啟動(dòng)Jocky混淆編譯器,jocky的命令行參數(shù)和javac完全相同,但增加了一個(gè)新的參數(shù)-scramble,它的用法如下:
    -scramble          混淆所有package private或private符號(hào)
    -scrambleall       混淆所有符號(hào)
    -scramble:
    <level>  混淆相應(yīng)級(jí)別的符號(hào)
    其中
    <level>指定混淆級(jí)別,可以是以下幾種級(jí)別:
    -scramble:none        不進(jìn)行混淆
    -scramble:private     對(duì)所有private訪問(wèn)級(jí)別的元素進(jìn)行混淆
    -scramble:package     對(duì)所有private或package private元素進(jìn)行混淆
    -scramble:protected   對(duì)所有private, package private, protected元素進(jìn)行混淆
    -scramble:public      對(duì)所有的元素都進(jìn)行混淆
    -scramble:all         相當(dāng)于-scramble:public
    如果使用-scramble不帶級(jí)別參數(shù),則相當(dāng)于-scramble:package

    2.2 Jocky for Ant

        近年來(lái),Ant已經(jīng)成為Java應(yīng)用開(kāi)發(fā)中打包工具的事實(shí)上的標(biāo)準(zhǔn)。在應(yīng)用的開(kāi)發(fā)過(guò)程中,我們往往都會(huì)有一個(gè)Ant腳本,通過(guò)該腳本,能夠?qū)?yīng)用進(jìn)行編譯、打包、發(fā)布等一系列過(guò)程。因此,Jocky的最佳切入點(diǎn)便是對(duì)Ant的支持。
        在Ant中使用Jocky非常簡(jiǎn)單:

        1. 將lib\jocky-ant.jar copy至ANT_HOME\lib目錄下。

        2. 在ant腳本中加入這樣一行代碼,以引入Jocky Task
      
         <taskdef resource="jockytasks/"> 

        3. 設(shè)置Jocky的一些基本屬性,包括: jocky.jar包的位置,以及混淆級(jí)別,如下所示:
        
       <jocky jar=" F:\Works2\Jocky\jocky1.0\lib\jocky.jar" enable="true" level="private/"> 

        4. 當(dāng)設(shè)置jocky的enable屬性為true時(shí),此時(shí),Ant腳本中的javac編譯命令,便會(huì)被自動(dòng)替換成Jocky編譯器;當(dāng)設(shè)置enable屬性為false時(shí),javac編譯命令將恢復(fù)成正常設(shè)置,示例腳本如下:

     1<project name="jocky" default="build"> 
     2<!-- 引入Jocky Ant Task,要確保jocky-ant.jar位于ANT_HOME\lib目錄下 -->
     3<taskdef resource="jockytasks"> </taskdef>
     4<target name="build"> 
     5<!-- 設(shè)置jocky.jar的位置以及混淆級(jí)別,當(dāng)enable為true時(shí),javac task將被自動(dòng)替換成Jocky混淆編譯器 -->
     6<jocky jar=" F:\Works2\Jocky\jocky1.0\lib\jocky.jar" enable=" true" level=" private"> </jocky> 
     7<!-- 下面的編譯,將使用Jocky混淆編譯器 -->
     8<javac destdir="bin2" debug="on" source="1.5" target="1.4"> 
     9<src path="src"></src>
    10</javac>
    11<!-- 當(dāng)enable為false時(shí),javac task將被恢復(fù)成正常設(shè)置, Jocky編譯器不再起作用 -->
    12<jocky enable="false"></jocky>
    13<!-- 下面的編譯,將使用正常的Javac編譯器 -->
    14<javac destdir="bin3" debug="on" target="1.4"> 
    15<src path="src"></src>
    16</javac>
    17</target>
    18</project>
    <Jocky的Ant腳本示例>

        注意: Jocky for Ant在Ant 1.6.5上開(kāi)發(fā),推薦使用該版本。

    2.3 Jocky for Eclipse

        Jocky提供了Eclipse的插件,從而能夠直接在Eclipse中使用Jocky。
        1. Jocky插件的安裝:
        將Jocky插件安裝至Eclipse中非常簡(jiǎn)單,只需要將eclipse/plugins/org.apusic.jocky_1.0.0目錄 copy 至 Eclipse的 plugins目錄即可。或者在Eclipse/links文件夾中,通過(guò)link方式指定Jocky的插件目錄。

        2. 在Eclipse中使用Jocky:
        在Eclipse中使用Jocky也非常簡(jiǎn)單,任何一個(gè)Java工程,選中工程通過(guò)右鍵菜單,都可以出現(xiàn)Jocky的快捷菜單:

     
    <Jocky在Eclipse中的右鍵菜單>

     
    <Jocky在Eclipse中的屬性設(shè)置>


        事實(shí)上,在Eclipse中使用Jocky時(shí),Jocky也是首先針對(duì)所選工程生成Ant的Build文件(默認(rèn)名稱jocky_build.xml),然后再通過(guò)Ant完成混淆編譯。

        以下是Jocky在Eclipse中自動(dòng)生成的Ant Build 文件示例:

     1<project basedir="." default="build" name="jocky.example.jocky"> 
     2<property name="jocky.jar" value="f:\EclipseWTP1.0.8\workspace_jdk5_apusicstudio\org.apusic.jocky\jocky.jar"></property>
     3<property name="jocky.output.dir" value="jocky"></property>
     4<property name="jocky.scramble.level" value="package"></property>
     5<property name="target" value="1.4"></property>
     6<path id="project.classpath"> 
     7<pathelement location="bin"></pathelement>
     8</path>
     9<target name="init"> 
    10<jocky jar="${jocky.jar}" level="${jocky.scramble.level}"></jocky>
    11<mkdir dir="${jocky.output.dir}"></mkdir>
    12<mkdir dir="${jocky.output.dir}/bin"></mkdir>
    13</target>
    14<target name="clean"> 
    15<delete dir="${jocky.output.dir}/bin"></delete>
    16<delete dir="${jocky.output.dir}"></delete>
    17</target>
    18<target depends="init" name="build"> 
    19<echo message="${ant.project.name}: ${ant.file}"></echo>
    20<jocky enable="true"></jocky>
    21<javac destdir="${jocky.output.dir}/bin" target="${target}"> 
    22<src path="src"></src>
    23<classpath refid="project.classpath"></classpath>
    24</javac>
    25</target>
    26</project>
    <Jocky在Eclipse中自動(dòng)生成的Ant腳本示例>

    注1:只支持Eclipse 3.1.1及以上版本。
    注2:如果在Eclipse中找不到Jocky插件,請(qǐng)刪除 Eclipse安裝目錄/configuration/org.eclipse.update 文件夾 (Maybe an eclipse bug?)。

    2.4 如何使用符號(hào)保留指令

       除了在命令行用 -scramble 參數(shù)控制符號(hào)混淆級(jí)別外,還可以在源代碼中使用符號(hào)保留指令來(lái)控制那些符號(hào)需要保留。符號(hào)保留指令是一個(gè)Java文檔注釋指令,可以插入在類和類成員的文檔注釋中,例如:
     1/**
     2 * This class should preserve.
     3 * @preserve
     4 */
     5public class Foo {
     6    /**
     7     * You can specify which field should be preserved.
     8     * @preserve
     9     */
    10    private int x;
    11
    12    /**
    13     * This field is not preserved.
    14     */
    15    private int y;
    16
    17    /**
    18     * You can also preserve methods.
    19     * @preserve
    20     */
    21    public void hello() {}
    22
    23    /**
    24     * This method is not preserved.
    25     */
    26    private void collect() {}
    27
    <使用preserved指令的示例>

       如果沒(méi)有@preserve指令,則根據(jù)混淆級(jí)別及成員的訪問(wèn)級(jí)別來(lái)確定符號(hào)是否保留。
       對(duì)于類的符號(hào)保留指令可以附帶一個(gè)保留級(jí)別參數(shù),來(lái)控制類成員的符號(hào)保留,包括:
    @preserve            僅對(duì)類名進(jìn)行保留,類成員的保留根據(jù)-scramble命令行參數(shù)決定
    @preserve public     保留所有public成員
    @preserve protected  保留所有public和protected成員
    @preserve package    保留所有public, protected, package private成員
    @preserve private    保留所有成員
    @preserve all        相當(dāng)于@preserve private
       事實(shí)上,即便不加@preserve指令,Jocky對(duì)Java語(yǔ)言特有的一些private級(jí)別的方法不進(jìn)行混淆,譬如,在序列化時(shí)有特殊作用的writeObject及readObject方法等。但筆者強(qiáng)烈建議: 針對(duì)這些有特殊含義不能夠被混淆的 private級(jí)別的方法或者字段,請(qǐng)以@preserve指令予以保護(hù)。

    注1:建議通過(guò)IDE的JavaDoc設(shè)置,來(lái)輔助@preserve指令的書(shū)寫(xiě)。

    三、Jocky的限制

       正如前文所說(shuō),Jocky是基于源代碼的混淆編譯器,因此,Jocky不支持分別編譯,必須對(duì)所有的源文件同時(shí)進(jìn)行混淆編譯。但事實(shí)上,倘若混淆級(jí)別控制在private級(jí)別上,該限制便不復(fù)存在。

    posted on 2007-06-28 16:55 冰封的愛(ài) 閱讀(11548) 評(píng)論(6)  編輯  收藏 所屬分類: 開(kāi)源項(xiàng)目

    FeedBack:
    # re: Jocky混淆JAVA代碼(保護(hù)你的JAVA項(xiàng)目)
    2007-08-22 09:54 | wqh
    dsaffads  回復(fù)  更多評(píng)論
      
    # re: Jocky混淆JAVA代碼(保護(hù)你的JAVA項(xiàng)目)
    2007-09-17 10:16 | 紫楓凝瀟煙
    是誰(shuí)開(kāi)發(fā)的,使用的包在哪里下載  回復(fù)  更多評(píng)論
      
    # re: Jocky混淆JAVA代碼(保護(hù)你的JAVA項(xiàng)目)
    2007-09-17 10:54 | 冰封的愛(ài)
    這個(gè)插件在網(wǎng)上可以搜索到,一搜索就OK  回復(fù)  更多評(píng)論
      
    # re: Jocky混淆JAVA代碼(保護(hù)你的JAVA項(xiàng)目)
    2012-03-26 10:41 | Mr.CT
    支持1.6就好啊  回復(fù)  更多評(píng)論
      
    # re: Jocky混淆JAVA代碼(保護(hù)你的JAVA項(xiàng)目)
    2013-05-10 16:34 | ss
    # re: Jocky混淆JAVA代碼(保護(hù)你的JAVA項(xiàng)目)
    2014-05-31 12:52 | pro
    求支持 JDK 1.7的版本  回復(fù)  更多評(píng)論
      

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    <2014年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(3)

    隨筆檔案

    文章分類

    文章檔案

    相冊(cè)

    搜索

    •  

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 成年美女黄网站色大免费视频| 成年网在线观看免费观看网址| 久久精品私人影院免费看| mm1313亚洲精品无码又大又粗| 亚洲综合色一区二区三区| 成人无遮挡毛片免费看| 亚洲.国产.欧美一区二区三区| 在线免费观看一级片| 精品亚洲国产成人av| 国产一级淫片视频免费看| 日韩一级片免费观看| 亚洲欧洲精品无码AV| 嫩草影院在线播放www免费观看| 久久精品亚洲综合专区| 1000部夫妻午夜免费| 亚洲综合在线成人一区| 久久天天躁狠狠躁夜夜免费观看| 亚洲а∨天堂久久精品9966 | 亚洲日产2021三区在线| 24小时日本电影免费看| 亚洲AV色吊丝无码| 国产老女人精品免费视频| 一区二区免费国产在线观看 | 亚洲视屏在线观看| 成年在线观看免费人视频草莓| 亚洲大码熟女在线观看| 在线观看亚洲天天一三视| 久久99精品免费视频| 学生妹亚洲一区二区| 亚洲成av人片在线观看天堂无码| 成全视频免费观看在线看| 亚洲欧洲自拍拍偷午夜色| 国产精品久久香蕉免费播放| 一级成人a做片免费| 精品亚洲A∨无码一区二区三区| 四虎成人免费观看在线网址| 国产精品免费一区二区三区 | 亚洲 综合 国产 欧洲 丝袜| 日本黄色动图免费在线观看| 亚洲精品自偷自拍无码| 亚洲国产一二三精品无码|