/* * Copyright (C) 2012 Sony Mobile Communications AB * * This file is part of ApkAnalyser. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package andreflect; import java.io.IOException; import java.util.ArrayList; import java.util.List; import mereflect.MEClass; import mereflect.MEMethod; import mereflect.Type; import org.jf.dexlib.ClassDataItem; import org.jf.dexlib.Code.Instruction; import andreflect.definition.DexMethodDefinition; public class DexMethod extends MEMethod { ClassDataItem.EncodedMethod m_method; DexMethodDefinition m_def = null; public List<MEMethod.Invokation> m_dexInvokations = null; public DexMethod(DexClass clazzDex, ClassDataItem.EncodedMethod encodedMethod) { super(clazzDex); m_method = encodedMethod; } public DexMethodDefinition getDefinition() { if (m_def == null) { m_def = new DexMethodDefinition(m_method); } return m_def; } @Override public String getName() { return m_method.method.getMethodName().getStringValue(); } @Override public String getDescriptor() { //System.out.println("desc= "+ m_method.method.getMethodName().getStringValue() + " : "+ m_method.method.getPrototype().getPrototypeString()); return m_method.method.getPrototype().getPrototypeString(); } @Override public byte[] getByteCodes() { return null; } @Override public List<MEMethod.Invokation> getInvokations() { return m_dexInvokations; } @Override public MEClass[] getExceptions() throws IOException { return m_exceptions; } public void setExceptions(MEClass[] excptions) { m_exceptions = excptions; } public ClassDataItem.EncodedMethod getEncodedMethod() { return m_method; } @Override public String getArgumentsStringUml() { try { Type[] args = getArguments(); ArrayList<String> params = getDefinition().getParameters(); boolean hasParam = params.size() != 0 && params.size() == args.length; StringBuffer sb = new StringBuffer(); for (int i = 0; i < args.length; i++) { sb.append((hasParam && params.get(i) != null) ? params.get(i) : "?"); sb.append(" : "); sb.append(Util.shortenClassName(args[i].toString())); if (i < args.length - 1) { sb.append(", "); } } return sb.toString(); } catch (Exception e) { return "?"; } } @Override public String getArgumentsString(Type[] args) { ArrayList<String> params = getDefinition().getParameters(); boolean hasParam = params.size() != 0 && params.size() == args.length; StringBuffer sb = new StringBuffer(); for (int i = 0; i < args.length; i++) { sb.append(args[i]); sb.append(" "); sb.append((hasParam && params.get(i) != null) ? params.get(i) : "?"); if (i < args.length - 1) { sb.append(", "); } } return sb.toString(); } public String getParameterName(int i, int length) { ArrayList<String> params = getDefinition().getParameters(); boolean hasParam = params.size() != 0 && params.size() == length; return (hasParam && params.get(i) != null) ? params.get(i) : "?"; } public Instruction getNextInstruction(Instruction ins) { Instruction[] instructions = m_method.codeItem.getInstructions(); Instruction result = null; for (int i = 0; i < instructions.length; i++) { if (ins == instructions[i]) { result = instructions[i + 1]; break; } } return result; } public Instruction getInstructionAtCodeAddress(int codeAddress) { Instruction result = null; Instruction[] instructions = m_method.codeItem.getInstructions(); int currentCodeAddress = 0; for (int i = 0; i < instructions.length; i++) { if (currentCodeAddress == codeAddress) { result = instructions[i]; break; } currentCodeAddress += instructions[i].getSize(currentCodeAddress); } return result; } public Instruction getPreviousInstructionAtCodeAddress(int codeAddress) { Instruction[] instructions = m_method.codeItem.getInstructions(); Instruction result = instructions[0]; int currentCodeAddress = 0; for (int i = 0; i < instructions.length; i++) { if (currentCodeAddress == codeAddress) { break; } else { result = instructions[i]; } currentCodeAddress += instructions[i].getSize(currentCodeAddress); } return result; } }