public string EncodedValueToString(EncodedValue value, Class currentClass) { switch (value.EncodedType) { case EncodedValueType.VALUE_BYTE: return(((EncodedNumber)value).AsByte().ToString()); case EncodedValueType.VALUE_NULL: return("null"); case EncodedValueType.VALUE_BOOLEAN: return(((EncodedNumber)value).AsBoolean().ToString().ToLower()); case EncodedValueType.VALUE_SHORT: return(((EncodedNumber)value).AsShort().ToString()); case EncodedValueType.VALUE_CHAR: return(((EncodedNumber)value).AsChar().ToString()); case EncodedValueType.VALUE_INT: return(((EncodedNumber)value).AsInt().ToString()); case EncodedValueType.VALUE_LONG: return(((EncodedNumber)value).AsLong().ToString()); case EncodedValueType.VALUE_FLOAT: return(((EncodedNumber)value).AsFloat().ToString()); case EncodedValueType.VALUE_DOUBLE: return(((EncodedNumber)value).AsDouble().ToString()); case EncodedValueType.VALUE_STRING: return(String.Format("\"{0}\"", _dex.GetString(((EncodedNumber)value).AsId()).Replace("\n", "\\n"))); case EncodedValueType.VALUE_TYPE: return(_dex.GetTypeName(((EncodedNumber)value).AsId())); case EncodedValueType.VALUE_FIELD: case EncodedValueType.VALUE_ENUM: return(_getFieldName(((EncodedNumber)value).AsId(), currentClass, true)); case EncodedValueType.VALUE_METHOD: var method = _dex.GetMethod(((EncodedNumber)value).AsId()); return(string.Format("{0}.{1}", _dex.GetTypeName(method.ClassIndex), method.Name)); case EncodedValueType.VALUE_ARRAY: var encodedArray = (EncodedArray)value; var array = new List <string> ((int)encodedArray.Count); foreach (var arrayValue in encodedArray.GetValues()) { array.Add(EncodedValueToString(arrayValue, currentClass)); } return(string.Format("[{0}]", string.Join(",", array))); case EncodedValueType.VALUE_ANNOTATION: var stringAnnotation = new StringWriter(); _annToString(stringAnnotation, (EncodedAnnotation)value, currentClass, new Indentation()); return(stringAnnotation.ToString()); } return("Unknown"); }
public override string ToString() { return(Dex.GetString(ShortyIndex)); }
string OpCodeToString(OpCode opcode, Class currentClass, Method method, JumpTable jumpTable) { switch (opcode.Instruction) { case Instructions.Const: case Instructions.Const4: case Instructions.Const16: case Instructions.ConstHigh: case Instructions.ConstWide16: case Instructions.ConstWide32: case Instructions.ConstWide: case Instructions.ConstWideHigh: dynamic constOpCode = opcode; return(string.Format("{1} = #{2}", constOpCode.Name, GetRegisterName(constOpCode.Destination, method), constOpCode.Value)); case Instructions.Move: case Instructions.MoveFrom16: case Instructions.Move16: case Instructions.MoveWide: case Instructions.MoveWideFrom16: case Instructions.MoveWide16: case Instructions.MoveObject: case Instructions.MoveObjectFrom16: case Instructions.MoveObject16: dynamic moveOpCode = opcode; return(string.Format("{1} = {2}", moveOpCode.Name, GetRegisterName(moveOpCode.To, method), GetRegisterName(moveOpCode.From, method))); case Instructions.MoveResult: case Instructions.MoveResultWide: case Instructions.MoveResultObject: case Instructions.MoveException: dynamic moveResultOpCode = opcode; return(string.Format("{0} {1}", moveResultOpCode.Name, GetRegisterName(moveResultOpCode.Destination, method))); case Instructions.ConstString: case Instructions.ConstStringJumbo: dynamic constStringOpCode = opcode; return(string.Format("{1} = \"{2}\"", constStringOpCode.Name, GetRegisterName(constStringOpCode.Destination, method), _dex.GetString(constStringOpCode.StringIndex).Replace("\n", "\\n"))); case Instructions.ConstClass: return(string.Format("{0} = {1}", GetRegisterName(((ConstClassOpCode)opcode).Destination, method), _dex.GetTypeName(((ConstClassOpCode)opcode).TypeIndex))); case Instructions.CheckCast: var typeCheckCast = _dex.GetTypeName(((CheckCastOpCode)opcode).TypeIndex); return(string.Format("({1}){0}", GetRegisterName(((CheckCastOpCode)opcode).Destination, method), typeCheckCast)); case Instructions.InstanceOf: var typeInstanceOf = _dex.GetTypeName(((InstanceOfOpCode)opcode).TypeIndex); return(string.Format("instance-of v{0}, v{1}, {2}", ((InstanceOfOpCode)opcode).Destination, ((InstanceOfOpCode)opcode).Reference, typeInstanceOf)); case Instructions.NewInstance: var typeNewInstance = _dex.GetTypeName(((NewInstanceOpCode)opcode).TypeIndex); return(string.Format("{0} = new {1}", GetRegisterName(((NewInstanceOpCode)opcode).Destination, method), typeNewInstance)); case Instructions.NewArrayOf: var newArrayOpCode = (NewArrayOfOpCode)opcode; var typeNewArrayOfOpCode = _dex.GetTypeName(newArrayOpCode.TypeIndex); return(string.Format("{0} = new {1}", GetRegisterName(newArrayOpCode.Destination, method), typeNewArrayOfOpCode.Replace("[]", string.Format("[{0}]", GetRegisterName(newArrayOpCode.Size, method))))); case Instructions.FilledNewArrayOf: var typeFilledNewArrayOf = _dex.GetTypeName(((FilledNewArrayOfOpCode)opcode).TypeIndex); return(string.Format("filled-new-array {0}, {1}", string.Join(",", ((FilledNewArrayOfOpCode)opcode).Values), typeFilledNewArrayOf)); case Instructions.FilledNewArrayRange: var typeFilledNewArrayRange = _dex.GetTypeName(((FilledNewArrayRangeOpCode)opcode).TypeIndex); return(string.Format("filled-new-array/range {0}, {1}", string.Join(",", ((FilledNewArrayRangeOpCode)opcode).Values), typeFilledNewArrayRange)); case Instructions.ArrayLength: var arrayLengthOpcode = (ArrayLengthOpCode)opcode; return(string.Format("{0} = {1}.length", GetRegisterName(arrayLengthOpcode.Destination, method), GetRegisterName(arrayLengthOpcode.ArrayReference, method))); case Instructions.InvokeVirtual: case Instructions.InvokeSuper: case Instructions.InvokeDirect: case Instructions.InvokeStatic: case Instructions.InvokeInterface: var invokeOpcode = (InvokeOpCode)opcode; var invokeMethod = _dex.GetMethod(invokeOpcode.MethodIndex); string invokeObject; if (invokeMethod.IsStatic() || invokeOpcode.Instruction == Instructions.InvokeStatic) { invokeObject = _dex.GetTypeName(invokeMethod.ClassIndex); } else { invokeObject = GetRegisterName(invokeOpcode.ArgumentRegisters [0], method); } string[] registerNames = {}; if (invokeOpcode.ArgumentRegisters.Length > 0) { var instanceAdjustment = invokeMethod.IsStatic()?0:1; registerNames = new string[invokeOpcode.ArgumentRegisters.Length - instanceAdjustment]; for (int i = 0; i < registerNames.Length; i++) { registerNames [i] = GetRegisterName(invokeOpcode.ArgumentRegisters[i + instanceAdjustment], method); } } return(string.Format("{2}.{3}({1})", ((InvokeOpCode)opcode).Name, string.Join(",", registerNames), invokeObject, invokeMethod.Name)); case Instructions.Sput: case Instructions.SputWide: case Instructions.SputObject: case Instructions.SputBoolean: case Instructions.SputChar: case Instructions.SputShort: case Instructions.SputByte: var sputOpcode = (StaticOpOpCode)opcode; return(string.Format("{2} = {1}", sputOpcode.Name, GetRegisterName(sputOpcode.Destination, method), GetFieldName(sputOpcode.Index, currentClass, true))); case Instructions.Sget: case Instructions.SgetWide: case Instructions.SgetObject: case Instructions.SgetBoolean: case Instructions.SgetChar: case Instructions.SgetShort: case Instructions.SgetByte: var sgetOpcode = (StaticOpOpCode)opcode; return(string.Format("{1} = {2}", sgetOpcode.Name, GetRegisterName(sgetOpcode.Destination, method), GetFieldName(sgetOpcode.Index, currentClass, true))); case Instructions.Iput: case Instructions.IputWide: case Instructions.IputObject: case Instructions.IputBoolean: case Instructions.IputChar: case Instructions.IputShort: case Instructions.IputByte: var iputOpCode = (IinstanceOpOpCode)opcode; return(string.Format("{2} = {1}", iputOpCode.Name, GetRegisterName(iputOpCode.Destination, method), GetFieldName(iputOpCode.Index, currentClass))); case Instructions.Iget: case Instructions.IgetWide: case Instructions.IgetObject: case Instructions.IgetBoolean: case Instructions.IgetChar: case Instructions.IgetShort: case Instructions.IgetByte: var igetOpCode = (IinstanceOpOpCode)opcode; return(string.Format("{1} = {2}", igetOpCode.Name, GetRegisterName(igetOpCode.Destination, method), GetFieldName(igetOpCode.Index, currentClass))); case Instructions.Aput: case Instructions.AputWide: case Instructions.AputObject: case Instructions.AputBoolean: case Instructions.AputChar: case Instructions.AputShort: case Instructions.AputByte: var aputOpCode = (ArrayOpOpCode)opcode; return(string.Format("{2}[{3}] = {1}", aputOpCode.Name, GetRegisterName(aputOpCode.Destination, method), GetRegisterName(aputOpCode.Array, method), GetRegisterName(aputOpCode.Index, method))); case Instructions.Aget: case Instructions.AgetWide: case Instructions.AgetObject: case Instructions.AgetBoolean: case Instructions.AgetChar: case Instructions.AgetShort: case Instructions.AgetByte: var agetOpCode = (ArrayOpOpCode)opcode; return(string.Format("{1} = {2}[{3}]", agetOpCode.Name, GetRegisterName(agetOpCode.Destination, method), GetRegisterName(agetOpCode.Array, method), GetRegisterName(agetOpCode.Index, method))); case Instructions.AddInt: case Instructions.AddLong: case Instructions.AddFloat: case Instructions.AddDouble: return(FormatBinaryOperation((BinaryOpOpCode)opcode, "+", method)); case Instructions.SubInt: case Instructions.SubLong: case Instructions.SubFloat: case Instructions.SubDouble: return(FormatBinaryOperation((BinaryOpOpCode)opcode, "-", method)); case Instructions.MulInt: case Instructions.MulLong: case Instructions.MulFloat: case Instructions.MulDouble: return(FormatBinaryOperation((BinaryOpOpCode)opcode, "*", method)); case Instructions.DivInt: case Instructions.DivLong: case Instructions.DivFloat: case Instructions.DivDouble: return(FormatBinaryOperation((BinaryOpOpCode)opcode, "/", method)); case Instructions.RemInt: case Instructions.RemLong: case Instructions.RemFloat: case Instructions.RemDouble: return(FormatBinaryOperation((BinaryOpOpCode)opcode, "&", method)); case Instructions.AndInt: case Instructions.AndLong: return(FormatBinaryOperation((BinaryOpOpCode)opcode, "&", method)); case Instructions.OrInt: case Instructions.OrLong: return(FormatBinaryOperation((BinaryOpOpCode)opcode, "|", method)); case Instructions.XorInt: case Instructions.XorLong: return(FormatBinaryOperation((BinaryOpOpCode)opcode, "^", method)); case Instructions.ShlInt: case Instructions.ShlLong: return(FormatBinaryOperation((BinaryOpOpCode)opcode, "<<", method)); case Instructions.ShrInt: case Instructions.UshrInt: case Instructions.ShrLong: case Instructions.UshrLong: return(FormatBinaryOperation((BinaryOpOpCode)opcode, ">>", method)); case Instructions.IfEq: return(FormatIfOperation((IfOpCode)opcode, "=", method, jumpTable)); case Instructions.IfNe: return(FormatIfOperation((IfOpCode)opcode, "!=", method, jumpTable)); case Instructions.IfLt: return(FormatIfOperation((IfOpCode)opcode, "<", method, jumpTable)); case Instructions.IfGe: return(FormatIfOperation((IfOpCode)opcode, ">=", method, jumpTable)); case Instructions.IfGt: return(FormatIfOperation((IfOpCode)opcode, ">", method, jumpTable)); case Instructions.IfLe: return(FormatIfOperation((IfOpCode)opcode, "<=", method, jumpTable)); case Instructions.IfEqz: return(FormatIfzOperation((IfzOpCode)opcode, "=", method, jumpTable)); case Instructions.IfNez: return(FormatIfzOperation((IfzOpCode)opcode, "!=", method, jumpTable)); case Instructions.IfLtz: return(FormatIfzOperation((IfzOpCode)opcode, "<", method, jumpTable)); case Instructions.IfGez: return(FormatIfzOperation((IfzOpCode)opcode, ">=", method, jumpTable)); case Instructions.IfGtz: return(FormatIfzOperation((IfzOpCode)opcode, ">", method, jumpTable)); case Instructions.IfLez: return(FormatIfzOperation((IfzOpCode)opcode, "<=", method, jumpTable)); case Instructions.RsubInt: case Instructions.RsubIntLit8: dynamic rsubIntOpCode = opcode; return(string.Format("{0} = #{2} - {1}", GetRegisterName(rsubIntOpCode.Destination, method), GetRegisterName(rsubIntOpCode.Source, method), rsubIntOpCode.Constant)); case Instructions.AddIntLit16: case Instructions.AddIntLit8: return(FormatBinaryLiteralOperation(opcode, "+", method)); case Instructions.MulIntLit16: case Instructions.MulIntLit8: return(FormatBinaryLiteralOperation(opcode, "*", method)); case Instructions.DivIntLit16: case Instructions.DivIntLit8: return(FormatBinaryLiteralOperation(opcode, "/", method)); case Instructions.RemIntLit16: case Instructions.RemIntLit8: return(FormatBinaryLiteralOperation(opcode, "%", method)); case Instructions.AndIntLit16: case Instructions.AndIntLit8: return(FormatBinaryLiteralOperation(opcode, "&", method)); case Instructions.OrIntLit16: case Instructions.OrIntLit8: return(FormatBinaryLiteralOperation(opcode, "|", method)); case Instructions.XorIntLit16: case Instructions.XorIntLit8: return(FormatBinaryLiteralOperation(opcode, "^", method)); case Instructions.ShlIntLit8: return(FormatBinaryLiteralOperation(opcode, "<<", method)); case Instructions.ShrIntLit8: return(FormatBinaryLiteralOperation(opcode, ">>", method)); case Instructions.UshrIntLit8: return(FormatBinaryLiteralOperation(opcode, ">>", method)); case Instructions.AddInt2Addr: case Instructions.AddLong2Addr: case Instructions.AddFloat2Addr: case Instructions.AddDouble2Addr: return(FormatBinary2AddrOperation((BinaryOp2OpCode)opcode, "+", method)); case Instructions.SubInt2Addr: case Instructions.SubLong2Addr: case Instructions.SubFloat2Addr: case Instructions.SubDouble2Addr: return(FormatBinary2AddrOperation((BinaryOp2OpCode)opcode, "-", method)); case Instructions.MulInt2Addr: case Instructions.MulLong2Addr: case Instructions.MulFloat2Addr: case Instructions.MulDouble2Addr: return(FormatBinary2AddrOperation((BinaryOp2OpCode)opcode, "*", method)); case Instructions.DivInt2Addr: case Instructions.DivLong2Addr: case Instructions.DivFloat2Addr: case Instructions.DivDouble2Addr: return(FormatBinary2AddrOperation((BinaryOp2OpCode)opcode, "/", method)); case Instructions.RemInt2Addr: case Instructions.RemLong2Addr: case Instructions.RemFloat2Addr: case Instructions.RemDouble2Addr: return(FormatBinary2AddrOperation((BinaryOp2OpCode)opcode, "&", method)); case Instructions.AndInt2Addr: case Instructions.AndLong2Addr: return(FormatBinary2AddrOperation((BinaryOp2OpCode)opcode, "&", method)); case Instructions.OrInt2Addr: case Instructions.OrLong2Addr: return(FormatBinary2AddrOperation((BinaryOp2OpCode)opcode, "|", method)); case Instructions.XorInt2Addr: case Instructions.XorLong2Addr: return(FormatBinary2AddrOperation((BinaryOp2OpCode)opcode, "^", method)); case Instructions.ShlInt2Addr: case Instructions.ShlLong2Addr: return(FormatBinary2AddrOperation((BinaryOp2OpCode)opcode, "<<", method)); case Instructions.ShrInt2Addr: case Instructions.UshrInt2Addr: case Instructions.ShrLong2Addr: case Instructions.UshrLong2Addr: return(FormatBinary2AddrOperation((BinaryOp2OpCode)opcode, ">>", method)); case Instructions.Goto: case Instructions.Goto16: case Instructions.Goto32: dynamic gotoOpCode = opcode; return(string.Format("{0} {1}", gotoOpCode.Name, jumpTable.GetReferrerLabel(gotoOpCode.OpCodeOffset))); case Instructions.PackedSwitch: var packedSwitchOpCode = (PackedSwitchOpCode)opcode; return(string.Format("{0} {1} - First:{2} - [{3}]", opcode.Name, GetRegisterName(packedSwitchOpCode.Destination, method), packedSwitchOpCode.FirstKey, string.Join(",", jumpTable.GetReferrerLabels(packedSwitchOpCode.OpCodeOffset)))); case Instructions.SparseSwitch: var sparseSwitchOpCode = (SparseSwitchOpCode)opcode; return(string.Format("{0} {1} - Keys:[{2}] Targets:[{3}]", opcode.Name, GetRegisterName(sparseSwitchOpCode.Destination, method), string.Join(",", sparseSwitchOpCode.Keys), string.Join(",", jumpTable.GetReferrerLabels(sparseSwitchOpCode.OpCodeOffset)))); default: return(opcode.ToString()); } }
public string GetName(Dex dex) { return(dex.GetString(NameIdx)); }