/*
* 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.injection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.jf.dexlib.CodeItem;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.MethodIdItem;
import org.jf.dexlib.ProtoIdItem;
import org.jf.dexlib.StringIdItem;
import org.jf.dexlib.TypeIdItem;
import org.jf.dexlib.TypeListItem;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.Format.Instruction10x;
public class ItemCreator {
public DexFile m_dex;
public MethodIdItem[] methodItems = new MethodIdItem[DebugMethod.values().length];
public HashMap<String, StringIdItem> stringItems = new HashMap<String, StringIdItem>();
public ItemCreator(DexFile dexfile) {
m_dex = dexfile;
}
public MethodIdItem prepareMethodIdItem(DebugMethod method) {
if (methodItems[method.ordinal()] == null) {
methodItems[method.ordinal()] = addMethodIdItem(method.className, method.returnName, method.params, method.methodName);
}
return methodItems[method.ordinal()];
}
public StringIdItem prepareStringIdItem(String string) {
StringIdItem stringIdItem = stringItems.get(string);
if (stringIdItem == null) {
stringIdItem = addStringIdItem(string);
stringItems.put(string, stringIdItem);
}
return addStringIdItem(string);
}
private StringIdItem addStringIdItem(String string) {
StringIdItem item = StringIdItem.lookupStringIdItem(m_dex, string);
if (item == null) {
item = StringIdItem.internStringIdItem(m_dex, string);
}
return item;
}
public TypeIdItem addTypeIdItem(String string) {
TypeIdItem item = TypeIdItem.lookupTypeIdItem(m_dex, string);
if (item == null) {
StringIdItem typeIdStringIdItem = addStringIdItem(string);
item = TypeIdItem.internTypeIdItem(m_dex, typeIdStringIdItem);
}
return item;
}
private TypeListItem addTypeListItem(String[] paramType) {
if (paramType.length == 0) {
return null;
}
List<TypeIdItem> paramTypeList = new ArrayList<TypeIdItem>();
for (String param : paramType) {
paramTypeList.add(addTypeIdItem(param));
}
TypeListItem item = TypeListItem.lookupTypeListItem(m_dex, paramTypeList);
if (item == null) {
item = TypeListItem.internTypeListItem(m_dex, paramTypeList);
}
return item;
}
public MethodIdItem addMethodIdItem(String classType, String returnType, String[] paramType, String methodName) {
TypeIdItem classTypeIdItem = addTypeIdItem(classType);
TypeIdItem returnTypeIdItem = addTypeIdItem(returnType);
TypeListItem paramTypeListItem = addTypeListItem(paramType);
ProtoIdItem protoItem = ProtoIdItem.lookupProtoIdItem(m_dex, returnTypeIdItem, paramTypeListItem);
if (protoItem == null) {
protoItem = ProtoIdItem.internProtoIdItem(m_dex, returnTypeIdItem, paramTypeListItem);
}
StringIdItem nameStringIdItem = addStringIdItem(methodName);
return MethodIdItem.internMethodIdItem(m_dex, classTypeIdItem, protoItem, nameStringIdItem);
}
public CodeItem addEmptyVirtualCodeItem() {
ArrayList<Instruction> instructions = new ArrayList<Instruction>();
instructions.add(new Instruction10x(Opcode.RETURN_VOID)); //NOT SET INJECT FLAG HERE
CodeItem item = CodeItem.internCodeItem(m_dex,
1, //registerCount
1, //inWords
0, //outWords
null, //debugInfo
instructions,
null, //tries
null); //encodedCatchHandlers
return item;
}
}