防止JAVA代码被反编译的方法

本文版权归原作者,中国JAVA手机网收录本文的目的是让更多人阅读到此文章。转载请注明出处为中国JAVA手机网<www.cnjm.net>

[本文章最后由 rocks 在2006-04-14 13:08:50编辑过]


[转载于minisoyo]
原文: http://www.minisoyo.com/forum/thread.jspa?threadID=943&tstart=0
作者:bb

我们都知道JAVA是一种解析型语言,这就决定JAVA文件编译后不是机器码,而是一个字节码文件,也就是CLASS文件。而这样的文件是存在规律的,经过反编译工具是可以还原回来的。例如Decafe、FrontEnd,YingJAD和Jode等等软件。下面是《Nokia中Short数组转换算法》
类中Main函数的ByteCode:
0 ldc #16 
2 invokestatic #18 
5 astore_1
6 return

其源代码是:short [] pixels = parseImage("/ef1s.png");
我们通过反编译工具是可以还原出以上源代码的。而通过简单的分析,我们也能自己写出源代码的。
第一行:ldc #16 
ldc为虚拟机的指令,作用是:压入常量池的项,形式如下
ldc index
这个index就是上面的16,也就是在常量池中的有效索引,当我们去看常量池的时候,我们就会找到index为16的值为String_info,里面存了/ef1s.png.
所以这行的意思就是把/ef1s.pn作为一个String存在常量池中,其有效索引为16。
第二行:2 invokestatic #18 
invokestatic为虚拟机指令,作用是:调用类(static)方法,形式如下
invokestatic indexbyte1 indexbyte2
其中indexbyte1和indexbyte2必须是在常量池中的有效索引,而是指向的类型必须有Methodref标记,对类名,方法名和方法的描述符的引用。
所以当我们看常量池中索引为18的地方,我们就会得到以下信息:
Class Name : cp_info#1 
Name Type : cp_info#19 
1 和19都是常量池中的有效索引,值就是右边<>中的值,再往下跟踪我就不多说了,有兴趣的朋友可以去JAVA虚拟机规范。
这里我简单介绍一下parseImage(Ljava/lang/String;)[S 的意思。
这就是parseImage这个函数的运行,我们反过来看看parseImage的原型就明白了
short [] parseImage(String)
那么Ljava/lang/String;就是说需要传入一个String对象,而为什么前面要有一个L呢,这是JAVA虚拟机用来表示这是一个Object。如果是基本类型,这里就不需要有L了。然后返回为short的一维数组,也就是对应的[S。是不是很有意思,S对应着Short类型,而“[”对应一维数组,那有些朋友要问了,两维呢,那就“[[”,呵呵,是不是很有意思。
好了,调用了函数,返回的值要保存下来吧。那么就是第三行要做的事情了。
第三行:5 astore_1
呵呵,很简单的。但是却有文章,也是比较容易混乱的地方。
astore_为虚拟机指令,作用为:将当前reference存储到局部变量中去。而必须是对当前框架的局部变量的有效索引。打个比方,可能我们这个函数中可能还要用到这个局部变量,我们可以通过来找到它。例如调用虚拟机指令:
aload_1,就能得到该值。
第四行:6 return
同样的,return也是虚拟机指令了,它的作用为:从方法返回void。
这里也就是退出main函数。
----------------------------------------------------------------------------
ok,终于啰嗦完毕了。有些朋友可能要问,这么复杂,才四行就说这么多,呵呵,可能是我这人废话过多,当然如果你熟悉了,一点就能看懂了。通过肉眼就可以反编译程序了。目前所有的反编译工具都无法做到完美反编译,在有问题的地方还需要人去修正。
好了,说了半天如何反编译,我们就来看看如果在你的程序如果防止别人来反编译。好不容易写好的程序被人反编译了,多郁闷。哈哈。工欲善其事,必先利其器,这句话用对了吗?
什么混淆等等的方法,我就不说了,我这里主要是要说一种通过添加代码来在某种程度来避免当前流行的反编译工具对你的代码进行反编译。
方案一。
1,首先要添加一个参数为Exception类型的函数,例如这样。
   public static void Fake(Exception e)
   {
       e.toString();
   }
  一定要有e.toString();,因为要防止你的混淆器把无用的代码过滤。
2,然后在每个类中调用这个函数,放在try...catch(Exception e)..中的catch里面,例如:
   try
   {
    ...
   }
   catch (Exception e)
   {
       Fake(e);
   }
请注意 ,一定要放在catch才有用,其他地方无用。
方案二。
如果以上方法还不够专业,我们再来一个。呵呵~
1,同样的,我们定义一个类,这个类叫做AntiCrack.。名字好像有点大。。。代码如下:
public class AntiCrack
{
   private AntiCrack()
   {
   }
   public static Throwable Fake(Throwable throwable, Throwable throwable1)
   {
       try
       {
           throwable.getClass().getMethod("initCause", new Class[] {
               java.lang.Throwable.class
           }).invoke(throwable, new Object[] {
               throwable1
           });
       }
       catch(Exception exception) { }
       return throwable;
   }
}
2,同样的,我们在catch里面调用该函数。例如如下。
           try
           {
               //your code here 
           }
           catch(IOException ioexception)
           {
               IllegalArgumentException illegalargumentexception = new IllegalArgumentException(ioexception.toString());
               AntiCrack.fake(illegalargumentexception, ioexception);
               throw illegalargumentexception;
           }
或者也可以这样
public class AntiException extends Exception
{
   public AntiException()
   {
   }
   public AntiException(String s)
   {
       super(s);
   }
   public AntiException(String s, Throwable throwable)
   {
       super(s);
       AntiCrack.fake(this, throwable);
   }
}
然后在你的程序里面 
try
{
}
catch(IoException e)
{

     throw new AntiException(ioexception.toString(), ioexception);

}

当采用以上方式后,任何类只要调用了该函数,生成的class反编译后出错,得不到结果。
Decafe、FrontEnd和YingJAD,反编译时都有exception,然后无法进行下去。大家可以多测试变得反编译工具。建议推荐用第二个方法。
呵呵,有什么问题可以给我mail 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android代码可以通过以下几种方式来防止反编译: 1. 混淆代码:在构建APK时启用代码混淆。混淆工具可以重命名方法和变量名,删除无用的代码,并对代码进行优化,使得反编译后的代码难以理解。可以在项目的build.gradle文件中配置混淆规则,如启用ProGuard混淆。 2. 加密敏感数据:对于敏感数据,可以使用加密算法进行加密处理,使得反编译后的代码无法直接获取到明文数据。 3. 使用动态加载:将一部分代码或资源以加密形式存储在服务器端,通过动态加载的方式在运行时进行解密和加载。这样可以减少静态分析的可能性。 4. 使用JNI(Java Native Interface):将关键代码使用JNI封装,以本地代码的形式实现,这样可以使得反编译后的代码无法直接获取到关键逻辑。 5. 使用数字签名:为APK文件添加数字签名,确保应用程序的完整性和真实性。如果APK文件被篡改,数字签名将无效,从而防止被恶意修改和破解。 总结起来,通过代码混淆、数据加密、动态加载、使用JNI和数字签名等方式可以有效地提高Android代码的安全性,减少反编译的可能性。但需要注意,这些方法并不能完全防止反编译,只能增加攻击者的难度。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Android反编译工具与实践](https://blog.csdn.net/lfdfhl/article/details/129941419)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [android 防止反编译 安全加固技术](https://blog.csdn.net/skyjie6/article/details/118388579)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值