• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            教父的告白
            一切都是紙老虎
            posts - 82,  comments - 7,  trackbacks - 0

            稍微深入研究過一點 java 的同學,恐怕都知道什么叫做 “反編譯” 。也就是說,隨便拿一個 class 文件,找一個 jad 來,所有的 “智慧結晶” 就全都 “真相大白” 了,跟原先的 source code 相比,區別只是沒有注釋而已。

            對于開源軟件開發者來說,這本是無所謂的事,但對于商業開發者而言,這簡直就是噩夢。在 java 的世界,道高一尺魔高一丈(及其反復迭代)的結果是,這件事最終演變得比較詭異,以至于專門誕生了一個名叫 “代碼混淆” 的產業。在我上一次關注的時候,這個領域的最新進展是可以 “混淆” 程序執行的流程,以至于正常的人類閱讀反編譯出來的源碼,將會導致嚴重的腦殘。不過,傳說又出了個叫做 “流程優化器” 的東東……(這個故事未完待續)。

            其實,這件事困擾的不僅只是 java ,幾乎所有 “有源代碼” 的程序都有這個煩惱。比如,飽受折磨的還有 php, asp 以及 .net。不知道有沒有高人能從 “機器碼” 反編譯出 C 和 C++ 的源程序呢,反正我挺好奇的。不過,話說回來, “沒有源代碼” 的程序,恐怕還真的沒有。保護源代碼,在我們現如今 “處處是山寨,遍地是豺狼” 的產業現狀之下,似乎仍然是個不得不認真對待的事情。

            在源代碼保護的問題上,Erlang 的表現又會如何?今天體驗了一把,應該說,設計得很細致,至于說這樣的設計是否能夠完全杜絕源代碼的泄露,這個問題恐怕仍然需要留給 “專家” 們去研究。好吧,口水就噴到這里,下面上干貨。

            目前這個階段,對 Erlang 源代碼的保護,主要是在 debug_info 上做手腳,因為,在 debug_info 里面有完整的源代碼,可以極其輕松的從中 “找回” 源碼(兩個語句而已,在官方文檔之中都有例子)。

            先看如何從 Erlang 的 beam 文件獲取源代碼。象這樣的一個簡單程序:

            -module(a).
             
            -
            export([test/0]).
             
            test() ->
             
            io:format("source code.~n", []).

            帶 debug_info 編譯,并運行之。

            $ erlc +debug_info a.erl
            $ erl -s a test -s c q -noshell
            source code.
            $

            我們可以這樣還原它的源碼:

            $ erl
            1>  {ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks(code:which(a), abstract_code]).
            {ok,{a,[{abstract_code,
                        {raw_abstract_v1,
                            [{attribute,1,file,{"./a.erl",1}},
                             {attribute,1,module,a},
                             {attribute,3,export,[{test,0}]},
                             {function,5,test,0,
                                 [{clause,5,[],[],[{call,6,{remote,...},[...]}]}]},
                             {eof,7}]}}]}}
            2> io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).
            -file("./a.erl", 1).

            -module(a).

            -export([test/0]).

            test() -> io:format("source code.~n", []).


            ok
            3>

            看,和源碼幾乎完全一致。

            那么,如果我們編譯的時候不帶 debug_info 呢?是的,完全可以。不過,如果你想要在這樣的 beam 上執行 debugger 或者 xref 之類的動作,那么,沒有 debug_info 就做不了。天知道我們會不會有需要做 “現場調試” 的時候呢。有沒有既保留 debug_info 又阻止其他人通過 debug_info 來得到源碼的辦法呢?有,那就是——加密 debug_info 。

            首先建立一個 ~/.erlang.crypt 文件,內容如下:

            $ cat ~/.erlang.crypt
            [{debug_info, des3_cbc, [], "my_source_code_secret_key"}].

            這里的 “my_source_code_secret_key” 就被用來生成對 debug_info 加密的密鑰。用 encrypt_debug_info 參數編譯,并運行之。

            $ erlc +encrypt_debug_info a.erl
            $ erl -s a test -s c q -noshell
            source code.

            現在拿掉 ~/.erlang.crypt (模擬生產機環境),看看能否正常運行。

            $ mv ~/.erlang.crypt ~/.erlang.old.crypt
            $ erl -s a test -s c q -noshell
            source code.

            運行沒問題。此時,是否還能還原源碼呢。

            $ erl
            1>  beam_lib:chunks(code:which(a), [abstract_code]).
            {error,beam_lib,
                   {key_missing_or_invalid,"./a.beam",abstract_code}}

            這正是我們想要的。

            比如說,假如某日我們需要在這臺生產機上做 “現場調試”,那就再加上 ~/.erlang.crypt 文件。作為驗證,我們再執行一次還原源碼的操作。

            $ mv ~/.erlang.old.crypt ~/.erlang.crypt
            $ erl
            1>  {ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks(code:which(a), abstract_code]).
            {ok,{a,[{abstract_code,
                        {raw_abstract_v1,
                            [{attribute,1,file,{"./a.erl",1}},
                             {attribute,1,module,a},
                             {attribute,3,export,[{test,0}]},
                             {function,5,test,0,
                                 [{clause,5,[],[],[{call,6,{remote,...},[...]}]}]},
                             {eof,7}]}}]}}
            2> io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).
            -file("./a.erl", 1).

            -module(a).

            -export([test/0]).

            test() -> io:format("source code.~n", []).


            ok
            3>

            看 debug_info 還原出來了。

            我們藏在 debug_info 中的源碼是被 des3_cbc 算法保護起來的,有興趣的童鞋可以去 wiki 百科了解它的加密強度,解開它的關鍵是 ~/.erlang.crypt 文件,只要它不泄露,那么在生產環境下,我們的代碼就仍然是安全的,也就是說,就算這臺機器被黑掉了,也還原不出源碼(如果我說錯了,請糾正我),而且只要你持有 .erlang.crypt 文件,(在需要的時候)仍然可以進行調試。

            實驗之前,確實沒想到 Erlang 還設計了這么一個機制,挺細致的。需要說明的是,上述方案是對 beam 中的 debug_info 進行了加密,從而阻止其他人從中獲取源碼,至于是否還有其他的還原源碼的可能,目前還不是很清楚。比如,理論上,是否有可能通過 beam 之中的 op code 反編譯出原始的 source code 呢?對于這個話題,如果有童鞋知道,請不吝賜教。

            posted on 2009-09-07 16:18 暗夜教父 閱讀(711) 評論(0)  編輯 收藏 引用

            <2010年2月>
            31123456
            78910111213
            14151617181920
            21222324252627
            28123456
            78910111213

            常用鏈接

            留言簿(2)

            隨筆分類

            隨筆檔案

            文章分類

            文章檔案

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            久久久久久毛片免费看| 99久久国产精品免费一区二区| 久久偷看各类wc女厕嘘嘘| 久久精品黄AA片一区二区三区| 精品久久国产一区二区三区香蕉| 久久99精品久久久久久9蜜桃| 国产激情久久久久影院老熟女免费| 色悠久久久久久久综合网| 久久丫精品国产亚洲av不卡| 久久精品无码av| 91精品国产乱码久久久久久| 色99久久久久高潮综合影院| 久久r热这里有精品视频| 国产偷久久久精品专区 | 无码人妻久久一区二区三区蜜桃| 99久久国产精品免费一区二区| 国产AV影片久久久久久| 久久综合给久久狠狠97色| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 亚洲精品乱码久久久久久蜜桃 | 东方aⅴ免费观看久久av| 精品乱码久久久久久夜夜嗨| 久久水蜜桃亚洲av无码精品麻豆| 欧美精品福利视频一区二区三区久久久精品 | 久久久久国色AV免费看图片| 国产精品免费看久久久| 亚洲狠狠婷婷综合久久久久| 久久婷婷色香五月综合激情| 色婷婷久久久SWAG精品| 中文字幕久久欲求不满| 91精品国产高清久久久久久国产嫩草 | 国产V亚洲V天堂无码久久久| 亚洲国产精品无码久久久蜜芽| 2021国内久久精品| 精品久久久久成人码免费动漫| 亚洲精品WWW久久久久久| 色老头网站久久网| 人妻无码精品久久亚瑟影视 | 国产A级毛片久久久精品毛片| 亚洲精品高清一二区久久| 亚洲国产一成久久精品国产成人综合|