Android apk反编译心得
工程文件反编译后,首先查看资源文件与配置文件格式是否对的,将src下的R文件放入gen下,修正src下源文件的编码错误.
R.styleable:R下文件的编码错误通常是由资源文件引起的,修改资源文件
<declare-styleablename="TileView">
<attrname="tileSize"format="integer"/>
</declare-styleable>
通常反编译后类型为Object的,修改其编译类型,如int的则修改为int类型.
null值错误,可以看其类型改为0或""
去掉:importdalvik.annotation.Signature;
去掉:@Signature({"Ljava/util/ArrayList","<","Lcom/example/android/snake/SnakeView$Coordinate;",">;"})
这是反编译时dalvik虚拟机自动生成的.
javaclass利用jad反编译之后,偶尔回碰到一些不正常的代码,例如:label0:_L1MISSING_BLOCK_LABEL_30、JVMINSTRret7、JVMINSTRtableswitch13:default269、JVMINSTRmonitorexit、JVMINSTRmonitorenter,这些一般是由特殊的for循环、trycatchfinally语句块、synchronized语句反编译后产生的。下面,就简单介绍一下,一些反编译后的特殊代码的还原规则。
异常
下面的代码前提是类中有如下属性,
显示代码打印1Calendarcal=Calendar.getInstance();
1、Exceptioin的还原
反编译后的代码如下:
显示代码打印1publicbooleanf1(){returncal.getTime().after(newDate());
2Exceptione;
3e;
4e.printStackTrace();
5returnfalse;
6}
还原后的Java代码
显示代码打印1publicbooleanf1(){try{returncal.getTime().after(newDate());
2}catch(Exceptione){e.printStackTrace();
3returnfalse;
4}}
2、finally代码的还原反编译后的Java代码如下:
显示代码打印01publicbooleanf2(){booleanflag=cal.getTime().after(newDate());
02System.out.println("finally");
03returnflag;
04Exceptione;
05e;
06e.printStackTrace();
07System.out.println("finally");
08returnfalse;
09Exceptionexception;
10exception;
11System.out.println("finally");
12throwexception;
13}
还原后的代码如下:
显示代码打印1publicbooleanf2(){try{returncal.getTime().after(newDate());
2}catch(Exceptione){e.printStackTrace();
3returnfalse;
4}finally{System.out.println("finally");
5}}
3、MISSING_BLOCK_LABEL_的还原反编译后的代码
显示代码打印01publicObjectf22(){Datedate=cal.getTime();
02System.out.println("finally");
03returndate;
04Exceptione;
05e;
06e.printStackTrace();
07System.out.println("finally");
08breakMISSING_BLOCK_LABEL_45;
09Exceptionexception;
10exception;
11System.out.println("finally");
12throwexception;
13returnnull;
14}
还原后的Java代码
显示代码打印1publicObjectf22(){try{returncal.getTime();
2}catch(Exceptione){e.printStackTrace();
3}finally{System.out.println("finally");
4}returnnull;
5}
4、异常中:label的还原反编译后的代码
显示代码打印01publicStringf4()throwsException{label0:{try{Integeri=newInteger(1);
02if(i.intValue()>
030){System.out.println(i);
04breaklabel0;
05}System.err.println(i);
06}catch(Exceptiondae){System.err.println(dae);
07thrownewRuntimeException(dae);
08}returnnull;
09}return"Hello";
10}
注意,这个代码有点诡异,实际代码如下:
显示代码打印1publicStringf4()throwsException{try{Integeri=newInteger(1);
2if(i.intValue()>
30){System.out.println(i);
4}else{System.err.println(i);
5returnnull;
6}return"Hello";
7}catch(Exceptiondae){System.err.println(dae);
8thrownewRuntimeException(dae);
9}}
5、典型数据库操作代码还原反编译后代码
显示代码打印01publicHashMapf5(){Connectionconn=null;
02HashMaphashmap;
03HashMapmap=newHashMap();
04Class.forName("");
05conn=DriverManager.getConnection("jdbc:odbc:");
06PreparedStatementpstmt=conn.prepareStatement("select*fromtable");
07pstmt.setString(1,"param");
08StringcolumnVallue;
09for(ResultSetrs=pstmt.executeQuery();
10rs.next();
11map.put(columnVallue,""))columnVallue=rs.getString("column");
12hashmap=map;
13if(conn!=null)try{conn.close();
14}catch(SQLExceptionsqlce){sqlce.printStackTrace();
15}returnhashmap;
16ClassNotFoundExceptioncnfe;
17cnfe;
18cnfe.printStackTrace();
19if(conn!=null)try{conn.close();
20}catch(SQLExceptionsqlce){sqlce.printStackTrace();
21}breakMISSING_BLOCK_LABEL_188;
22SQLExceptionsqle;
23sqle;
24sqle.printStackTrace();
25if(conn!=null)try{conn.close();
26}catch(SQLExceptionsqlce){sqlce.printStackTrace();
27}breakMISSING_BLOCK_LABEL_188;
28Exceptionexception;
29exception;
30if(conn!=null)try{conn.close();
31}catch(SQLExceptionsqlce){sqlce.printStackTrace();
32}throwexception;
33returnnull;
34}
实际代码如下:
显示代码打印01publicHashMapf5(){Connectionconn=null;
02try{HashMapmap=newHashMap();
03Class.forName("");
04conn=DriverManager.getConnection("jdbc:odbc:");
05PreparedStatementpstmt=conn.prepareStatement("select*fromtable");
06pstmt.setString(1,"param");
07ResultSetrs=pstmt.executeQuery();
08while(rs.next()){StringcolumnVallue=rs.getString("column");
09map.put(columnVallue,"");
10}returnmap;
11}catch(ClassNotFoundExceptioncnfe){cnfe.printStackTrace();
12}catch(SQLExceptionsqle){sqle.printStackTrace();
13}finally{if(conn!=null){try{conn.close();
14}catch(SQLExceptionsqlce){sqlce.printStackTrace();
15}}}returnnull;
16}
6、两层异常嵌套代码还原反编译后的代码
显示代码打印01publicintf6(){inti=cal.getTime().compareTo(newDate());
02System.out.println("finally");
03returni;
04Exceptione1;
05e1;
06e1.printStackTrace();
07System.out.println("finally");
08return-1;
09Exceptione2;
10e2;
11e2.printStackTrace();
12System.out.println("finally");
13return-2;
14Exceptionexception;
15exception;
16System.out.println("finally");
17throwexception;
18}
实际代码
显示代码打印1publicintf6(){try{try{returncal.getTime().compareTo(newDate());
2}catch(Exceptione1){e1.printStackTrace();
3return-1;
4}}catch(Exceptione2){e2.printStackTrace();
5return-2;
6}finally{System.out.println("finally");
7}}
7、非常诡异的代码反编译后的代码
显示代码打印01publicintf7(){inti=cal.getTime().compareTo(newDate());
02System.out.println("finally");
03returni;
04Exceptione1;
05e1;
06e1.printStackTrace();
07_L2:System.out.println("finally");
08return-1;
09Exceptione2;
10e2;
11e2.printStackTrace();
12if(true)goto_L2;
13elsegoto_L1_L1:Exceptionexception;
14exception;
15System.out.println("finally");
16throwexception;
17}
原始代码
显示代码打印1publicintf7(){try{try{returncal.getTime().compareTo(newDate());
2}catch(Exceptione1){e1.printStackTrace();
3return-1;
4}}catch(Exceptione2){e2.printStackTrace();
5return-1;
6}finally{System.out.println("finally");
7}}