反编译需要多少内存
⑴ app可以被反编译到什么程度
Android APK中的java代码可以被反编译到什么程度主要看APK的加密程度。
第一种情况:无混淆无加密无加壳。
直接利用Dex2jar和JD-GUI可把源码从APK里抠出来,代码逻辑清晰,基本上做到可复用,只是资源文件的引用需要计算一下。
第二种情况:混淆。
通常是利用Proguard做的防护。因为是对jar做的不可逆混淆(除非有mapping),因此不能还原成原来的代码。但是代码结构,代码逻辑一致,只要花长时间对代码进行梳理一样可找准核心代码,解密方法跟第一种一致。
第三种情况:加密。
这里以DexGuard为例。对于这种代码加密的方法,在程序运行中必定会进行解密,只要抽出它解密的逻辑便可。PS:我自己做过DexGuard的解密,如果用Dex2jar反编译看的话逻辑是不对的,一定要从Smali代码看。后来发现网上已经有人做了。
解密的脚本:A look inside Dexguard
第四种情况:加壳。
这种情况跟第三种类似。无论你怎么加壳,运行的时候必定是Dalvik可识别的Odex代码,建议直接在内存里mp出来。这里推荐Xpose的ZjDroid。
加固可以在一定程度上保护自己核心代码算法,提高破解/盗版/二次打包的难度,缓解代码注入/动态调试/内存注入攻击等。
目前市面上有很多第三方加固的平台, 如果新应用发布前需要扫描或者加固的话,可以先试试免费的,例如腾讯御安全,建议自己先去扫描测试下。
⑵ delPhi有反编译工具吗
反向工程一直被认为是技术奇才的专有艺术,需要熟悉汇编语言和调试器。下面几个Delphi反编译器允许任何人反编译大多数Delphi可执行文件,即使只有有限的技术知识。 如果你对Delphi程序反向工程感兴趣,我建议你看一看以下几个“反编译器”:DeDeDeDe是一个非常快的程序,用于分析Delphi编译的可执行文件。反编译之后,DeDe会提供以下信息:所有的目标dfm文件。你可以用Delphi打开并编辑它们; 带有良好的注释的ASM代码的所有发布的方法,它涉及字符串、输入函数调用、类方法调用、单元的组件、Try-Except和Try-Finally块。默认情况下,DeDe仅仅只获得已发布方法的源代码,但如果你通过使用Tools | Disassemble Proc菜单知道RVA偏移量的话,你也可以处理可执行文件中的其他过程。 大量的附加信息。 你可以创建一个带有所有的dfm、pas、dpr文件的Delphi工程的文件夹。注:pas文件包含上面提及的被良好注释过的ASM代码。他们不能被再编译!RevendeproRevendepro可以找到程序中几乎所有的结构(类、类型、过程等),并生成pascal表达式、过程则以汇编程序的形式写出来。由于汇编程序的某些限制,生成的结果不能被在编译。这个反编译器的源代码可以免费获得。不幸的是,这是唯一一个我不能使用的反编译器—当试图用它反编译某些Delphi可执行文件时,总提示异常。 MRIP这个对用途文件分割器可以从其它文件中寻找和摘取文件。MRIP分割100多种文件格式。对我们而言,最重要的是MRipper可以反编译任何Delphi可执行文件。该工具可以从Delphi应用程序中摘取所有的资源:cursors(光标)、icons(图标)、dfm文件、pas文件和其他资源。pas文件不包含事件过程执行。MRIP是一个DOS工具。 DfmExplorer 以下是DfmExplorer的说明(包括原始资料):通过调用Win32 API的“LoadLibrary”或“LoadLibraryEx”函数在内存中载入可执行模块(EXE\DLL\BPL\DPL)。 通过Win32 API的“EnumResourceName”函数找寻RCDATA资源。 载入每个发现的DFM块,解码它并以表的形式(包括它们的名称)存储在内存中。 在程序的主窗口我们可以以文本方式可视化所有载入可执行文件的所有的DFM。 最后,程序可以保存到DFM选择的磁盘,作为ASCII文件(.RC)或作为二进制块(DAT)连接到可执行文件中。 Exe2Dpr如果你试图放松你的工程源代码,这个Delphi工程源代码救助器可以挽救丢失的源码部分。救助器生成所有的带已分配属性和事件的工程表单和数据模块。生成的事件过程没有主程序(它不是反编译器),但又在可执行文件中的代码地址。这个工具没有GUI—它使用命令行的形式:'exe2dpr [-o] exeFile'。工程源代码在当前目录创建。
⑶ 易语言反破解教程说信息框用自定义窗口就是自己新建窗口,请问新建窗口怎么做到程序等待或者系统等待效果
4.随机验证
随机验证很重要,例如你的一处验证是一直存在的,奸人就很容易地下断点跟踪了。因此在软件启动时进行一次正常验证外,其他情况下的验证最好是随机的,用30分之一或50分之一的机会进行验证,这样奸人会不停地试你的软件在哪一处进行了验证,因此破解的时间会相当地长。
加密第14定理:足够多的随机验证足以让破解者累死。
随机验证包括随机进入不同的验证子程序。
或随机中的最大数大一些,只有30分之一的机会验证。
或在窗口中放上一些颜色与底图一样的图片框,这样奸人不一定会点击这里,但用户万一点中了,就会触发验证。
我们假设所有软件都能被破解,包括易语言在内,那么如果他破解的速度跟不上你发布新软件的速度,那么他永远在破最新版而累死。或者说他破解的时间比你写一个软件的代价大,这时还不如他直接写这个软件来得合算。
反破解的任务之一就是让奸人累死,或浪费他的生命。
下面的办法也可以使用:你可以在读到待验证的注册码、公钥、注册文件后,通过定义10000个数组,存入上述同样的内容以备以后进行验证,这最多浪费一些内存。验证时随机使用其中的一个进行验证,由于奸人不知你用的是数组中的哪一个进行的比对,而且是随机的,每次验证的值都不一样,不让奸人吐血才怪呢。
计次循环首(10000,计次)
数组[计次] = “123456” ’ 复制一万个公开注册码或公钥,破解者知道也无所谓。
计次循环尾
数组[取随机数(1,10000)]
你不要立刻检查注册码,10000份拷贝你只要以后随机找一份用就行了,破解的人不知道你正在用的是那一个,同时你可以事先编好且运行时不断使用一些假的读取注册码数组的调用干扰破解者。这种方法对程序的性能影响微不足到,只是浪费一点内存。因为Debug对内存下断点的局限,这种情况他要下断点,累死的就是破解的人了。
5.不同权限验证
在启动时进行一次验证是非常必要的,这样让奸人知道确实是验证了,以让他心理放松警惕,而这次的验证只是一部分验证,并没有完全验证。
还有的建议在启动时将注册信息读入后不要进行验证,保不定在哪里进行验证,个人认为这样让破解者提高了警惕性,会认为软件作者很有经验。麻痹敌人也很重要呀。
例如,在启动时验证通过一次,验证级别加强一级,然后再在其他的地方再进行验证就可以了。
下面代码是确认了一个级别
计次循环首(到数值(验证1),)
已注册 = 1
计次循环尾()
……
……
在另一个触发子程序中再通过这个级别再验证:
计次循环首(已注册)
计次循环首(到数值(验证2),)
已注册 = 2
跳出循环()
计次循环尾()
跳出循环()
计次循环尾()
在其他触发子程序中再通过这个级别再验证:
计次循环首(已注册)
计次循环首(到数值(验证3),)
已注册 =3
跳出循环()
计次循环尾()
跳出循环()
计次循环尾()
有时也可以将级别降一降,怎么降,当然是不考虑级别直接验证了:
6.忽悠型的GHOFFICE过滤词语验证代码
前面已讲过花指令的原理,在程序中人为地再放一些GHOFFICE过滤词语代码以忽悠奸人也是一个好办法。GHOFFICE过滤词语代码就是一些假的验证代码,基本上是明文的,这样的代码上百上千,足以让奸人累死。
其实对付那些“根据跳转指令的爆破”高手来说,一个办法就够他们头疼的了,就是你在程序中不明显加入与判断是否正版有关的语句,也不做任何提示,以免让他们顺藤摸瓜,而是在判断为盗版后,跳转到另一个看似很合理的分支,而那个分支和正版的分支代码差不多,只是在计算公式或其它算法上稍动一下,使其运算结果不正确,这样,他们就在机器码级别上就分不清哪个是对的,哪个是错的了,即使他们认为破解成功,其实运行时,得的结果错误百出,他们就没兴趣了,呵呵,算损的吧!!!
加密第15定理:大量添加GHOFFICE过滤词语代码虽然是无奈之举,但很管用。
作业1:制作一个常量****器
要求:制作一个常量代码自动生成器。可随机生成成百上千个易语言源代码形式,可直接拷贝到易语言中成为常量。变量也可以这样制作。
写好这样一个程序后,就可以自动生成GHOFFICE过滤词语代码,然后复制,粘贴到易语言的常量表中即可。如下图所示:
变量也可以这样生成,不过生成的变量可以任意拷贝为全局变量,或程序集变量,或局部变量。制作时的名称可以为中文名称,直接编译后不会在EXE文件中找到同名的中文名称。因此您可以放心地将这些名称定义为:“GHOFFICE过滤词语常量1”、“GHOFFICE过滤词语变量1”等等以示与正常代码进行区别。
作业2:制作一个代码迷乱器
本次作业性质同上,也是自动生成易语言的一些无用GHOFFICE过滤词语代码,以迷乱奸人的破解,让他找到的全是GHOFFICE过滤词语代码,从而大大延长了破解时间。
通过直接拷贝编辑框中的内容,粘贴到您的代码中,可自动完成任务,如下图所示:
上图所生成的是一些明文的加密方法的GHOFFICE过滤词语代码,让奸人去研究这些GHOFFICE过滤词语吧。
上述子程序名称最好也有时调用一下,反正不会真正产生作用的,用多线程调用最好。
或者您平时注意多收集一些别人用于加密时的子程序,拷贝到一个易语言程序中,保存,这样的代码作为GHOFFICE过滤词语代码放在你有用的程序中,虽然增加了一些程序的体积,但安全性是大大提高了。并且基本上没有牺牲软件性能与稳定性。
7.伪验证技术
还是先举一个例子说明吧,易表软件在10.0版本前已发现有大量的注册机存在,于是易表作者其后改变了加密方式,易表10.0推出后还是出现了注册机,并且这种注册机注册过的软件可以使用。于是有些用户用注册机取得的注册码使用了,过了一段时间,当盗版用户将重要数据存入易表后,突然有一天数据库被锁定了,于是只好注册易表,并且让易表作者为数据库解锁。
从这里可以基本上判定易表新版本采用了伪验证技术,即在较为明显的地方提供了一级验证,这种验证方式没有经过太强的加密,而二级验证在一定的条件下才触发,而这个条件是检查到了用户输入了重要的数据,或大量的数据,或使用次数较多。
基本原理是注册文件由前后两个注册码拼接而成。一般情况下只进行第一个注册码的验证,而当条件成熟时进行第二个注册码验证。
这是一种双赢的策略,易表作者即收到了注册费,付费的人还会道歉,并且感谢易表作者。哈哈,大家要学习这招哦。
但本办法对于数据库应用及数据量大时检查最好,而对于一些没有生成数据的用户无效。
发布软件的时候发布自己编写的注册机,弄个假破解版,那么想破解的就可能不来了,即使有真的破解,谁会有自己给自己写假破解快啊!可能假破解版中只破解一半,等用户使用了,有数据了再锁定,让他们注册后再给解锁,付了钱还要谢谢你,哈哈,损招,但有用!
加密第16定理:伪验证可以迷惑一般破解者,甚至自己发布一个伪注册机。
8.定时验证、延时验证、客户数据集累验证
过一段时间后再验证,如你在2005年1月发布一个软件,那么就内定2005年6月后触发验证机会。
或您的软件是一个数据库产品,那么您可以在程序中设置如果数据库大于5MB时就进行验证,并且最好您能确定这些数据是不重复的,刻意加入的。
如易表设置了伪验证,这时市场上出现了新的注册机,当用户用这个注册机后,提示是注册成功了,但当用户输入重要数据后的某个日子,突然打不开数据库了,用户很着急,因为以为是破解成功了,所以将重要的资料输入了,只能拿钱向易表作者进行注册了。而且还千恩万谢,后悔自己不该用破解。哈哈,一举两得呀。
这个方法对于数据库应用软件来说是绝好的办法。
作业:制作一个算法程序放在你的数据库软件中,这个子程序可以统计你的数据库软件使用时,用户输入的是否是拷贝的东西,还是正常的数据。当统计到1000时触发验证。方法思路为:可以通过查看用户有没有使用复制与粘贴快捷键,或资料进行排序,如果有大量重复的,就说明是奸人在拷贝数据破解,否则是一个资料一个资料的输入的,说明是正常使用的重要资料,这时进行对比就好了。
本方法对有资料的破解使用者有极好的控制作用,通过第6条的伪验证技术与本技术结合,那么就可以知道是不是正版用户,并且可以锁定数据库,等他注册后再给他解锁。
加密第17定理:加密的结果应该是双赢,伪验证是一个上策。
9.验证与专业知识相结合技术
将验证与专业知识相结合,让奸人必须学习专业知识后才能真正去破解,这样所花的功夫比自己写一个软件的代价还要大,而有的专业知识不是专家是不知道的,因此是一个较好的加密方法。
前述中采用了“到数值(验证1())”这样的代码返回的是0或1两者之间的一个数,可以用乘法进行混合计算,如:
音量 = 播放位置X到数值(验证1())
当验证正确时返回的是1,这时的结果是正确的,否则返回0,这时的结果为0,是错误的。
这样的代码可以混合到您的专业知识中,如:算命软件可将天干地支、生辰八字中的某个地方进行此类计算,计算类软件可以将某种特殊的计算过程如此结合计算,绘图类软件可将绘图中的算法部分加入此类计算,音响设计类、机床设计软件……
加密第18定理:你知道的专业知识,破解者不一定了解哦。让专业知识与验证相结合吧。
10.伪装,用易语言写自有支持库
大家可以将DLL文件的扩展名改为易语言的支持库文件FNE扩展名,这样进行非独立编译后,与其他FNE文件混合在一起,甚至您可以用易语言写一个支持库,将其中一部分作为验证部分。
易语言的支持库文件FNE文件其实就是一个DLL文件,只不过扩展名改变了而已,用易语言写支持库的方法金眼睛已发过一篇贴子,进行过说明,请大家在易语言论坛上搜索金眼睛的贴子就可以找到了。
作业:找到金眼睛关于用易语言写支持库的贴子,并且自己写一个支持库。
11.绝妙的暗桩设置
应该想到的用代码实现的暗桩前面都讲了不少,下面是一些特别的暗桩供奸人品味的。
大家可以在一些不起眼的地方再放一些暗桩,如:在窗口最小化事件中随机验证,如在某个组件鼠标被移动事件中验证,
有时需要将数据完整性验证放在更高一级的验证中,不要一上来就检查文件是否被更改。
同一验证可以使用多次,这样奸人认为你已经验证过了,没有必要会再验证一次,而相反这时又产生了验证,让奸人防不胜防。如启动时就立即检查程序完整性,如果发现被更改,那就立即退出程序,而在一些子程序中也随机放这样的验证。
更多的暗桩大家自己设计最好。
加密第19定理:加密重要的是暗桩的设置,破解不完全就是一个无效破解。
12.发布不完整版本
有的软件作者在发布共享软件时,放在外面的是不完整版本,将更多的数据资料在注册后提供。这样做也可以,只是麻烦一些而已。如有的图形制作软件,将图片资源另外打包,用户注册后再给完全版的图片。
也有的将DLL文件中的验证部分作了空处理,而在注册后提供真正的注册DLL文件及注册码。还有的直接将KEY文件放在了DLL文件中另外提供。
加密第20定理:不要发布完整版本,以静制动。
13.程序、数据结合加密技术
把程序运行所必需要的资源放到一个数据库文件中,给这个数据库设密码,密码是主程序的数据摘要变换后的结果。程序运行是先验证有没有注册,如果已经注册,就对运行程序本身(取执行文件名())取数据摘要,用自己设计的算法多次变换后形成一个字串,用该字串作为数据库的密码打开数据库文件。如果打开数据库失败,就说明主程序被人修改了,终止程序运行即可。(不终止也没戏,程序找不到运行所需的资源。)
另外设计一个程序,用同样的算法算出数据库密码,然后给数据库加密即可。
密码形成算法建议使用大数支持库。但如果是汇编高手用汇编写注册机的话,会直接将支持库的所有反汇编码抄进去就可以了,问题是他们有没有时间搞。
14.自定义算法
前面讲过采用RSA与数值计算支持库交叉计算的办法,这就是一种自有的算法,如果能用上数值计算支持库中的矩阵、傅丽叶变换等高级功能就更好了。
多重RSA交叉打乱:大家也可以多用一些RSA密钥,如用5个,10个都无所谓,重要的是将这些注册码都打乱,让奸人哭死。打乱的方法就是你自己独创的方法了。
更多的自有算法就要靠大家自己去研究了。祝大家好运。
加密第21定理:加密不反对古怪和变态的方法,鼓励哦。
15.加密框图
下面给出一个加密的设计框图,大家可以根据自己的实际情况改变加密的策略:
图中主程序外围进行了花指令编译,并且用加普通壳进行保护。脱壳了也无所谓,因为设置了暗桩,随机检查。
图中表示主程序运行后,首先进行了常规的注册码第一次验证,找有没有注册文件。如果这个被破解,注册码应该是一个短的RSA,而真正的注册码是三个RSA的叠加。会生成伪注册机也无所谓。
主程序中用暗桩的形式对窗口标题、版权信息进行验证,这是考虑到如果一启动就验证这些很容易被奸人看出来从而会跳过去。因此用一些随机,或分级,或条件法取得不固定的验证。
主程序中用暗桩的方式对加壳后主程序的完整性进行校验,这个也不要放在常规的验证中,否则很容易被跳过去。可以查文件长度,MD5或CRC32都可以上。
主程序中用暗桩的方式加入了反调试模块。
主程序中布满GHOFFICE过滤词语验证代码。并且源代码有备注,不会搞错的。
主程序在某个条件下随机进行第二级验证,从注册码中取第二段数据,如果注册码长度不够且取不到第二段数据,那么就说明已使用了伪注册机,将用户的数据库锁定,等他付钱来注册。
主程序在一个条件下再激活验证,从注册码文件中取第三段数据,如果注册码长度不够,且取不到第三段数据,那么就说明已使用了伪注册机,将用户的数据库锁定,等他付钱来注册。
编程中还注意将加密的字符串搅乱且分不同地方存放,用吴氏加密命令加密重要数据,也可加入数值计算支持库的算法,也可以加入一些惩罚手段,也可以再加入自己的一些算法。
以下是一些人的编程体会摘录,基本未改其中的内容,在此表示感谢!
附录1加密已形成密码学
我引用《应用密码学》作者的话:
世界上有两种密码:一种是防止你的小妹妹看你的文件;另一种是防止奸人阅读你的文件资料。
如果把一封信锁在保险柜中,把保险柜藏在纽约的某个地方…,然后告诉你去看这封信。这并不是安全,而是隐藏。相反,如果把一封信锁在保险柜中,然后把保险柜及其设计规范和许多同样的保险柜给你,以便你和世界上最好的开保险柜的专家能够研究锁的装置。而你还是无法打开保险柜去读这封信,这样才是安全的。
意思是说,一个密码系统的安全性只在于密钥的保密性,而不在算法的保密性。
对纯数据的加密的确是这样。对于你不愿意让他看到这些数据(数据的明文)的人,用可靠的加密算法,只要破解者不知道被加密数据的密码,他就不可解读这些数据。
但是,软件的加密不同于数据的加密,它只能是“隐藏”。不管你愿意不愿意让他(合法用户,或 Cracker)看见这些数据(软件的明文),软件最终总要在机器上运行,对机器,它就必须是明文。既然机器可以“看见”这些明文,那么 Cracker,通过一些技术,也可以看到这些明文。
于是,从理论上,任何软件加密技术都可以破解。只是破解的难度不同而已。有的要让最高明的 Cracker 忙上几个月,有的可能不费吹灰之力,就被破解了。
所以,反盗版的任务(技术上的反盗版,而非行政上的反盗版)就是增加 Cracker 的破解难度。让他们花费在破解软件上的成本,比他破解这个软件的获利还要高。这样 Cracker 的破解变得毫无意义——谁会花比正版软件更多的钱去买盗版软件 ?
然而,要做到“难破解”,何尝容易? Sony 曾宣称的超强反盗版(Key 2 Audio音乐 CD反盗版),使用了很尖端的技术,然而最近却被一枝记号笔破解了,成为人们的饭后笑料!
所以,很多看上去很好的技术,可能在 Cracker 面前的确不堪一击。就像马其诺防线一样,Cracker 不从你的防线入手,而是“绕道”。这样,让你的反盗版技术在你做梦也想不到的地方被 Crack 了。
为什么会这样呢 ?归根到底是因为软件在机器上运行,并且软件和机器是分离的——这一点是关键,如果软件和硬件完全绑定,不能分离,是可以做到象 IDEA 之类几乎不可破解的系统的。这将在后面谈传统软件保护技术时详细说明。
对我的这个解决方案,我不能保证Crack高手在几天之内不能破解它,我只能说:“在这个软件中,我尽量堵住了当前破解者普遍使用的方法以及“我想得到”的可能的缺口。”但是我相信,倾注了我三个月心血的反盗版软件,决不是一个“玩具式”的反盗版软件。
附录2《如何用简单方法防止破解》
北极异型
在Debug的手册里可以看到Debug工具的局限:第一个局限是只能下4个内存区域的断点,每个断点不能控制超过两个字节,这样内存断点不能控制超过16个字节的区域;第二个局限是对多线程只能同时跟踪一个线程。
假设你的注册部分有300行,你可以分成30个子程序调用或重复的func1(),func2()... func30()。将他们随意放到程序的各个部分,一定不能放在一起(自己能找到就行了)。不要用Memcpy等常用系统调用拷贝注册码,尽可能自己写,像Memcpy很好写,性能差点无所谓。经过编译后inline函数展开,注册部分和其他代码混在一起,他要写出注册机就像大海里捞针,在几十万甚至上百万汇编代码里找出有用的注册部分。
利用Debug的第一个局限最重要的一点是:注册码也不要放在一起,假设你的注册码是12位,千万不要用一个12位的数组放注册码,你可以在程序的不同位置定义12个全局字符变量,每个放一位,这样注册码在内存就不连续了。最好再加密处理一下(简单的字符异或就可以),验证时再解密。也不要用连续内存保存验证用到的变量,尽量将用到的验证临时变量分散定义在程序的不同处,再在验证中,不断转移一些值到其他变量中,对付暴力和Loader会比较有效。
没有必要用复杂的加密算法,更容易成为追踪的目标。只要你将注册部分隐藏的足够好,也没有漏洞,你花1天写的加密算法,破解者可能会花100-1000倍的时间破解。大部分人都会放弃。
你将注册做在一起,就像将你的财宝放在现代保险箱里,虽然非常坚固难以解密,对于开锁高手两分钟就打开了。
而古代海盗用的方法是将财宝埋在海岛上,这样没有藏宝图,对所有高手和低手都只有一条路,拿一把铁撬挖,可能要挖一生。程序有那么多代码,反编译出来可能超过百万行,你将注册部分藏在里面,藏的好就如同将财宝埋在海岛里。那些所谓的Crackme只是给高手玩儿的现代保险箱而已,用原始的方法可以达到同样效果。
⑷ 如何防止程序员反编译
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!”);
}
}
在编译代码时(如使用ant或maven),使用插件将代码进行加密(加密方式自己选),将class文件里面的内容读取成byte[],然后进行加密后再写回到class文件(这时候class文件里面的内容不是标准的class,无法被反编译了)
在启动项目代码时,指定使用我们自定义的ClassLoader就行了,而自定义的部分,主要就是在这里做解密工作!
上面这段代码,大家都认识。但我要问的是:如果我们使用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文件就行了,在这之前是什么样子无所谓!所以,我们的加密的整个逻辑就是:
如此,搞定!以上的做法比较完整的阐述,可以仔细阅读一下这篇文章: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就得跟着这个项目到处走啊!
⑸ 如何反编译EXE执行文件
C32asm 可反编译成汇编文件
http://www.25it.net/SoftView.Asp?SoftID=227
C32asm 是一款非常不错的国产静态反编译工具!
C32Asm现具有如下功能:
快速静态反编译PE格式文件(Exe、Dll等)
提供Hex文件编辑功能,功能强大
提供内存Dump、内存编辑、PE文件Dump、PE内存ImageSize修正等多种实用功能
提供内存反汇编功能,提供汇编语句直接修改功能,免去OPCode的直接操作的繁琐
提供反编译语句彩色语法功能,方便阅读分析,能方便自定义语法色彩
提供输入表、输出表、参考字符、跳转、调用、PE文件分析结果等显示
提供方便的跳转、调用目标地址的代码显示
提供汇编语句逐字节分析功能,有助于分析花指令等干扰代码
⑹ 如何修改EXE文件
exe文件信息一般不能直接更改,因为是编译好的,并且一般都加了壳。
想改的话,得用脱壳了吧。不同的文件有可能用了不同的软件加了壳。
用各类脱壳工具测试并脱壳后,再反编译,有可能得到相关文件信息并更改。
(一)壳的概念
作者编好软件后,编译成exe可执行文件。 1.有一些版权信息需要保护起来,不想让别人随便改动,如作者的姓名,即为了保护软件不被破解,通常都是采用加壳来进行保护。 2.需要把程序搞的小一点,从而方便使用。于是,需要用到一些软件,它们能将exe可执行文件压缩, 3.在黑客界给木马等软件加壳脱壳以躲避杀毒软件。实现上述功能,这些软件称为加壳软件。
(二)加壳软件最常见的加壳软件ASPACK ,UPX,PEcompact 不常用的加壳软件WWPACK32;PE-PACK ;PETITE NEOLITE
(三)侦测壳和软件所用编写语言的软件,因为脱壳之前要查他的壳的类型。 1.侦测壳的软件fileinfo.exe 简称fi.exe(侦测壳的能力极强) 2.侦测壳和软件所用编写语言的软件language.exe(两个功能合为一体,很棒) 推荐language2000中文版(专门检测加壳类型) 3.软件常用编写语言Delphi,VisualBasic(VB)---最难破,VisualC(VC)
(四)脱壳软件。 软件加壳是作者写完软件后,为了保护自己的代码或维护软件产权等利益所常用到的手段。目前有很多加壳工具,当然有盾,自然就有矛,只要我们收集全常用脱壳工具,那就不怕他加壳了。软件脱壳有手动脱和自动脱壳之分,下面我们先介绍自动脱壳,因为手动脱壳需要运用汇编语言,要跟踪断点等,不适合初学者,但我们在后边将稍作介绍。
加壳一般属于软件加密,现在越来越多的软件经过压缩处理,给汉化带来许多不便,软件汉化爱好者也不得不学习掌握这种技能。现在脱壳一般分手动和自动两种,手动就是用TRW2000、TR、SOFTICE等调试工具对付,对脱壳者有一定水平要求,涉及到很多汇编语言和软件调试方面的知识。而自动就是用专门的脱壳工具来脱,最常用某种压缩软件都有他人写的反压缩工具对应,有些压缩工具自身能解压,如UPX;有些不提供这功能,如:ASPACK,就需要UNASPACK对付,好处是简单,缺点是版本更新了就没用了。另外脱壳就是用专门的脱壳工具来对付,最流行的是PROCDUMP v1.62 ,可对付目前各种压缩软件的压缩档。在这里介绍的是一些通用的方法和工具,希望对大家有帮助。我们知道文件的加密方式,就可以使用不同的工具、不同的方法进行脱壳。下面是我们常常会碰到的加壳方式及简单的脱壳措施,供大家参考: 脱壳的基本原则就是单步跟踪,只能往前,不能往后。脱壳的一般流程是:查壳->寻找OEP->Dump->修复 找OEP的一般思路如下: 先看壳是加密壳还是压缩壳,压缩壳相对来说容易些,一般是没有异常,找到对应的popad后就能到入口,跳到入口的方式一般为。 我们知道文件被一些压缩加壳软件加密,下一步我们就要分析加密软件的名称、版本。因为不同软件甚至不同版本加的壳,脱壳处理的方法都不相同。
常用脱壳工具: 1、文件分析工具(侦测壳的类型):Fi,GetTyp,peid,pe-scan, 2、OEP入口查找工具:SoftICE,TRW,ollydbg,loader,peid 3、mp工具:IceDump,TRW,PEditor,ProcDump32,LordPE 4、PE文件编辑工具PEditor,ProcDump32,LordPE 5、重建Import Table工具:ImportREC,ReVirgin 6、ASProtect脱壳专用工具:Caspr(ASPr V1.1-V1.2有效),Rad(只对ASPr V1.1有效),loader,peid(1)Aspack: 用的最多,但只要用UNASPACK或PEDUMP32脱壳就行了 (2)ASProtect+aspack:次之,国外的软件多用它加壳,脱壳时需要用到SOFTICE+ICEDUMP,需要一定的专业知识,但最新版现在暂时没有办法。 (3)Upx: 可以用UPX本身来脱壳,但要注意版本是否一致,用-D 参数 (4)Armadill: 可以用SOFTICE+ICEDUMP脱壳,比较烦 (5)Dbpe: 国内比较好的加密软件,新版本暂时不能脱,但可以破解 (6)NeoLite: 可以用自己来脱壳 (7)Pcguard: 可以用SOFTICE+ICEDUMP+FROGICE来脱壳 (8)Pecompat: 用SOFTICE配合PEDUMP32来脱壳,但不要专业知识 (9)Petite: 有一部分的老版本可以用PEDUMP32直接脱壳,新版本脱壳时需要用到SOFTICE+ICEDUMP,需要一定的专业知识 (10)WWpack32: 和PECOMPACT一样其实有一部分的老版本可以用PEDUMP32直接脱壳,不过有时候资源无法修改,也就无法汉化,所以最好还是用SOFTICE配合 PEDUMP32脱壳 我们通常都会使用Procmp32这个通用脱壳软件,它是一个强大的脱壳软件,他可以解开绝大部分的加密外壳,还有脚本功能可以使用脚本轻松解开特定外壳的加密文件。另外很多时候我们要用到exe可执行文件编辑软件ultraedit。我们可以下载它的汉化注册版本,它的注册机可从网上搜到。ultraedit打开一个中文软件,若加壳,许多汉字不能被认出 ultraedit打开一个中文软件,若未加壳或已经脱壳,许多汉字能被认出 ultraedit可用来检验壳是否脱掉,以后它的用处还很多,请熟练掌握例如,可用它的替换功能替换作者的姓名为你的姓名注意字节必须相等,两个汉字替两个,三个替三个,不足处在ultraedit编辑器左边用00补。
常见的壳脱法:
(一)aspack壳 脱壳可用unaspack或caspr 1.unaspack ,使用方法类似lanuage,傻瓜式软件,运行后选取待脱壳的软件即可. 缺点:只能脱aspack早些时候版本的壳,不能脱高版本的壳 2.caspr第一种:待脱壳的软件(如aa.exe)和caspr.exe位于同一目录下,执行windows起始菜单的运行,键入 caspr aa.exe脱壳后的文件为aa.ex_,删掉原来的aa.exe,将aa.ex_改名为aa.exe即可。使用方法类似fi 优点:可以脱aspack任何版本的壳,脱壳能力极强缺点:Dos界面。第二种:将aa.exe的图标拖到caspr.exe的图标上***若已侦测出是aspack壳,用unaspack脱壳出错,说明是aspack高版本的壳,用caspr脱即可。 (二)upx壳 脱壳可用upx待脱壳的软件(如aa.exe)和upx.exe位于同一目录下,执行windows起始菜单的运行,键入upx -d aa.exe (三)PEcompact壳 脱壳用unpecompact 使用方法类似lanuage傻瓜式软件,运行后选取待脱壳的软件即可 (四)procmp 万能脱壳但不精,一般不要用 使用方法:运行后,先指定壳的名称,再选定欲脱壳软件,确定即可脱壳后的文件大于原文件由于脱壳软件很成熟,手动脱壳一般用不到。
三、压缩与脱壳
现在脱壳一般分手动和自动两种,手动就是用TRW2000、TR、SOFTICE等调试工具对付,对脱壳者有一定水平要求。而自动就稍好些,用专门的脱壳工具来脱,最常用某种压缩软件都有他人写的反压缩工具对应,有些压缩工具自身能解压,如UPX;有些不提供这功能,如:ASPACK,就需要UNASPACK对付。很多文件使用了一些压缩加壳软件加密过,这就需要对文件进行解压脱壳处理后,才能汉化。这种压缩与我们平时接触的压缩工具如winzip,winrar等压缩不同,winzip和winrar等压缩后的文件不能直接执行,而这种 EXE 压缩软件,EXE文件压缩后,仍可以运行。这种压缩工具把文件压缩后,会在文件开头一部分,加了一段解压代码。执行时该文件时,该代码先执行解压还原文件,不过这些都是在内存中完成的,由于微机速度快,我们基本感觉不出有什么不同。这样的程序很多,如 The bat,Acdsee,Winxfile等等。
要脱壳就应先了解常用压缩工具有哪些,这样知己知彼,如今越来越多的软件商喜欢用压缩方式发行自己的产品,如The bat!用UPX压缩,ACDSEE3.0用ASPACK压缩等。它有以下因素:一是:微机性能越来越好,执行过程中解压使人感觉不出来,用户能接受(给软件加壳,类似WINZIP 的效果,只不过这个加壳压缩之后的文件,可以独立运行,解压过程完全隐蔽,都在内存中完成。解压原理,是加壳工具在文件头里加了一段指令,告诉CPU,怎么才能解压自己。现在的CPU都很快,所以这个解压过程你看不出什么异常。因为软件一下子就打开了,只有你机器配置非常差,才会感觉到不加壳和加壳后的软件运行速度的差别。)。 二是:压缩后软件体积缩小,便于网络传输。三是:增加破解的难度。首先,加壳软件不同于一般的winzip,winrar等压缩软件.它是压缩exe可执行文件的,压缩后的文件可以直接运行.而winzip,winrar等压缩软件可压缩任何文件,但压缩后不能直接运行。很多站点不允许上传可执行文件,而只能上传压缩的文件,一方面处于速度考虑,也是为了安全性考虑。用加壳软件压缩的文件就是体积缩小,别的性质没改变。还是EXE文件,仍可执行,只是运行过程和以前不一样了。压缩工具把文件压缩后,在文件开头一部分,加了一段解压代码。执行时该文件时,该代码先执行解压还原文件,不过这些都是在内存中完成的,由于微机速度快,我们基本感觉不出有什么不同。
⑺ 一个小程序反编译,谁会破解exe文件,能绕过验证码
……都不用说了……7ZIP加上SIXXPACK估计没人脱得掉了
用VS调试可以到验证的地方通过改EIP可以跳过验证但是不能得到内存的地址只是知道那个函数叫ZhuCe.Check……
反编译这个文件里面除了MANIFEST就两块东西……sevenzip和sixxpack……
这两个不用说都知道是什么了……又得不到内存地址不知道是不是我的VS设置有问题反正看不到函数所在的内存要不然内存补丁都行……
还有哪位牛人自认为真的很牛的可以来试试看我试过了IDAODSmartCheckVBExplorer都不行的……只有VS的调试器可以……
(PS.分数给我好不好……呵呵我加了你的)
⑻ VB反编译还原代码 求助
如果说 VB3、VB4 还有可能的话,那么 VB5、VB6 反编译就是完全的痴人说梦了,VB6 已经不是纯粹的解释性语言了,根本不可能反编译出完整的源代码,对于这种语言写出来的程序,只能获得中间语言或低级语言。一般来说 VB6 都是 P 代码,而 P-Code 的代码逆向回来只能自己看,机器是识别不了的。
举个例子:
比如在 VB6 中有一句代码 : MsgBox "Decompile Test."
那么反编译出来的结果就是:
(代码太长不贴,这里贴主要的)
...
mov dword ptr [ebp-58], 004012E4 ; 这里把 "Decompile Test."的地址弄进去了。
...
call dword ptr [<&MSVBVM60.__vbaVarDup>]; 可以清楚的看出来,复制了一份变量的句柄。因为VB里字符串指向的是内存地址。
...
call dword ptr [<&MSVBVM60.#595>] ; 这一句弹出了MsgBox.这里如果跟进去的话是一大堆API 。
...
所以正常反编译(学汇编语言和计算机编译原理去吧)的话,看到段了就会知道这是一个 Msgbox 函数,但是具体显示的内容是什么,那是根本看不出来的。
P.S. 针对楼上[你不懂就别乱说]说的插一嘴,未加壳的 .NET 为何能被反编译出源代码,那是因为 .NET 是托管,而托管有中间语言,所以它的源代码被编译成 msil 这种中间语言而非像 VB6 直接编译成机器语言了。