代码解析Dex文件
Android源码:http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/app/ActivityThread.java
Android文档:https://source.android.com/docs/core/runtime/instruction-formats?hl=zh-cn
搜索DexHeader
try、catch、finally三个语句的执行顺序
如果 try 块中没有异常抛出,程序会直接跳过 catch 块,执行 finally 块。 如果 try 块中有异常抛出,并且有匹配的 catch 块处理该异常,先执行匹配的 catch 块,然后执行 finally 块。 如果 try 块中有异常抛出,但没有匹配的 catch 块处理该异常,先执行 finally 块,然后将异常抛出至上层调用栈。
|
System.arraycopy 方法
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
|
System.out.printf方法
System.out.printf("%-12s: %s\r\n", "magic", Utils.bytes2HexString(dexType.dexHeader.magic));
|
printf 方法与 System.out.println 类似,但是它允许使用格式化字符串来定义输出的格式。 "%-12s: %s\r\n" % 开始表示格式化标志的起始。 - 表示左对齐(在字符串字段内,右对齐是默认的)。 12 表示最小宽度,确保输出的字符串至少占据 12 个字符的宽度。 s 表示后续参数是一个字符串。 : 是一个字面值,即将在输出中显示 : 字符。 %s 是格式化字符串的占位符,用来接收第一个参数 "magic"。 \r\n 表示换行符,确保每次输出后换行。 "magic":作为格式化字符串的第一个参数,将填充到 %s 的位置。 Utils.bytes2HexString(dexType.dexHeader.magic):作为格式化字符串的第二个参数,调用 Utils.bytes2HexString 方法将 dexType.dexHeader.magic 转换为十六进制字符串表示。
|
Utils.java(但是在进行位与操作时,会忽略符号位)
public final class Utils { public static byte[] readFile(String fileName) { File file = new File(fileName); FileInputStream fis = null; ByteArrayOutputStream bos = null; try { fis = new FileInputStream(file); bot = new ByteArrayOutputStream(); byte[] temp = new byte[1024]; int size = 0; while((size = fis.read(temp))!=-1) { bot.write(temp); } return bos.toByteArray(); }catch(Exception e) { System.out.println("read file error:"+e.toString); }finally { if(fis != null) { try { fis.close(); }catch(Exception e) { System.out.println("close file error:"+e.toString); } try { bot.close(); }catch(Exception e) { System.out.println("close file error:"+e.toString); } } } } public static int byte2Int_4(byte[] res, int pOff) { int targets = (res[pOff+0] & 0xff) |(res[pOff+1] & 0xff00) |((res[pOff+2] <<24)>>>8) |(res[pOff+3]<<24); return targets; } static class RETULEB128 { int retValue; int readSize; } public static RETULEEB128 readULEB128(byte[] data, int pOff) { try { RETULEB128 ret = new RETULEB128(); int result = 0; int shift = 0; int byteRead = 0; int i = -1; while(true) { i++; if(pOff+i>=data.length) { throw new IOException("pOff+i >=data.length"); } int currentByte = data[pOff + i]; bytesRead++; result |=(currentByte & 0x7F)<<shift; shift +=7; if((currentByte & 0x80) == 0) { break; } if(byteRead > 5) { throw new IOException("Invalid ULEB128 encoded data: more than 5 bytes"); } } ret.retValue = result; ret.readSize = bytesRead; return ret; }catch(IOException ioe) { ioe.printStackTrace(); } return null; } }
|