java從誕生以來,其基因就是開放精神,也正因此,其可以得到廣泛愛好者的支持和奉獻,最終很快發展壯大,以至於有今天之風光!但隨著java的應用領域越來越廣,特別是一些功能要發布到終端用戶手中(如Android開發的app),有時候,公司為了商業技術的保密考慮,不希望這裡面的一些核心代碼能夠被人破解(破解之後,甚至可以被簡單改改就發布出去,說嚴重點,就可能會擾亂公司的正常軟體的市場行為),這時候就要求這些java代碼不能夠被反編譯。
這里要先說一下反編譯的現象。因為java一直秉持著開放共享的理念,所以大家也都知道,我們一般共享一個自己寫的jar包時,同時會共享一個對應的source包。但這些依然與反編譯沒有什麼關系,但java的共享理念,不只是建議我們這樣做,而且它自己也在底層上「強迫」我們這么做!在java寫的.java文件後,使用javac編譯成class文件,在編譯的過程,不像C/C++或C#那樣編譯時進行加密或混淆,它是直接對其進行符號化、標記化的編譯處理,於是,也產生了一個逆向工程的問題:可以根據class文件反向解析成原來的java文件!這就是反編譯的由來。
但很多時候,有些公司出於如上述的原因考慮時,真的不希望自己寫的代碼被別人反編譯,尤其是那些收費的app或桌面軟體(甚至還有一些j2ee的wen項目)!這時候,防止反編譯就成了必然!但前面也說過了,因為開放理念的原因,class是可以被反編譯的,那現在有這樣的需求之後,有哪些方式可以做到防止反編譯呢?經過研究java源代碼並進行了一些技術實現(結果發現,以前都有人想到過,所以在對應章節的時候,我會貼出一些寫得比較細的文章,而我就簡單闡述一下,也算偷個懶吧),我總共整理出以下這幾種方式:
代碼混淆
這種方式的做法正如其名,是把代碼打亂,並摻入一些隨機或特殊的字元,讓代碼的可讀性大大降低,「曲線救國」似的達到所謂的加密。其實,其本質就是打亂代碼的順序、將各類符號(如類名、方法名、屬性名)進行隨機或亂命名,使其無意義,讓人讀代碼時很累,進而讓人乍一看,以為這些代碼是加過密的!
由其實現方式上可知,其實現原理只是擾亂正常的代碼可讀性,並不是真正的加密,如果一個人的耐心很好,依然可以理出整個程序在做什麼,更何況,一個應用中,其核心代碼才是人們想去了解的,所以大大縮小了代碼閱讀的范圍!
當然,這種方式的存在,而且還比較流行,其原因在於,基本能防範一些技術人員進行反編譯(比如說我,讓我破解一個混淆的代碼,我寧願自己重寫一個了)!而且其實現較為簡單,對項目的代碼又無開發上的侵入性。目前業界也有較多這類工具,有商用的,也有免費的,目前比較流行的免費的是:proguard(我現象臨時用的就是這個)。
上面說了,這種方式其實並不是真正加密代碼,其實代碼還是能夠被人反編譯(有人可能說,使用proguard中的optimize選項,可以從位元組流層面更改代碼,甚至可以讓JD這些反編譯軟體可以無法得到內容。說得有點道理,但有兩個問題:1、使用optimize對JDK及環境要求較高,容易造成混淆後的代碼無法正常運行;2、這種方式其實還是混淆,JD反編譯有點問題,可以有更強悍的工具,矛盾哲學在哪兒都是存在的^_^)。那如何能做到我的class代碼無法被人反編譯呢?那就需要我們下面的「加密class」!
加密class
在說加密class之前,我們要先了解一些java的基本概念,如:ClassLoader。做java的人已經或者以後會知道,java程序的運行,是類中的邏輯在JVM中運行,而類又是怎麼載入到JVM中的呢(JVM內幕之類的,不在本文中闡述,所以點到為止)?答案是:ClassLoader。JVM在啟動時是如何初始化整個環境的,有哪些ClassLoader及作用是什麼,大家可以自己問度娘,也不在本文中討論。
讓我們從最常見的代碼開始,揭開一下ClassLoader的一點點面紗!看下面的代碼:
Java代碼
publicclassDemo{
publicstaticvoidmain(String[]args){
System.out.println(「helloworld!」);
}
}
上面這段代碼,大家都認識。但我要問的是:如果我們使用javac對其進行編譯,然後使用java使其運行(為什麼不在Eclipse中使用Runas功能呢?因為Eclipse幫我們封閉,從而簡化了太多東西,使我們忽略了太多的底層細節,只有從原始的操作上,我們才能看到本質),那麼,它是怎麼載入到JVM中的?答案是:通過AppClassLoader載入的(相關知識點可以參考:http://hxraid.iteye.com/blog/747625)!如果不相信的話,可以輸出一下System.out.println(Thread.currentThrea().getContextLoader());看看。
那又有一個新的問題產生了:ClassLoader又是怎樣載入class的呢?其實,AppClassLoader繼承自java.lang.ClassLoader類,所以,基本操作都在這個類裡面,讓我們直接看下面這段核心代碼吧:
看到這里,已經沒有必要再往下面看了(再往下就是native方法了,這是一個重大伏筆哦),我們要做的手腳就在這里!
手腳怎麼做呢?很簡單,上面的代碼邏輯告訴我們,ClassLoader只是拿到class文件中的內容byte[],然後交給JVM初始化!於是我們的邏輯就簡單了:只要在交給JVM時是正確的class文件就行了,在這之前是什麼樣子無所謂!所以,我們的加密的整個邏輯就是:
在編譯代碼時(如使用ant或maven),使用插件將代碼進行加密(加密方式自己選),將class文件裡面的內容讀取成byte[],然後進行加密後再寫回到class文件(這時候class文件裡面的內容不是標準的class,無法被反編譯了)
在啟動項目代碼時,指定使用我們自定義的ClassLoader就行了,而自定義的部分,主要就是在這里做解密工作!
如此,搞定!以上的做法比較完整的闡述,可以仔細閱讀一下這篇文章:https://www.ddtsoft.com/#developerworks/cn/java/l-secureclass/文章中的介紹。
通過這個方法貌似可以解決代碼反編譯的問題了!錯!這里有一個巨大的坑!因為我們自定義的ClassLoader是不能加密的,要不然JVM不認識,就全歇菜了!如果我來反編譯,呵呵,我只要反編譯一下這個自定義的ClassLoader,然後把裡面解密後的內容寫到指定的文件中保存下來,再把這個加了邏輯的自定義ClassLoader放回去運行,你猜結果會怎樣?沒錯,你會想死!因為你好不容易想出來的加密演算法,結果人家根本不需要破解,直接就繞過去了!
現在,讓我們總結一下這個方法的優缺點:實現方式簡單有效,同時對代碼幾乎沒有侵入性,不影響正常開發與發布。缺點也很明顯,就是很容易被人破解!
當然啦,關於缺點問題,你也可以這么干:先對所有代碼進行混淆、再進行加密,保證:1、不容易找到我們自定義的那個ClassLoader;2、就算找到了,破解了,代碼可讀性還是很差,讓你看得吐血!(有一篇文章,我覺得寫得不錯,大家可以看一看:http://www.scjgcj.com/#blog/851544)
嗯,我覺得這個方法很好,我自己也差點被這個想法感動了,但是,作為一個嚴謹的程序員,我真的不願意留下一個隱患在這里!所以,我繼續思索!
高級加密class
前面我們說過有個伏筆來著,還記得吧?沒錯,就是那個native!native定義的方法是什麼方法?就是我們傳說中的JNI調用!前面介紹過的有一篇文章中提到過,其實jvm的真實身份並不是java,而是c++寫的jvm.dll(windows版本下),java與dll文件的調用就是通過JNI實現的!於是,我們就可以這樣想:JNI可以調用第三方語言的類庫,那麼,我們可不可以把解密與裝載使用第三方語言寫(如C++,因為它們生成的庫是不好反編譯的),這樣它可以把解密出來的class內容直接調jvm.dll的載入介面進行初始化成class,再返回給我們的ClassLoader?這樣,我們自定義的ClassLoader只要使用JNI調用這個第三方語言寫的組件,整個解密過程,都在黑盒中進行,別人就無從破解了!
嗯,這個方法真的很不錯的!但也有兩個小問題:1.使用第三方語言寫,得會第三方語言,我說的會,是指很溜!2.對於不同的操作系統,甚至同一操作系統不同的版本,都可能要有差異化的代碼生成對應環境下的組件(如window下是exe,linux是so等)!如果你不在乎這兩個問題,我覺得,這個方式真的挺不錯的。但對於我來說,我的信條是,越復雜的方式越容易出錯!我個人比較崇尚簡潔的美,所以,這個方法我不會輕易使用!
對了,如果大家覺得這個方法還算可行的話,可以推薦一個我無意中看到的東西給大家看看(我都沒有用過的):jinstall,
更改JVM
看到這個標題,我想你可能會震驚。是的,你沒看錯,做為一個程序員,是應該要具有懷疑一切、敢想敢做的信念。如果你有意留心的話,你會發現JVM版本在業界其實也有好幾個版本的,如:Sun公司的、IBM的、Apache的、Google的……
所以,不要阻礙自己的想像力,現在沒有這個能力,並不代表不可能。所以,我想到,如果我把jvm改了,在裡面對載入的類進行解密,那不就可以了嗎?我在設計構思過程中,突然發現:人老了就是容易糊塗!前面使用第三方語言實現解密的兩個問題,正好也是更改JVM要面對的兩個問題,而且還有一個更大的問題:這個JVM就得跟著這個項目到處走啊!
② 我有一個軟體類的想法想藉此創業,我不懂程序的話怎麼防止合作的程序員帶著我的想法跑了單干
古人雲:「不積跬步,無以至千里;不積小流,無以成江海。」說的就是想要成大事、大氣候必須從小事做起的道理。所以,在工作中,認真做好每一件小事情,反映的就是一種忠於職業、盡職盡責、一絲不苟、善始善終的職業道德和精神,其中也糅合著一種使命感和道德責任感。把每一件小事、每一個細節都做到完美,我們才會有機會在工作中鑄就自己的輝煌。
俗語說,「一滴水,可以折射出整個太陽。」一件「大事」都是由許多件微不足道的「小事」組成的。日常工作和生活也是如此,那些看似瑣碎繁雜、不足掛齒的事情比比皆是。如果你對工作和生活中的這些小事輕視怠慢,敷衍了事,到頭來就會因「一著不慎」而輸掉整盤棋。所以,每個人、每個員工在處理每一個細節的時候,都應當認認真真。要想把每一件事情都做到無懈可擊,就必須從小事做起,付出你的熱情和努力。士兵每天做的工作就是隊列訓練、戰術操練、巡邏排查、擦拭槍械等等的小事;飯店服務員每天的工作就是對顧客微笑、回答顧客的提問、整理打掃房間、細心周到服務等等的小事;在辦公室里,你每天所做的事也可能就是一些接聽電話、整理文件、繪制圖表之類的細節。但是我們如果能夠一絲不苟地認真做好這些小事,沒准將來你就可能因此而是軍隊中的將領、飯店裡的經理、企業里的老總。反之,你如果對此感到乏味、厭倦不已,始終提不起精神,或者敷衍應付差事,勉強應付工作,將一切都推到「英雄無用武之地」的借口上,那麼你現在的位置也可能會處於那種岌岌可危的處境。在小事上都不能勝任,何談在大事上「大顯身手」呢?沒有做好「小事」的態度和能力,想做好「大事」只會成為「無本之木,無源之水」,根本就成不了氣候的。可以這樣說,平時的每一件「小事」其實就是一個房子的地基,如果沒有這些材料,想像中那美麗的房子只會是「空中樓閣」,根本無法變成現實的「實物」。在職場中,每一個細節的積累都是今後事業穩步上升的基礎。
大常人們都想做大事,而不願意或者不屑於做小事。想做大事的人太多,而願意把小事做好的人又太少。事實上,隨著社會的進步,經濟的發展,專業化程度越來越高,社會分工越來越細,真正所謂的大事越來越少,比如,一台拖拉機,有五六千個零部件,需要幾十個工廠進行合作生產協作;一輛小轎車,有上萬個零件,需要上百家企業生產協作;一架飛機,共有四百多萬個零部件,涉及需要協作生產的企業單位更多。
因此,我們大多數人平時所做的工作還只是一些具體的事、瑣碎的事、單調的事、不起眼的事,這些事也許過於平淡,也許是一些雞毛蒜皮,但這就是工作,就是生活,就是成就大事不可缺少的基礎。所以無論做人、做事,都要注意細節,都要從小事做起。一個不願意做小事的人,是不可能成功的。老子就一直告誡人們:天下難事,必作於易;天下大事,必作於細。要想比別人更優秀,只有在每一件小事上下功夫。不會做小事的人,也做不出大事來。
↓※1★咨¤一☆一★一★
↓※3★詢¤份☆種★台★
↓※2★加¤堅☆智★電★
↓※8 ★我¤持☆慧★腦★
↓※9 ★←¤★☆★★※★
↓※6 ★騰¤一☆一★一★
↓※3 ★訊¤生☆次★根★
↓※9 ★網¤精☆選★網★
↓※4 ★號¤彩☆擇★線
↓※6★
【 歡迎==咨詢==我們==一起==成功】
③ 怎麼防止公司的網站源碼不被程序員盜走呢
把網路隔離啊
工作用台式機,連區域網,不能上公網
把usb封了,刻錄光碟機卸了
很多軟體公司都是這樣的
還得在交換機設置,識別mac
禁止外來電腦發起的連接
④ 為防被程序員「砍」,產品經理需要注意這些場景
互聯網行業中,眾人熱衷於討論「程序員砍產品經理」。雖然,「砍」更多是調侃的意思,一種消遣工作的方式;但是,這不是一個飯後笑話,側面反應了產品經理和程序員間的對立關系。很多時候,產品經理和程序員間就像對手,產品研發過程就像打仗,總要爭個你死我亡。「砍」的本質,是程序員表達對產品經理的不滿,也是一種情緒的宣洩。
在產品研發的過程中,產品經理與程序員對立關系,會嚴重影響項目的推進。一旦產品經理和程序員對立關系公開化,很容易導致團隊人心渙散。這種對立關系,經常滋生出一些極端的事情,罵娘、打架已屢見不鮮。
下文就列舉一些程序員想砍產品經理的場景。這些場景都是我過去和很多程序員朋友交流時,他們遇到的對產品不滿的場景。這些場景,都會以產品經理的溝通話語表現出來。通過這些場景,去解析這種對立關系產生的原因。以及,作為對照,產品經理應該如何規避和處理這種對立關系。
這樣說法是程序員們最不喜歡的,最容易惹毛程序員的。這句話,在程序員們看來就是削減工時、加班的代名詞,他們當然不喜歡。而且他們也非常討厭,一個非技術人員為技術人員做技術難度的定論。簡不簡單,都需要技術人員做了技術評估,才能下結論。
這種言語,會讓程序員們覺得產品經理不靠譜。大家通常都是比較排斥借鑒。借鑒你也得有合理明確的理由。以我某程序員朋友的話來說:微信怎麼做的,你就怎麼做,那你不如去微信做產品算了。
每個產品,在表面的UI下,都有其背後的復雜的業務邏輯。如果產品經理只是叫程序員照著某個產品做,很多時候技術們是很難實現的,因為他們也需要弄懂背後的邏輯和流程。當然,這應該是產品經理的工作。
這就是抬杠。產品經理雖然名字裡面有「經理」二字,但並沒有經理的權利,當然不能命令合作的技術們。這句話,言下之意也是拒絕了商量和討論。而程序員也需要參與感和團隊感。
這就是質疑他人能力,是人都不會喜歡。如果產品經理提出的方案,程序員們沒有理解。那就說明產品經理的解釋說明和文檔,做的不夠優秀,不夠簡潔易懂。讓程序員們理解需求,是產品經理的基本工作內容。
在互聯網產品開發中,修改需求和插入新需求都是挺常見的。對於程序員們來說,這是非常不爽的事情。這種操作通常會打斷程序員的思路,思路被打斷是非常痛苦的。當然,這樣也會影響他們的開發效率。更可怕的是,反復的修改需求,會使他們有種勞動成果不被尊重的感受,同時也會對項目的未來抱有懷疑的態度。反復的更改方案,也說明產品經理設計是未經過嚴密的論證,或對細節的把控是不夠。
程序員都比較討厭反復的催促。當項目的節點確定後,技術們會嚴格遵守節點,產品應該信任他們。當然,時間比較緊湊時,反復催促也會加大程序員們的壓力,使他們變得非常煩躁。在這種時候,催促就是添麻煩。
甩鍋會導致團隊分崩離析,人心不齊。不管任何問題,都是團隊的責任,不要將責任指定給某人。特別是在項目復盤時,如果心態不好同事,這是非常難堪的。所以,我們要盡量以原因和結果為導向,而不是責任為導向。
程序員也是也是團隊的一份子,有權利知道知道需求的背景。同時,了解需求背景也利於程序員們更好的開發程序。
產品經理給程序員們畫餅是最不切實際的,只會引起大家的反感。程序員都是喜歡偏實際的東西,虛的東西只會招致白眼。
任何傳遞給程序員的需求,都是需要有計劃和規范的。如果口頭傳達一個需求,很容易導致開發出的功能與需求不匹配。同時,因為缺乏相關的記錄和文檔,可能會造成需求流失。這對於程序員們來說,可能就是延遲、加班、返工、擔責等等風險。這是團隊合作的大忌,也是項目管理不專業的體現。
以上的這些場景,可能出現一次,程序員們都會順著我們的想法做。但是,這會漸漸改變程序員們的心態,最終會使產品經理與程序員間產生隔閡和矛盾。如果出現這些場景,作為產品經理都需要小心的處理好,以免影響項目的正常推進。當然,最好是不要出現這些場景。作為產品經理,我們的最終目標,都是要保證我們的產品,准時、保質、保量的落地。
產品經理在與程序員們合作時,產品經理需要講究合作共贏、互相體諒。在產品經理的相關工作中,最要避免的就是抬杠。抬杠是一切矛盾的根源。很多時候,產品經理要站在程序員的角度考慮問題。比如,對於產品來說可能就是改改需求,但對於程序員,他們更在意的可能是因為改需求而導致的加班。
產品經理在工作中,經常會追求產品上的極致。追求極致本身是好事,但是切忌過分偏執。我們也需要考慮團隊的現狀和資源,在極致和現實間尋找均衡。畢竟,如果沒有喬布斯的團隊,要像喬布斯一樣做產品,只會拖垮團隊。
在產品開發的過程,改需求、改方案等項目異常,都是不可避免的。這是項目管理的第一部分。如何進行項目異常的處理,考驗的是產品經理的溝通能力和項目管理能力。產品經理需要在保持技術們高效工作的情況下,完成項目異常的處理。
當然,在產品經理工作中,矛盾的根源也並不總是產品經理。有時候,也可能是某些程序員的性格或者對該工作的態度導致的。這時候,產品經理要明確,作為團隊的潤滑劑,有責任推動和協調大家的工作。如果,矛盾不可調和,我們需要盡早提出問題、控制風險,避免「勉強」行事。
有時候,程序員在私下評價一起工作的產品經理時,總是會補加一句「我感覺我也能做產品經理」。這句話的背後,是產品經理沒有讓程序員們感受到產品工作的價值。在這種背景下,產品經理是很難獲取程序員們的注重,也會為很多爭論埋下誘因。那如何感受到我們工作的價值那?其實很簡單,就是保持工作信息的透明。將我們針對需求和產品做的相關工作,體現在我們的溝通或者文檔中。
導致程序員想「砍」產品經理,本質是產品經理工作方式的問題,也有情商的問題。在我的產品經理工作經驗中,我總結下了以下四點,我們需要注意和避免的。這四點,都可以和上文的場景相對應,是最容易慢慢改變程序員的心態的。
⑤ 怎麼樣防止程序員自己盜用資料庫資料
你都給人家導入數據的許可權了,相信人家吧
用人不疑,疑人不用。
技術手段是有,不值得用。