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下,都有其背后的复杂的业务逻辑。如果产品经理只是叫程序员照着某个产品做,很多时候技术们是很难实现的,因为他们也需要弄懂背后的逻辑和流程。当然,这应该是产品经理的工作。
这就是抬杠。产品经理虽然名字里面有“经理”二字,但并没有经理的权利,当然不能命令合作的技术们。这句话,言下之意也是拒绝了商量和讨论。而程序员也需要参与感和团队感。
这就是质疑他人能力,是人都不会喜欢。如果产品经理提出的方案,程序员们没有理解。那就说明产品经理的解释说明和文档,做的不够优秀,不够简洁易懂。让程序员们理解需求,是产品经理的基本工作内容。
在互联网产品开发中,修改需求和插入新需求都是挺常见的。对于程序员们来说,这是非常不爽的事情。这种操作通常会打断程序员的思路,思路被打断是非常痛苦的。当然,这样也会影响他们的开发效率。更可怕的是,反复的修改需求,会使他们有种劳动成果不被尊重的感受,同时也会对项目的未来抱有怀疑的态度。反复的更改方案,也说明产品经理设计是未经过严密的论证,或对细节的把控是不够。
程序员都比较讨厌反复的催促。当项目的节点确定后,技术们会严格遵守节点,产品应该信任他们。当然,时间比较紧凑时,反复催促也会加大程序员们的压力,使他们变得非常烦躁。在这种时候,催促就是添麻烦。
甩锅会导致团队分崩离析,人心不齐。不管任何问题,都是团队的责任,不要将责任指定给某人。特别是在项目复盘时,如果心态不好同事,这是非常难堪的。所以,我们要尽量以原因和结果为导向,而不是责任为导向。
程序员也是也是团队的一份子,有权利知道知道需求的背景。同时,了解需求背景也利于程序员们更好的开发程序。
产品经理给程序员们画饼是最不切实际的,只会引起大家的反感。程序员都是喜欢偏实际的东西,虚的东西只会招致白眼。
任何传递给程序员的需求,都是需要有计划和规范的。如果口头传达一个需求,很容易导致开发出的功能与需求不匹配。同时,因为缺乏相关的记录和文档,可能会造成需求流失。这对于程序员们来说,可能就是延迟、加班、返工、担责等等风险。这是团队合作的大忌,也是项目管理不专业的体现。
以上的这些场景,可能出现一次,程序员们都会顺着我们的想法做。但是,这会渐渐改变程序员们的心态,最终会使产品经理与程序员间产生隔阂和矛盾。如果出现这些场景,作为产品经理都需要小心的处理好,以免影响项目的正常推进。当然,最好是不要出现这些场景。作为产品经理,我们的最终目标,都是要保证我们的产品,准时、保质、保量的落地。
产品经理在与程序员们合作时,产品经理需要讲究合作共赢、互相体谅。在产品经理的相关工作中,最要避免的就是抬杠。抬杠是一切矛盾的根源。很多时候,产品经理要站在程序员的角度考虑问题。比如,对于产品来说可能就是改改需求,但对于程序员,他们更在意的可能是因为改需求而导致的加班。
产品经理在工作中,经常会追求产品上的极致。追求极致本身是好事,但是切忌过分偏执。我们也需要考虑团队的现状和资源,在极致和现实间寻找均衡。毕竟,如果没有乔布斯的团队,要像乔布斯一样做产品,只会拖垮团队。
在产品开发的过程,改需求、改方案等项目异常,都是不可避免的。这是项目管理的第一部分。如何进行项目异常的处理,考验的是产品经理的沟通能力和项目管理能力。产品经理需要在保持技术们高效工作的情况下,完成项目异常的处理。
当然,在产品经理工作中,矛盾的根源也并不总是产品经理。有时候,也可能是某些程序员的性格或者对该工作的态度导致的。这时候,产品经理要明确,作为团队的润滑剂,有责任推动和协调大家的工作。如果,矛盾不可调和,我们需要尽早提出问题、控制风险,避免“勉强”行事。
有时候,程序员在私下评价一起工作的产品经理时,总是会补加一句“我感觉我也能做产品经理”。这句话的背后,是产品经理没有让程序员们感受到产品工作的价值。在这种背景下,产品经理是很难获取程序员们的注重,也会为很多争论埋下诱因。那如何感受到我们工作的价值那?其实很简单,就是保持工作信息的透明。将我们针对需求和产品做的相关工作,体现在我们的沟通或者文档中。
导致程序员想“砍”产品经理,本质是产品经理工作方式的问题,也有情商的问题。在我的产品经理工作经验中,我总结下了以下四点,我们需要注意和避免的。这四点,都可以和上文的场景相对应,是最容易慢慢改变程序员的心态的。
⑤ 怎么样防止程序员自己盗用数据库资料
你都给人家导入数据的权限了,相信人家吧
用人不疑,疑人不用。
技术手段是有,不值得用。