From 03fc77cca80ea84881b8881455e17b5e185c9bf1 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Fri, 11 Oct 2013 11:43:59 -0500 Subject: [PATCH] [smali] update to 2.0 final --- .../jf/baksmali/Adaptors/ClassDefinition.java | 4 +- .../baksmali/Adaptors/MethodDefinition.java | 13 +- .../src/main/java/org/jf/baksmali/main.java | 2 +- .../java/org/jf/baksmali/AnalysisTest.java | 2 +- brut.apktool.smali/build.gradle | 6 +- brut.apktool.smali/dexlib/build.gradle | 36 - .../jf/dexlib/AnnotationDirectoryItem.java | 610 --- .../java/org/jf/dexlib/AnnotationItem.java | 162 - .../java/org/jf/dexlib/AnnotationSetItem.java | 190 - .../org/jf/dexlib/AnnotationSetRefList.java | 170 - .../org/jf/dexlib/AnnotationVisibility.java | 55 - .../java/org/jf/dexlib/ClassDataItem.java | 844 ---- .../main/java/org/jf/dexlib/ClassDefItem.java | 374 -- .../Code/Analysis/AnalyzedInstruction.java | 343 -- .../jf/dexlib/Code/Analysis/ClassPath.java | 1342 ------ .../Analysis/CustomInlineMethodResolver.java | 115 - .../jf/dexlib/Code/Analysis/DeodexUtil.java | 293 -- .../dexlib/Code/Analysis/DexFileClassMap.java | 56 - .../jf/dexlib/Code/Analysis/DumpFields.java | 160 - .../jf/dexlib/Code/Analysis/DumpVtables.java | 159 - .../Code/Analysis/InlineMethodResolver.java | 187 - .../dexlib/Code/Analysis/MethodAnalyzer.java | 3755 ----------------- .../OdexedFieldInstructionMapper.java | 235 -- .../jf/dexlib/Code/Analysis/RegisterType.java | 322 -- .../Analysis/SyntheticAccessorResolver.java | 140 - .../Code/Analysis/ValidationException.java | 52 - .../Code/EncodedLiteralInstruction.java | 36 - .../dexlib/Code/FiveRegisterInstruction.java | 37 - .../Format/ArrayDataPseudoInstruction.java | 152 - .../org/jf/dexlib/Code/Format/Format.java | 83 - .../jf/dexlib/Code/Format/Instruction10t.java | 92 - .../jf/dexlib/Code/Format/Instruction10x.java | 64 - .../jf/dexlib/Code/Format/Instruction11n.java | 89 - .../jf/dexlib/Code/Format/Instruction11x.java | 76 - .../jf/dexlib/Code/Format/Instruction12x.java | 83 - .../dexlib/Code/Format/Instruction20bc.java | 100 - .../jf/dexlib/Code/Format/Instruction20t.java | 94 - .../jf/dexlib/Code/Format/Instruction21c.java | 111 - .../jf/dexlib/Code/Format/Instruction21h.java | 94 - .../jf/dexlib/Code/Format/Instruction21s.java | 85 - .../jf/dexlib/Code/Format/Instruction21t.java | 103 - .../jf/dexlib/Code/Format/Instruction22b.java | 93 - .../jf/dexlib/Code/Format/Instruction22c.java | 96 - .../dexlib/Code/Format/Instruction22cs.java | 97 - .../jf/dexlib/Code/Format/Instruction22s.java | 93 - .../jf/dexlib/Code/Format/Instruction22t.java | 112 - .../jf/dexlib/Code/Format/Instruction22x.java | 88 - .../jf/dexlib/Code/Format/Instruction23x.java | 93 - .../jf/dexlib/Code/Format/Instruction30t.java | 78 - .../jf/dexlib/Code/Format/Instruction31c.java | 79 - .../jf/dexlib/Code/Format/Instruction31i.java | 85 - .../jf/dexlib/Code/Format/Instruction31t.java | 90 - .../jf/dexlib/Code/Format/Instruction32x.java | 86 - .../jf/dexlib/Code/Format/Instruction35c.java | 170 - .../dexlib/Code/Format/Instruction35mi.java | 136 - .../dexlib/Code/Format/Instruction35ms.java | 136 - .../jf/dexlib/Code/Format/Instruction3rc.java | 138 - .../dexlib/Code/Format/Instruction3rmi.java | 107 - .../dexlib/Code/Format/Instruction3rms.java | 107 - .../jf/dexlib/Code/Format/Instruction51l.java | 85 - .../Format/InstructionWithJumboReference.java | 57 - .../Format/InstructionWithJumboVariant.java | 38 - .../PackedSwitchDataPseudoInstruction.java | 158 - .../SparseSwitchDataPseudoInstruction.java | 177 - .../Code/Format/UnknownInstruction.java | 47 - .../Format/UnresolvedOdexInstruction.java | 62 - .../java/org/jf/dexlib/Code/Instruction.java | 71 - .../jf/dexlib/Code/InstructionIterator.java | 98 - .../dexlib/Code/InstructionWithReference.java | 126 - .../org/jf/dexlib/Code/InvokeInstruction.java | 33 - .../jf/dexlib/Code/LiteralInstruction.java | 33 - .../dexlib/Code/MultiOffsetInstruction.java | 34 - .../org/jf/dexlib/Code/OdexedFieldAccess.java | 33 - .../jf/dexlib/Code/OdexedInvokeInline.java | 36 - .../jf/dexlib/Code/OdexedInvokeVirtual.java | 33 - .../org/jf/dexlib/Code/OffsetInstruction.java | 38 - .../main/java/org/jf/dexlib/Code/Opcode.java | 471 --- .../org/jf/dexlib/Code/ReferenceType.java | 80 - .../dexlib/Code/RegisterRangeInstruction.java | 33 - .../Code/SingleRegisterInstruction.java | 33 - .../dexlib/Code/ThreeRegisterInstruction.java | 33 - .../dexlib/Code/TwoRegisterInstruction.java | 35 - .../jf/dexlib/Code/VerificationErrorType.java | 99 - .../src/main/java/org/jf/dexlib/CodeItem.java | 1085 ----- .../main/java/org/jf/dexlib/Convertible.java | 39 - .../Debug/DebugInstructionIterator.java | 364 -- .../java/org/jf/dexlib/Debug/DebugOpcode.java | 64 - .../java/org/jf/dexlib/DebugInfoItem.java | 620 --- .../src/main/java/org/jf/dexlib/DexFile.java | 904 ---- .../java/org/jf/dexlib/EncodedArrayItem.java | 135 - .../AnnotationEncodedSubValue.java | 169 - .../EncodedValue/AnnotationEncodedValue.java | 72 - .../EncodedValue/ArrayEncodedSubValue.java | 141 - .../EncodedValue/ArrayEncodedValue.java | 67 - .../EncodedValue/BooleanEncodedValue.java | 109 - .../dexlib/EncodedValue/ByteEncodedValue.java | 86 - .../dexlib/EncodedValue/CharEncodedValue.java | 93 - .../EncodedValue/DoubleEncodedValue.java | 94 - .../jf/dexlib/EncodedValue/EncodedValue.java | 125 - .../dexlib/EncodedValue/EnumEncodedValue.java | 95 - .../EncodedValue/FieldEncodedValue.java | 95 - .../EncodedValue/FloatEncodedValue.java | 93 - .../dexlib/EncodedValue/IntEncodedValue.java | 91 - .../dexlib/EncodedValue/LongEncodedValue.java | 91 - .../EncodedValue/MethodEncodedValue.java | 95 - .../dexlib/EncodedValue/NullEncodedValue.java | 72 - .../EncodedValue/ShortEncodedValue.java | 91 - .../EncodedValue/StringEncodedValue.java | 96 - .../dexlib/EncodedValue/TypeEncodedValue.java | 95 - .../org/jf/dexlib/EncodedValue/ValueType.java | 86 - .../main/java/org/jf/dexlib/FieldIdItem.java | 263 -- .../main/java/org/jf/dexlib/HeaderItem.java | 301 -- .../java/org/jf/dexlib/IndexedSection.java | 81 - .../src/main/java/org/jf/dexlib/Item.java | 224 - .../main/java/org/jf/dexlib/ItemFactory.java | 71 - .../src/main/java/org/jf/dexlib/ItemType.java | 123 - .../src/main/java/org/jf/dexlib/MapItem.java | 138 - .../main/java/org/jf/dexlib/MethodIdItem.java | 256 -- .../java/org/jf/dexlib/OdexDependencies.java | 76 - .../main/java/org/jf/dexlib/OdexHeader.java | 74 - .../java/org/jf/dexlib/OffsettedSection.java | 53 - .../main/java/org/jf/dexlib/ProtoIdItem.java | 231 - .../main/java/org/jf/dexlib/ReadContext.java | 200 - .../src/main/java/org/jf/dexlib/Section.java | 221 - .../java/org/jf/dexlib/StringDataItem.java | 170 - .../main/java/org/jf/dexlib/StringIdItem.java | 177 - .../main/java/org/jf/dexlib/TypeIdItem.java | 211 - .../main/java/org/jf/dexlib/TypeListItem.java | 288 -- .../java/org/jf/dexlib/Util/AccessFlags.java | 178 - .../org/jf/dexlib/Util/AnnotatedOutput.java | 91 - .../java/org/jf/dexlib/Util/ArrayUtils.java | 71 - .../java/org/jf/dexlib/Util/ByteArray.java | 253 -- .../dexlib/Util/ByteArrayAnnotatedOutput.java | 681 --- .../org/jf/dexlib/Util/ByteArrayInput.java | 325 -- .../org/jf/dexlib/Util/ByteArrayOutput.java | 581 --- .../org/jf/dexlib/Util/DebugInfoBuilder.java | 451 -- .../org/jf/dexlib/Util/EncodedValueUtils.java | 143 - .../java/org/jf/dexlib/Util/FileUtils.java | 140 - .../org/jf/dexlib/Util/IndentingWriter.java | 177 - .../main/java/org/jf/dexlib/Util/Input.java | 165 - .../java/org/jf/dexlib/Util/Leb128Utils.java | 107 - .../java/org/jf/dexlib/Util/NumberUtils.java | 200 - .../main/java/org/jf/dexlib/Util/Output.java | 141 - .../main/java/org/jf/dexlib/Util/Pair.java | 40 - .../org/jf/dexlib/Util/ReadOnlyArrayList.java | 52 - .../java/org/jf/dexlib/Util/SparseArray.java | 366 -- .../org/jf/dexlib/Util/SparseIntArray.java | 261 -- .../org/jf/dexlib/Util/TryListBuilder.java | 347 -- .../org/jf/dexlib/Util/TwoColumnOutput.java | 258 -- .../java/org/jf/dexlib/Util/TypeUtils.java | 64 - .../jf/dexlib2/builder/BuilderDebugItem.java | 4 +- .../jf/dexlib2/builder/MethodLocation.java | 14 +- .../builder/MutableMethodImplementation.java | 18 +- .../builder/debug/BuilderEndLocal.java | 6 +- .../builder/debug/BuilderEpilogueBegin.java | 6 +- .../builder/debug/BuilderLineNumber.java | 7 +- .../builder/debug/BuilderPrologueEnd.java | 6 +- .../builder/debug/BuilderRestartLocal.java | 6 +- .../builder/debug/BuilderSetSourceFile.java | 6 +- .../builder/debug/BuilderStartLocal.java | 6 +- .../dexlib2/immutable/ImmutableClassDef.java | 12 +- .../java/org/jf/dexlib2/writer/DexWriter.java | 20 +- .../writer/builder/BuilderClassDef.java | 25 +- .../writer/builder/BuilderInstruction.java | 426 -- .../builder/BuilderInstructionFactory.java | 223 - .../jf/dexlib2/writer/builder/DexBuilder.java | 4 +- .../org/jf/dexlib2/writer/pool/DexPool.java | 5 +- .../smali/src/main/antlr3/smaliTreeWalker.g | 2 - 168 files changed, 69 insertions(+), 28897 deletions(-) delete mode 100644 brut.apktool.smali/dexlib/build.gradle delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationDirectoryItem.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationItem.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationSetItem.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationSetRefList.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationVisibility.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ClassDataItem.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ClassDefItem.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/AnalyzedInstruction.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/ClassPath.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/CustomInlineMethodResolver.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DeodexUtil.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DexFileClassMap.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DumpFields.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DumpVtables.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/InlineMethodResolver.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/OdexedFieldInstructionMapper.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/RegisterType.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/SyntheticAccessorResolver.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/ValidationException.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/EncodedLiteralInstruction.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/FiveRegisterInstruction.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/ArrayDataPseudoInstruction.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Format.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction10t.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction10x.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction11n.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction11x.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction12x.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction20bc.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction20t.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction21c.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction21h.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction21s.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction21t.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22b.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22c.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22cs.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22s.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22t.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22x.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction23x.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction30t.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction31c.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction31i.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction31t.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction32x.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35c.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35mi.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35ms.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rc.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rmi.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rms.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction51l.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/InstructionWithJumboReference.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/InstructionWithJumboVariant.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/PackedSwitchDataPseudoInstruction.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/SparseSwitchDataPseudoInstruction.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/UnknownInstruction.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/UnresolvedOdexInstruction.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Instruction.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/InstructionIterator.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/InstructionWithReference.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/InvokeInstruction.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/LiteralInstruction.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/MultiOffsetInstruction.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/OdexedFieldAccess.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/OdexedInvokeInline.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/OdexedInvokeVirtual.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/OffsetInstruction.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Opcode.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/ReferenceType.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/RegisterRangeInstruction.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/SingleRegisterInstruction.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/ThreeRegisterInstruction.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/TwoRegisterInstruction.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/VerificationErrorType.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/CodeItem.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Convertible.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Debug/DebugInstructionIterator.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Debug/DebugOpcode.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/DebugInfoItem.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/DexFile.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedArrayItem.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/AnnotationEncodedSubValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/AnnotationEncodedValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/ArrayEncodedSubValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/ArrayEncodedValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/BooleanEncodedValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/ByteEncodedValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/CharEncodedValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/DoubleEncodedValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/EncodedValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/EnumEncodedValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/FieldEncodedValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/FloatEncodedValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/IntEncodedValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/LongEncodedValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/MethodEncodedValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/NullEncodedValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/ShortEncodedValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/StringEncodedValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/TypeEncodedValue.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/ValueType.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/FieldIdItem.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/HeaderItem.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/IndexedSection.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Item.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ItemFactory.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ItemType.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/MapItem.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/MethodIdItem.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/OdexDependencies.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/OdexHeader.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/OffsettedSection.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ProtoIdItem.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ReadContext.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Section.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/StringDataItem.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/StringIdItem.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/TypeIdItem.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/TypeListItem.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/AccessFlags.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/AnnotatedOutput.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ArrayUtils.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ByteArray.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ByteArrayAnnotatedOutput.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ByteArrayInput.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ByteArrayOutput.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/DebugInfoBuilder.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/EncodedValueUtils.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/FileUtils.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/IndentingWriter.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/Input.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/Leb128Utils.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/NumberUtils.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/Output.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/Pair.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ReadOnlyArrayList.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/SparseArray.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/SparseIntArray.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/TryListBuilder.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/TwoColumnOutput.java delete mode 100644 brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/TypeUtils.java delete mode 100644 brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderInstruction.java delete mode 100644 brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderInstructionFactory.java diff --git a/brut.apktool.smali/baksmali/src/main/java/org/jf/baksmali/Adaptors/ClassDefinition.java b/brut.apktool.smali/baksmali/src/main/java/org/jf/baksmali/Adaptors/ClassDefinition.java index 8c5e4846..60ef448c 100644 --- a/brut.apktool.smali/baksmali/src/main/java/org/jf/baksmali/Adaptors/ClassDefinition.java +++ b/brut.apktool.smali/baksmali/src/main/java/org/jf/baksmali/Adaptors/ClassDefinition.java @@ -263,7 +263,7 @@ public class ClassDefinition { MethodImplementation methodImpl = method.getImplementation(); if (methodImpl == null) { - MethodDefinition.writeEmptyMethodTo(methodWriter, method); + MethodDefinition.writeEmptyMethodTo(methodWriter, method, options); } else { MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl); methodDefinition.writeTo(methodWriter); @@ -308,7 +308,7 @@ public class ClassDefinition { MethodImplementation methodImpl = method.getImplementation(); if (methodImpl == null) { - MethodDefinition.writeEmptyMethodTo(methodWriter, method); + MethodDefinition.writeEmptyMethodTo(methodWriter, method, options); } else { MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl); methodDefinition.writeTo(methodWriter); diff --git a/brut.apktool.smali/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java b/brut.apktool.smali/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java index 611936b6..8ebd1e78 100644 --- a/brut.apktool.smali/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java +++ b/brut.apktool.smali/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java @@ -31,6 +31,7 @@ package org.jf.baksmali.Adaptors; import com.google.common.collect.ImmutableList; import org.jf.baksmali.Adaptors.Debug.DebugMethodItem; import org.jf.baksmali.Adaptors.Format.InstructionMethodItemFactory; +import org.jf.baksmali.baksmaliOptions; import org.jf.dexlib2.AccessFlags; import org.jf.dexlib2.Format; import org.jf.dexlib2.Opcode; @@ -113,7 +114,8 @@ public class MethodDefinition { } } - public static void writeEmptyMethodTo(IndentingWriter writer, Method method) throws IOException { + public static void writeEmptyMethodTo(IndentingWriter writer, Method method, + baksmaliOptions options) throws IOException { writer.write(".method "); writeAccessFlags(writer, method.getAccessFlags()); writer.write(method.getName()); @@ -127,7 +129,7 @@ public class MethodDefinition { writer.write('\n'); writer.indent(4); - writeParameters(writer, method, methodParameters); + writeParameters(writer, method, methodParameters, options); AnnotationFormatter.writeTo(writer, method.getAnnotations()); writer.deindent(4); writer.write(".end method\n"); @@ -164,7 +166,7 @@ public class MethodDefinition { writer.printSignedIntAsDec(methodImpl.getRegisterCount()); } writer.write('\n'); - writeParameters(writer, method, methodParameters); + writeParameters(writer, method, methodParameters, classDef.options); if (registerFormatter == null) { registerFormatter = new RegisterFormatter(classDef.options, methodImpl.getRegisterCount(), @@ -218,7 +220,8 @@ public class MethodDefinition { } private static void writeParameters(IndentingWriter writer, Method method, - List parameters) throws IOException { + List parameters, + baksmaliOptions options) throws IOException { boolean isStatic = AccessFlags.STATIC.isSet(method.getAccessFlags()); int registerNumber = isStatic?0:1; for (MethodParameter parameter: parameters) { @@ -229,7 +232,7 @@ public class MethodDefinition { writer.write(".param p"); writer.printSignedIntAsDec(registerNumber); - if (parameterName != null) { + if (parameterName != null && options.outputDebugInfo) { writer.write(", "); ReferenceFormatter.writeStringReference(writer, parameterName); } diff --git a/brut.apktool.smali/baksmali/src/main/java/org/jf/baksmali/main.java b/brut.apktool.smali/baksmali/src/main/java/org/jf/baksmali/main.java index e9d80389..83009a6d 100644 --- a/brut.apktool.smali/baksmali/src/main/java/org/jf/baksmali/main.java +++ b/brut.apktool.smali/baksmali/src/main/java/org/jf/baksmali/main.java @@ -148,7 +148,7 @@ public class main { options.addCodeOffsets = true; break; case 'r': - String[] values = commandLine.getOptionValues("r"); + String[] values = commandLine.getOptionValues('r'); int registerInfo = 0; if (values == null || values.length == 0) { diff --git a/brut.apktool.smali/baksmali/src/test/java/org/jf/baksmali/AnalysisTest.java b/brut.apktool.smali/baksmali/src/test/java/org/jf/baksmali/AnalysisTest.java index 046ee493..9e1b11f0 100644 --- a/brut.apktool.smali/baksmali/src/test/java/org/jf/baksmali/AnalysisTest.java +++ b/brut.apktool.smali/baksmali/src/test/java/org/jf/baksmali/AnalysisTest.java @@ -104,7 +104,7 @@ public class AnalysisTest { className.substring(1, className.length() - 1)); String smaliContents = readResource(smaliPath); - Assert.assertEquals(smaliContents, stringWriter.toString().replace("\r\n", "\n")); + Assert.assertEquals(smaliContents.replace("\r\n", "\n"), stringWriter.toString().replace("\r\n", "\n")); } } diff --git a/brut.apktool.smali/build.gradle b/brut.apktool.smali/build.gradle index 82fd9d1f..e6d738ed 100644 --- a/brut.apktool.smali/build.gradle +++ b/brut.apktool.smali/build.gradle @@ -31,7 +31,7 @@ apply plugin: 'idea' -version = '2.0b5' +version = '2.0' def jarVersion = version @@ -98,4 +98,8 @@ buildscript { dependencies { classpath 'org.eclipse.jgit:org.eclipse.jgit:2.0.0.201206130900-r' } +} + +task wrapper(type: Wrapper) { + gradleVersion = '1.8' } \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/build.gradle b/brut.apktool.smali/dexlib/build.gradle deleted file mode 100644 index dd81dd5d..00000000 --- a/brut.apktool.smali/dexlib/build.gradle +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2012, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -dependencies { - compile project('brut.apktool.smali:util') - compile depends.findbugs - compile depends.guava -} \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationDirectoryItem.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationDirectoryItem.java deleted file mode 100644 index 56d60ead..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationDirectoryItem.java +++ /dev/null @@ -1,610 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import com.google.common.base.Preconditions; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.util.ExceptionWithContext; -import org.jf.dexlib.Util.Input; -import org.jf.dexlib.Util.ReadOnlyArrayList; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.*; - -public class AnnotationDirectoryItem extends Item { - @Nullable - private AnnotationSetItem classAnnotations; - @Nullable - private FieldAnnotation[] fieldAnnotations; - @Nullable - private MethodAnnotation[] methodAnnotations; - @Nullable - private ParameterAnnotation[] parameterAnnotations; - - /** - * Creates a new uninitialized AnnotationDirectoryItem - * @param dexFile The DexFile that this item belongs to - */ - protected AnnotationDirectoryItem(DexFile dexFile) { - super(dexFile); - } - - /** - * Creates a new AnnotationDirectoryItem with the given values - * @param dexFile The DexFile that this item belongs to - * @param classAnnotations The annotations associated with the overall class - * @param fieldAnnotations A list of FieldAnnotation objects that contain the field annotations for - * this class - * @param methodAnnotations A list of MethodAnnotation objects that contain the method annotations for - * this class - * @param parameterAnnotations A list of ParameterAnnotation objects that contain the parameter - * annotations for the methods in this class - */ - private AnnotationDirectoryItem(DexFile dexFile, @Nullable AnnotationSetItem classAnnotations, - @Nullable List fieldAnnotations, - @Nullable List methodAnnotations, - @Nullable List parameterAnnotations) { - super(dexFile); - this.classAnnotations = classAnnotations; - - if (fieldAnnotations == null || fieldAnnotations.size() == 0) { - this.fieldAnnotations = null; - } else { - this.fieldAnnotations = new FieldAnnotation[fieldAnnotations.size()]; - this.fieldAnnotations = fieldAnnotations.toArray(this.fieldAnnotations); - Arrays.sort(this.fieldAnnotations); - } - - if (methodAnnotations == null || methodAnnotations.size() == 0) { - this.methodAnnotations = null; - } else { - this.methodAnnotations = new MethodAnnotation[methodAnnotations.size()]; - this.methodAnnotations = methodAnnotations.toArray(this.methodAnnotations); - Arrays.sort(this.methodAnnotations); - } - - if (parameterAnnotations == null || parameterAnnotations.size() == 0) { - this.parameterAnnotations = null; - } else { - this.parameterAnnotations = new ParameterAnnotation[parameterAnnotations.size()]; - this.parameterAnnotations = parameterAnnotations.toArray(this.parameterAnnotations); - Arrays.sort(this.parameterAnnotations); - } - } - - /** - * Returns an AnnotationDirectoryItem for the given values, and that has been interned into the given - * DexFile - * @param dexFile The DexFile that this item belongs to - * @param classAnnotations The annotations associated with the class - * @param fieldAnnotations A list of FieldAnnotation objects containing the field annotations - * @param methodAnnotations A list of MethodAnnotation objects containing the method annotations - * @param parameterAnnotations A list of ParameterAnnotation objects containin the parameter - * annotations - * @return an AnnotationItem for the given values, and that has been interned into the given - * DexFile - */ - public static AnnotationDirectoryItem internAnnotationDirectoryItem(DexFile dexFile, - AnnotationSetItem classAnnotations, - List fieldAnnotations, - List methodAnnotations, - List parameterAnnotations) { - AnnotationDirectoryItem annotationDirectoryItem = new AnnotationDirectoryItem(dexFile, classAnnotations, - fieldAnnotations, methodAnnotations, parameterAnnotations); - return dexFile.AnnotationDirectoriesSection.intern(annotationDirectoryItem); - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - classAnnotations = (AnnotationSetItem)readContext.getOptionalOffsettedItemByOffset( - ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt()); - - int fieldAnnotationCount = in.readInt(); - if (fieldAnnotationCount > 0) { - fieldAnnotations = new FieldAnnotation[fieldAnnotationCount]; - } else { - fieldAnnotations = null; - } - - int methodAnnotationCount = in.readInt(); - if (methodAnnotationCount > 0) { - methodAnnotations = new MethodAnnotation[methodAnnotationCount]; - } else { - methodAnnotations = null; - } - - int parameterAnnotationCount = in.readInt(); - if (parameterAnnotationCount > 0) { - parameterAnnotations = new ParameterAnnotation[parameterAnnotationCount]; - } else { - parameterAnnotations = null; - } - - if (fieldAnnotations != null) { - for (int i=0; i 0) { - return fieldAnnotations[0].field.getContainingClass(); - } - if (methodAnnotations != null && methodAnnotations.length > 0) { - return methodAnnotations[0].method.getContainingClass(); - } - if (parameterAnnotations != null && parameterAnnotations.length > 0) { - return parameterAnnotations[0].method.getContainingClass(); - } - return null; - } - - /** - * @return An AnnotationSetItem containing the annotations associated with this class, or null - * if there are no class annotations - */ - @Nullable - public AnnotationSetItem getClassAnnotations() { - return classAnnotations; - } - - /** - * Get a list of the field annotations in this AnnotationDirectoryItem - * @return A list of FieldAnnotation objects, or null if there are no field annotations - */ - @Nonnull - public List getFieldAnnotations() { - if (fieldAnnotations == null) { - return Collections.emptyList(); - } - return ReadOnlyArrayList.of(fieldAnnotations); - } - - /** - * Get a list of the method annotations in this AnnotationDirectoryItem - * @return A list of MethodAnnotation objects, or null if there are no method annotations - */ - @Nonnull - public List getMethodAnnotations() { - if (methodAnnotations == null) { - return Collections.emptyList(); - } - return ReadOnlyArrayList.of(methodAnnotations); - } - - /** - * Get a list of the parameter annotations in this AnnotationDirectoryItem - * @return A list of ParameterAnnotation objects, or null if there are no parameter annotations - */ - @Nonnull - public List getParameterAnnotations() { - if (parameterAnnotations == null) { - return Collections.emptyList(); - } - return ReadOnlyArrayList.of(parameterAnnotations); - } - - /** - * Gets the field annotations for the given field, or null if no annotations are defined for that field - * @param fieldIdItem The field to get the annotations for - * @return An AnnotationSetItem containing the field annotations, or null if none are found - */ - @Nullable - public AnnotationSetItem getFieldAnnotations(FieldIdItem fieldIdItem) { - if (fieldAnnotations == null) { - return null; - } - int index = Arrays.binarySearch(fieldAnnotations, fieldIdItem); - if (index < 0) { - return null; - } - return fieldAnnotations[index].annotationSet; - } - - /** - * Gets the method annotations for the given method, or null if no annotations are defined for that method - * @param methodIdItem The method to get the annotations for - * @return An AnnotationSetItem containing the method annotations, or null if none are found - */ - @Nullable - public AnnotationSetItem getMethodAnnotations(MethodIdItem methodIdItem) { - if (methodAnnotations == null) { - return null; - } - int index = Arrays.binarySearch(methodAnnotations, methodIdItem); - if (index < 0) { - return null; - } - return methodAnnotations[index].annotationSet; - } - - /** - * Gets the parameter annotations for the given method, or null if no parameter annotations are defined for that - * method - * @param methodIdItem The method to get the parameter annotations for - * @return An AnnotationSetRefList containing the parameter annotations, or null if none are found - */ - @Nullable - public AnnotationSetRefList getParameterAnnotations(MethodIdItem methodIdItem) { - if (parameterAnnotations == null) { - return null; - } - int index = Arrays.binarySearch(parameterAnnotations, methodIdItem); - if (index < 0) { - return null; - } - return parameterAnnotations[index].annotationSet; - } - - /** - * - */ - public int getClassAnnotationCount() { - if (classAnnotations == null) { - return 0; - } - AnnotationItem[] annotations = classAnnotations.getAnnotations(); - return annotations.length; - } - - /** - * @return The number of field annotations in this AnnotationDirectoryItem - */ - public int getFieldAnnotationCount() { - if (fieldAnnotations == null) { - return 0; - } - return fieldAnnotations.length; - } - - /** - * @return The number of method annotations in this AnnotationDirectoryItem - */ - public int getMethodAnnotationCount() { - if (methodAnnotations == null) { - return 0; - } - return methodAnnotations.length; - } - - /** - * @return The number of parameter annotations in this AnnotationDirectoryItem - */ - public int getParameterAnnotationCount() { - if (parameterAnnotations == null) { - return 0; - } - return parameterAnnotations.length; - } - - @Override - public int hashCode() { - // If the item has a single parent, we can use the re-use the identity (hash) of that parent - TypeIdItem parentType = getParentType(); - if (parentType != null) { - return parentType.hashCode(); - } - if (classAnnotations != null) { - return classAnnotations.hashCode(); - } - return 0; - } - - @Override - public boolean equals(Object o) { - if (this==o) { - return true; - } - if (o==null || !this.getClass().equals(o.getClass())) { - return false; - } - - AnnotationDirectoryItem other = (AnnotationDirectoryItem)o; - return (this.compareTo(other) == 0); - } - - public static class FieldAnnotation implements Comparable>, Convertible { - public final FieldIdItem field; - public final AnnotationSetItem annotationSet; - - public FieldAnnotation(FieldIdItem field, AnnotationSetItem annotationSet) { - this.field = field; - this.annotationSet = annotationSet; - } - - public int compareTo(Convertible other) { - return field.compareTo(other.convert()); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - return compareTo((FieldAnnotation)o) == 0; - } - - @Override - public int hashCode() { - return field.hashCode() + 31 * annotationSet.hashCode(); - } - - public FieldIdItem convert() { - return field; - } - } - - public static class MethodAnnotation implements Comparable>, Convertible { - public final MethodIdItem method; - public final AnnotationSetItem annotationSet; - - public MethodAnnotation(MethodIdItem method, AnnotationSetItem annotationSet) { - this.method = method; - this.annotationSet = annotationSet; - } - - public int compareTo(Convertible other) { - return method.compareTo(other.convert()); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - return compareTo((MethodAnnotation)o) == 0; - } - - @Override - public int hashCode() { - return method.hashCode() + 31 * annotationSet.hashCode(); - } - - public MethodIdItem convert() { - return method; - } - } - - public static class ParameterAnnotation implements Comparable>, - Convertible { - public final MethodIdItem method; - public final AnnotationSetRefList annotationSet; - - public ParameterAnnotation(MethodIdItem method, AnnotationSetRefList annotationSet) { - this.method = method; - this.annotationSet = annotationSet; - } - - public int compareTo(Convertible other) { - return method.compareTo(other.convert()); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - return compareTo((ParameterAnnotation)o) == 0; - } - - @Override - public int hashCode() { - return method.hashCode() + 31 * annotationSet.hashCode(); - } - - public MethodIdItem convert() { - return method; - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationItem.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationItem.java deleted file mode 100644 index f35a414b..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationItem.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.dexlib.EncodedValue.AnnotationEncodedSubValue; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; - -public class AnnotationItem extends Item { - private int hashCode = 0; - - private AnnotationVisibility visibility; - private AnnotationEncodedSubValue annotationValue; - - /** - * Creates a new uninitialized AnnotationItem - * @param dexFile The DexFile that this item belongs to - */ - protected AnnotationItem(DexFile dexFile) { - super(dexFile); - } - - /** - * Creates a new AnnotationItem with the given values - * @param dexFile The DexFile that this item belongs to - * @param visibility The visibility of this annotation - * @param annotationValue The value of this annotation - */ - private AnnotationItem(DexFile dexFile, AnnotationVisibility visibility, - AnnotationEncodedSubValue annotationValue) { - super(dexFile); - this.visibility = visibility; - this.annotationValue = annotationValue; - } - - /** - * Returns an AnnotationItem for the given values, and that has been interned into the given - * DexFile - * @param dexFile The DexFile that this item belongs to - * @param visibility The visibility of this annotation - * @param annotationValue The value of this annotation - * @return an AnnotationItem for the given values, and that has been interned into the given - * DexFile - */ - public static AnnotationItem internAnnotationItem(DexFile dexFile, AnnotationVisibility visibility, - AnnotationEncodedSubValue annotationValue) { - AnnotationItem annotationItem = new AnnotationItem(dexFile, visibility, annotationValue); - return dexFile.AnnotationsSection.intern(annotationItem); - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - visibility = AnnotationVisibility.fromByte(in.readByte()); - annotationValue = new AnnotationEncodedSubValue(dexFile, in); - } - - /** {@inheritDoc} */ - protected int placeItem(int offset) { - return annotationValue.placeValue(offset + 1); - } - - /** {@inheritDoc} */ - protected void writeItem(AnnotatedOutput out) { - if (out.annotates()) { - out.annotate("visibility: " + visibility.name()); - out.writeByte(visibility.value); - annotationValue.writeValue(out); - }else { - out.writeByte(visibility.value); - annotationValue.writeValue(out); - } - } - - /** {@inheritDoc} */ - public ItemType getItemType() { - return ItemType.TYPE_ANNOTATION_ITEM; - } - - /** {@inheritDoc} */ - public String getConciseIdentity() { - return "annotation_item @0x" + Integer.toHexString(getOffset()); - } - - /** {@inheritDoc} */ - public int compareTo(AnnotationItem o) { - int comp = visibility.value - o.visibility.value; - if (comp == 0) { - comp = annotationValue.compareTo(o.annotationValue); - } - return comp; - } - - /** - * @return The visibility of this annotation - */ - public AnnotationVisibility getVisibility() { - return visibility; - } - - /** - * @return The encoded annotation value of this annotation - */ - public AnnotationEncodedSubValue getEncodedAnnotation() { - return annotationValue; - } - - /** - * calculate and cache the hashcode - */ - private void calcHashCode() { - hashCode = visibility.value; - hashCode = hashCode * 31 + annotationValue.hashCode(); - } - - @Override - public int hashCode() { - //there's a small possibility that the actual hash code will be 0. If so, we'll - //just end up recalculating it each time - if (hashCode == 0) - calcHashCode(); - return hashCode; - } - - @Override - public boolean equals(Object o) { - if (this==o) { - return true; - } - if (o==null || !this.getClass().equals(o.getClass())) { - return false; - } - - AnnotationItem other = (AnnotationItem)o; - return visibility == other.visibility && annotationValue.equals(other.annotationValue); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationSetItem.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationSetItem.java deleted file mode 100644 index e221ad02..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationSetItem.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; - -public class AnnotationSetItem extends Item { - private int hashCode = 0; - - private AnnotationItem[] annotations; - - /** - * Creates a new uninitialized AnnotationSetItem - * @param dexFile The DexFile that this item belongs to - */ - protected AnnotationSetItem(DexFile dexFile) { - super(dexFile); - } - - /** - * Creates a new AnnotationSetItem for the given annotations - * @param dexFile The DexFile that this item belongs to - * @param annotations The annotations for this AnnotationSetItem - */ - private AnnotationSetItem(DexFile dexFile, AnnotationItem[] annotations) { - super(dexFile); - this.annotations = annotations; - } - - /** - * Returns an AnnotationSetItem for the given annotations, and that has been interned into the given - * DexFile - * @param dexFile The DexFile that this item belongs to - * @param annotations The annotations for this AnnotationSetItem - * @return an AnnotationSetItem for the given annotations - */ - public static AnnotationSetItem internAnnotationSetItem(DexFile dexFile, List annotations) { - AnnotationSetItem annotationSetItem; - if (annotations == null) { - annotationSetItem = new AnnotationSetItem(dexFile, new AnnotationItem[0]); - } else { - AnnotationItem[] annotationsArray = new AnnotationItem[annotations.size()]; - annotations.toArray(annotationsArray); - annotationSetItem = new AnnotationSetItem(dexFile, annotationsArray); - } - return dexFile.AnnotationSetsSection.intern(annotationSetItem); - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - annotations = new AnnotationItem[in.readInt()]; - - for (int i=0; i() { - public int compare(AnnotationItem annotationItem, AnnotationItem annotationItem2) { - int annotationItemIndex = annotationItem.getEncodedAnnotation().annotationType.getIndex(); - int annotationItemIndex2 = annotationItem2.getEncodedAnnotation().annotationType.getIndex(); - if (annotationItemIndex < annotationItemIndex2) { - return -1; - } else if (annotationItemIndex == annotationItemIndex2) { - return 0; - } - return 1; - } - }); - - - if (out.annotates()) { - out.annotate(4, "size: 0x" + Integer.toHexString(annotations.length) + " (" + annotations.length + ")"); - for (AnnotationItem annotationItem: annotations) { - out.annotate(4, "annotation_off: 0x" + Integer.toHexString(annotationItem.getOffset()) + " - " + - annotationItem.getEncodedAnnotation().annotationType.getTypeDescriptor()); - } - } - out.writeInt(annotations.length); - for (AnnotationItem annotationItem: annotations) { - out.writeInt(annotationItem.getOffset()); - } - } - - /** {@inheritDoc} */ - public ItemType getItemType() { - return ItemType.TYPE_ANNOTATION_SET_ITEM; - } - - /** {@inheritDoc} */ - public String getConciseIdentity() { - return "annotation_set_item @0x" + Integer.toHexString(getOffset()); - } - -/** {@inheritDoc} */ - public int compareTo(AnnotationSetItem o) { - if (o == null) { - return 1; - } - - int comp = annotations.length - o.annotations.length; - if (comp == 0) { - for (int i=0; iAnnotationItem objects in this AnnotationSetItem - */ - public AnnotationItem[] getAnnotations() { - return annotations; - } - - /** - * calculate and cache the hashcode - */ - private void calcHashCode() { - hashCode = 0; - for (AnnotationItem annotationItem: annotations) { - hashCode = hashCode * 31 + annotationItem.hashCode(); - } - } - - @Override - public int hashCode() { - //there's a small possibility that the actual hash code will be 0. If so, we'll - //just end up recalculating it each time - if (hashCode == 0) - calcHashCode(); - return hashCode; - } - - @Override - public boolean equals(Object o) { - if (this==o) { - return true; - } - if (o==null || !this.getClass().equals(o.getClass())) { - return false; - } - - AnnotationSetItem other = (AnnotationSetItem)o; - return (this.compareTo(other) == 0); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationSetRefList.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationSetRefList.java deleted file mode 100644 index e38ce31c..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationSetRefList.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; - -import java.util.List; - -public class AnnotationSetRefList extends Item { - private int hashCode = 0; - - private AnnotationSetItem[] annotationSets; - - /** - * Creates a new uninitialized AnnotationSetRefList - * @param dexFile The DexFile that this item belongs to - */ - protected AnnotationSetRefList(DexFile dexFile) { - super(dexFile); - } - - /** - * Creates a new AnnotationSetRefList for the given annotation sets - * @param dexFile The DexFile that this item belongs to - * @param annotationSets The annotationSets for this AnnotationSetRefList - */ - private AnnotationSetRefList(DexFile dexFile, AnnotationSetItem[] annotationSets) { - super(dexFile); - this.annotationSets = annotationSets; - } - - /** - * Returns an AnnotationSetRefList for the given annotation sets, and that has been interned into the - * given DexFile - * @param dexFile The DexFile that this item belongs to - * @param annotationSets The annotation sets for this AnnotationSetRefList - * @return an AnnotationSetItem for the given annotations - */ - public static AnnotationSetRefList internAnnotationSetRefList(DexFile dexFile, - List annotationSets) { - AnnotationSetItem[] annotationSetsArray = new AnnotationSetItem[annotationSets.size()]; - annotationSets.toArray(annotationSetsArray); - AnnotationSetRefList annotationSetRefList = new AnnotationSetRefList(dexFile, annotationSetsArray); - return dexFile.AnnotationSetRefListsSection.intern(annotationSetRefList); - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - annotationSets = new AnnotationSetItem[in.readInt()]; - - for (int i=0; iAnnotationSetItem objects that make up this - * AnnotationSetRefList - */ - public AnnotationSetItem[] getAnnotationSets() { - return annotationSets; - } - - /** - * calculate and cache the hashcode - */ - private void calcHashCode() { - hashCode = 0; - for (AnnotationSetItem annotationSetItem: annotationSets) { - hashCode = hashCode * 31 + annotationSetItem.hashCode(); - } - } - - @Override - public int hashCode() { - //there's a small possibility that the actual hash code will be 0. If so, we'll - //just end up recalculating it each time - if (hashCode == 0) - calcHashCode(); - return hashCode; - } - - @Override - public boolean equals(Object o) { - if (this==o) { - return true; - } - if (o==null || !this.getClass().equals(o.getClass())) { - return false; - } - - AnnotationSetRefList other = (AnnotationSetRefList)o; - return (this.compareTo(other) == 0); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationVisibility.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationVisibility.java deleted file mode 100644 index 03ae96f0..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/AnnotationVisibility.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -public enum AnnotationVisibility { - BUILD((byte)0, "build"), - RUNTIME((byte)1, "runtime"), - SYSTEM((byte)2, "system"); - - public final byte value; - public final String visibility; - private AnnotationVisibility(byte value, String visibility) { - this.value = value; - this.visibility = visibility; - } - - public static AnnotationVisibility fromByte(byte value) { - switch (value) { - case (byte)0: - return BUILD; - case (byte)1: - return RUNTIME; - case (byte)2: - return SYSTEM; - default: - throw new RuntimeException("Invalid annotation visibility value: " + value); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ClassDataItem.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ClassDataItem.java deleted file mode 100644 index afd3f889..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ClassDataItem.java +++ /dev/null @@ -1,844 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import com.google.common.base.Preconditions; -import org.jf.dexlib.Util.*; -import org.jf.util.ExceptionWithContext; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.*; - -public class ClassDataItem extends Item { - @Nullable - private EncodedField[] staticFields = null; - @Nullable - private EncodedField[] instanceFields = null; - @Nullable - private EncodedMethod[] directMethods = null; - @Nullable - private EncodedMethod[] virtualMethods = null; - - /** - * Creates a new uninitialized ClassDataItem - * @param dexFile The DexFile that this item belongs to - */ - public ClassDataItem(final DexFile dexFile) { - super(dexFile); - } - - /** - * Creates a new ClassDataItem with the given values - * @param dexFile The DexFile that this item belongs to - * @param staticFields The static fields for this class - * @param instanceFields The instance fields for this class - * @param directMethods The direct methods for this class - * @param virtualMethods The virtual methods for this class - */ - private ClassDataItem(DexFile dexFile, @Nullable EncodedField[] staticFields, - @Nullable EncodedField[] instanceFields, @Nullable EncodedMethod[] directMethods, - @Nullable EncodedMethod[] virtualMethods) { - super(dexFile); - this.staticFields = staticFields; - this.instanceFields = instanceFields; - this.directMethods = directMethods; - this.virtualMethods = virtualMethods; - } - - /** - * Creates a new ClassDataItem with the given values - * @param dexFile The DexFile that this item belongs to - * @param staticFields The static fields for this class - * @param instanceFields The instance fields for this class - * @param directMethods The direct methods for this class - * @param virtualMethods The virtual methods for this class - * @return a new ClassDataItem with the given values - */ - public static ClassDataItem internClassDataItem(DexFile dexFile, @Nullable List staticFields, - @Nullable List instanceFields, - @Nullable List directMethods, - @Nullable List virtualMethods) { - EncodedField[] staticFieldsArray = null; - EncodedField[] instanceFieldsArray = null; - EncodedMethod[] directMethodsArray = null; - EncodedMethod[] virtualMethodsArray = null; - - if (staticFields != null && staticFields.size() > 0) { - SortedSet staticFieldsSet = new TreeSet(); - for (EncodedField staticField: staticFields) { - if (staticFieldsSet.contains(staticField)) { - System.err.println(String.format("Ignoring duplicate static field definition: %s", - staticField.field.getFieldString())); - continue; - } - staticFieldsSet.add(staticField); - } - - staticFieldsArray = new EncodedField[staticFieldsSet.size()]; - staticFieldsArray = staticFieldsSet.toArray(staticFieldsArray); - } - - if (instanceFields != null && instanceFields.size() > 0) { - SortedSet instanceFieldsSet = new TreeSet(); - for (EncodedField instanceField: instanceFields) { - if (instanceFieldsSet.contains(instanceField)) { - System.err.println(String.format("Ignoring duplicate instance field definition: %s", - instanceField.field.getFieldString())); - continue; - } - instanceFieldsSet.add(instanceField); - } - - instanceFieldsArray = new EncodedField[instanceFieldsSet.size()]; - instanceFieldsArray = instanceFieldsSet.toArray(instanceFieldsArray); - } - - TreeSet directMethodSet = new TreeSet(); - - if (directMethods != null && directMethods.size() > 0) { - for (EncodedMethod directMethod: directMethods) { - if (directMethodSet.contains(directMethod)) { - System.err.println(String.format("Ignoring duplicate direct method definition: %s", - directMethod.method.getMethodString())); - continue; - } - directMethodSet.add(directMethod); - } - - directMethodsArray = new EncodedMethod[directMethodSet.size()]; - directMethodsArray = directMethodSet.toArray(directMethodsArray); - } - - if (virtualMethods != null && virtualMethods.size() > 0) { - TreeSet virtualMethodSet = new TreeSet(); - for (EncodedMethod virtualMethod: virtualMethods) { - if (directMethodSet.contains(virtualMethod)) { - // If both a direct and virtual definition is present, dalvik's behavior seems to be undefined, - // so we can't gracefully handle this case, like we can if the duplicates are all direct or all - // virtual -- in which case, we ignore all but the first definition - throw new RuntimeException(String.format("Duplicate direct+virtual method definition: %s", - virtualMethod.method.getMethodString())); - } - if (virtualMethodSet.contains(virtualMethod)) { - System.err.println(String.format("Ignoring duplicate virtual method definition: %s", - virtualMethod.method.getMethodString())); - continue; - } - virtualMethodSet.add(virtualMethod); - } - - virtualMethodsArray = new EncodedMethod[virtualMethodSet.size()]; - virtualMethodsArray = virtualMethodSet.toArray(virtualMethodsArray); - } - - ClassDataItem classDataItem = new ClassDataItem(dexFile, staticFieldsArray, instanceFieldsArray, - directMethodsArray, virtualMethodsArray); - return dexFile.ClassDataSection.intern(classDataItem); - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - int staticFieldsCount = in.readUnsignedLeb128(); - int instanceFieldsCount = in.readUnsignedLeb128(); - int directMethodsCount = in.readUnsignedLeb128(); - int virtualMethodsCount = in.readUnsignedLeb128(); - - if (staticFieldsCount > 0) { - staticFields = new EncodedField[staticFieldsCount]; - EncodedField previousEncodedField = null; - for (int i=0; i 0) { - instanceFields = new EncodedField[instanceFieldsCount]; - EncodedField previousEncodedField = null; - for (int i=0; i 0) { - directMethods = new EncodedMethod[directMethodsCount]; - EncodedMethod previousEncodedMethod = null; - for (int i=0; i 0) { - virtualMethods = new EncodedMethod[virtualMethodsCount]; - EncodedMethod previousEncodedMethod = null; - for (int i=0; i 0) { - return staticFields[0].field.getContainingClass(); - } - if (instanceFields != null && instanceFields.length > 0) { - return instanceFields[0].field.getContainingClass(); - } - if (directMethods != null && directMethods.length > 0) { - return directMethods[0].method.getContainingClass(); - } - if (virtualMethods != null && virtualMethods.length > 0) { - return virtualMethods[0].method.getContainingClass(); - } - return null; - } - - /** - * @return the static fields for this class - */ - @Nonnull - public List getStaticFields() { - if (staticFields == null) { - return Collections.emptyList(); - } - return ReadOnlyArrayList.of(staticFields); - } - - /** - * @return the instance fields for this class - */ - @Nonnull - public List getInstanceFields() { - if (instanceFields == null) { - return Collections.emptyList(); - } - return ReadOnlyArrayList.of(instanceFields); - } - - /** - * @return the direct methods for this class - */ - @Nonnull - public List getDirectMethods() { - if (directMethods == null) { - return Collections.emptyList(); - } - return ReadOnlyArrayList.of(directMethods); - } - - /** - * @return the virtual methods for this class - */ - @Nonnull - public List getVirtualMethods() { - if (virtualMethods == null) { - return Collections.emptyList(); - } - return ReadOnlyArrayList.of(virtualMethods); - } - - /** - * @return The number of static fields in this ClassDataItem - */ - public int getStaticFieldCount() { - if (staticFields == null) { - return 0; - } - return staticFields.length; - } - - /** - * @return The number of instance fields in this ClassDataItem - */ - public int getInstanceFieldCount() { - if (instanceFields == null) { - return 0; - } - return instanceFields.length; - } - - /** - * @return The number of direct methods in this ClassDataItem - */ - public int getDirectMethodCount() { - if (directMethods == null) { - return 0; - } - return directMethods.length; - } - - /** - * @return The number of virtual methods in this ClassDataItem - */ - public int getVirtualMethodCount() { - if (virtualMethods == null) { - return 0; - } - return virtualMethods.length; - } - - /** - * @return true if this is an empty ClassDataItem - */ - public boolean isEmpty() { - return (getStaticFieldCount() + getInstanceFieldCount() + - getDirectMethodCount() + getVirtualMethodCount()) == 0; - } - - /** - * Performs a binary search for the definition of the specified direct method - * @param methodIdItem The MethodIdItem of the direct method to search for - * @return The EncodedMethod for the specified direct method, or null if not found - */ - public EncodedMethod findDirectMethodByMethodId(MethodIdItem methodIdItem) { - return findMethodByMethodIdInternal(methodIdItem.index, directMethods); - } - - /** - * Performs a binary search for the definition of the specified virtual method - * @param methodIdItem The MethodIdItem of the virtual method to search for - * @return The EncodedMethod for the specified virtual method, or null if not found - */ - public EncodedMethod findVirtualMethodByMethodId(MethodIdItem methodIdItem) { - return findMethodByMethodIdInternal(methodIdItem.index, virtualMethods); - } - - /** - * Performs a binary search for the definition of the specified method. It can be either direct or virtual - * @param methodIdItem The MethodIdItem of the virtual method to search for - * @return The EncodedMethod for the specified virtual method, or null if not found - */ - public EncodedMethod findMethodByMethodId(MethodIdItem methodIdItem) { - EncodedMethod encodedMethod = findMethodByMethodIdInternal(methodIdItem.index, directMethods); - if (encodedMethod != null) { - return encodedMethod; - } - - return findMethodByMethodIdInternal(methodIdItem.index, virtualMethods); - } - - private static EncodedMethod findMethodByMethodIdInternal(int methodIdItemIndex, EncodedMethod[] encodedMethods) { - int min = 0; - int max = encodedMethods.length; - - while (min>1; - - EncodedMethod encodedMethod = encodedMethods[index]; - - int encodedMethodIndex = encodedMethod.method.getIndex(); - if (encodedMethodIndex == methodIdItemIndex) { - return encodedMethod; - } else if (encodedMethodIndex < methodIdItemIndex) { - if (min == index) { - break; - } - min = index; - } else { - if (max == index) { - break; - } - max = index; - } - } - - return null; - } - - public static class EncodedField implements Comparable { - /** - * The FieldIdItem that this EncodedField is associated with - */ - public final FieldIdItem field; - - /** - * The access flags for this field - */ - public final int accessFlags; - - /** - * Constructs a new EncodedField with the given values - * @param field The FieldIdItem that this EncodedField is associated with - * @param accessFlags The access flags for this field - */ - public EncodedField(FieldIdItem field, int accessFlags) { - this.field = field; - this.accessFlags = accessFlags; - } - - /** - * This is used internally to construct a new EncodedField while reading in a DexFile - * @param dexFile The DexFile that is being read in - * @param in the Input object to read the EncodedField from - * @param previousEncodedField The previous EncodedField in the list containing this - * EncodedField. - */ - private EncodedField(DexFile dexFile, Input in, @Nullable EncodedField previousEncodedField) { - int previousIndex = previousEncodedField==null?0:previousEncodedField.field.getIndex(); - field = dexFile.FieldIdsSection.getItemByIndex(in.readUnsignedLeb128() + previousIndex); - accessFlags = in.readUnsignedLeb128(); - } - - /** - * Writes the EncodedField to the given AnnotatedOutput object - * @param out the AnnotatedOutput object to write to - * @param previousEncodedField The previous EncodedField in the list containing this - * EncodedField. - */ - private void writeTo(AnnotatedOutput out, EncodedField previousEncodedField) { - int previousIndex = previousEncodedField==null?0:previousEncodedField.field.getIndex(); - - if (out.annotates()) { - out.annotate("field: " + field.getFieldString()); - out.writeUnsignedLeb128(field.getIndex() - previousIndex); - out.annotate("access_flags: " + AccessFlags.formatAccessFlagsForField(accessFlags)); - out.writeUnsignedLeb128(accessFlags); - }else { - out.writeUnsignedLeb128(field.getIndex() - previousIndex); - out.writeUnsignedLeb128(accessFlags); - } - } - - /** - * Calculates the size of this EncodedField and returns the offset - * immediately following it - * @param offset the offset of this EncodedField in the DexFile - * @param previousEncodedField The previous EncodedField in the list containing this - * EncodedField. - * @return the offset immediately following this EncodedField - */ - private int place(int offset, EncodedField previousEncodedField) { - int previousIndex = previousEncodedField==null?0:previousEncodedField.field.getIndex(); - - offset += Leb128Utils.unsignedLeb128Size(field.getIndex() - previousIndex); - offset += Leb128Utils.unsignedLeb128Size(accessFlags); - return offset; - } - - /** - * Compares this EncodedField to another, based on the comparison of the associated - * FieldIdItem - * @param other The EncodedField to compare against - * @return a standard integer comparison value indicating the relationship - */ - public int compareTo(EncodedField other) - { - return field.compareTo(other.field); - } - - /** - * Determines if this EncodedField is equal to other, based on the equality of the associated - * FieldIdItem - * @param other The EncodedField to test for equality - * @return true if other is equal to this instance, otherwise false - */ - public boolean equals(Object other) { - if (other instanceof EncodedField) { - return compareTo((EncodedField)other) == 0; - } - return false; - } - - /** - * @return true if this is a static field - */ - public boolean isStatic() { - return (accessFlags & AccessFlags.STATIC.getValue()) != 0; - } - } - - public static class EncodedMethod implements Comparable { - /** - * The MethodIdItem that this EncodedMethod is associated with - */ - public final MethodIdItem method; - - /** - * The access flags for this method - */ - public final int accessFlags; - - /** - * The CodeItem containing the code for this method, or null if there is no code for this method - * (i.e. an abstract method) - */ - public final CodeItem codeItem; - - /** - * Constructs a new EncodedMethod with the given values - * @param method The MethodIdItem that this EncodedMethod is associated with - * @param accessFlags The access flags for this method - * @param codeItem The CodeItem containing the code for this method, or null if there is no code - * for this method (i.e. an abstract method) - */ - public EncodedMethod(MethodIdItem method, int accessFlags, CodeItem codeItem) { - this.method = method; - this.accessFlags = accessFlags; - this.codeItem = codeItem; - if (codeItem != null) { - codeItem.setParent(this); - } - } - - /** - * This is used internally to construct a new EncodedMethod while reading in a DexFile - * @param dexFile The DexFile that is being read in - * @param readContext a ReadContext object to hold information that is only needed while reading - * in a file - * @param in the Input object to read the EncodedMethod from - * @param previousEncodedMethod The previous EncodedMethod in the list containing this - * EncodedMethod. - */ - public EncodedMethod(DexFile dexFile, ReadContext readContext, Input in, EncodedMethod previousEncodedMethod) { - int previousIndex = previousEncodedMethod==null?0:previousEncodedMethod.method.getIndex(); - method = dexFile.MethodIdsSection.getItemByIndex(in.readUnsignedLeb128() + previousIndex); - accessFlags = in.readUnsignedLeb128(); - if (dexFile.skipInstructions()) { - in.readUnsignedLeb128(); - codeItem = null; - } else { - codeItem = (CodeItem)readContext.getOptionalOffsettedItemByOffset(ItemType.TYPE_CODE_ITEM, - in.readUnsignedLeb128()); - } - if (codeItem != null) { - codeItem.setParent(this); - } - } - - /** - * Writes the EncodedMethod to the given AnnotatedOutput object - * @param out the AnnotatedOutput object to write to - * @param previousEncodedMethod The previous EncodedMethod in the list containing this - * EncodedMethod. - */ - private void writeTo(AnnotatedOutput out, EncodedMethod previousEncodedMethod) { - int previousIndex = previousEncodedMethod==null?0:previousEncodedMethod.method.getIndex(); - - if (out.annotates()) { - out.annotate("method: " + method.getMethodString()); - out.writeUnsignedLeb128(method.getIndex() - previousIndex); - out.annotate("access_flags: " + AccessFlags.formatAccessFlagsForMethod(accessFlags)); - out.writeUnsignedLeb128(accessFlags); - if (codeItem != null) { - out.annotate("code_off: 0x" + Integer.toHexString(codeItem.getOffset())); - out.writeUnsignedLeb128(codeItem.getOffset()); - } else { - out.annotate("code_off: 0x0"); - out.writeUnsignedLeb128(0); - } - }else { - out.writeUnsignedLeb128(method.getIndex() - previousIndex); - out.writeUnsignedLeb128(accessFlags); - out.writeUnsignedLeb128(codeItem==null?0:codeItem.getOffset()); - } - } - - /** - * Calculates the size of this EncodedMethod and returns the offset - * immediately following it - * @param offset the offset of this EncodedMethod in the DexFile - * @param previousEncodedMethod The previous EncodedMethod in the list containing this - * EncodedMethod. - * @return the offset immediately following this EncodedField - */ - private int place(int offset, EncodedMethod previousEncodedMethod) { - int previousIndex = previousEncodedMethod==null?0:previousEncodedMethod.method.getIndex(); - - offset += Leb128Utils.unsignedLeb128Size(method.getIndex() - previousIndex); - offset += Leb128Utils.unsignedLeb128Size(accessFlags); - offset += codeItem==null?1:Leb128Utils.unsignedLeb128Size(codeItem.getOffset()); - return offset; - } - - /** - * Compares this EncodedMethod to another, based on the comparison of the associated - * MethodIdItem - * @param other The EncodedMethod to compare against - * @return a standard integer comparison value indicating the relationship - */ - public int compareTo(EncodedMethod other) { - return method.compareTo(other.method); - } - - /** - * Determines if this EncodedMethod is equal to other, based on the equality of the associated - * MethodIdItem - * @param other The EncodedMethod to test for equality - * @return true if other is equal to this instance, otherwise false - */ - public boolean equals(Object other) { - if (other instanceof EncodedMethod) { - return compareTo((EncodedMethod)other) == 0; - } - return false; - } - - /** - * @return true if this is a direct method - */ - public boolean isDirect() { - return ((accessFlags & (AccessFlags.STATIC.getValue() | AccessFlags.PRIVATE.getValue() | - AccessFlags.CONSTRUCTOR.getValue())) != 0); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ClassDefItem.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ClassDefItem.java deleted file mode 100644 index 9664b997..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ClassDefItem.java +++ /dev/null @@ -1,374 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.dexlib.EncodedValue.ArrayEncodedSubValue; -import org.jf.dexlib.EncodedValue.EncodedValue; -import org.jf.dexlib.Util.AccessFlags; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; -import org.jf.dexlib.Util.TypeUtils; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.*; - -public class ClassDefItem extends Item { - private TypeIdItem classType; - private int accessFlags; - private @Nullable TypeIdItem superType; - private @Nullable TypeListItem implementedInterfaces; - private @Nullable StringIdItem sourceFile; - private @Nullable AnnotationDirectoryItem annotations; - private @Nullable ClassDataItem classData; - private @Nullable EncodedArrayItem staticFieldInitializers; - - /** - * Creates a new uninitialized ClassDefItem - * @param dexFile The DexFile that this item belongs to - */ - protected ClassDefItem(DexFile dexFile) { - super(dexFile); - } - - /** - * Creates a new ClassDefItem with the given values - * @param dexFile The DexFile that this item belongs to - * @param classType The type of this class - * @param accessFlags The access flags of this class - * @param superType The superclass of this class, or null if none (only valid for java.lang.Object) - * @param implementedInterfaces A list of the interfaces that this class implements, or null if none - * @param sourceFile The main source file that this class is defined in, or null if not available - * @param annotations The annotations for this class and its fields, methods and method parameters, or null if none - * @param classData The ClassDataItem containing the method and field definitions for this class - * @param staticFieldInitializers The initial values for this class's static fields, or null if none. The initial - * values should be in the same order as the static fields in the ClassDataItem. It can contain - * fewer items than static fields, in which case the remaining static fields will be initialized with a default - * value of null/0. The initial value for any fields that don't specifically have a value can be either the - * type-appropriate null/0 encoded value, or null. - */ - private ClassDefItem(DexFile dexFile, TypeIdItem classType, int accessFlags, @Nullable TypeIdItem superType, - @Nullable TypeListItem implementedInterfaces, @Nullable StringIdItem sourceFile, - @Nullable AnnotationDirectoryItem annotations, @Nullable ClassDataItem classData, - @Nullable EncodedArrayItem staticFieldInitializers) { - super(dexFile); - assert classType != null; - this.classType = classType; - this.accessFlags = accessFlags; - this.superType = superType; - this.implementedInterfaces = implementedInterfaces; - this.sourceFile = sourceFile; - this.annotations = annotations; - this.classData = classData; - this.staticFieldInitializers = staticFieldInitializers; - } - - /** - * Returns a ClassDefItem for the given values, and that has been interned into the given - * DexFile - * @param dexFile The DexFile that this item belongs to - * @param classType The type of this class - * @param accessFlags The access flags of this class - * @param superType The superclass of this class, or null if none (only valid for java.lang.Object) - * @param implementedInterfaces A list of the interfaces that this class implements, or null if none - * @param sourceFile The main source file that this class is defined in, or null if not available - * @param annotations The annotations for this class and its fields, methods and method parameters, or null if none - * @param classData The ClassDataItem containing the method and field definitions for this class - * @param staticFieldInitializers The initial values for this class's static fields, or null if none. If it is not - * null, it must contain the same number of items as the number of static fields in this class. The value in the - * StaticFieldInitializer for any field that doesn't have an explicit initial value can either be null - * or be the type-appropriate null/0 value. - * @return a ClassDefItem for the given values, and that has been interned into the given - * DexFile - */ - public static ClassDefItem internClassDefItem(DexFile dexFile, TypeIdItem classType, int accessFlags, - @Nullable TypeIdItem superType, @Nullable TypeListItem implementedInterfaces, - @Nullable StringIdItem sourceFile, @Nullable AnnotationDirectoryItem annotations, - @Nullable ClassDataItem classData, - @Nullable List staticFieldInitializers) { - EncodedArrayItem encodedArrayItem = null; - if(!dexFile.getInplace() && staticFieldInitializers != null && staticFieldInitializers.size() > 0) { - assert classData != null; - assert staticFieldInitializers.size() == classData.getStaticFieldCount(); - encodedArrayItem = makeStaticFieldInitializersItem(dexFile, staticFieldInitializers); - } - - ClassDefItem classDefItem = new ClassDefItem(dexFile, classType, accessFlags, superType, implementedInterfaces, - sourceFile, annotations, classData, encodedArrayItem); - return dexFile.ClassDefsSection.intern(classDefItem); - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - classType = dexFile.TypeIdsSection.getItemByIndex(in.readInt()); - accessFlags = in.readInt(); - superType = dexFile.TypeIdsSection.getOptionalItemByIndex(in.readInt()); - implementedInterfaces = (TypeListItem)readContext.getOptionalOffsettedItemByOffset(ItemType.TYPE_TYPE_LIST, - in.readInt()); - sourceFile = dexFile.StringIdsSection.getOptionalItemByIndex(in.readInt()); - annotations = (AnnotationDirectoryItem)readContext.getOptionalOffsettedItemByOffset( - ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM, in.readInt()); - classData = (ClassDataItem)readContext.getOptionalOffsettedItemByOffset(ItemType.TYPE_CLASS_DATA_ITEM, in.readInt()); - staticFieldInitializers = (EncodedArrayItem)readContext.getOptionalOffsettedItemByOffset( - ItemType.TYPE_ENCODED_ARRAY_ITEM, in.readInt()); - } - - /** {@inheritDoc} */ - protected int placeItem(int offset) { - return offset + 32; - } - - /** {@inheritDoc} */ - protected void writeItem(AnnotatedOutput out) { - if (out.annotates()) { - out.annotate(4, "class_type: " + classType.getTypeDescriptor()); - out.annotate(4, "access_flags: " + AccessFlags.formatAccessFlagsForClass(accessFlags)); - out.annotate(4, "superclass_type: " + (superType==null?"":superType.getTypeDescriptor())); - out.annotate(4, "interfaces: " + - (implementedInterfaces==null?"":implementedInterfaces.getTypeListString(" "))); - out.annotate(4, "source_file: " + (sourceFile==null?"":sourceFile.getStringValue())); - out.annotate(4, "annotations_off: " + - (annotations==null?"":"0x"+Integer.toHexString(annotations.getOffset()))); - out.annotate(4, "class_data_off:" + - (classData==null?"":"0x"+Integer.toHexString(classData.getOffset()))); - out.annotate(4, "static_values_off: " + - (staticFieldInitializers==null?"":"0x"+Integer.toHexString(staticFieldInitializers.getOffset()))); - } - out.writeInt(classType.getIndex()); - out.writeInt(accessFlags); - out.writeInt(superType==null?-1:superType.getIndex()); - out.writeInt(implementedInterfaces==null?0:implementedInterfaces.getOffset()); - out.writeInt(sourceFile==null?-1:sourceFile.getIndex()); - out.writeInt(annotations==null?0:annotations.getOffset()); - out.writeInt(classData==null?0:classData.getOffset()); - out.writeInt(staticFieldInitializers==null?0:staticFieldInitializers.getOffset()); - } - - /** {@inheritDoc} */ - public ItemType getItemType() { - return ItemType.TYPE_CLASS_DEF_ITEM; - } - - /** {@inheritDoc} */ - public String getConciseIdentity() { - return "class_def_item: " + classType.getTypeDescriptor(); - } - - /** {@inheritDoc} */ - public int compareTo(ClassDefItem o) { - //The actual sorting for this class is done during the placement phase, in ClassDefPlacer. - //This method is just used for sorting the associated ClassDataItem items after the ClassDefItems have been - //placed, so we can just do the comparison based on the offsets - return this.getOffset() - o.getOffset(); - } - - public TypeIdItem getClassType() { - return classType; - } - - public int getAccessFlags() { - return accessFlags; - } - - @Nullable - public TypeIdItem getSuperclass() { - return superType; - } - - @Nullable - public TypeListItem getInterfaces() { - return implementedInterfaces; - } - - @Nullable - public StringIdItem getSourceFile() { - return sourceFile; - } - - @Nullable - public AnnotationDirectoryItem getAnnotations() { - return annotations; - } - - @Nullable - public ClassDataItem getClassData() { - return classData; - } - - @Nullable - public EncodedArrayItem getStaticFieldInitializers() { - return staticFieldInitializers; - } - - public static int placeClassDefItems(IndexedSection section, int offset) { - ClassDefPlacer cdp = new ClassDefPlacer(section); - return cdp.placeSection(offset); - } - - /** - * This class places the items within a ClassDefItem section, such that superclasses and interfaces are - * placed before sub/implementing classes - */ - private static class ClassDefPlacer { - private final IndexedSection section; - private final HashMap unplacedClassDefsByType = - new HashMap(); - - private int currentIndex = 0; - private int currentOffset; - - public ClassDefPlacer(IndexedSection section) { - this.section = section; - - for (ClassDefItem classDefItem: section.items) { - TypeIdItem typeIdItem = classDefItem.classType; - unplacedClassDefsByType.put(typeIdItem, classDefItem); - } - } - - public int placeSection(int offset) { - currentOffset = offset; - - if (section.DexFile.getSortAllItems()) { - //presort the list, to guarantee a unique ordering - Collections.sort(section.items, new Comparator() { - public int compare(ClassDefItem a, ClassDefItem b) { - return a.getClassType().compareTo(b.getClassType()); - } - }); - } - - //we need to initialize the offset for all the classes to -1, so we can tell which ones - //have been placed - for (ClassDefItem classDefItem: section.items) { - classDefItem.offset = -1; - } - - for (ClassDefItem classDefItem: section.items) { - placeClass(classDefItem); - } - - for (ClassDefItem classDefItem: unplacedClassDefsByType.values()) { - section.items.set(classDefItem.getIndex(), classDefItem); - } - - return currentOffset; - } - - private void placeClass(ClassDefItem classDefItem) { - if (!classDefItem.isPlaced()) { - TypeIdItem superType = classDefItem.superType; - ClassDefItem superClassDefItem = unplacedClassDefsByType.get(superType); - - if (superClassDefItem != null) { - placeClass(superClassDefItem); - } - - TypeListItem interfaces = classDefItem.implementedInterfaces; - - if (interfaces != null) { - for (TypeIdItem interfaceType: interfaces.getTypes()) { - ClassDefItem interfaceClass = unplacedClassDefsByType.get(interfaceType); - if (interfaceClass != null) { - placeClass(interfaceClass); - } - } - } - - currentOffset = classDefItem.placeAt(currentOffset, currentIndex++); - unplacedClassDefsByType.remove(classDefItem.classType); - } - } - } - - public static class StaticFieldInitializer implements Comparable { - public final EncodedValue value; - public final ClassDataItem.EncodedField field; - public StaticFieldInitializer(EncodedValue value, ClassDataItem.EncodedField field) { - this.value = value; - this.field = field; - } - - public int compareTo(StaticFieldInitializer other) { - return field.compareTo(other.field); - } - } - - - /** - * A helper method to sort the static field initializers and populate the default values as needed - * @param dexFile the DexFile - * @param staticFieldInitializers the initial values - * @return an interned EncodedArrayItem containing the static field initializers - */ - private static EncodedArrayItem makeStaticFieldInitializersItem(DexFile dexFile, - @Nonnull List staticFieldInitializers) { - if (staticFieldInitializers.size() == 0) { - return null; - } - - int len = staticFieldInitializers.size(); - - // make a copy before sorting. we don't want to modify the list passed to us - staticFieldInitializers = new ArrayList(staticFieldInitializers); - Collections.sort(staticFieldInitializers); - - int lastIndex = -1; - for (int i=len-1; i>=0; i--) { - StaticFieldInitializer staticFieldInitializer = staticFieldInitializers.get(i); - - if (staticFieldInitializer.value != null && - (staticFieldInitializer.value.compareTo(TypeUtils.makeDefaultValueForType( - staticFieldInitializer.field.field.getFieldType())) != 0)) { - lastIndex = i; - break; - } - } - - //we don't have any non-null/non-default values, so we don't need to create an EncodedArrayItem - if (lastIndex == -1) { - return null; - } - - EncodedValue[] values = new EncodedValue[lastIndex+1]; - - for (int i=0; i<=lastIndex; i++) { - StaticFieldInitializer staticFieldInitializer = staticFieldInitializers.get(i); - EncodedValue encodedValue = staticFieldInitializer.value; - if (encodedValue == null) { - encodedValue = TypeUtils.makeDefaultValueForType(staticFieldInitializer.field.field.getFieldType()); - } - - values[i] = encodedValue; - } - - ArrayEncodedSubValue encodedArrayValue = new ArrayEncodedSubValue(values); - return EncodedArrayItem.internEncodedArrayItem(dexFile, encodedArrayValue); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/AnalyzedInstruction.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/AnalyzedInstruction.java deleted file mode 100644 index a285b873..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/AnalyzedInstruction.java +++ /dev/null @@ -1,343 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Analysis; - -import org.jf.dexlib.Code.*; -import org.jf.dexlib.Item; -import org.jf.dexlib.ItemType; -import org.jf.dexlib.MethodIdItem; -import org.jf.util.ExceptionWithContext; - -import java.util.*; - -public class AnalyzedInstruction implements Comparable { - /** - * The actual instruction - */ - protected Instruction instruction; - - /** - * The index of the instruction, where the first instruction in the method is at index 0, and so on - */ - protected final int instructionIndex; - - /** - * Instructions that can pass on execution to this one during normal execution - */ - protected final TreeSet predecessors = new TreeSet(); - - /** - * Instructions that can execution could pass on to next during normal execution - */ - protected final LinkedList successors = new LinkedList(); - - /** - * This contains the register types *before* the instruction has executed - */ - protected final RegisterType[] preRegisterMap; - - /** - * This contains the register types *after* the instruction has executed - */ - protected final RegisterType[] postRegisterMap; - - /** - * When deodexing, we might need to deodex this instruction multiple times, when we merge in new register - * information. When this happens, we need to restore the original (odexed) instruction, so we can deodex it again - */ - protected final Instruction originalInstruction; - - /** - * An analyzed instruction's "deadness" is set during analysis (i.e. MethodAnalyzer.analyzer()). A dead instruction - * is one that the analyzer never reaches. This occurs either with natural "dead code" - code that simply has no - * code path that can ever reach it, or code that follows an odexed instruction that can't be deodexed. - */ - protected boolean dead = false; - - public AnalyzedInstruction(Instruction instruction, int instructionIndex, int registerCount) { - this.instruction = instruction; - this.originalInstruction = instruction; - this.instructionIndex = instructionIndex; - this.postRegisterMap = new RegisterType[registerCount]; - this.preRegisterMap = new RegisterType[registerCount]; - RegisterType unknown = RegisterType.getRegisterType(RegisterType.Category.Unknown, null); - for (int i=0; i getPredecessors() { - return Collections.unmodifiableSortedSet(predecessors); - } - - protected boolean addPredecessor(AnalyzedInstruction predecessor) { - return predecessors.add(predecessor); - } - - protected void addSuccessor(AnalyzedInstruction successor) { - successors.add(successor); - } - - protected void setDeodexedInstruction(Instruction instruction) { - assert originalInstruction.opcode.odexOnly(); - this.instruction = instruction; - } - - protected void restoreOdexedInstruction() { - assert originalInstruction.opcode.odexOnly(); - instruction = originalInstruction; - } - - public int getSuccessorCount() { - return successors.size(); - } - - public List getSuccesors() { - return Collections.unmodifiableList(successors); - } - - public Instruction getInstruction() { - return instruction; - } - - public Instruction getOriginalInstruction() { - return originalInstruction; - } - - public boolean isDead() { - return dead; - } - - /** - * Is this instruction a "beginning instruction". A beginning instruction is defined to be an instruction - * that can be the first successfully executed instruction in the method. The first instruction is always a - * beginning instruction. If the first instruction can throw an exception, and is covered by a try block, then - * the first instruction of any exception handler for that try block is also a beginning instruction. And likewise, - * if any of those instructions can throw an exception and are covered by try blocks, the first instruction of the - * corresponding exception handler is a beginning instruction, etc. - * - * To determine this, we simply check if the first predecessor is the fake "StartOfMethod" instruction, which has - * an instruction index of -1. - * @return a boolean value indicating whether this instruction is a beginning instruction - */ - public boolean isBeginningInstruction() { - //if this instruction has no predecessors, it is either the fake "StartOfMethod" instruction or it is an - //unreachable instruction. - if (predecessors.size() == 0) { - return false; - } - - if (predecessors.first().instructionIndex == -1) { - return true; - } - return false; - } - - /* - * Merges the given register type into the specified pre-instruction register, and also sets the post-instruction - * register type accordingly if it isn't a destination register for this instruction - * @param registerNumber Which register to set - * @param registerType The register type - * @returns true If the post-instruction register type was changed. This might be false if either the specified - * register is a destination register for this instruction, or if the pre-instruction register type didn't change - * after merging in the given register type - */ - protected boolean mergeRegister(int registerNumber, RegisterType registerType, BitSet verifiedInstructions) { - assert registerNumber >= 0 && registerNumber < postRegisterMap.length; - assert registerType != null; - - RegisterType oldRegisterType = preRegisterMap[registerNumber]; - RegisterType mergedRegisterType = oldRegisterType.merge(registerType); - - if (mergedRegisterType == oldRegisterType) { - return false; - } - - preRegisterMap[registerNumber] = mergedRegisterType; - verifiedInstructions.clear(instructionIndex); - - if (!setsRegister(registerNumber)) { - postRegisterMap[registerNumber] = mergedRegisterType; - return true; - } - - return false; - } - - /** - * Iterates over the predecessors of this instruction, and merges all the post-instruction register types for the - * given register. Any dead, unreachable, or odexed predecessor is ignored - * @param registerNumber the register number - * @return The register type resulting from merging the post-instruction register types from all predecessors - */ - protected RegisterType mergePreRegisterTypeFromPredecessors(int registerNumber) { - RegisterType mergedRegisterType = null; - for (AnalyzedInstruction predecessor: predecessors) { - RegisterType predecessorRegisterType = predecessor.postRegisterMap[registerNumber]; - assert predecessorRegisterType != null; - mergedRegisterType = predecessorRegisterType.merge(mergedRegisterType); - } - return mergedRegisterType; - } - - /* - * Sets the "post-instruction" register type as indicated. - * @param registerNumber Which register to set - * @param registerType The "post-instruction" register type - * @returns true if the given register type is different than the existing post-instruction register type - */ - protected boolean setPostRegisterType(int registerNumber, RegisterType registerType) { - assert registerNumber >= 0 && registerNumber < postRegisterMap.length; - assert registerType != null; - - RegisterType oldRegisterType = postRegisterMap[registerNumber]; - if (oldRegisterType == registerType) { - return false; - } - - postRegisterMap[registerNumber] = registerType; - return true; - } - - - protected boolean isInvokeInit() { - if (instruction == null || !instruction.opcode.canInitializeReference()) { - return false; - } - - //TODO: check access flags instead of name? - - InstructionWithReference instruction = (InstructionWithReference)this.instruction; - Item item = instruction.getReferencedItem(); - assert item.getItemType() == ItemType.TYPE_METHOD_ID_ITEM; - MethodIdItem method = (MethodIdItem)item; - - if (!method.getMethodName().getStringValue().equals("")) { - return false; - } - - return true; - } - - public boolean setsRegister() { - return instruction.opcode.setsRegister(); - } - - public boolean setsWideRegister() { - return instruction.opcode.setsWideRegister(); - } - - public boolean setsRegister(int registerNumber) { - //When constructing a new object, the register type will be an uninitialized reference after the new-instance - //instruction, but becomes an initialized reference once the method is called. So even though invoke - //instructions don't normally change any registers, calling an method will change the type of its - //object register. If the uninitialized reference has been copied to other registers, they will be initialized - //as well, so we need to check for that too - if (isInvokeInit()) { - int destinationRegister; - if (instruction instanceof FiveRegisterInstruction) { - destinationRegister = ((FiveRegisterInstruction)instruction).getRegisterD(); - } else { - assert instruction instanceof RegisterRangeInstruction; - RegisterRangeInstruction rangeInstruction = (RegisterRangeInstruction)instruction; - assert rangeInstruction.getRegCount() > 0; - destinationRegister = rangeInstruction.getStartRegister(); - } - - if (registerNumber == destinationRegister) { - return true; - } - RegisterType preInstructionDestRegisterType = getPreInstructionRegisterType(registerNumber); - if (preInstructionDestRegisterType.category != RegisterType.Category.UninitRef && - preInstructionDestRegisterType.category != RegisterType.Category.UninitThis) { - - return false; - } - //check if the uninit ref has been copied to another register - if (getPreInstructionRegisterType(registerNumber) == preInstructionDestRegisterType) { - return true; - } - return false; - } - - if (!setsRegister()) { - return false; - } - int destinationRegister = getDestinationRegister(); - - if (registerNumber == destinationRegister) { - return true; - } - if (setsWideRegister() && registerNumber == (destinationRegister + 1)) { - return true; - } - return false; - } - - public int getDestinationRegister() { - if (!this.instruction.opcode.setsRegister()) { - throw new ExceptionWithContext("Cannot call getDestinationRegister() for an instruction that doesn't " + - "store a value"); - } - return ((SingleRegisterInstruction)instruction).getRegisterA(); - } - - public int getRegisterCount() { - return postRegisterMap.length; - } - - public RegisterType getPostInstructionRegisterType(int registerNumber) { - return postRegisterMap[registerNumber]; - } - - public RegisterType getPreInstructionRegisterType(int registerNumber) { - return preRegisterMap[registerNumber]; - } - - public int compareTo(AnalyzedInstruction analyzedInstruction) { - //TODO: out of curiosity, check the disassembly of this to see if it retrieves the value of analyzedInstruction.instructionIndex for every access. It should, because the field is final. What about if we set the field to non-final? - if (instructionIndex < analyzedInstruction.instructionIndex) { - return -1; - } else if (instructionIndex == analyzedInstruction.instructionIndex) { - return 0; - } else { - return 1; - } - } -} - diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/ClassPath.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/ClassPath.java deleted file mode 100644 index a1a93d6c..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/ClassPath.java +++ /dev/null @@ -1,1342 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Analysis; - -import org.jf.dexlib.*; -import org.jf.dexlib.Util.AccessFlags; -import org.jf.util.ExceptionWithContext; -import org.jf.dexlib.Util.SparseArray; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.io.File; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static org.jf.dexlib.ClassDataItem.EncodedField; -import static org.jf.dexlib.ClassDataItem.EncodedMethod; - -public class ClassPath { - private static ClassPath theClassPath = null; - - /** - * The current version of dalvik in master(AOSP) has a slight change to the way the - * virtual tables are computed. This should be set to true to use the new logic. - * TODO: set this based on api level, once it's present in a released version of Android - */ - private boolean checkPackagePrivateAccess; - - private final HashMap classDefs; - protected ClassDef javaLangObjectClassDef; //cached ClassDef for Ljava/lang/Object; - - // Contains the classes that we haven't loaded yet - private HashMap unloadedClasses; - - private static final Pattern dalvikCacheOdexPattern = Pattern.compile("@([^@]+)@classes.dex$"); - - /** - * Initialize the class path using the dependencies from an odex file - * @param classPathDirs The directories to search for boot class path files - * @param extraBootClassPathEntries any extra entries that should be added after the entries that are read - * from the odex file - * @param dexFilePath The path of the dex file (used for error reporting purposes only) - * @param dexFile The DexFile to load - it must represents an odex file - */ - public static void InitializeClassPathFromOdex(String[] classPathDirs, String[] extraBootClassPathEntries, - String dexFilePath, DexFile dexFile, - boolean checkPackagePrivateAccess) { - if (!dexFile.isOdex()) { - throw new ExceptionWithContext("Cannot use InitialiazeClassPathFromOdex with a non-odex DexFile"); - } - - if (theClassPath != null) { - throw new ExceptionWithContext("Cannot initialize ClassPath multiple times"); - } - - OdexDependencies odexDependencies = dexFile.getOdexDependencies(); - - String[] bootClassPath = new String[odexDependencies.getDependencyCount()]; - for (int i=0; i(); - } - - private void initClassPath(String[] classPathDirs, String[] bootClassPath, String[] extraBootClassPathEntries, - String dexFilePath, DexFile dexFile, boolean checkPackagePrivateAccess) { - this.checkPackagePrivateAccess = checkPackagePrivateAccess; - unloadedClasses = new LinkedHashMap(); - - if (bootClassPath != null) { - for (String bootClassPathEntry: bootClassPath) { - loadBootClassPath(classPathDirs, bootClassPathEntry); - } - } - - if (extraBootClassPathEntries != null) { - for (String bootClassPathEntry: extraBootClassPathEntries) { - loadBootClassPath(classPathDirs, bootClassPathEntry); - } - } - - if (dexFile != null) { - loadDexFile(dexFilePath, dexFile); - } - - javaLangObjectClassDef = getClassDef("Ljava/lang/Object;", false); - - for (String primitiveType: new String[]{"Z", "B", "S", "C", "I", "J", "F", "D"}) { - ClassDef classDef = new PrimitiveClassDef(primitiveType); - classDefs.put(primitiveType, classDef); - } - } - - private void loadBootClassPath(String[] classPathDirs, String bootClassPathEntry) { - for (String classPathDir: classPathDirs) { - File file = null; - DexFile dexFile = null; - - int extIndex = bootClassPathEntry.lastIndexOf("."); - - String baseEntry; - if (extIndex == -1) { - baseEntry = bootClassPathEntry; - } else { - baseEntry = bootClassPathEntry.substring(0, extIndex); - } - - for (String ext: new String[]{"", ".odex", ".jar", ".apk", ".zip"}) { - if (ext.length() == 0) { - file = new File(classPathDir, bootClassPathEntry); - } else { - file = new File(classPathDir, baseEntry + ext); - } - - if (file.exists()) { - if (!file.canRead()) { - System.err.println(String.format("warning: cannot open %s for reading. Will continue " + - "looking.", file.getPath())); - continue; - } - - try { - dexFile = new DexFile(file, false, true); - } catch (DexFile.NoClassesDexException ex) { - continue; - } catch (Exception ex) { - throw ExceptionWithContext.withContext(ex, "Error while reading boot class path entry \"" + - bootClassPathEntry + "\"."); - } - } - } - if (dexFile == null) { - continue; - } - - try { - loadDexFile(file.getPath(), dexFile); - } catch (Exception ex) { - throw ExceptionWithContext.withContext(ex, - String.format("Error while loading boot classpath entry %s", bootClassPathEntry)); - } - return; - } - throw new ExceptionWithContext(String.format("Cannot locate boot class path file %s", bootClassPathEntry)); - } - - private void loadDexFile(String dexFilePath, DexFile dexFile) { - for (ClassDefItem classDefItem: dexFile.ClassDefsSection.getItems()) { - try { - UnresolvedClassInfo unresolvedClassInfo = new UnresolvedClassInfo(dexFilePath, classDefItem); - - if (!unloadedClasses.containsKey(unresolvedClassInfo.classType)) { - unloadedClasses.put(unresolvedClassInfo.classType, unresolvedClassInfo); - } - } catch (Exception ex) { - throw ExceptionWithContext.withContext(ex, String.format("Error while loading class %s", - classDefItem.getClassType().getTypeDescriptor())); - } - } - } - - /** - * This method loads the given class (and any dependent classes, as needed), removing them from unloadedClasses - * @param classType the class to load - * @return the newly loaded ClassDef object for the given class, or null if the class cannot be found - */ - @Nullable - private static ClassDef loadClassDef(String classType) { - ClassDef classDef = null; - - UnresolvedClassInfo classInfo = theClassPath.unloadedClasses.get(classType); - if (classInfo == null) { - return null; - } - - try { - classDef = new ClassDef(classInfo); - theClassPath.classDefs.put(classDef.classType, classDef); - } catch (Exception ex) { - throw ExceptionWithContext.withContext(ex, String.format("Error while loading class %s from file %s", - classInfo.classType, classInfo.dexFilePath)); - } - theClassPath.unloadedClasses.remove(classType); - - return classDef; - } - - @Nonnull - public static ClassDef getClassDef(String classType, boolean createUnresolvedClassDef) { - ClassDef classDef = theClassPath.classDefs.get(classType); - if (classDef == null) { - //if it's an array class, try to create it - if (classType.charAt(0) == '[') { - return theClassPath.createArrayClassDef(classType); - } else { - try { - classDef = loadClassDef(classType); - if (classDef == null) { - throw new ExceptionWithContext( - String.format("Could not find definition for class %s", classType)); - } - } catch (Exception ex) { - RuntimeException exWithContext = ExceptionWithContext.withContext(ex, - String.format("Error while loading ClassPath class %s", classType)); - if (createUnresolvedClassDef) { - //TODO: add warning message - return theClassPath.createUnresolvedClassDef(classType); - } else { - throw exWithContext; - } - } - } - } - return classDef; - } - - public static ClassDef getClassDef(String classType) { - return getClassDef(classType, true); - } - - public static ClassDef getClassDef(TypeIdItem classType) { - return getClassDef(classType.getTypeDescriptor()); - } - - public static ClassDef getClassDef(TypeIdItem classType, boolean creatUnresolvedClassDef) { - return getClassDef(classType.getTypeDescriptor(), creatUnresolvedClassDef); - } - - //256 [ characters - private static final String arrayPrefix = "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + - "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + - "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["; - private static ClassDef getArrayClassDefByElementClassAndDimension(ClassDef classDef, int arrayDimension) { - return getClassDef(arrayPrefix.substring(256 - arrayDimension) + classDef.classType); - } - - private static ClassDef unresolvedObjectClassDef = null; - public static ClassDef getUnresolvedObjectClassDef() { - if (unresolvedObjectClassDef == null) { - unresolvedObjectClassDef = new UnresolvedClassDef("Ljava/lang/Object;"); - } - return unresolvedObjectClassDef; - } - - private ClassDef createUnresolvedClassDef(String classType) { - assert classType.charAt(0) == 'L'; - - UnresolvedClassDef unresolvedClassDef = new UnresolvedClassDef(classType); - classDefs.put(classType, unresolvedClassDef); - return unresolvedClassDef; - } - - private ClassDef createArrayClassDef(String arrayClassName) { - assert arrayClassName != null; - assert arrayClassName.charAt(0) == '['; - - ArrayClassDef arrayClassDef = new ArrayClassDef(arrayClassName); - if (arrayClassDef.elementClass == null) { - return null; - } - - classDefs.put(arrayClassName, arrayClassDef); - return arrayClassDef; - } - - public static ClassDef getCommonSuperclass(ClassDef class1, ClassDef class2) { - if (class1 == class2) { - return class1; - } - - if (class1 == null) { - return class2; - } - - if (class2 == null) { - return class1; - } - - //TODO: do we want to handle primitive types here? I don't think so.. (if not, add assert) - - if (class2.isInterface) { - if (class1.implementsInterface(class2)) { - return class2; - } - return theClassPath.javaLangObjectClassDef; - } - - if (class1.isInterface) { - if (class2.implementsInterface(class1)) { - return class1; - } - return theClassPath.javaLangObjectClassDef; - } - - if (class1 instanceof ArrayClassDef && class2 instanceof ArrayClassDef) { - return getCommonArraySuperclass((ArrayClassDef)class1, (ArrayClassDef)class2); - } - - //we've got two non-array reference types. Find the class depth of each, and then move up the longer one - //so that both classes are at the same class depth, and then move each class up until they match - - //we don't strictly need to keep track of the class depth separately, but it's probably slightly faster - //to do so, rather than calling getClassDepth() many times - int class1Depth = class1.getClassDepth(); - int class2Depth = class2.getClassDepth(); - - while (class1Depth > class2Depth) { - class1 = class1.superclass; - class1Depth--; - } - - while (class2Depth > class1Depth) { - class2 = class2.superclass; - class2Depth--; - } - - while (class1Depth > 0) { - if (class1 == class2) { - return class1; - } - class1 = class1.superclass; - class1Depth--; - class2 = class2.superclass; - class2Depth--; - } - - return class1; - } - - private static ClassDef getCommonArraySuperclass(ArrayClassDef class1, ArrayClassDef class2) { - assert class1 != class2; - - //If one of the arrays is a primitive array, then the only option is to return java.lang.Object - //TODO: might it be possible to merge something like int[] and short[] into int[]? (I don't think so..) - if (class1.elementClass instanceof PrimitiveClassDef || class2.elementClass instanceof PrimitiveClassDef) { - return theClassPath.javaLangObjectClassDef; - } - - //if the two arrays have the same number of dimensions, then we should return an array class with the - //same number of dimensions, for the common superclass of the 2 element classes - if (class1.arrayDimensions == class2.arrayDimensions) { - ClassDef commonElementClass; - if (class1.elementClass instanceof UnresolvedClassDef || - class2.elementClass instanceof UnresolvedClassDef) { - commonElementClass = ClassPath.getUnresolvedObjectClassDef(); - } else { - commonElementClass = getCommonSuperclass(class1.elementClass, class2.elementClass); - } - return getArrayClassDefByElementClassAndDimension(commonElementClass, class1.arrayDimensions); - } - - //something like String[][][] and String[][] should be merged to Object[][] - //this also holds when the element classes aren't the same (but are both reference types) - int dimensions = Math.min(class1.arrayDimensions, class2.arrayDimensions); - return getArrayClassDefByElementClassAndDimension(theClassPath.javaLangObjectClassDef, dimensions); - } - - public static class ArrayClassDef extends ClassDef { - private final ClassDef elementClass; - private final int arrayDimensions; - - protected ArrayClassDef(String arrayClassType) { - super(arrayClassType, ClassDef.ArrayClassDef); - assert arrayClassType.charAt(0) == '['; - - int i=0; - while (arrayClassType.charAt(i) == '[') i++; - - String elementClassType = arrayClassType.substring(i); - - if (i>256) { - throw new ExceptionWithContext("Error while creating array class for element type " + elementClassType + - " with " + i + " dimensions. The maximum number of dimensions is 256"); - } - - try { - elementClass = ClassPath.getClassDef(arrayClassType.substring(i)); - } catch (Exception ex) { - throw ExceptionWithContext.withContext(ex, "Error while creating array class " + arrayClassType); - } - arrayDimensions = i; - } - - /** - * Returns the "base" element class of the array. - * - * For example, for a multi-dimensional array of strings ([[Ljava/lang/String;), this method would return - * Ljava/lang/String; - * @return the "base" element class of the array - */ - public ClassDef getBaseElementClass() { - return elementClass; - } - - /** - * Returns the "immediate" element class of the array. - * - * For example, for a multi-dimensional array of stings with 2 dimensions ([[Ljava/lang/String;), this method - * would return [Ljava/lang/String; - * @return the immediate element class of the array - */ - public ClassDef getImmediateElementClass() { - if (arrayDimensions == 1) { - return elementClass; - } - return getArrayClassDefByElementClassAndDimension(elementClass, arrayDimensions - 1); - } - - public int getArrayDimensions() { - return arrayDimensions; - } - - @Override - public boolean extendsClass(ClassDef superclassDef) { - if (!(superclassDef instanceof ArrayClassDef)) { - if (superclassDef == ClassPath.theClassPath.javaLangObjectClassDef) { - return true; - } else if (superclassDef.isInterface) { - return this.implementsInterface(superclassDef); - } - return false; - } - - ArrayClassDef arraySuperclassDef = (ArrayClassDef)superclassDef; - if (this.arrayDimensions == arraySuperclassDef.arrayDimensions) { - ClassDef baseElementClass = arraySuperclassDef.getBaseElementClass(); - - if (baseElementClass.isInterface) { - return true; - } - - return baseElementClass.extendsClass(arraySuperclassDef.getBaseElementClass()); - } else if (this.arrayDimensions > arraySuperclassDef.arrayDimensions) { - ClassDef baseElementClass = arraySuperclassDef.getBaseElementClass(); - if (baseElementClass.isInterface) { - return true; - } - - if (baseElementClass == ClassPath.theClassPath.javaLangObjectClassDef) { - return true; - } - return false; - } - return false; - } - } - - public static class PrimitiveClassDef extends ClassDef { - protected PrimitiveClassDef(String primitiveClassType) { - super(primitiveClassType, ClassDef.PrimitiveClassDef); - assert primitiveClassType.charAt(0) != 'L' && primitiveClassType.charAt(0) != '['; - } - } - - public static class UnresolvedClassDef extends ClassDef { - protected UnresolvedClassDef(String unresolvedClassDef) { - super(unresolvedClassDef, ClassDef.UnresolvedClassDef); - assert unresolvedClassDef.charAt(0) == 'L'; - } - - protected ValidationException unresolvedValidationException() { - return new ValidationException(String.format("class %s cannot be resolved.", this.getClassType())); - } - - public ClassDef getSuperclass() { - throw unresolvedValidationException(); - } - - public int getClassDepth() { - throw unresolvedValidationException(); - } - - public boolean isInterface() { - throw unresolvedValidationException(); - } - - public boolean extendsClass(ClassDef superclassDef) { - if (superclassDef != theClassPath.javaLangObjectClassDef && superclassDef != this) { - throw unresolvedValidationException(); - } - return true; - } - - public boolean implementsInterface(ClassDef interfaceDef) { - throw unresolvedValidationException(); - } - - public boolean hasVirtualMethod(String method) { - if (!super.hasVirtualMethod(method)) { - throw unresolvedValidationException(); - } - return true; - } - } - - public static class FieldDef { - public final String definingClass; - public final String name; - public final String type; - - public FieldDef(String definingClass, String name, String type) { - this.definingClass = definingClass; - this.name = name; - this.type = type; - } - } - - public static class ClassDef implements Comparable { - private final String classType; - private final ClassDef superclass; - /** - * This is a list of all of the interfaces that a class implements, either directly or indirectly. It includes - * all interfaces implemented by the superclass, and all super-interfaces of any implemented interface. The - * intention is to make it easier to determine whether the class implements a given interface or not. - */ - private final TreeSet implementedInterfaces; - - private final boolean isInterface; - - private final int classDepth; - - private final VirtualMethod[] vtable; - - //this maps a method name of the form method(III)Ljava/lang/String; to an integer - //If the value is non-negative, it is a vtable index - //If it is -1, it is a non-static direct method, - //If it is -2, it is a static method - private final HashMap methodLookup; - - private final SparseArray instanceFields; - - public final static int ArrayClassDef = 0; - public final static int PrimitiveClassDef = 1; - public final static int UnresolvedClassDef = 2; - - private final static int DirectMethod = -1; - private final static int StaticMethod = -2; - - /** - * The following fields are used only during the initial loading of classes, and are set to null afterwards - * TODO: free these - */ - - //This is only the virtual methods that this class declares itself. - private VirtualMethod[] virtualMethods; - //this is a list of all the interfaces that the class implements directory, or any super interfaces of those - //interfaces. It is generated in such a way that it is ordered in the same way as dalvik's ClassObject.iftable, - private LinkedHashMap interfaceTable; - - /** - * This constructor is used for the ArrayClassDef, PrimitiveClassDef and UnresolvedClassDef subclasses - * @param classType the class type - * @param classFlavor one of ArrayClassDef, PrimitiveClassDef or UnresolvedClassDef - */ - protected ClassDef(String classType, int classFlavor) { - if (classFlavor == ArrayClassDef) { - assert classType.charAt(0) == '['; - this.classType = classType; - this.superclass = ClassPath.theClassPath.javaLangObjectClassDef; - implementedInterfaces = new TreeSet(); - implementedInterfaces.add(ClassPath.getClassDef("Ljava/lang/Cloneable;")); - implementedInterfaces.add(ClassPath.getClassDef("Ljava/io/Serializable;")); - isInterface = false; - - vtable = superclass.vtable; - methodLookup = superclass.methodLookup; - - instanceFields = superclass.instanceFields; - classDepth = 1; //1 off from java.lang.Object - - virtualMethods = null; - interfaceTable = null; - } else if (classFlavor == PrimitiveClassDef) { - //primitive type - assert classType.charAt(0) != '[' && classType.charAt(0) != 'L'; - - this.classType = classType; - this.superclass = null; - implementedInterfaces = null; - isInterface = false; - vtable = null; - methodLookup = null; - instanceFields = null; - classDepth = 0; //TODO: maybe use -1 to indicate not applicable? - - virtualMethods = null; - interfaceTable = null; - } else /*if (classFlavor == UnresolvedClassDef)*/ { - assert classType.charAt(0) == 'L'; - this.classType = classType; - this.superclass = ClassPath.getClassDef("Ljava/lang/Object;"); - implementedInterfaces = new TreeSet(); - isInterface = false; - - vtable = superclass.vtable; - methodLookup = superclass.methodLookup; - - instanceFields = superclass.instanceFields; - classDepth = 1; //1 off from java.lang.Object - - virtualMethods = null; - interfaceTable = null; - } - } - - protected ClassDef(UnresolvedClassInfo classInfo) { - classType = classInfo.classType; - isInterface = classInfo.isInterface; - - superclass = loadSuperclass(classInfo); - if (superclass == null) { - classDepth = 0; - } else { - classDepth = superclass.classDepth + 1; - } - - implementedInterfaces = loadAllImplementedInterfaces(classInfo); - - //TODO: we can probably get away with only creating the interface table for interface types - interfaceTable = loadInterfaceTable(classInfo); - virtualMethods = classInfo.virtualMethods; - vtable = loadVtable(classInfo); - - int directMethodCount = 0; - if (classInfo.directMethods != null) { - directMethodCount = classInfo.directMethods.length; - } - methodLookup = new HashMap((int)Math.ceil(((vtable.length + directMethodCount)/ .7f)), .75f); - for (int i=0; i 0) { - for (int i=0; i getInstanceFields() { - return instanceFields; - } - - public int getClassDepth() { - return classDepth; - } - - public boolean isInterface() { - return this.isInterface; - } - - public boolean extendsClass(ClassDef superclassDef) { - if (superclassDef == null) { - return false; - } - - if (this == superclassDef) { - return true; - } - - if (superclassDef instanceof UnresolvedClassDef) { - throw ((UnresolvedClassDef)superclassDef).unresolvedValidationException(); - } - - int superclassDepth = superclassDef.classDepth; - ClassDef ancestor = this; - while (ancestor.classDepth > superclassDepth) { - ancestor = ancestor.getSuperclass(); - } - - return ancestor == superclassDef; - } - - /** - * Returns true if this class implements the given interface. This searches the interfaces that this class - * directly implements, any interface implemented by this class's superclasses, and any super-interface of - * any of these interfaces. - * @param interfaceDef the interface - * @return true if this class implements the given interface - */ - public boolean implementsInterface(ClassDef interfaceDef) { - assert !(interfaceDef instanceof UnresolvedClassDef); - return implementedInterfaces.contains(interfaceDef); - } - - public boolean hasVirtualMethod(String method) { - Integer val = methodLookup.get(method); - if (val == null || val < 0) { - return false; - } - return true; - } - - public int getMethodType(String method) { - Integer val = methodLookup.get(method); - if (val == null) { - return -1; - } - if (val >= 0) { - return DeodexUtil.Virtual; - } - if (val == DirectMethod) { - return DeodexUtil.Direct; - } - if (val == StaticMethod) { - return DeodexUtil.Static; - } - throw new RuntimeException("Unexpected method type"); - } - - public FieldDef getInstanceField(int fieldOffset) { - return this.instanceFields.get(fieldOffset, null); - } - - public String getVirtualMethod(int vtableIndex) { - if (vtableIndex < 0 || vtableIndex >= vtable.length) { - return null; - } - return this.vtable[vtableIndex].method; - } - - private void swap(byte[] fieldTypes, FieldDef[] fields, int position1, int position2) { - byte tempType = fieldTypes[position1]; - fieldTypes[position1] = fieldTypes[position2]; - fieldTypes[position2] = tempType; - - FieldDef tempField = fields[position1]; - fields[position1] = fields[position2]; - fields[position2] = tempField; - } - - private ClassDef loadSuperclass(UnresolvedClassInfo classInfo) { - if (classInfo.classType.equals("Ljava/lang/Object;")) { - if (classInfo.superclassType != null) { - throw new ExceptionWithContext("Invalid superclass " + - classInfo.superclassType + " for Ljava/lang/Object;. " + - "The Object class cannot have a superclass"); - } - return null; - } else { - String superclassType = classInfo.superclassType; - if (superclassType == null) { - throw new ExceptionWithContext(classInfo.classType + " has no superclass"); - } - - ClassDef superclass; - try { - superclass = ClassPath.getClassDef(superclassType); - } catch (Exception ex) { - throw ExceptionWithContext.withContext(ex, - String.format("Could not find superclass %s", superclassType)); - } - - if (!isInterface && superclass.isInterface) { - throw new ValidationException("Class " + classType + " has the interface " + superclass.classType + - " as its superclass"); - } - if (isInterface && !superclass.isInterface && superclass != - ClassPath.theClassPath.javaLangObjectClassDef) { - throw new ValidationException("Interface " + classType + " has the non-interface class " + - superclass.classType + " as its superclass"); - } - - return superclass; - } - } - - private TreeSet loadAllImplementedInterfaces(UnresolvedClassInfo classInfo) { - assert classType != null; - assert classType.equals("Ljava/lang/Object;") || superclass != null; - assert classInfo != null; - - TreeSet implementedInterfaceSet = new TreeSet(); - - if (superclass != null) { - for (ClassDef interfaceDef: superclass.implementedInterfaces) { - implementedInterfaceSet.add(interfaceDef); - } - } - - - if (classInfo.interfaces != null) { - for (String interfaceType: classInfo.interfaces) { - ClassDef interfaceDef; - try { - interfaceDef = ClassPath.getClassDef(interfaceType); - } catch (Exception ex) { - throw ExceptionWithContext.withContext(ex, - String.format("Could not find interface %s", interfaceType)); - } - assert interfaceDef.isInterface(); - implementedInterfaceSet.add(interfaceDef); - - interfaceDef = interfaceDef.getSuperclass(); - while (!interfaceDef.getClassType().equals("Ljava/lang/Object;")) { - assert interfaceDef.isInterface(); - implementedInterfaceSet.add(interfaceDef); - interfaceDef = interfaceDef.getSuperclass(); - } - } - } - - return implementedInterfaceSet; - } - - private LinkedHashMap loadInterfaceTable(UnresolvedClassInfo classInfo) { - if (classInfo.interfaces == null) { - return null; - } - - LinkedHashMap interfaceTable = new LinkedHashMap(); - - for (String interfaceType: classInfo.interfaces) { - if (!interfaceTable.containsKey(interfaceType)) { - ClassDef interfaceDef; - try { - interfaceDef = ClassPath.getClassDef(interfaceType); - } catch (Exception ex) { - throw ExceptionWithContext.withContext(ex, - String.format("Could not find interface %s", interfaceType)); - } - interfaceTable.put(interfaceType, interfaceDef); - - if (interfaceDef.interfaceTable != null) { - for (ClassDef superInterface: interfaceDef.interfaceTable.values()) { - if (!interfaceTable.containsKey(superInterface.classType)) { - interfaceTable.put(superInterface.classType, superInterface); - } - } - } - } - } - - return interfaceTable; - } - - //TODO: check the case when we have a package private method that overrides an interface method - private VirtualMethod[] loadVtable(UnresolvedClassInfo classInfo) { - //TODO: it might be useful to keep track of which class's implementation is used for each virtual method. In other words, associate the implementing class type with each vtable entry - List virtualMethodList = new LinkedList(); - - //copy the virtual methods from the superclass - int methodIndex = 0; - if (superclass != null) { - for (int i=0; i vtable) { - for (VirtualMethod virtualMethod: localMethods) { - boolean found = false; - for (int i=0; i loadFields(UnresolvedClassInfo classInfo) { - //This is a bit of an "involved" operation. We need to follow the same algorithm that dalvik uses to - //arrange fields, so that we end up with the same field offsets (which is needed for deodexing). - //See mydroid/dalvik/vm/oo/Class.c - computeFieldOffsets() - - final byte REFERENCE = 0; - final byte WIDE = 1; - final byte OTHER = 2; - - FieldDef[] fields = null; - //the "type" for each field in fields. 0=reference,1=wide,2=other - byte[] fieldTypes = null; - - if (classInfo.instanceFields != null) { - fields = new FieldDef[classInfo.instanceFields.length]; - fieldTypes = new byte[fields.length]; - - for (int i=0; i front) { - if (fieldTypes[back] == REFERENCE) { - swap(fieldTypes, fields, front, back--); - break; - } - back--; - } - } - - if (fieldTypes[front] != REFERENCE) { - break; - } - } - - - int startFieldOffset = 8; - if (this.superclass != null) { - startFieldOffset = this.superclass.getNextFieldOffset(); - } - - int fieldIndexMod; - if ((startFieldOffset % 8) == 0) { - fieldIndexMod = 0; - } else { - fieldIndexMod = 1; - } - - //next, we need to group all the wide fields after the reference fields. But the wide fields have to be - //8-byte aligned. If we're on an odd field index, we need to insert a 32-bit field. If the next field - //is already a 32-bit field, use that. Otherwise, find the first 32-bit field from the end and swap it in. - //If there are no 32-bit fields, do nothing for now. We'll add padding when calculating the field offsets - if (front < fields.length && (front % 2) != fieldIndexMod) { - if (fieldTypes[front] == WIDE) { - //we need to swap in a 32-bit field, so the wide fields will be correctly aligned - back = fields.length - 1; - while (back > front) { - if (fieldTypes[back] == OTHER) { - swap(fieldTypes, fields, front++, back); - break; - } - back--; - } - } else { - //there's already a 32-bit field here that we can use - front++; - } - } - - //do the swap thing for wide fields - back = fields.length - 1; - for (; front front) { - if (fieldTypes[back] == WIDE) { - swap(fieldTypes, fields, front, back--); - break; - } - back--; - } - } - - if (fieldTypes[front] != WIDE) { - break; - } - } - - int superFieldCount = 0; - if (superclass != null) { - superFieldCount = superclass.instanceFields.size(); - } - - //now the fields are in the correct order. Add them to the SparseArray and lookup, and calculate the offsets - int totalFieldCount = superFieldCount + fields.length; - SparseArray instanceFields = new SparseArray(totalFieldCount); - - int fieldOffset; - - if (superclass != null && superFieldCount > 0) { - for (int i=0; i types = typeList.getTypes(); - if (types != null && types.size() > 0) { - String[] interfaces = new String[types.size()]; - for (int i=0; i encodedMethods = classDataItem.getDirectMethods(); - if (encodedMethods.size() > 0) { - boolean[] staticMethods = new boolean[encodedMethods.size()]; - String[] directMethods = new String[encodedMethods.size()]; - - for (int i=0; i encodedMethods = classDataItem.getVirtualMethods(); - if (encodedMethods.size() > 0) { - VirtualMethod[] virtualMethods = new VirtualMethod[encodedMethods.size()]; - for (int i=0; i encodedFields = classDataItem.getInstanceFields(); - if (encodedFields.size() > 0) { - String[][] instanceFields = new String[encodedFields.size()][2]; - for (int i=0; i lines = new ArrayList(); - - BufferedReader br = new BufferedReader(fr); - - try { - String line = br.readLine(); - - while (line != null) { - if (line.length() > 0) { - lines.add(line); - } - - line = br.readLine(); - } - } catch (IOException ex) { - throw new RuntimeException("Error while reading file: " + inlineTable, ex); - } - - inlineMethods = new DeodexUtil.InlineMethod[lines.size()]; - - for (int i=0; i= inlineMethods.length) { - throw new RuntimeException("Invalid method index: " + methodIndex); - } - return inlineMethods[methodIndex]; - } - - private static final Pattern longMethodPattern = Pattern.compile("(L[^;]+;)->([^(]+)\\(([^)]*)\\)(.+)"); - - private DeodexUtil.InlineMethod parseAndResolveInlineMethod(String inlineMethod) { - Matcher m = longMethodPattern.matcher(inlineMethod); - if (!m.matches()) { - assert false; - throw new RuntimeException("Invalid method descriptor: " + inlineMethod); - } - - String className = m.group(1); - String methodName = m.group(2); - String methodParams = m.group(3); - String methodRet = m.group(4); - - ClassPath.ClassDef classDef = ClassPath.getClassDef(className, false); - int methodType = classDef.getMethodType(String.format("%s(%s)%s", methodName, methodParams, methodRet)); - - if (methodType == -1) { - throw new RuntimeException("Cannot resolve inline method: " + inlineMethod); - } - - return new DeodexUtil.InlineMethod(methodType, className, methodName, methodParams, methodRet); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DeodexUtil.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DeodexUtil.java deleted file mode 100644 index be689ccd..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DeodexUtil.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Analysis; - -import org.jf.dexlib.*; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class DeodexUtil { - public static final int Virtual = 0; - public static final int Direct = 1; - public static final int Static = 2; - - private final InlineMethodResolver inlineMethodResolver; - - public final DexFile dexFile; - - public DeodexUtil(DexFile dexFile) { - this.dexFile = dexFile; - OdexHeader odexHeader = dexFile.getOdexHeader(); - if (odexHeader == null) { - //if there isn't an odex header, why are we creating an DeodexUtil object? - assert false; - throw new RuntimeException("Cannot create a DeodexUtil object for a dex file without an odex header"); - } - inlineMethodResolver = InlineMethodResolver.createInlineMethodResolver(this, odexHeader.version); - } - - public DeodexUtil(DexFile dexFile, InlineMethodResolver inlineMethodResolver) { - this.dexFile = dexFile; - this.inlineMethodResolver = inlineMethodResolver; - } - - public InlineMethod lookupInlineMethod(AnalyzedInstruction instruction) { - return inlineMethodResolver.resolveExecuteInline(instruction); - } - - public FieldIdItem lookupField(ClassPath.ClassDef classDef, int fieldOffset) { - ClassPath.FieldDef field = classDef.getInstanceField(fieldOffset); - if (field == null) { - return null; - } - - return parseAndResolveField(classDef, field); - } - - private static final Pattern shortMethodPattern = Pattern.compile("([^(]+)\\(([^)]*)\\)(.+)"); - - public MethodIdItem lookupVirtualMethod(ClassPath.ClassDef classDef, int methodIndex) { - String method = classDef.getVirtualMethod(methodIndex); - if (method == null) { - return null; - } - - Matcher m = shortMethodPattern.matcher(method); - if (!m.matches()) { - assert false; - throw new RuntimeException("Invalid method descriptor: " + method); - } - - String methodName = m.group(1); - String methodParams = m.group(2); - String methodRet = m.group(3); - - if (classDef instanceof ClassPath.UnresolvedClassDef) { - //if this is an unresolved class, the only way getVirtualMethod could have found a method is if the virtual - //method being looked up was a method on java.lang.Object. - classDef = ClassPath.getClassDef("Ljava/lang/Object;"); - } else if (classDef.isInterface()) { - classDef = classDef.getSuperclass(); - assert classDef != null; - } - - return parseAndResolveMethod(classDef, methodName, methodParams, methodRet); - } - - private MethodIdItem parseAndResolveMethod(ClassPath.ClassDef classDef, String methodName, String methodParams, - String methodRet) { - StringIdItem methodNameItem = StringIdItem.lookupStringIdItem(dexFile, methodName); - if (methodNameItem == null) { - return null; - } - - LinkedList paramList = new LinkedList(); - - for (int i=0; i 0) { - paramListItem = TypeListItem.lookupTypeListItem(dexFile, paramList); - if (paramListItem == null) { - return null; - } - } - - TypeIdItem retType = TypeIdItem.lookupTypeIdItem(dexFile, methodRet); - if (retType == null) { - return null; - } - - ProtoIdItem protoItem = ProtoIdItem.lookupProtoIdItem(dexFile, retType, paramListItem); - if (protoItem == null) { - return null; - } - - ClassPath.ClassDef methodClassDef = classDef; - - do { - TypeIdItem classTypeItem = TypeIdItem.lookupTypeIdItem(dexFile, methodClassDef.getClassType()); - - if (classTypeItem != null) { - MethodIdItem methodIdItem = MethodIdItem.lookupMethodIdItem(dexFile, classTypeItem, protoItem, methodNameItem); - if (methodIdItem != null) { - return methodIdItem; - } - } - - methodClassDef = methodClassDef.getSuperclass(); - } while (methodClassDef != null); - return null; - } - - private FieldIdItem parseAndResolveField(ClassPath.ClassDef classDef, ClassPath.FieldDef field) { - String definingClass = field.definingClass; - String fieldName = field.name; - String fieldType = field.type; - - StringIdItem fieldNameItem = StringIdItem.lookupStringIdItem(dexFile, fieldName); - if (fieldNameItem == null) { - return null; - } - - TypeIdItem fieldTypeItem = TypeIdItem.lookupTypeIdItem(dexFile, fieldType); - if (fieldTypeItem == null) { - return null; - } - - ClassPath.ClassDef fieldClass = classDef; - - ArrayList parents = new ArrayList(); - parents.add(fieldClass); - - while (fieldClass != null && !fieldClass.getClassType().equals(definingClass)) { - fieldClass = fieldClass.getSuperclass(); - parents.add(fieldClass); - } - - for (int i=parents.size()-1; i>=0; i--) { - fieldClass = parents.get(i); - - TypeIdItem classTypeItem = TypeIdItem.lookupTypeIdItem(dexFile, fieldClass.getClassType()); - if (classTypeItem == null) { - continue; - } - - FieldIdItem fieldIdItem = FieldIdItem.lookupFieldIdItem(dexFile, classTypeItem, fieldTypeItem, fieldNameItem); - if (fieldIdItem != null) { - return fieldIdItem; - } - } - return null; - } - - public static class InlineMethod { - public final int methodType; - public final String classType; - public final String methodName; - public final String parameters; - public final String returnType; - - private MethodIdItem methodIdItem = null; - - InlineMethod(int methodType, String classType, String methodName, String parameters, - String returnType) { - this.methodType = methodType; - this.classType = classType; - this.methodName = methodName; - this.parameters = parameters; - this.returnType = returnType; - } - - public MethodIdItem getMethodIdItem(DeodexUtil deodexUtil) { - if (methodIdItem == null) { - loadMethod(deodexUtil); - } - return methodIdItem; - } - - private void loadMethod(DeodexUtil deodexUtil) { - ClassPath.ClassDef classDef = ClassPath.getClassDef(classType); - - this.methodIdItem = deodexUtil.parseAndResolveMethod(classDef, methodName, parameters, returnType); - } - - public String getMethodString() { - return String.format("%s->%s(%s)%s", classType, methodName, parameters, returnType); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DexFileClassMap.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DexFileClassMap.java deleted file mode 100644 index ca442687..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DexFileClassMap.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2011 Ben Gruver - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Analysis; - -import org.jf.dexlib.ClassDefItem; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.TypeIdItem; - -import java.util.HashMap; - -/** - * Keeps a simple map of classes defined in a dex file, allowing you to look them up by TypeIdItem or name - */ -public class DexFileClassMap { - private final HashMap definedClasses = new HashMap(); - - public DexFileClassMap(DexFile dexFile) { - for (ClassDefItem classDefItem: dexFile.ClassDefsSection.getItems()) { - definedClasses.put(classDefItem.getClassType().getTypeDescriptor(), classDefItem); - } - } - - public ClassDefItem getClassDefByName(String typeName) { - return definedClasses.get(typeName); - } - - public ClassDefItem getClassDefByType(TypeIdItem typeIdItem) { - return definedClasses.get(typeIdItem.getTypeDescriptor()); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DumpFields.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DumpFields.java deleted file mode 100644 index 3f6ccf23..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DumpFields.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2013, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Analysis; - -import com.google.common.base.Splitter; -import com.google.common.collect.Lists; -import org.apache.commons.cli.*; -import org.jf.dexlib.ClassDefItem; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.SparseArray; -import org.jf.util.ConsoleUtil; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; - -public class DumpFields { - private static final Options options; - - static { - options = new Options(); - buildOptions(); - } - - public static void main(String[] args) { - CommandLineParser parser = new PosixParser(); - CommandLine commandLine; - - try { - commandLine = parser.parse(options, args); - } catch (ParseException ex) { - usage(); - return; - } - - String[] remainingArgs = commandLine.getArgs(); - - Option[] parsedOptions = commandLine.getOptions(); - ArrayList bootClassPathDirs = Lists.newArrayList(); - String outFile = "fields.txt"; - - for (int i=0; i fields = classDef.getInstanceFields(); - String className = "Class " + classDef.getClassType() + " : " + fields.size() + " instance fields\n"; - outStream.write(className.getBytes()); - for (int i=0;i"); - } - - private static void buildOptions() { - Option classPathDirOption = OptionBuilder.withLongOpt("bootclasspath-dir") - .withDescription("the base folder to look for the bootclasspath files in. Defaults to the current " + - "directory") - .hasArg() - .withArgName("DIR") - .create("d"); - - Option outputFileOption = OptionBuilder.withLongOpt("out-file") - .withDescription("output file") - .hasArg() - .withArgName("FILE") - .create("o"); - - options.addOption(classPathDirOption); - options.addOption(outputFileOption); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DumpVtables.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DumpVtables.java deleted file mode 100644 index 5aab9edc..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/DumpVtables.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2013, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Analysis; - -import com.google.common.base.Splitter; -import com.google.common.collect.Lists; -import org.apache.commons.cli.*; -import org.jf.dexlib.ClassDefItem; -import org.jf.dexlib.DexFile; -import org.jf.util.ConsoleUtil; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; - -public class DumpVtables { - private static final Options options; - - static { - options = new Options(); - buildOptions(); - } - - public static void main(String[] args) { - CommandLineParser parser = new PosixParser(); - CommandLine commandLine; - - try { - commandLine = parser.parse(options, args); - } catch (ParseException ex) { - usage(); - return; - } - - String[] remainingArgs = commandLine.getArgs(); - - Option[] parsedOptions = commandLine.getOptions(); - ArrayList bootClassPathDirs = Lists.newArrayList(); - String outFile = "vtables.txt"; - - for (int i=0; i" + methods[i].method + "\n"; - outStream.write(method.getBytes()); - } - outStream.write("\n".getBytes()); - } - outStream.close(); - } catch (IOException ex) { - System.out.println("IOException thrown when trying to open a dex file or write out vtables: " + ex); - } - - } - - /** - * Prints the usage message. - */ - private static void usage() { - int consoleWidth = ConsoleUtil.getConsoleWidth(); - if (consoleWidth <= 0) { - consoleWidth = 80; - } - - System.out.println("java -cp baksmali.jar org.jf.dexlib.Code.Analysis.DumpVtables -d path/to/jar/files "); - } - - private static void buildOptions() { - Option classPathDirOption = OptionBuilder.withLongOpt("bootclasspath-dir") - .withDescription("the base folder to look for the bootclasspath files in. Defaults to the current " + - "directory") - .hasArg() - .withArgName("DIR") - .create("d"); - - Option outputFileOption = OptionBuilder.withLongOpt("out-file") - .withDescription("output file") - .hasArg() - .withArgName("FILE") - .create("o"); - - options.addOption(classPathDirOption); - options.addOption(outputFileOption); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/InlineMethodResolver.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/InlineMethodResolver.java deleted file mode 100644 index a14a667b..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/InlineMethodResolver.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Analysis; - -import org.jf.dexlib.Code.OdexedInvokeInline; -import org.jf.dexlib.Code.OdexedInvokeVirtual; - -import static org.jf.dexlib.Code.Analysis.DeodexUtil.Static; -import static org.jf.dexlib.Code.Analysis.DeodexUtil.Virtual; -import static org.jf.dexlib.Code.Analysis.DeodexUtil.Direct; - -public abstract class InlineMethodResolver { - public static InlineMethodResolver createInlineMethodResolver(DeodexUtil deodexUtil, int odexVersion) { - if (odexVersion == 35) { - return new InlineMethodResolver_version35(deodexUtil); - } else if (odexVersion == 36) { - return new InlineMethodResolver_version36(deodexUtil); - } else { - throw new RuntimeException(String.format("odex version %d is not supported yet", odexVersion)); - } - } - - protected InlineMethodResolver() { - } - - public abstract DeodexUtil.InlineMethod resolveExecuteInline(AnalyzedInstruction instruction); - - private static class InlineMethodResolver_version35 extends InlineMethodResolver - { - private final DeodexUtil.InlineMethod[] inlineMethods; - - public InlineMethodResolver_version35(DeodexUtil deodexUtil) { - inlineMethods = new DeodexUtil.InlineMethod[] { - new DeodexUtil.InlineMethod(Static, "Lorg/apache/harmony/dalvik/NativeTestTarget;", "emptyInlineMethod", "", "V"), - new DeodexUtil.InlineMethod(Virtual, "Ljava/lang/String;", "charAt", "I", "C"), - new DeodexUtil.InlineMethod(Virtual, "Ljava/lang/String;", "compareTo", "Ljava/lang/String;", "I"), - new DeodexUtil.InlineMethod(Virtual, "Ljava/lang/String;", "equals", "Ljava/lang/Object;", "Z"), - new DeodexUtil.InlineMethod(Virtual, "Ljava/lang/String;", "length", "", "I"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "abs", "I", "I"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "abs", "J", "J"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "abs", "F", "F"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "abs", "D", "D"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "min", "II", "I"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "max", "II", "I"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "sqrt", "D", "D"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "cos", "D", "D"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "sin", "D", "D") - }; - } - - @Override - public DeodexUtil.InlineMethod resolveExecuteInline(AnalyzedInstruction analyzedInstruction) { - assert analyzedInstruction.instruction instanceof OdexedInvokeInline; - - OdexedInvokeInline instruction = (OdexedInvokeInline)analyzedInstruction.instruction; - int inlineIndex = instruction.getInlineIndex(); - - if (inlineIndex < 0 || inlineIndex >= inlineMethods.length) { - throw new RuntimeException("Invalid inline index: " + inlineIndex); - } - return inlineMethods[inlineIndex]; - } - } - - private static class InlineMethodResolver_version36 extends InlineMethodResolver - { - private final DeodexUtil.InlineMethod[] inlineMethods; - private final DeodexUtil.InlineMethod indexOfIMethod; - private final DeodexUtil.InlineMethod indexOfIIMethod; - private final DeodexUtil.InlineMethod fastIndexOfMethod; - private final DeodexUtil.InlineMethod isEmptyMethod; - - - public InlineMethodResolver_version36(DeodexUtil deodexUtil) { - //The 5th and 6th entries differ between froyo and gingerbread. We have to look at the parameters being - //passed to distinguish between them. - - //froyo - indexOfIMethod = new DeodexUtil.InlineMethod(Virtual, "Ljava/lang/String;", "indexOf", "I", "I"); - indexOfIIMethod = new DeodexUtil.InlineMethod(Virtual, "Ljava/lang/String;", "indexOf", "II", "I"); - - //gingerbread - fastIndexOfMethod = new DeodexUtil.InlineMethod(Direct, "Ljava/lang/String;", "fastIndexOf", "II", "I"); - isEmptyMethod = new DeodexUtil.InlineMethod(Virtual, "Ljava/lang/String;", "isEmpty", "", "Z"); - - inlineMethods = new DeodexUtil.InlineMethod[] { - new DeodexUtil.InlineMethod(Static, "Lorg/apache/harmony/dalvik/NativeTestTarget;", "emptyInlineMethod", "", "V"), - new DeodexUtil.InlineMethod(Virtual, "Ljava/lang/String;", "charAt", "I", "C"), - new DeodexUtil.InlineMethod(Virtual, "Ljava/lang/String;", "compareTo", "Ljava/lang/String;", "I"), - new DeodexUtil.InlineMethod(Virtual, "Ljava/lang/String;", "equals", "Ljava/lang/Object;", "Z"), - //froyo: deodexUtil.new InlineMethod(Virtual, "Ljava/lang/String;", "indexOf", "I", "I"), - //gingerbread: deodexUtil.new InlineMethod(Virtual, "Ljava/lang/String;", "fastIndexOf", "II", "I"), - null, - //froyo: deodexUtil.new InlineMethod(Virtual, "Ljava/lang/String;", "indexOf", "II", "I"), - //gingerbread: deodexUtil.new InlineMethod(Virtual, "Ljava/lang/String;", "isEmpty", "", "Z"), - null, - new DeodexUtil.InlineMethod(Virtual, "Ljava/lang/String;", "length", "", "I"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "abs", "I", "I"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "abs", "J", "J"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "abs", "F", "F"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "abs", "D", "D"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "min", "II", "I"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "max", "II", "I"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "sqrt", "D", "D"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "cos", "D", "D"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Math;", "sin", "D", "D"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Float;", "floatToIntBits", "F", "I"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Float;", "floatToRawIntBits", "F", "I"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Float;", "intBitsToFloat", "I", "F"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Double;", "doubleToLongBits", "D", "J"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Double;", "doubleToRawLongBits", "D", "J"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/Double;", "longBitsToDouble", "J", "D"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/StrictMath;", "abs", "I", "I"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/StrictMath;", "abs", "J", "J"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/StrictMath;", "abs", "F", "F"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/StrictMath;", "abs", "D", "D"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/StrictMath;", "min", "II", "I"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/StrictMath;", "max", "II", "I"), - new DeodexUtil.InlineMethod(Static, "Ljava/lang/StrictMath;", "sqrt", "D", "D"), - }; - } - - @Override - public DeodexUtil.InlineMethod resolveExecuteInline(AnalyzedInstruction analyzedInstruction) { - assert analyzedInstruction.instruction instanceof OdexedInvokeInline; - - OdexedInvokeInline instruction = (OdexedInvokeInline)analyzedInstruction.instruction; - int inlineIndex = instruction.getInlineIndex(); - - if (inlineIndex < 0 || inlineIndex >= inlineMethods.length) { - throw new RuntimeException("Invalid method index: " + inlineIndex); - } - - if (inlineIndex == 4) { - int parameterCount = getParameterCount(instruction); - if (parameterCount == 2) { - return indexOfIMethod; - } else if (parameterCount == 3) { - return fastIndexOfMethod; - } else { - throw new RuntimeException("Could not determine the correct inline method to use"); - } - } else if (inlineIndex == 5) { - int parameterCount = getParameterCount(instruction); - if (parameterCount == 3) { - return indexOfIIMethod; - } else if (parameterCount == 1) { - return isEmptyMethod; - } else { - throw new RuntimeException("Could not determine the correct inline method to use"); - } - } - - return inlineMethods[inlineIndex]; - } - - private int getParameterCount(OdexedInvokeInline instruction) { - return instruction.getRegCount(); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java deleted file mode 100644 index ddf7e5ff..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java +++ /dev/null @@ -1,3755 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Analysis; - -import org.jf.dexlib.*; -import org.jf.dexlib.Code.*; -import org.jf.dexlib.Code.Format.*; -import org.jf.dexlib.Util.AccessFlags; -import org.jf.util.ExceptionWithContext; -import org.jf.dexlib.Util.SparseArray; - -import java.util.BitSet; -import java.util.EnumSet; -import java.util.List; - -/** - * The MethodAnalyzer performs several functions. It "analyzes" the instructions and infers the register types - * for each register, it can deodex odexed instructions, and it can verify the bytecode. The analysis and verification - * are done in two separate passes, because the analysis has to process instructions multiple times in some cases, and - * there's no need to perform the verification multiple times, so we wait until the method is fully analyzed and then - * verify it. - * - * Before calling the analyze() method, you must have initialized the ClassPath by calling - * ClassPath.InitializeClassPath - */ -public class MethodAnalyzer { - private final ClassDataItem.EncodedMethod encodedMethod; - - private final DeodexUtil deodexUtil; - - private SparseArray instructions; - - private static final int NOT_ANALYZED = 0; - private static final int ANALYZED = 1; - private static final int VERIFIED = 2; - private int analyzerState = NOT_ANALYZED; - - private BitSet analyzedInstructions; - - private ValidationException validationException = null; - - //This is a dummy instruction that occurs immediately before the first real instruction. We can initialize the - //register types for this instruction to the parameter types, in order to have them propagate to all of its - //successors, e.g. the first real instruction, the first instructions in any exception handlers covering the first - //instruction, etc. - private AnalyzedInstruction startOfMethod; - - public MethodAnalyzer(ClassDataItem.EncodedMethod encodedMethod, boolean deodex, - InlineMethodResolver inlineResolver) { - if (encodedMethod == null) { - throw new IllegalArgumentException("encodedMethod cannot be null"); - } - if (encodedMethod.codeItem == null || encodedMethod.codeItem.getInstructions().length == 0) { - throw new IllegalArgumentException("The method has no code"); - } - this.encodedMethod = encodedMethod; - - if (deodex) { - if (inlineResolver != null) { - this.deodexUtil = new DeodexUtil(encodedMethod.method.getDexFile(), inlineResolver); - } else { - this.deodexUtil = new DeodexUtil(encodedMethod.method.getDexFile()); - } - } else { - this.deodexUtil = null; - } - - //override AnalyzedInstruction and provide custom implementations of some of the methods, so that we don't - //have to handle the case this special case of instruction being null, in the main class - startOfMethod = new AnalyzedInstruction(null, -1, encodedMethod.codeItem.getRegisterCount()) { - public boolean setsRegister() { - return false; - } - - @Override - public boolean setsWideRegister() { - return false; - } - - @Override - public boolean setsRegister(int registerNumber) { - return false; - } - - @Override - public int getDestinationRegister() { - assert false; - return -1; - }; - }; - - buildInstructionList(); - - analyzedInstructions = new BitSet(instructions.size()); - } - - public boolean isAnalyzed() { - return analyzerState >= ANALYZED; - } - - public boolean isVerified() { - return analyzerState == VERIFIED; - } - - public void analyze() { - assert encodedMethod != null; - assert encodedMethod.codeItem != null; - - if (analyzerState >= ANALYZED) { - //the instructions have already been analyzed, so there is nothing to do - return; - } - - CodeItem codeItem = encodedMethod.codeItem; - MethodIdItem methodIdItem = encodedMethod.method; - - int totalRegisters = codeItem.getRegisterCount(); - int parameterRegisters = methodIdItem.getPrototype().getParameterRegisterCount(); - - int nonParameterRegisters = totalRegisters - parameterRegisters; - - for (AnalyzedInstruction instruction: instructions.getValues()) { - instruction.dead = true; - } - - //if this isn't a static method, determine which register is the "this" register and set the type to the - //current class - if ((encodedMethod.accessFlags & AccessFlags.STATIC.getValue()) == 0) { - nonParameterRegisters--; - int thisRegister = totalRegisters - parameterRegisters - 1; - - //if this is a constructor, then set the "this" register to an uninitialized reference of the current class - if ((encodedMethod.accessFlags & AccessFlags.CONSTRUCTOR.getValue()) != 0) { - setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister, - RegisterType.getRegisterType(RegisterType.Category.UninitThis, - ClassPath.getClassDef(methodIdItem.getContainingClass()))); - } else { - setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister, - RegisterType.getRegisterType(RegisterType.Category.Reference, - ClassPath.getClassDef(methodIdItem.getContainingClass()))); - } - } - - TypeListItem parameters = methodIdItem.getPrototype().getParameters(); - if (parameters != null) { - RegisterType[] parameterTypes = getParameterTypes(parameters, parameterRegisters); - for (int i=0; i=0; i=instructionsToAnalyze.nextSetBit(i+1)) { - instructionsToAnalyze.clear(i); - if (analyzedInstructions.get(i)) { - continue; - } - AnalyzedInstruction instructionToAnalyze = instructions.valueAt(i); - instructionToAnalyze.dead = false; - try { - if (instructionToAnalyze.originalInstruction.opcode.odexOnly()) { - //if we had deodexed an odex instruction in a previous pass, we might have more specific - //register information now, so let's restore the original odexed instruction and - //re-deodex it - instructionToAnalyze.restoreOdexedInstruction(); - } - - if (!analyzeInstruction(instructionToAnalyze)) { - undeodexedInstructions.set(i); - continue; - } else { - didSomething = true; - undeodexedInstructions.clear(i); - } - } catch (ValidationException ex) { - this.validationException = ex; - int codeAddress = getInstructionAddress(instructionToAnalyze); - ex.setCodeAddress(codeAddress); - ex.addContext(String.format("opcode: %s", instructionToAnalyze.instruction.opcode.name)); - ex.addContext(String.format("CodeAddress: %d", codeAddress)); - ex.addContext(String.format("Method: %s", encodedMethod.method.getMethodString())); - break; - } - - analyzedInstructions.set(instructionToAnalyze.getInstructionIndex()); - - for (AnalyzedInstruction successor: instructionToAnalyze.successors) { - instructionsToAnalyze.set(successor.getInstructionIndex()); - } - } - if (validationException != null) { - break; - } - } - - if (!didSomething) { - break; - } - - if (!undeodexedInstructions.isEmpty()) { - for (int i=undeodexedInstructions.nextSetBit(0); i>=0; i=undeodexedInstructions.nextSetBit(i+1)) { - instructionsToAnalyze.set(i); - } - } - } while (true); - - //Now, go through and fix up any unresolvable odex instructions. These are usually odex instructions - //that operate on a null register, and thus always throw an NPE. They can also be any sort of odex instruction - //that occurs after an unresolvable odex instruction. We deodex if possible, or replace with an - //UnresolvableOdexInstruction - for (int i=0; i=0; i=instructionsToVerify.nextSetBit(i+1)) { - instructionsToVerify.clear(i); - if (verifiedInstructions.get(i)) { - continue; - } - AnalyzedInstruction instructionToVerify = instructions.valueAt(i); - try { - verifyInstruction(instructionToVerify); - } catch (ValidationException ex) { - this.validationException = ex; - int codeAddress = getInstructionAddress(instructionToVerify); - ex.setCodeAddress(codeAddress); - ex.addContext(String.format("opcode: %s", instructionToVerify.instruction.opcode.name)); - ex.addContext(String.format("CodeAddress: %d", codeAddress)); - ex.addContext(String.format("Method: %s", encodedMethod.method.getMethodString())); - break; - } - - verifiedInstructions.set(instructionToVerify.getInstructionIndex()); - - for (AnalyzedInstruction successor: instructionToVerify.successors) { - instructionsToVerify.set(successor.getInstructionIndex()); - } - } - if (validationException != null) { - break; - } - } - - analyzerState = VERIFIED; - } - - private int getThisRegister() { - assert (encodedMethod.accessFlags & AccessFlags.STATIC.getValue()) == 0; - - CodeItem codeItem = encodedMethod.codeItem; - assert codeItem != null; - - MethodIdItem methodIdItem = encodedMethod.method; - assert methodIdItem != null; - - int totalRegisters = codeItem.getRegisterCount(); - if (totalRegisters == 0) { - throw new ValidationException("A non-static method must have at least 1 register"); - } - - int parameterRegisters = methodIdItem.getPrototype().getParameterRegisterCount(); - - return totalRegisters - parameterRegisters - 1; - } - - private boolean isInstanceConstructor() { - return (encodedMethod.accessFlags & AccessFlags.STATIC.getValue()) == 0 && - (encodedMethod.accessFlags & AccessFlags.CONSTRUCTOR.getValue()) != 0; - } - - private boolean isStaticConstructor() { - return (encodedMethod.accessFlags & AccessFlags.STATIC.getValue()) != 0 && - (encodedMethod.accessFlags & AccessFlags.CONSTRUCTOR.getValue()) != 0; - } - - public AnalyzedInstruction getStartOfMethod() { - return startOfMethod; - } - - /** - * @return a read-only list containing the instructions for tihs method. - */ - public List getInstructions() { - return instructions.getValues(); - } - - public ClassDataItem.EncodedMethod getMethod() { - return this.encodedMethod; - } - - public ValidationException getValidationException() { - return validationException; - } - - private static RegisterType[] getParameterTypes(TypeListItem typeListItem, int parameterRegisterCount) { - assert typeListItem != null; - assert parameterRegisterCount == typeListItem.getRegisterCount(); - - RegisterType[] registerTypes = new RegisterType[parameterRegisterCount]; - - int registerNum = 0; - for (TypeIdItem type: typeListItem.getTypes()) { - if (type.getRegisterCount() == 2) { - registerTypes[registerNum++] = RegisterType.getWideRegisterTypeForTypeIdItem(type, true); - registerTypes[registerNum++] = RegisterType.getWideRegisterTypeForTypeIdItem(type, false); - } else { - registerTypes[registerNum++] = RegisterType.getRegisterTypeForTypeIdItem(type); - } - } - - return registerTypes; - } - - public int getInstructionAddress(AnalyzedInstruction instruction) { - return instructions.keyAt(instruction.instructionIndex); - } - - private void setDestinationRegisterTypeAndPropagateChanges(AnalyzedInstruction analyzedInstruction, - RegisterType registerType) { - setPostRegisterTypeAndPropagateChanges(analyzedInstruction, analyzedInstruction.getDestinationRegister(), - registerType); - } - - private void setPostRegisterTypeAndPropagateChanges(AnalyzedInstruction analyzedInstruction, int registerNumber, - RegisterType registerType) { - - BitSet changedInstructions = new BitSet(instructions.size()); - - if (!analyzedInstruction.setPostRegisterType(registerNumber, registerType)) { - return; - } - - propagateRegisterToSuccessors(analyzedInstruction, registerNumber, changedInstructions); - - //Using a for loop inside the while loop optimizes for the common case of the successors of an instruction - //occurring after the instruction. Any successors that occur prior to the instruction will be picked up on - //the next iteration of the while loop. - //This could also be done recursively, but in large methods it would likely cause very deep recursion, - //which requires the user to specify a larger stack size. This isn't really a problem, but it is slightly - //annoying. - while (!changedInstructions.isEmpty()) { - for (int instructionIndex=changedInstructions.nextSetBit(0); - instructionIndex>=0; - instructionIndex=changedInstructions.nextSetBit(instructionIndex+1)) { - - changedInstructions.clear(instructionIndex); - - propagateRegisterToSuccessors(instructions.valueAt(instructionIndex), registerNumber, - changedInstructions); - } - } - - if (registerType.category == RegisterType.Category.LongLo) { - checkWidePair(registerNumber, analyzedInstruction); - setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1, - RegisterType.getRegisterType(RegisterType.Category.LongHi, null)); - } else if (registerType.category == RegisterType.Category.DoubleLo) { - checkWidePair(registerNumber, analyzedInstruction); - setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1, - RegisterType.getRegisterType(RegisterType.Category.DoubleHi, null)); - } - } - - private void propagateRegisterToSuccessors(AnalyzedInstruction instruction, int registerNumber, - BitSet changedInstructions) { - RegisterType postRegisterType = instruction.getPostInstructionRegisterType(registerNumber); - for (AnalyzedInstruction successor: instruction.successors) { - if (successor.mergeRegister(registerNumber, postRegisterType, analyzedInstructions)) { - changedInstructions.set(successor.instructionIndex); - } - } - } - - private void buildInstructionList() { - assert encodedMethod != null; - assert encodedMethod.codeItem != null; - int registerCount = encodedMethod.codeItem.getRegisterCount(); - - Instruction[] insns = encodedMethod.codeItem.getInstructions(); - - instructions = new SparseArray(insns.length); - - //first, create all the instructions and populate the instructionAddresses array - int currentCodeAddress = 0; - for (int i=0; i currentCodeAddress); - - currentTry = tryItem; - - currentExceptionHandlers = buildExceptionHandlerArray(tryItem); - } - } - - //if we're inside a try block, and the instruction can throw an exception, then add the exception handlers - //for the current instruction - if (currentTry != null && instructionOpcode.canThrow()) { - exceptionHandlers[i] = currentExceptionHandlers; - } - } - } - - //finally, populate the successors and predecessors for each instruction. We start at the fake "StartOfMethod" - //instruction and follow the execution path. Any unreachable code won't have any predecessors or successors, - //and no reachable code will have an unreachable predessor or successor - assert instructions.size() > 0; - BitSet instructionsToProcess = new BitSet(insns.length); - - addPredecessorSuccessor(startOfMethod, instructions.valueAt(0), exceptionHandlers, instructionsToProcess); - while (!instructionsToProcess.isEmpty()) { - int currentInstructionIndex = instructionsToProcess.nextSetBit(0); - instructionsToProcess.clear(currentInstructionIndex); - - AnalyzedInstruction instruction = instructions.valueAt(currentInstructionIndex); - Opcode instructionOpcode = instruction.instruction.opcode; - int instructionCodeAddress = getInstructionAddress(instruction); - - if (instruction.instruction.opcode.canContinue()) { - if (instruction.instruction.opcode != Opcode.NOP || - !instruction.instruction.getFormat().variableSizeFormat) { - - if (currentInstructionIndex == instructions.size() - 1) { - throw new ValidationException("Execution can continue past the last instruction"); - } - - AnalyzedInstruction nextInstruction = instructions.valueAt(currentInstructionIndex+1); - addPredecessorSuccessor(instruction, nextInstruction, exceptionHandlers, instructionsToProcess); - } - } - - if (instruction.instruction instanceof OffsetInstruction) { - OffsetInstruction offsetInstruction = (OffsetInstruction)instruction.instruction; - - if (instructionOpcode == Opcode.PACKED_SWITCH || instructionOpcode == Opcode.SPARSE_SWITCH) { - MultiOffsetInstruction switchDataInstruction = - (MultiOffsetInstruction)instructions.get(instructionCodeAddress + - offsetInstruction.getTargetAddressOffset()).instruction; - for (int targetAddressOffset: switchDataInstruction.getTargets()) { - AnalyzedInstruction targetInstruction = instructions.get(instructionCodeAddress + - targetAddressOffset); - - addPredecessorSuccessor(instruction, targetInstruction, exceptionHandlers, - instructionsToProcess); - } - } else { - int targetAddressOffset = offsetInstruction.getTargetAddressOffset(); - AnalyzedInstruction targetInstruction = instructions.get(instructionCodeAddress + - targetAddressOffset); - addPredecessorSuccessor(instruction, targetInstruction, exceptionHandlers, instructionsToProcess); - } - } - } - } - - private void addPredecessorSuccessor(AnalyzedInstruction predecessor, AnalyzedInstruction successor, - AnalyzedInstruction[][] exceptionHandlers, - BitSet instructionsToProcess) { - addPredecessorSuccessor(predecessor, successor, exceptionHandlers, instructionsToProcess, false); - } - - private void addPredecessorSuccessor(AnalyzedInstruction predecessor, AnalyzedInstruction successor, - AnalyzedInstruction[][] exceptionHandlers, - BitSet instructionsToProcess, boolean allowMoveException) { - - if (!allowMoveException && successor.instruction.opcode == Opcode.MOVE_EXCEPTION) { - throw new ValidationException("Execution can pass from the " + predecessor.instruction.opcode.name + - " instruction at code address 0x" + Integer.toHexString(getInstructionAddress(predecessor)) + - " to the move-exception instruction at address 0x" + - Integer.toHexString(getInstructionAddress(successor))); - } - - if (!successor.addPredecessor(predecessor)) { - return; - } - - predecessor.addSuccessor(successor); - instructionsToProcess.set(successor.getInstructionIndex()); - - - //if the successor can throw an instruction, then we need to add the exception handlers as additional - //successors to the predecessor (and then apply this same logic recursively if needed) - //Technically, we should handle the monitor-exit instruction as a special case. The exception is actually - //thrown *after* the instruction executes, instead of "before" the instruction executes, lke for any other - //instruction. But since it doesn't modify any registers, we can treat it like any other instruction. - AnalyzedInstruction[] exceptionHandlersForSuccessor = exceptionHandlers[successor.instructionIndex]; - if (exceptionHandlersForSuccessor != null) { - //the item for this instruction in exceptionHandlersForSuccessor should only be set if this instruction - //can throw an exception - assert successor.instruction.opcode.canThrow(); - - for (AnalyzedInstruction exceptionHandler: exceptionHandlersForSuccessor) { - addPredecessorSuccessor(predecessor, exceptionHandler, exceptionHandlers, instructionsToProcess, true); - } - } - } - - private AnalyzedInstruction[] buildExceptionHandlerArray(CodeItem.TryItem tryItem) { - int exceptionHandlerCount = tryItem.encodedCatchHandler.handlers.length; - int catchAllHandler = tryItem.encodedCatchHandler.getCatchAllHandlerAddress(); - if (catchAllHandler != -1) { - exceptionHandlerCount++; - } - - AnalyzedInstruction[] exceptionHandlers = new AnalyzedInstruction[exceptionHandlerCount]; - for (int i=0; i Primitive32BitCategories = EnumSet.of( - RegisterType.Category.Null, - RegisterType.Category.One, - RegisterType.Category.Boolean, - RegisterType.Category.Byte, - RegisterType.Category.PosByte, - RegisterType.Category.Short, - RegisterType.Category.PosShort, - RegisterType.Category.Char, - RegisterType.Category.Integer, - RegisterType.Category.Float); - - private static final EnumSet WideLowCategories = EnumSet.of( - RegisterType.Category.LongLo, - RegisterType.Category.DoubleLo); - - private static final EnumSet WideHighCategories = EnumSet.of( - RegisterType.Category.LongHi, - RegisterType.Category.DoubleHi); - - private static final EnumSet ReferenceCategories = EnumSet.of( - RegisterType.Category.Null, - RegisterType.Category.Reference); - - private static final EnumSet ReferenceOrUninitThisCategories = EnumSet.of( - RegisterType.Category.Null, - RegisterType.Category.UninitThis, - RegisterType.Category.Reference); - - private static final EnumSet ReferenceOrUninitCategories = EnumSet.of( - RegisterType.Category.Null, - RegisterType.Category.UninitRef, - RegisterType.Category.UninitThis, - RegisterType.Category.Reference); - - private static final EnumSet ReferenceAndPrimitive32BitCategories = EnumSet.of( - RegisterType.Category.Null, - RegisterType.Category.One, - RegisterType.Category.Boolean, - RegisterType.Category.Byte, - RegisterType.Category.PosByte, - RegisterType.Category.Short, - RegisterType.Category.PosShort, - RegisterType.Category.Char, - RegisterType.Category.Integer, - RegisterType.Category.Float, - RegisterType.Category.Reference); - - private static final EnumSet BooleanCategories = EnumSet.of( - RegisterType.Category.Null, - RegisterType.Category.One, - RegisterType.Category.Boolean); - - private void analyzeMove(AnalyzedInstruction analyzedInstruction) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, sourceRegisterType); - } - - private void verifyMove(AnalyzedInstruction analyzedInstruction, EnumSet validCategories) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), validCategories); - } - - private void analyzeMoveResult(AnalyzedInstruction analyzedInstruction) { - AnalyzedInstruction previousInstruction = instructions.valueAt(analyzedInstruction.instructionIndex-1); - if (!previousInstruction.instruction.opcode.setsResult()) { - throw new ValidationException(analyzedInstruction.instruction.opcode.name + " must occur after an " + - "invoke-*/fill-new-array instruction"); - } - - RegisterType resultRegisterType; - InstructionWithReference invokeInstruction = (InstructionWithReference)previousInstruction.instruction; - Item item = invokeInstruction.getReferencedItem(); - - if (item.getItemType() == ItemType.TYPE_METHOD_ID_ITEM) { - resultRegisterType = RegisterType.getRegisterTypeForTypeIdItem( - ((MethodIdItem)item).getPrototype().getReturnType()); - } else { - assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM; - resultRegisterType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item); - } - - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, resultRegisterType); - } - - private void verifyMoveResult(AnalyzedInstruction analyzedInstruction, - EnumSet allowedCategories) { - if (analyzedInstruction.instructionIndex == 0) { - throw new ValidationException(analyzedInstruction.instruction.opcode.name + " cannot be the first " + - "instruction in a method. It must occur after an invoke-*/fill-new-array instruction"); - } - - AnalyzedInstruction previousInstruction = instructions.valueAt(analyzedInstruction.instructionIndex-1); - - if (!previousInstruction.instruction.opcode.setsResult()) { - throw new ValidationException(analyzedInstruction.instruction.opcode.name + " must occur after an " + - "invoke-*/fill-new-array instruction"); - } - - //TODO: does dalvik allow a move-result after an invoke with a void return type? - RegisterType resultRegisterType; - - InstructionWithReference invokeInstruction = (InstructionWithReference)previousInstruction.getInstruction(); - Item item = invokeInstruction.getReferencedItem(); - - if (item instanceof MethodIdItem) { - resultRegisterType = RegisterType.getRegisterTypeForTypeIdItem( - ((MethodIdItem)item).getPrototype().getReturnType()); - } else { - assert item instanceof TypeIdItem; - resultRegisterType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item); - } - - if (!allowedCategories.contains(resultRegisterType.category)) { - throw new ValidationException(String.format("Wrong move-result* instruction for return value %s", - resultRegisterType.toString())); - } - } - - private void analyzeMoveException(AnalyzedInstruction analyzedInstruction) { - CodeItem.TryItem[] tries = encodedMethod.codeItem.getTries(); - int instructionAddress = getInstructionAddress(analyzedInstruction); - - if (tries == null) { - throw new ValidationException("move-exception must be the first instruction in an exception handler block"); - } - - RegisterType exceptionType = null; - - for (CodeItem.TryItem tryItem: encodedMethod.codeItem.getTries()) { - if (tryItem.encodedCatchHandler.getCatchAllHandlerAddress() == instructionAddress) { - exceptionType = RegisterType.getRegisterType(RegisterType.Category.Reference, - ClassPath.getClassDef("Ljava/lang/Throwable;")); - break; - } - for (CodeItem.EncodedTypeAddrPair handler: tryItem.encodedCatchHandler.handlers) { - if (handler.getHandlerAddress() == instructionAddress) { - exceptionType = RegisterType.getRegisterTypeForTypeIdItem(handler.exceptionType) - .merge(exceptionType); - } - } - } - - if (exceptionType == null) { - throw new ValidationException("move-exception must be the first instruction in an exception handler block"); - } - - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, exceptionType); - } - - private void verifyMoveException(AnalyzedInstruction analyzedInstruction) { - CodeItem.TryItem[] tries = encodedMethod.codeItem.getTries(); - int instructionAddress = getInstructionAddress(analyzedInstruction); - - if (tries == null) { - throw new ValidationException("move-exception must be the first instruction in an exception handler block"); - } - - RegisterType exceptionType = null; - - for (CodeItem.TryItem tryItem: encodedMethod.codeItem.getTries()) { - if (tryItem.encodedCatchHandler.getCatchAllHandlerAddress() == instructionAddress) { - exceptionType = RegisterType.getRegisterType(RegisterType.Category.Reference, - ClassPath.getClassDef("Ljava/lang/Throwable;")); - break; - } - for (CodeItem.EncodedTypeAddrPair handler: tryItem.encodedCatchHandler.handlers) { - if (handler.getHandlerAddress() == instructionAddress) { - exceptionType = RegisterType.getRegisterTypeForTypeIdItem(handler.exceptionType) - .merge(exceptionType); - } - } - } - - if (exceptionType == null) { - throw new ValidationException("move-exception must be the first instruction in an exception handler block"); - } - - //TODO: check if the type is a throwable. Should we throw a ValidationException or print a warning? (does dalvik validate that it's a throwable? It doesn't in CodeVerify.c, but it might check in DexSwapVerify.c) - if (exceptionType.category != RegisterType.Category.Reference) { - throw new ValidationException(String.format("Exception type %s is not a reference type", - exceptionType.toString())); - } - } - - private void analyzeReturnVoidBarrier(AnalyzedInstruction analyzedInstruction) { - analyzeReturnVoidBarrier(analyzedInstruction, true); - } - - private void analyzeReturnVoidBarrier(AnalyzedInstruction analyzedInstruction, boolean analyzeResult) { - Instruction10x instruction = (Instruction10x)analyzedInstruction.instruction; - - Instruction10x deodexedInstruction = new Instruction10x(Opcode.RETURN_VOID); - - analyzedInstruction.setDeodexedInstruction(deodexedInstruction); - - if (analyzeResult) { - analyzeInstruction(analyzedInstruction); - } - } - - private void verifyReturnVoid(AnalyzedInstruction analyzedInstruction) { - TypeIdItem returnType = encodedMethod.method.getPrototype().getReturnType(); - if (returnType.getTypeDescriptor().charAt(0) != 'V') { - //TODO: could add which return-* variation should be used instead - throw new ValidationException("Cannot use return-void with a non-void return type (" + - returnType.getTypeDescriptor() + ")"); - } - } - - private void verifyReturn(AnalyzedInstruction analyzedInstruction, EnumSet validCategories) { - /*if (this.isInstanceConstructor()) { - checkConstructorReturn(analyzedInstruction); - }*/ - - SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; - int returnRegister = instruction.getRegisterA(); - RegisterType returnRegisterType = getAndCheckSourceRegister(analyzedInstruction, returnRegister, - validCategories); - - TypeIdItem returnType = encodedMethod.method.getPrototype().getReturnType(); - if (returnType.getTypeDescriptor().charAt(0) == 'V') { - throw new ValidationException("Cannot use return with a void return type. Use return-void instead"); - } - - RegisterType methodReturnRegisterType = RegisterType.getRegisterTypeForTypeIdItem(returnType); - - if (!validCategories.contains(methodReturnRegisterType.category)) { - //TODO: could add which return-* variation should be used instead - throw new ValidationException(String.format("Cannot use %s with return type %s", - analyzedInstruction.instruction.opcode.name, returnType.getTypeDescriptor())); - } - - if (validCategories == ReferenceCategories) { - if (methodReturnRegisterType.type.isInterface()) { - if (returnRegisterType.category != RegisterType.Category.Null && - !returnRegisterType.type.implementsInterface(methodReturnRegisterType.type)) { - //TODO: how to handle warnings? - } - } else { - if (returnRegisterType.category == RegisterType.Category.Reference && - !returnRegisterType.type.extendsClass(methodReturnRegisterType.type)) { - - throw new ValidationException(String.format("The return value in register v%d (%s) is not " + - "compatible with the method's return type %s", returnRegister, - returnRegisterType.type.getClassType(), methodReturnRegisterType.type.getClassType())); - } - } - } - } - - private void analyzeConst(AnalyzedInstruction analyzedInstruction) { - LiteralInstruction instruction = (LiteralInstruction)analyzedInstruction.instruction; - - RegisterType newDestinationRegisterType = RegisterType.getRegisterTypeForLiteral(instruction.getLiteral()); - - //we assume that the literal value is a valid value for the given instruction type, because it's impossible - //to store an invalid literal with the instruction. so we don't need to check the type of the literal - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, newDestinationRegisterType); - } - - private void analyzeConstHigh16(AnalyzedInstruction analyzedInstruction) { - //the literal value stored in the instruction is a 16-bit value. When shifted left by 16, it will always be an - //integer - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getRegisterType(RegisterType.Category.Integer, null)); - } - - private void analyzeWideConst(AnalyzedInstruction analyzedInstruction) { - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getRegisterType(RegisterType.Category.LongLo, null)); - } - - private void analyzeConstString(AnalyzedInstruction analyzedInstruction) { - ClassPath.ClassDef stringClassDef = ClassPath.getClassDef("Ljava/lang/String;"); - RegisterType stringType = RegisterType.getRegisterType(RegisterType.Category.Reference, stringClassDef); - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, stringType); - } - - private void analyzeConstClass(AnalyzedInstruction analyzedInstruction) { - ClassPath.ClassDef classClassDef = ClassPath.getClassDef("Ljava/lang/Class;"); - RegisterType classType = RegisterType.getRegisterType(RegisterType.Category.Reference, classClassDef); - - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, classType); - } - - - private void verifyConstClass(AnalyzedInstruction analyzedInstruction) { - ClassPath.ClassDef classClassDef = ClassPath.getClassDef("Ljava/lang/Class;"); - RegisterType classType = RegisterType.getRegisterType(RegisterType.Category.Reference, classClassDef); - - InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; - Item item = instruction.getReferencedItem(); - assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM; - - //TODO: need to check class access - //make sure the referenced class is resolvable - ClassPath.getClassDef((TypeIdItem)item); - } - - private void verifyMonitor(AnalyzedInstruction analyzedInstruction) { - SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), ReferenceCategories); - } - - private void analyzeCheckCast(AnalyzedInstruction analyzedInstruction) { - InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; - - Item item = instruction.getReferencedItem(); - assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM; - - RegisterType castRegisterType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item); - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, castRegisterType); - } - - private void verifyCheckCast(AnalyzedInstruction analyzedInstruction) { - { - //ensure the "source" register is a reference type - SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; - - RegisterType registerType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), - ReferenceCategories); - } - - { - //resolve and verify the class that we're casting to - InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; - - Item item = instruction.getReferencedItem(); - assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM; - - //TODO: need to check class access - RegisterType castRegisterType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item); - if (castRegisterType.category != RegisterType.Category.Reference) { - //TODO: verify that dalvik allows a non-reference type.. - //TODO: print a warning, but don't re-throw the exception. dalvik allows a non-reference type during validation (but throws an exception at runtime) - } - } - } - - private void analyzeInstanceOf(AnalyzedInstruction analyzedInstruction) { - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getRegisterType(RegisterType.Category.Boolean, null)); - } - - private void verifyInstanceOf(AnalyzedInstruction analyzedInstruction) { - { - //ensure the register that is being checks is a reference type - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), ReferenceCategories); - } - - { - //resolve and verify the class that we're checking against - InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; - - Item item = instruction.getReferencedItem(); - assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM; - RegisterType registerType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item); - if (registerType.category != RegisterType.Category.Reference) { - throw new ValidationException(String.format("Cannot use instance-of with a non-reference type %s", - registerType.toString())); - } - - //TODO: is it valid to use an array type? - //TODO: could probably do an even more sophisticated check, where we check the possible register types against the specified type. In some cases, we could determine that it always fails, and print a warning to that effect. - } - } - - private void analyzeArrayLength(AnalyzedInstruction analyzedInstruction) { - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getRegisterType(RegisterType.Category.Integer, null)); - } - - private void verifyArrayLength(AnalyzedInstruction analyzedInstruction) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - int arrayRegisterNumber = instruction.getRegisterB(); - RegisterType arrayRegisterType = getAndCheckSourceRegister(analyzedInstruction, arrayRegisterNumber, - ReferenceCategories); - - if (arrayRegisterType.type != null) { - if (arrayRegisterType.type.getClassType().charAt(0) != '[') { - throw new ValidationException(String.format("Cannot use array-length with non-array type %s", - arrayRegisterType.type.getClassType())); - } - assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; - } - } - - private void analyzeNewInstance(AnalyzedInstruction analyzedInstruction) { - InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; - - int register = ((SingleRegisterInstruction)analyzedInstruction.instruction).getRegisterA(); - RegisterType destRegisterType = analyzedInstruction.getPostInstructionRegisterType(register); - if (destRegisterType.category != RegisterType.Category.Unknown) { - assert destRegisterType.category == RegisterType.Category.UninitRef; - - //the post-instruction destination register will only be set if we have already analyzed this instruction - //at least once. If this is the case, then the uninit reference has already been propagated to all - //successors and nothing else needs to be done. - return; - } - - Item item = instruction.getReferencedItem(); - assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM; - - RegisterType classType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item); - - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getUnitializedReference(classType.type)); - } - - private void verifyNewInstance(AnalyzedInstruction analyzedInstruction) { - InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; - - int register = ((SingleRegisterInstruction)analyzedInstruction.instruction).getRegisterA(); - RegisterType destRegisterType = analyzedInstruction.postRegisterMap[register]; - if (destRegisterType.category != RegisterType.Category.Unknown) { - assert destRegisterType.category == RegisterType.Category.UninitRef; - - //the "post-instruction" destination register will only be set if we've gone over - //this instruction at least once before. If this is the case, then we need to check - //all the other registers, and make sure that none of them contain the same - //uninitialized reference that is in the destination register. - - for (int i=0; i= 1<<16) { - throw new ValidationException(String.format("Invalid register range {v%d .. v%d}. The ending register " + - "is larger than the largest allowed register of v65535.", - instruction.getStartRegister(), - instruction.getStartRegister() + instruction.getRegCount() - 1)); - } - - verifyFilledNewArrayCommon(analyzedInstruction, new Format3rcRegisterIterator(instruction)); - } - - private void verifyFillArrayData(AnalyzedInstruction analyzedInstruction) { - SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; - - int register = instruction.getRegisterA(); - RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(register); - assert registerType != null; - - if (registerType.category == RegisterType.Category.Null) { - return; - } - - if (registerType.category != RegisterType.Category.Reference) { - throw new ValidationException(String.format("Cannot use fill-array-data with non-array register v%d of " + - "type %s", register, registerType.toString())); - } - - assert registerType.type instanceof ClassPath.ArrayClassDef; - ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)registerType.type; - - if (arrayClassDef.getArrayDimensions() != 1) { - throw new ValidationException(String.format("Cannot use fill-array-data with array type %s. It can only " + - "be used with a one-dimensional array of primitives.", arrayClassDef.getClassType())); - } - - int elementWidth; - switch (arrayClassDef.getBaseElementClass().getClassType().charAt(0)) { - case 'Z': - case 'B': - elementWidth = 1; - break; - case 'C': - case 'S': - elementWidth = 2; - break; - case 'I': - case 'F': - elementWidth = 4; - break; - case 'J': - case 'D': - elementWidth = 8; - break; - default: - throw new ValidationException(String.format("Cannot use fill-array-data with array type %s. It can " + - "only be used with a one-dimensional array of primitives.", arrayClassDef.getClassType())); - } - - - int arrayDataAddressOffset = ((OffsetInstruction)analyzedInstruction.instruction).getTargetAddressOffset(); - int arrayDataCodeAddress = getInstructionAddress(analyzedInstruction) + arrayDataAddressOffset; - AnalyzedInstruction arrayDataInstruction = this.instructions.get(arrayDataCodeAddress); - if (arrayDataInstruction == null || arrayDataInstruction.instruction.getFormat() != Format.ArrayData) { - throw new ValidationException(String.format("Could not find an array data structure at code address 0x%x", - arrayDataCodeAddress)); - } - - ArrayDataPseudoInstruction arrayDataPseudoInstruction = - (ArrayDataPseudoInstruction)arrayDataInstruction.instruction; - - if (elementWidth != arrayDataPseudoInstruction.getElementWidth()) { - throw new ValidationException(String.format("The array data at code address 0x%x does not have the " + - "correct element width for array type %s. Expecting element width %d, got element width %d.", - arrayDataCodeAddress, arrayClassDef.getClassType(), elementWidth, - arrayDataPseudoInstruction.getElementWidth())); - } - } - - private void verifyThrow(AnalyzedInstruction analyzedInstruction) { - int register = ((SingleRegisterInstruction)analyzedInstruction.instruction).getRegisterA(); - - RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(register); - assert registerType != null; - - if (registerType.category == RegisterType.Category.Null) { - return; - } - - if (registerType.category != RegisterType.Category.Reference) { - throw new ValidationException(String.format("Cannot use throw with non-reference type %s in register v%d", - registerType.toString(), register)); - } - - assert registerType.type != null; - - if (!registerType.type.extendsClass(ClassPath.getClassDef("Ljava/lang/Throwable;"))) { - throw new ValidationException(String.format("Cannot use throw with non-throwable type %s in register v%d", - registerType.type.getClassType(), register)); - } - } - - private void analyzeArrayDataOrSwitch(AnalyzedInstruction analyzedInstruction) { - int dataAddressOffset = ((OffsetInstruction)analyzedInstruction.instruction).getTargetAddressOffset(); - - int dataCodeAddress = this.getInstructionAddress(analyzedInstruction) + dataAddressOffset; - AnalyzedInstruction dataAnalyzedInstruction = instructions.get(dataCodeAddress); - - if (dataAnalyzedInstruction != null) { - dataAnalyzedInstruction.dead = false; - - //if there is a preceding nop, it's deadness should be the same - AnalyzedInstruction priorInstruction = - instructions.valueAt(dataAnalyzedInstruction.getInstructionIndex()-1); - if (priorInstruction.getInstruction().opcode == Opcode.NOP && - !priorInstruction.getInstruction().getFormat().variableSizeFormat) { - - priorInstruction.dead = false; - } - } - } - - private void verifySwitch(AnalyzedInstruction analyzedInstruction, Format expectedSwitchDataFormat) { - int register = ((SingleRegisterInstruction)analyzedInstruction.instruction).getRegisterA(); - int switchCodeAddressOffset = ((OffsetInstruction)analyzedInstruction.instruction).getTargetAddressOffset(); - - getAndCheckSourceRegister(analyzedInstruction, register, Primitive32BitCategories); - - int switchDataCodeAddress = this.getInstructionAddress(analyzedInstruction) + switchCodeAddressOffset; - AnalyzedInstruction switchDataAnalyzedInstruction = instructions.get(switchDataCodeAddress); - - if (switchDataAnalyzedInstruction == null || - switchDataAnalyzedInstruction.instruction.getFormat() != expectedSwitchDataFormat) { - throw new ValidationException(String.format("There is no %s structure at code address 0x%x", - expectedSwitchDataFormat.name(), switchDataCodeAddress)); - } - } - - private void analyzeFloatWideCmp(AnalyzedInstruction analyzedInstruction) { - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getRegisterType(RegisterType.Category.Byte, null)); - } - - private void verifyFloatWideCmp(AnalyzedInstruction analyzedInstruction, EnumSet validCategories) { - ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), validCategories); - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), validCategories); - } - - private void verifyIfEqNe(AnalyzedInstruction analyzedInstruction) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - RegisterType registerType1 = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA()); - assert registerType1 != null; - - RegisterType registerType2 = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); - assert registerType2 != null; - - if (!( - (ReferenceCategories.contains(registerType1.category) && - ReferenceCategories.contains(registerType2.category)) - || - (Primitive32BitCategories.contains(registerType1.category) && - Primitive32BitCategories.contains(registerType2.category)) - )) { - - throw new ValidationException(String.format("%s cannot be used on registers of dissimilar types %s and " + - "%s. They must both be a reference type or a primitive 32 bit type.", - analyzedInstruction.instruction.opcode.name, registerType1.toString(), registerType2.toString())); - } - } - - private void verifyIf(AnalyzedInstruction analyzedInstruction) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), Primitive32BitCategories); - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), Primitive32BitCategories); - } - - private void verifyIfEqzNez(AnalyzedInstruction analyzedInstruction) { - SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), - ReferenceAndPrimitive32BitCategories); - } - - private void verifyIfz(AnalyzedInstruction analyzedInstruction) { - SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), Primitive32BitCategories); - } - - private void analyze32BitPrimitiveAget(AnalyzedInstruction analyzedInstruction, - RegisterType.Category instructionCategory) { - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getRegisterType(instructionCategory, null)); - } - - private void verify32BitPrimitiveAget(AnalyzedInstruction analyzedInstruction, - RegisterType.Category instructionCategory) { - ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories); - - RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); - assert arrayRegisterType != null; - - if (arrayRegisterType.category != RegisterType.Category.Null) { - if (arrayRegisterType.category != RegisterType.Category.Reference) { - throw new ValidationException(String.format("Cannot use %s with non-array type %s", - analyzedInstruction.instruction.opcode.name, arrayRegisterType.category.toString())); - } - - assert arrayRegisterType.type != null; - if (arrayRegisterType.type.getClassType().charAt(0) != '[') { - throw new ValidationException(String.format("Cannot use %s with non-array type %s", - analyzedInstruction.instruction.opcode.name, arrayRegisterType.type.getClassType())); - } - - assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; - ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type; - - if (arrayClassDef.getArrayDimensions() != 1) { - throw new ValidationException(String.format("Cannot use %s with multi-dimensional array type %s", - analyzedInstruction.instruction.opcode.name, arrayRegisterType.type.getClassType())); - } - - RegisterType arrayBaseType = - RegisterType.getRegisterTypeForType(arrayClassDef.getBaseElementClass().getClassType()); - if (!checkArrayFieldAssignment(arrayBaseType.category, instructionCategory)) { - throw new ValidationException(String.format("Cannot use %s with array type %s. Incorrect array type " + - "for the instruction.", analyzedInstruction.instruction.opcode.name, - arrayRegisterType.type.getClassType())); - } - } - } - - private void analyzeAgetWide(AnalyzedInstruction analyzedInstruction) { - ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; - - RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); - assert arrayRegisterType != null; - - if (arrayRegisterType.category != RegisterType.Category.Null) { - assert arrayRegisterType.type != null; - if (arrayRegisterType.type.getClassType().charAt(0) != '[') { - throw new ValidationException(String.format("Cannot use aget-wide with non-array type %s", - arrayRegisterType.type.getClassType())); - } - - assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; - ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type; - - char arrayBaseType = arrayClassDef.getBaseElementClass().getClassType().charAt(0); - if (arrayBaseType == 'J') { - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getRegisterType(RegisterType.Category.LongLo, null)); - } else if (arrayBaseType == 'D') { - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getRegisterType(RegisterType.Category.DoubleLo, null)); - } else { - throw new ValidationException(String.format("Cannot use aget-wide with array type %s. Incorrect " + - "array type for the instruction.", arrayRegisterType.type.getClassType())); - } - } else { - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getRegisterType(RegisterType.Category.LongLo, null)); - } - } - - private void verifyAgetWide(AnalyzedInstruction analyzedInstruction) { - ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories); - - RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); - assert arrayRegisterType != null; - - if (arrayRegisterType.category != RegisterType.Category.Null) { - if (arrayRegisterType.category != RegisterType.Category.Reference) { - throw new ValidationException(String.format("Cannot use aget-wide with non-array type %s", - arrayRegisterType.category.toString())); - } - - assert arrayRegisterType.type != null; - if (arrayRegisterType.type.getClassType().charAt(0) != '[') { - throw new ValidationException(String.format("Cannot use aget-wide with non-array type %s", - arrayRegisterType.type.getClassType())); - } - - assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; - ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type; - - if (arrayClassDef.getArrayDimensions() != 1) { - throw new ValidationException(String.format("Cannot use aget-wide with multi-dimensional array type %s", - arrayRegisterType.type.getClassType())); - } - - char arrayBaseType = arrayClassDef.getBaseElementClass().getClassType().charAt(0); - if (arrayBaseType != 'J' && arrayBaseType != 'D') { - throw new ValidationException(String.format("Cannot use aget-wide with array type %s. Incorrect " + - "array type for the instruction.", arrayRegisterType.type.getClassType())); - } - } - } - - private void analyzeAgetObject(AnalyzedInstruction analyzedInstruction) { - ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; - - RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); - assert arrayRegisterType != null; - - if (arrayRegisterType.category != RegisterType.Category.Null) { - assert arrayRegisterType.type != null; - if (arrayRegisterType.type.getClassType().charAt(0) != '[') { - throw new ValidationException(String.format("Cannot use aget-object with non-array type %s", - arrayRegisterType.type.getClassType())); - } - - assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; - ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type; - - ClassPath.ClassDef elementClassDef = arrayClassDef.getImmediateElementClass(); - char elementTypePrefix = elementClassDef.getClassType().charAt(0); - if (elementTypePrefix != 'L' && elementTypePrefix != '[') { - throw new ValidationException(String.format("Cannot use aget-object with array type %s. Incorrect " + - "array type for the instruction.", arrayRegisterType.type.getClassType())); - } - - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getRegisterType(RegisterType.Category.Reference, elementClassDef)); - } else { - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getRegisterType(RegisterType.Category.Null, null)); - } - } - - private void verifyAgetObject(AnalyzedInstruction analyzedInstruction) { - ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories); - - RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); - assert arrayRegisterType != null; - - if (arrayRegisterType.category != RegisterType.Category.Null) { - if (arrayRegisterType.category != RegisterType.Category.Reference) { - throw new ValidationException(String.format("Cannot use aget-object with non-array type %s", - arrayRegisterType.category.toString())); - } - - assert arrayRegisterType.type != null; - if (arrayRegisterType.type.getClassType().charAt(0) != '[') { - throw new ValidationException(String.format("Cannot use aget-object with non-array type %s", - arrayRegisterType.type.getClassType())); - } - - assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; - ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type; - - ClassPath.ClassDef elementClassDef = arrayClassDef.getImmediateElementClass(); - char elementTypePrefix = elementClassDef.getClassType().charAt(0); - if (elementTypePrefix != 'L' && elementTypePrefix != '[') { - throw new ValidationException(String.format("Cannot use aget-object with array type %s. Incorrect " + - "array type for the instruction.", arrayRegisterType.type.getClassType())); - } - } - } - - private void verify32BitPrimitiveAput(AnalyzedInstruction analyzedInstruction, - RegisterType.Category instructionCategory) { - ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories); - - RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA()); - assert sourceRegisterType != null; - RegisterType instructionRegisterType = RegisterType.getRegisterType(instructionCategory, null); - if (!sourceRegisterType.canBeAssignedTo(instructionRegisterType)) { - throw new ValidationException(String.format("Cannot use %s with source register type %s.", - analyzedInstruction.instruction.opcode.name, sourceRegisterType.toString())); - } - - - RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); - assert arrayRegisterType != null; - - if (arrayRegisterType.category != RegisterType.Category.Null) { - if (arrayRegisterType.category != RegisterType.Category.Reference) { - throw new ValidationException(String.format("Cannot use %s with non-array type %s", - analyzedInstruction.instruction.opcode.name, arrayRegisterType.category.toString())); - } - - assert arrayRegisterType.type != null; - if (arrayRegisterType.type.getClassType().charAt(0) != '[') { - throw new ValidationException(String.format("Cannot use %s with non-array type %s", - analyzedInstruction.instruction.opcode.name, arrayRegisterType.type.getClassType())); - } - - assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; - ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type; - - if (arrayClassDef.getArrayDimensions() != 1) { - throw new ValidationException(String.format("Cannot use %s with multi-dimensional array type %s", - analyzedInstruction.instruction.opcode.name, arrayRegisterType.type.getClassType())); - } - - RegisterType arrayBaseType = - RegisterType.getRegisterTypeForType(arrayClassDef.getBaseElementClass().getClassType()); - if (!checkArrayFieldAssignment(arrayBaseType.category, instructionCategory)) { - throw new ValidationException(String.format("Cannot use %s with array type %s. Incorrect array type " + - "for the instruction.", analyzedInstruction.instruction.opcode.name, - arrayRegisterType.type.getClassType())); - } - } - } - - private void verifyAputWide(AnalyzedInstruction analyzedInstruction) { - ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories); - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), WideLowCategories); - - RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); - assert arrayRegisterType != null; - - if (arrayRegisterType.category != RegisterType.Category.Null) { - if (arrayRegisterType.category != RegisterType.Category.Reference) { - throw new ValidationException(String.format("Cannot use aput-wide with non-array type %s", - arrayRegisterType.category.toString())); - } - - assert arrayRegisterType.type != null; - if (arrayRegisterType.type.getClassType().charAt(0) != '[') { - throw new ValidationException(String.format("Cannot use aput-wide with non-array type %s", - arrayRegisterType.type.getClassType())); - } - - assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; - ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type; - - if (arrayClassDef.getArrayDimensions() != 1) { - throw new ValidationException(String.format("Cannot use aput-wide with multi-dimensional array type %s", - arrayRegisterType.type.getClassType())); - } - - char arrayBaseType = arrayClassDef.getBaseElementClass().getClassType().charAt(0); - if (arrayBaseType != 'J' && arrayBaseType != 'D') { - throw new ValidationException(String.format("Cannot use aput-wide with array type %s. Incorrect " + - "array type for the instruction.", arrayRegisterType.type.getClassType())); - } - } - } - - private void verifyAputObject(AnalyzedInstruction analyzedInstruction) { - ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories); - - RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA()); - assert sourceRegisterType != null; - - //TODO: ensure sourceRegisterType is a Reference type? - - RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); - assert arrayRegisterType != null; - - if (arrayRegisterType.category != RegisterType.Category.Null) { - //don't check the source type against the array type, just make sure it is an array of reference types - - if (arrayRegisterType.category != RegisterType.Category.Reference) { - throw new ValidationException(String.format("Cannot use aget-object with non-array type %s", - arrayRegisterType.category.toString())); - } - - assert arrayRegisterType.type != null; - if (arrayRegisterType.type.getClassType().charAt(0) != '[') { - throw new ValidationException(String.format("Cannot use aget-object with non-array type %s", - arrayRegisterType.type.getClassType())); - } - - assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef; - ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type; - - ClassPath.ClassDef elementClassDef = arrayClassDef.getImmediateElementClass(); - char elementTypePrefix = elementClassDef.getClassType().charAt(0); - if (elementTypePrefix != 'L' && elementTypePrefix != '[') { - throw new ValidationException(String.format("Cannot use aget-object with array type %s. Incorrect " + - "array type for the instruction.", arrayRegisterType.type.getClassType())); - } - } - } - - private void analyze32BitPrimitiveIget(AnalyzedInstruction analyzedInstruction, - RegisterType.Category instructionCategory) { - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getRegisterType(instructionCategory, null)); - } - - private void verify32BitPrimitiveIget(AnalyzedInstruction analyzedInstruction, - RegisterType.Category instructionCategory) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), - ReferenceOrUninitThisCategories); - - //TODO: check access - Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); - assert referencedItem instanceof FieldIdItem; - FieldIdItem field = (FieldIdItem)referencedItem; - - if (objectRegisterType.category != RegisterType.Category.Null && - !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) { - throw new ValidationException(String.format("Cannot access field %s through type %s", - field.getFieldString(), objectRegisterType.type.getClassType())); - } - - RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); - - if (!checkArrayFieldAssignment(fieldType.category, instructionCategory)) { - throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + - "for the instruction.", analyzedInstruction.instruction.opcode.name, - field.getFieldString())); - } - } - - private void analyzeIgetWideObject(AnalyzedInstruction analyzedInstruction) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); - assert referencedItem instanceof FieldIdItem; - FieldIdItem field = (FieldIdItem)referencedItem; - - RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, fieldType); - } - - private void verifyIgetWide(AnalyzedInstruction analyzedInstruction) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), - ReferenceOrUninitThisCategories); - - //TODO: check access - Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); - assert referencedItem instanceof FieldIdItem; - FieldIdItem field = (FieldIdItem)referencedItem; - - if (objectRegisterType.category != RegisterType.Category.Null && - !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) { - throw new ValidationException(String.format("Cannot access field %s through type %s", - field.getFieldString(), objectRegisterType.type.getClassType())); - } - - RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); - - if (!WideLowCategories.contains(fieldType.category)) { - throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + - "for the instruction.", analyzedInstruction.instruction.opcode.name, - field.getFieldString())); - } - } - - private void verifyIgetObject(AnalyzedInstruction analyzedInstruction) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), - ReferenceOrUninitThisCategories); - - //TODO: check access - Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); - assert referencedItem instanceof FieldIdItem; - FieldIdItem field = (FieldIdItem)referencedItem; - - if (objectRegisterType.category != RegisterType.Category.Null && - !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) { - throw new ValidationException(String.format("Cannot access field %s through type %s", - field.getFieldString(), objectRegisterType.type.getClassType())); - } - - RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); - - if (fieldType.category != RegisterType.Category.Reference) { - throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + - "for the instruction.", analyzedInstruction.instruction.opcode.name, - field.getFieldString())); - } - } - - private void verify32BitPrimitiveIput(AnalyzedInstruction analyzedInstruction, - RegisterType.Category instructionCategory) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), - ReferenceOrUninitThisCategories); - - RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA()); - assert sourceRegisterType != null; - - //per CodeVerify.c in dalvik: - //java generates synthetic functions that write byte values into boolean fields - if (sourceRegisterType.category == RegisterType.Category.Byte && - instructionCategory == RegisterType.Category.Boolean) { - - sourceRegisterType = RegisterType.getRegisterType(RegisterType.Category.Boolean, null); - } - - RegisterType instructionRegisterType = RegisterType.getRegisterType(instructionCategory, null); - if (!sourceRegisterType.canBeAssignedTo(instructionRegisterType)) { - throw new ValidationException(String.format("Cannot use %s with source register type %s.", - analyzedInstruction.instruction.opcode.name, sourceRegisterType.toString())); - } - - - //TODO: check access - Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); - assert referencedItem instanceof FieldIdItem; - FieldIdItem field = (FieldIdItem)referencedItem; - - if (objectRegisterType.category != RegisterType.Category.Null && - !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) { - throw new ValidationException(String.format("Cannot access field %s through type %s", - field.getFieldString(), objectRegisterType.type.getClassType())); - } - - RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); - - if (!checkArrayFieldAssignment(fieldType.category, instructionCategory)) { - throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + - "for the instruction.", analyzedInstruction.instruction.opcode.name, - field.getFieldString())); - } - } - - private void verifyIputWide(AnalyzedInstruction analyzedInstruction) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), - ReferenceOrUninitThisCategories); - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), WideLowCategories); - - //TODO: check access - Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); - assert referencedItem instanceof FieldIdItem; - FieldIdItem field = (FieldIdItem)referencedItem; - - if (objectRegisterType.category != RegisterType.Category.Null && - !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) { - throw new ValidationException(String.format("Cannot access field %s through type %s", - field.getFieldString(), objectRegisterType.type.getClassType())); - } - - RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); - - if (!WideLowCategories.contains(fieldType.category)) { - throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + - "for the instruction.", analyzedInstruction.instruction.opcode.name, - field.getFieldString())); - } - } - - private void verifyIputObject(AnalyzedInstruction analyzedInstruction) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), - ReferenceOrUninitThisCategories); - - RegisterType sourceRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), - ReferenceCategories); - - //TODO: check access - Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); - assert referencedItem instanceof FieldIdItem; - FieldIdItem field = (FieldIdItem)referencedItem; - - if (objectRegisterType.category != RegisterType.Category.Null && - !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) { - throw new ValidationException(String.format("Cannot access field %s through type %s", - field.getFieldString(), objectRegisterType.type.getClassType())); - } - - RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); - - if (fieldType.category != RegisterType.Category.Reference) { - throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + - "for the instruction.", analyzedInstruction.instruction.opcode.name, - field.getFieldString())); - } - - if (sourceRegisterType.category != RegisterType.Category.Null && - !fieldType.type.isInterface() && - !sourceRegisterType.type.extendsClass(fieldType.type)) { - - throw new ValidationException(String.format("Cannot store a value of type %s into a field of type %s", - sourceRegisterType.type.getClassType(), fieldType.type.getClassType())); - } - } - - private void analyze32BitPrimitiveSget(AnalyzedInstruction analyzedInstruction, - RegisterType.Category instructionCategory) { - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getRegisterType(instructionCategory, null)); - } - - private void verify32BitPrimitiveSget(AnalyzedInstruction analyzedInstruction, - RegisterType.Category instructionCategory) { - //TODO: check access - Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); - assert referencedItem instanceof FieldIdItem; - FieldIdItem field = (FieldIdItem)referencedItem; - - RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); - - if (!checkArrayFieldAssignment(fieldType.category, instructionCategory)) { - throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + - "for the instruction.", analyzedInstruction.instruction.opcode.name, - field.getFieldString())); - } - } - - private void analyzeSgetWideObject(AnalyzedInstruction analyzedInstruction) { - Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); - assert referencedItem instanceof FieldIdItem; - FieldIdItem field = (FieldIdItem)referencedItem; - - RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, fieldType); - } - - private void verifySgetWide(AnalyzedInstruction analyzedInstruction) { - //TODO: check access - Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); - assert referencedItem instanceof FieldIdItem; - FieldIdItem field = (FieldIdItem)referencedItem; - - RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); - - - if (fieldType.category != RegisterType.Category.LongLo && - fieldType.category != RegisterType.Category.DoubleLo) { - - throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + - "for the instruction.", analyzedInstruction.instruction.opcode.name, - field.getFieldString())); - } - } - - private void verifySgetObject(AnalyzedInstruction analyzedInstruction) { - //TODO: check access - Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); - assert referencedItem instanceof FieldIdItem; - FieldIdItem field = (FieldIdItem)referencedItem; - - RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); - - if (fieldType.category != RegisterType.Category.Reference) { - throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + - "for the instruction.", analyzedInstruction.instruction.opcode.name, - field.getFieldString())); - } - } - - private void verify32BitPrimitiveSput(AnalyzedInstruction analyzedInstruction, - RegisterType.Category instructionCategory) { - SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; - - RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA()); - assert sourceRegisterType != null; - - //per CodeVerify.c in dalvik: - //java generates synthetic functions that write byte values into boolean fields - if (sourceRegisterType.category == RegisterType.Category.Byte && - instructionCategory == RegisterType.Category.Boolean) { - - sourceRegisterType = RegisterType.getRegisterType(RegisterType.Category.Boolean, null); - } - - RegisterType instructionRegisterType = RegisterType.getRegisterType(instructionCategory, null); - if (!sourceRegisterType.canBeAssignedTo(instructionRegisterType)) { - throw new ValidationException(String.format("Cannot use %s with source register type %s.", - analyzedInstruction.instruction.opcode.name, sourceRegisterType.toString())); - } - - //TODO: check access - Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); - assert referencedItem instanceof FieldIdItem; - FieldIdItem field = (FieldIdItem)referencedItem; - - RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); - - if (!checkArrayFieldAssignment(fieldType.category, instructionCategory)) { - throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + - "for the instruction.", analyzedInstruction.instruction.opcode.name, - field.getFieldString())); - } - } - - private void verifySputWide(AnalyzedInstruction analyzedInstruction) { - SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; - - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), WideLowCategories); - - //TODO: check access - Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); - assert referencedItem instanceof FieldIdItem; - FieldIdItem field = (FieldIdItem)referencedItem; - - RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); - - if (!WideLowCategories.contains(fieldType.category)) { - throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + - "for the instruction.", analyzedInstruction.instruction.opcode.name, - field.getFieldString())); - } - } - - private void verifySputObject(AnalyzedInstruction analyzedInstruction) { - SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; - - RegisterType sourceRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), - ReferenceCategories); - - //TODO: check access - Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem(); - assert referencedItem instanceof FieldIdItem; - FieldIdItem field = (FieldIdItem)referencedItem; - - RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType()); - - if (fieldType.category != RegisterType.Category.Reference) { - throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " + - "for the instruction.", analyzedInstruction.instruction.opcode.name, - field.getFieldString())); - } - - if (sourceRegisterType.category != RegisterType.Category.Null && - !fieldType.type.isInterface() && - !sourceRegisterType.type.extendsClass(fieldType.type)) { - - throw new ValidationException(String.format("Cannot store a value of type %s into a field of type %s", - sourceRegisterType.type.getClassType(), fieldType.type.getClassType())); - } - } - - private void analyzeInvokeDirect(AnalyzedInstruction analyzedInstruction) { - FiveRegisterInstruction instruction = (FiveRegisterInstruction)analyzedInstruction.instruction; - analyzeInvokeDirectCommon(analyzedInstruction, new Format35cRegisterIterator(instruction)); - } - - private void verifyInvoke(AnalyzedInstruction analyzedInstruction, int invokeType) { - FiveRegisterInstruction instruction = (FiveRegisterInstruction)analyzedInstruction.instruction; - verifyInvokeCommon(analyzedInstruction, false, invokeType, new Format35cRegisterIterator(instruction)); - } - - private void analyzeInvokeDirectRange(AnalyzedInstruction analyzedInstruction) { - RegisterRangeInstruction instruction = (RegisterRangeInstruction)analyzedInstruction.instruction; - analyzeInvokeDirectCommon(analyzedInstruction, new Format3rcRegisterIterator(instruction)); - } - - private void verifyInvokeRange(AnalyzedInstruction analyzedInstruction, int invokeType) { - RegisterRangeInstruction instruction = (RegisterRangeInstruction)analyzedInstruction.instruction; - verifyInvokeCommon(analyzedInstruction, true, invokeType, new Format3rcRegisterIterator(instruction)); - } - - private static final int INVOKE_VIRTUAL = 0x01; - private static final int INVOKE_SUPER = 0x02; - private static final int INVOKE_DIRECT = 0x04; - private static final int INVOKE_INTERFACE = 0x08; - private static final int INVOKE_STATIC = 0x10; - - private void analyzeInvokeDirectCommon(AnalyzedInstruction analyzedInstruction, RegisterIterator registers) { - //the only time that an invoke instruction changes a register type is when using invoke-direct on a - //constructor () method, which changes the uninitialized reference (and any register that the same - //uninit reference has been copied to) to an initialized reference - - InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction; - - Item item = instruction.getReferencedItem(); - assert item.getItemType() == ItemType.TYPE_METHOD_ID_ITEM; - MethodIdItem methodIdItem = (MethodIdItem)item; - - if (!methodIdItem.getMethodName().getStringValue().equals("")) { - return; - } - - RegisterType objectRegisterType; - //the object register is always the first register - int objectRegister = registers.getRegister(); - - objectRegisterType = analyzedInstruction.getPreInstructionRegisterType(objectRegister); - assert objectRegisterType != null; - - if (objectRegisterType.category != RegisterType.Category.UninitRef && - objectRegisterType.category != RegisterType.Category.UninitThis) { - return; - } - - setPostRegisterTypeAndPropagateChanges(analyzedInstruction, objectRegister, - RegisterType.getRegisterType(RegisterType.Category.Reference, objectRegisterType.type)); - - for (int i=0; i method %s on uninitialized " + - "reference type %s", methodIdItem.getMethodString(), - objectRegisterType.type.getClassType())); - } - } else if (objectRegisterType.category == RegisterType.Category.Reference) { - if (isInit) { - throw new ValidationException(String.format("Cannot invoke %s on initialized reference type %s", - methodIdItem.getMethodString(), objectRegisterType.type.getClassType())); - } - } else if (objectRegisterType.category == RegisterType.Category.Null) { - if (isInit) { - throw new ValidationException(String.format("Cannot invoke %s on a null reference", - methodIdItem.getMethodString())); - } - } - else { - throw new ValidationException(String.format("Cannot invoke %s on non-reference type %s", - methodIdItem.getMethodString(), objectRegisterType.toString())); - } - - if (isInit) { - if (objectRegisterType.type.getSuperclass() == methodClassDef) { - if (!encodedMethod.method.getMethodName().getStringValue().equals("")) { - throw new ValidationException(String.format("Cannot call %s on type %s. The object type must " + - "match the method type exactly", methodIdItem.getMethodString(), - objectRegisterType.type.getClassType())); - } - } - } - - if ((invokeType & INVOKE_INTERFACE) == 0 && objectRegisterType.category != RegisterType.Category.Null && - !objectRegisterType.type.extendsClass(methodClassDef)) { - - throw new ValidationException(String.format("Cannot call method %s on an object of type %s, which " + - "does not extend %s.", methodIdItem.getMethodString(), objectRegisterType.type.getClassType(), - methodClassDef.getClassType())); - } - } - - if (typeListItem != null) { - List parameterTypes = typeListItem.getTypes(); - int parameterTypeIndex = 0; - while (!registers.pastEnd()) { - assert parameterTypeIndex < parameterTypes.size(); - RegisterType parameterType = - RegisterType.getRegisterTypeForTypeIdItem(parameterTypes.get(parameterTypeIndex)); - - int register = registers.getRegister(); - - RegisterType parameterRegisterType; - if (WideLowCategories.contains(parameterType.category)) { - parameterRegisterType = getAndCheckSourceRegister(analyzedInstruction, register, WideLowCategories); - - if (!registers.moveNext()) { - throw new ValidationException(String.format("No 2nd register specified for wide register pair v%d", - parameterTypeIndex+1)); - } - int nextRegister = registers.getRegister(); - - if (nextRegister != register + 1) { - throw new ValidationException(String.format("Invalid wide register pair (v%d, v%d). Registers " + - "must be consecutive.", register, nextRegister)); - } - } else { - parameterRegisterType = analyzedInstruction.getPreInstructionRegisterType(register); - } - - assert parameterRegisterType != null; - - if (!parameterRegisterType.canBeAssignedTo(parameterType)) { - throw new ValidationException( - String.format("Invalid register type %s for parameter %d %s.", - parameterRegisterType.toString(), parameterTypeIndex+1, - parameterType.toString())); - } - - parameterTypeIndex++; - registers.moveNext(); - } - } - } - - private void analyzeUnaryOp(AnalyzedInstruction analyzedInstruction, RegisterType.Category destRegisterCategory) { - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getRegisterType(destRegisterCategory, null)); - } - - private void verifyUnaryOp(AnalyzedInstruction analyzedInstruction, EnumSet validSourceCategories) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), validSourceCategories); - } - - private void analyzeBinaryOp(AnalyzedInstruction analyzedInstruction, RegisterType.Category destRegisterCategory, - boolean checkForBoolean) { - if (checkForBoolean) { - ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; - - RegisterType source1RegisterType = - analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); - RegisterType source2RegisterType = - analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterC()); - - if (BooleanCategories.contains(source1RegisterType.category) && - BooleanCategories.contains(source2RegisterType.category)) { - - destRegisterCategory = RegisterType.Category.Boolean; - } - } - - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getRegisterType(destRegisterCategory, null)); - } - - private void verifyBinaryOp(AnalyzedInstruction analyzedInstruction, EnumSet validSource1Categories, - EnumSet validSource2Categories) { - ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction; - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), validSource1Categories); - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), validSource2Categories); - } - - private void analyzeBinary2AddrOp(AnalyzedInstruction analyzedInstruction, - RegisterType.Category destRegisterCategory, boolean checkForBoolean) { - if (checkForBoolean) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - RegisterType source1RegisterType = - analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA()); - RegisterType source2RegisterType = - analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); - - if (BooleanCategories.contains(source1RegisterType.category) && - BooleanCategories.contains(source2RegisterType.category)) { - - destRegisterCategory = RegisterType.Category.Boolean; - } - } - - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getRegisterType(destRegisterCategory, null)); - } - - private void verifyBinary2AddrOp(AnalyzedInstruction analyzedInstruction, EnumSet validSource1Categories, - EnumSet validSource2Categories) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), validSource1Categories); - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), validSource2Categories); - } - - private void analyzeLiteralBinaryOp(AnalyzedInstruction analyzedInstruction, - RegisterType.Category destRegisterCategory, boolean checkForBoolean) { - if (checkForBoolean) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - RegisterType sourceRegisterType = - analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB()); - - if (BooleanCategories.contains(sourceRegisterType.category)) { - long literal = ((LiteralInstruction)analyzedInstruction.instruction).getLiteral(); - if (literal == 0 || literal == 1) { - destRegisterCategory = RegisterType.Category.Boolean; - } - } - } - - setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, - RegisterType.getRegisterType(destRegisterCategory, null)); - } - - private void verifyLiteralBinaryOp(AnalyzedInstruction analyzedInstruction) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), Primitive32BitCategories); - } - - private RegisterType.Category getDestTypeForLiteralShiftRight(AnalyzedInstruction analyzedInstruction, - boolean signedShift) { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - RegisterType sourceRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), - Primitive32BitCategories); - long literalShift = ((LiteralInstruction)analyzedInstruction.instruction).getLiteral(); - - if (literalShift == 0) { - return sourceRegisterType.category; - } - - RegisterType.Category destRegisterCategory; - if (!signedShift) { - destRegisterCategory = RegisterType.Category.Integer; - } else { - destRegisterCategory = sourceRegisterType.category; - } - - if (literalShift >= 32) { - //TODO: add warning - return destRegisterCategory; - } - - switch (sourceRegisterType.category) { - case Integer: - case Float: - if (!signedShift) { - if (literalShift > 24) { - return RegisterType.Category.PosByte; - } - if (literalShift >= 16) { - return RegisterType.Category.Char; - } - } else { - if (literalShift >= 24) { - return RegisterType.Category.Byte; - } - if (literalShift >= 16) { - return RegisterType.Category.Short; - } - } - break; - case Short: - if (signedShift && literalShift >= 8) { - return RegisterType.Category.Byte; - } - break; - case PosShort: - if (literalShift >= 8) { - return RegisterType.Category.PosByte; - } - break; - case Char: - if (literalShift > 8) { - return RegisterType.Category.PosByte; - } - break; - case Byte: - break; - case PosByte: - return RegisterType.Category.PosByte; - case Null: - case One: - case Boolean: - return RegisterType.Category.Null; - default: - assert false; - } - - return destRegisterCategory; - } - - - private void analyzeExecuteInline(AnalyzedInstruction analyzedInstruction) { - if (deodexUtil == null) { - throw new ValidationException("Cannot analyze an odexed instruction unless we are deodexing"); - } - - Instruction35mi instruction = (Instruction35mi)analyzedInstruction.instruction; - - DeodexUtil.InlineMethod inlineMethod = deodexUtil.lookupInlineMethod(analyzedInstruction); - MethodIdItem inlineMethodIdItem = inlineMethod.getMethodIdItem(deodexUtil); - if (inlineMethodIdItem == null) { - throw new ValidationException(String.format("Cannot load inline method with index %d", - instruction.getInlineIndex())); - } - - Opcode deodexedOpcode = null; - switch (inlineMethod.methodType) { - case DeodexUtil.Direct: - deodexedOpcode = Opcode.INVOKE_DIRECT; - break; - case DeodexUtil.Static: - deodexedOpcode = Opcode.INVOKE_STATIC; - break; - case DeodexUtil.Virtual: - deodexedOpcode = Opcode.INVOKE_VIRTUAL; - break; - default: - assert false; - } - - Instruction35c deodexedInstruction = new Instruction35c(deodexedOpcode, instruction.getRegCount(), - instruction.getRegisterD(), instruction.getRegisterE(), instruction.getRegisterF(), - instruction.getRegisterG(), instruction.getRegisterA(), inlineMethodIdItem); - - analyzedInstruction.setDeodexedInstruction(deodexedInstruction); - - analyzeInstruction(analyzedInstruction); - } - - private void analyzeExecuteInlineRange(AnalyzedInstruction analyzedInstruction) { - if (deodexUtil == null) { - throw new ValidationException("Cannot analyze an odexed instruction unless we are deodexing"); - } - - Instruction3rmi instruction = (Instruction3rmi)analyzedInstruction.instruction; - - DeodexUtil.InlineMethod inlineMethod = deodexUtil.lookupInlineMethod(analyzedInstruction); - MethodIdItem inlineMethodIdItem = inlineMethod.getMethodIdItem(deodexUtil); - if (inlineMethodIdItem == null) { - throw new ValidationException(String.format("Cannot load inline method with index %d", - instruction.getInlineIndex())); - } - - Opcode deodexedOpcode = null; - switch (inlineMethod.methodType) { - case DeodexUtil.Direct: - deodexedOpcode = Opcode.INVOKE_DIRECT_RANGE; - break; - case DeodexUtil.Static: - deodexedOpcode = Opcode.INVOKE_STATIC_RANGE; - break; - case DeodexUtil.Virtual: - deodexedOpcode = Opcode.INVOKE_VIRTUAL_RANGE; - break; - default: - assert false; - } - - Instruction3rc deodexedInstruction = new Instruction3rc(deodexedOpcode, (short)instruction.getRegCount(), - instruction.getStartRegister(), inlineMethodIdItem); - - analyzedInstruction.setDeodexedInstruction(deodexedInstruction); - - analyzeInstruction(analyzedInstruction); - } - - private void analyzeInvokeDirectEmpty(AnalyzedInstruction analyzedInstruction) { - analyzeInvokeDirectEmpty(analyzedInstruction, true); - } - - private void analyzeInvokeDirectEmpty(AnalyzedInstruction analyzedInstruction, boolean analyzeResult) { - Instruction35c instruction = (Instruction35c)analyzedInstruction.instruction; - - Instruction35c deodexedInstruction = new Instruction35c(Opcode.INVOKE_DIRECT, instruction.getRegCount(), - instruction.getRegisterD(), instruction.getRegisterE(), instruction.getRegisterF(), - instruction.getRegisterG(), instruction.getRegisterA(), instruction.getReferencedItem()); - - analyzedInstruction.setDeodexedInstruction(deodexedInstruction); - - if (analyzeResult) { - analyzeInstruction(analyzedInstruction); - } - } - - private void analyzeInvokeObjectInitRange(AnalyzedInstruction analyzedInstruction) { - analyzeInvokeObjectInitRange(analyzedInstruction, true); - } - - private void analyzeInvokeObjectInitRange(AnalyzedInstruction analyzedInstruction, boolean analyzeResult) { - Instruction3rc instruction = (Instruction3rc)analyzedInstruction.instruction; - - Instruction3rc deodexedInstruction = new Instruction3rc(Opcode.INVOKE_DIRECT_RANGE, - (short)instruction.getRegCount(), instruction.getStartRegister(), instruction.getReferencedItem()); - - analyzedInstruction.setDeodexedInstruction(deodexedInstruction); - - if (analyzeResult) { - analyzeInstruction(analyzedInstruction); - } - } - - private boolean analyzeIputIgetQuick(AnalyzedInstruction analyzedInstruction) { - Instruction22cs instruction = (Instruction22cs)analyzedInstruction.instruction; - - int fieldOffset = instruction.getFieldOffset(); - RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), - ReferenceOrUninitCategories); - - if (objectRegisterType.category == RegisterType.Category.Null) { - return false; - } - - FieldIdItem fieldIdItem = deodexUtil.lookupField(objectRegisterType.type, fieldOffset); - if (fieldIdItem == null) { - throw new ValidationException(String.format("Could not resolve the field in class %s at offset %d", - objectRegisterType.type.getClassType(), fieldOffset)); - } - - String fieldType = fieldIdItem.getFieldType().getTypeDescriptor(); - - Opcode opcode = OdexedFieldInstructionMapper.getAndCheckDeodexedOpcodeForOdexedOpcode(fieldType, instruction.opcode); - - Instruction22c deodexedInstruction = new Instruction22c(opcode, (byte)instruction.getRegisterA(), - (byte)instruction.getRegisterB(), fieldIdItem); - analyzedInstruction.setDeodexedInstruction(deodexedInstruction); - - analyzeInstruction(analyzedInstruction); - - return true; - } - - private boolean analyzeInvokeVirtualQuick(AnalyzedInstruction analyzedInstruction, boolean isSuper, - boolean isRange) { - int methodIndex; - int objectRegister; - - - if (isRange) { - Instruction3rms instruction = (Instruction3rms)analyzedInstruction.instruction; - methodIndex = instruction.getVtableIndex(); - objectRegister = instruction.getStartRegister(); - } else { - Instruction35ms instruction = (Instruction35ms)analyzedInstruction.instruction; - methodIndex = instruction.getVtableIndex(); - objectRegister = instruction.getRegisterD(); - } - - RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, objectRegister, - ReferenceOrUninitCategories); - - if (objectRegisterType.category == RegisterType.Category.Null) { - return false; - } - - MethodIdItem methodIdItem = null; - if (isSuper) { - ClassPath.ClassDef classDef = ClassPath.getClassDef(this.encodedMethod.method.getContainingClass(), false); - assert classDef != null; - - if (classDef.getSuperclass() != null) { - methodIdItem = deodexUtil.lookupVirtualMethod(classDef.getSuperclass(), methodIndex); - } - - if (methodIdItem == null) { - //it's possible that the pre-odexed instruction had used the method from the current class instead - //of from the superclass (although the superclass method is still what would actually be called). - //And so the MethodIdItem for the superclass method may not be in the dex file. Let's try to get the - //MethodIdItem for the method in the current class instead - methodIdItem = deodexUtil.lookupVirtualMethod(classDef, methodIndex); - } - } else{ - methodIdItem = deodexUtil.lookupVirtualMethod(objectRegisterType.type, methodIndex); - } - - if (methodIdItem == null) { - throw new ValidationException(String.format("Could not resolve the method in class %s at index %d", - objectRegisterType.type.getClassType(), methodIndex)); - } - - - Instruction deodexedInstruction; - if (isRange) { - Instruction3rms instruction = (Instruction3rms)analyzedInstruction.instruction; - Opcode opcode; - if (isSuper) { - opcode = Opcode.INVOKE_SUPER_RANGE; - } else { - opcode = Opcode.INVOKE_VIRTUAL_RANGE; - } - - deodexedInstruction = new Instruction3rc(opcode, (short)instruction.getRegCount(), - instruction.getStartRegister(), methodIdItem); - } else { - Instruction35ms instruction = (Instruction35ms)analyzedInstruction.instruction; - Opcode opcode; - if (isSuper) { - opcode = Opcode.INVOKE_SUPER; - } else { - opcode = Opcode.INVOKE_VIRTUAL; - } - - deodexedInstruction = new Instruction35c(opcode, instruction.getRegCount(), - instruction.getRegisterD(), instruction.getRegisterE(), instruction.getRegisterF(), - instruction.getRegisterG(), instruction.getRegisterA(), methodIdItem); - } - - analyzedInstruction.setDeodexedInstruction(deodexedInstruction); - analyzeInstruction(analyzedInstruction); - - return true; - } - - private boolean analyzePutGetVolatile(AnalyzedInstruction analyzedInstruction) { - return analyzePutGetVolatile(analyzedInstruction, true); - } - - private boolean analyzePutGetVolatile(AnalyzedInstruction analyzedInstruction, boolean analyzeResult) { - FieldIdItem fieldIdItem = - (FieldIdItem)(((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem()); - - String fieldType = fieldIdItem.getFieldType().getTypeDescriptor(); - - Opcode opcode = OdexedFieldInstructionMapper.getAndCheckDeodexedOpcodeForOdexedOpcode(fieldType, - analyzedInstruction.instruction.opcode); - - Instruction deodexedInstruction; - - if (analyzedInstruction.instruction.opcode.isOdexedStaticVolatile()) { - SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction; - deodexedInstruction = new Instruction21c(opcode, (byte)instruction.getRegisterA(), fieldIdItem); - } else { - TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction; - - deodexedInstruction = new Instruction22c(opcode, (byte)instruction.getRegisterA(), - (byte)instruction.getRegisterB(), fieldIdItem); - } - - analyzedInstruction.setDeodexedInstruction(deodexedInstruction); - - if (analyzeResult) { - analyzeInstruction(analyzedInstruction); - } - return true; - } - - private static boolean checkArrayFieldAssignment(RegisterType.Category arrayFieldCategory, - RegisterType.Category instructionCategory) { - if (arrayFieldCategory == instructionCategory) { - return true; - } - - if ((arrayFieldCategory == RegisterType.Category.Integer && - instructionCategory == RegisterType.Category.Float) || - (arrayFieldCategory == RegisterType.Category.Float && - instructionCategory == RegisterType.Category.Integer)) { - return true; - } - return false; - } - - private static RegisterType getAndCheckSourceRegister(AnalyzedInstruction analyzedInstruction, int registerNumber, - EnumSet validCategories) { - assert registerNumber >= 0 && registerNumber < analyzedInstruction.postRegisterMap.length; - - RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(registerNumber); - assert registerType != null; - - checkRegister(registerType, registerNumber, validCategories); - - if (validCategories == WideLowCategories) { - checkRegister(registerType, registerNumber, WideLowCategories); - checkWidePair(registerNumber, analyzedInstruction); - - RegisterType secondRegisterType = analyzedInstruction.getPreInstructionRegisterType(registerNumber + 1); - assert secondRegisterType != null; - checkRegister(secondRegisterType, registerNumber+1, WideHighCategories); - } - - return registerType; - } - - private static void checkRegister(RegisterType registerType, int registerNumber, EnumSet validCategories) { - if (!validCategories.contains(registerType.category)) { - throw new ValidationException(String.format("Invalid register type %s for register v%d.", - registerType.toString(), registerNumber)); - } - } - - private static void checkWidePair(int registerNumber, AnalyzedInstruction analyzedInstruction) { - if (registerNumber + 1 >= analyzedInstruction.postRegisterMap.length) { - throw new ValidationException(String.format("v%d cannot be used as the first register in a wide register" + - "pair because it is the last register.", registerNumber)); - } - } - - private static interface RegisterIterator { - int getRegister(); - boolean moveNext(); - int getCount(); - boolean pastEnd(); - } - - private static class Format35cRegisterIterator implements RegisterIterator { - private final int registerCount; - private final int[] registers; - private int currentRegister = 0; - - public Format35cRegisterIterator(FiveRegisterInstruction instruction) { - registerCount = instruction.getRegCount(); - registers = new int[]{instruction.getRegisterD(), instruction.getRegisterE(), - instruction.getRegisterF(), instruction.getRegisterG(), - instruction.getRegisterA()}; - } - - public int getRegister() { - return registers[currentRegister]; - } - - public boolean moveNext() { - currentRegister++; - return !pastEnd(); - } - - public int getCount() { - return registerCount; - } - - public boolean pastEnd() { - return currentRegister >= registerCount; - } - } - - private static class Format3rcRegisterIterator implements RegisterIterator { - private final int startRegister; - private final int registerCount; - private int currentRegister = 0; - - public Format3rcRegisterIterator(RegisterRangeInstruction instruction) { - startRegister = instruction.getStartRegister(); - registerCount = instruction.getRegCount(); - } - - public int getRegister() { - return startRegister + currentRegister; - } - - public boolean moveNext() { - currentRegister++; - return !pastEnd(); - } - - public int getCount() { - return registerCount; - } - - public boolean pastEnd() { - return currentRegister >= registerCount; - } - } -} \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/OdexedFieldInstructionMapper.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/OdexedFieldInstructionMapper.java deleted file mode 100644 index f15f0e51..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/OdexedFieldInstructionMapper.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Analysis; - -import org.jf.dexlib.Code.Opcode; - -public class OdexedFieldInstructionMapper { - private static Opcode[][][][] opcodeMap = new Opcode[][][][] { - //get opcodes - new Opcode[][][] { - //iget quick - new Opcode[][] { - //odexed - new Opcode[] { - /*Z*/ Opcode.IGET_QUICK, - /*B*/ Opcode.IGET_QUICK, - /*S*/ Opcode.IGET_QUICK, - /*C*/ Opcode.IGET_QUICK, - /*I,F*/ Opcode.IGET_QUICK, - /*J,D*/ Opcode.IGET_WIDE_QUICK, - /*L,[*/ Opcode.IGET_OBJECT_QUICK - }, - //deodexed - new Opcode[] { - /*Z*/ Opcode.IGET_BOOLEAN, - /*B*/ Opcode.IGET_BYTE, - /*S*/ Opcode.IGET_SHORT, - /*C*/ Opcode.IGET_CHAR, - /*I,F*/ Opcode.IGET, - /*J,D*/ Opcode.IGET_WIDE, - /*L,[*/ Opcode.IGET_OBJECT - } - }, - //iget volatile - new Opcode[][] { - //odexed - new Opcode[] { - /*Z*/ Opcode.IGET_VOLATILE, - /*B*/ Opcode.IGET_VOLATILE, - /*S*/ Opcode.IGET_VOLATILE, - /*C*/ Opcode.IGET_VOLATILE, - /*I,F*/ Opcode.IGET_VOLATILE, - /*J,D*/ Opcode.IGET_WIDE_VOLATILE, - /*L,[*/ Opcode.IGET_OBJECT_VOLATILE - }, - //deodexed - new Opcode[] { - /*Z*/ Opcode.IGET_BOOLEAN, - /*B*/ Opcode.IGET_BYTE, - /*S*/ Opcode.IGET_SHORT, - /*C*/ Opcode.IGET_CHAR, - /*I,F*/ Opcode.IGET, - /*J,D*/ Opcode.IGET_WIDE, - /*L,[*/ Opcode.IGET_OBJECT - } - }, - //sget volatile - new Opcode[][] { - //odexed - new Opcode[] { - /*Z*/ Opcode.SGET_VOLATILE, - /*B*/ Opcode.SGET_VOLATILE, - /*S*/ Opcode.SGET_VOLATILE, - /*C*/ Opcode.SGET_VOLATILE, - /*I,F*/ Opcode.SGET_VOLATILE, - /*J,D*/ Opcode.SGET_WIDE_VOLATILE, - /*L,[*/ Opcode.SGET_OBJECT_VOLATILE - }, - //deodexed - new Opcode[] { - /*Z*/ Opcode.SGET_BOOLEAN, - /*B*/ Opcode.SGET_BYTE, - /*S*/ Opcode.SGET_SHORT, - /*C*/ Opcode.SGET_CHAR, - /*I,F*/ Opcode.SGET, - /*J,D*/ Opcode.SGET_WIDE, - /*L,[*/ Opcode.SGET_OBJECT - } - } - }, - //put opcodes - new Opcode[][][] { - //iput quick - new Opcode[][] { - //odexed - new Opcode[] { - /*Z*/ Opcode.IPUT_QUICK, - /*B*/ Opcode.IPUT_QUICK, - /*S*/ Opcode.IPUT_QUICK, - /*C*/ Opcode.IPUT_QUICK, - /*I,F*/ Opcode.IPUT_QUICK, - /*J,D*/ Opcode.IPUT_WIDE_QUICK, - /*L,[*/ Opcode.IPUT_OBJECT_QUICK - }, - //deodexed - new Opcode[] { - /*Z*/ Opcode.IPUT_BOOLEAN, - /*B*/ Opcode.IPUT_BYTE, - /*S*/ Opcode.IPUT_SHORT, - /*C*/ Opcode.IPUT_CHAR, - /*I,F*/ Opcode.IPUT, - /*J,D*/ Opcode.IPUT_WIDE, - /*L,[*/ Opcode.IPUT_OBJECT - } - }, - //iput volatile - new Opcode[][] { - //odexed - new Opcode[] { - /*Z*/ Opcode.IPUT_VOLATILE, - /*B*/ Opcode.IPUT_VOLATILE, - /*S*/ Opcode.IPUT_VOLATILE, - /*C*/ Opcode.IPUT_VOLATILE, - /*I,F*/ Opcode.IPUT_VOLATILE, - /*J,D*/ Opcode.IPUT_WIDE_VOLATILE, - /*L,[*/ Opcode.IPUT_OBJECT_VOLATILE - }, - //deodexed - new Opcode[] { - /*Z*/ Opcode.IPUT_BOOLEAN, - /*B*/ Opcode.IPUT_BYTE, - /*S*/ Opcode.IPUT_SHORT, - /*C*/ Opcode.IPUT_CHAR, - /*I,F*/ Opcode.IPUT, - /*J,D*/ Opcode.IPUT_WIDE, - /*L,[*/ Opcode.IPUT_OBJECT - } - }, - //sput volatile - new Opcode[][] { - //odexed - new Opcode[] { - /*Z*/ Opcode.SPUT_VOLATILE, - /*B*/ Opcode.SPUT_VOLATILE, - /*S*/ Opcode.SPUT_VOLATILE, - /*C*/ Opcode.SPUT_VOLATILE, - /*I,F*/ Opcode.SPUT_VOLATILE, - /*J,D*/ Opcode.SPUT_WIDE_VOLATILE, - /*L,[*/ Opcode.SPUT_OBJECT_VOLATILE - }, - //deodexed - new Opcode[] { - /*Z*/ Opcode.SPUT_BOOLEAN, - /*B*/ Opcode.SPUT_BYTE, - /*S*/ Opcode.SPUT_SHORT, - /*C*/ Opcode.SPUT_CHAR, - /*I,F*/ Opcode.SPUT, - /*J,D*/ Opcode.SPUT_WIDE, - /*L,[*/ Opcode.SPUT_OBJECT - } - } - } - }; - - private static int getTypeIndex(char type) { - switch (type) { - case 'Z': - return 0; - case 'B': - return 1; - case 'S': - return 2; - case 'C': - return 3; - case 'I': - case 'F': - return 4; - case 'J': - case 'D': - return 5; - case 'L': - case '[': - return 6; - default: - } - throw new RuntimeException(String.format("Unknown type %s: ", type)); - } - - private static int getOpcodeSubtype(Opcode opcode) { - if (opcode.isOdexedInstanceQuick()) { - return 0; - } else if (opcode.isOdexedInstanceVolatile()) { - return 1; - } else if (opcode.isOdexedStaticVolatile()) { - return 2; - } - throw new RuntimeException(String.format("Not an odexed field access opcode: %s", opcode.name)); - } - - static Opcode getAndCheckDeodexedOpcodeForOdexedOpcode(String fieldType, Opcode odexedOpcode) { - int opcodeType = odexedOpcode.setsRegister()?0:1; - int opcodeSubType = getOpcodeSubtype(odexedOpcode); - int typeIndex = getTypeIndex(fieldType.charAt(0)); - - Opcode correctOdexedOpcode, deodexedOpcode; - - correctOdexedOpcode = opcodeMap[opcodeType][opcodeSubType][0][typeIndex]; - deodexedOpcode = opcodeMap[opcodeType][opcodeSubType][1][typeIndex]; - - if (correctOdexedOpcode != odexedOpcode) { - throw new ValidationException(String.format("Incorrect field type \"%s\" for %s", fieldType, - odexedOpcode.name)); - } - - return deodexedOpcode; - } -} - - diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/RegisterType.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/RegisterType.java deleted file mode 100644 index ed67732a..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/RegisterType.java +++ /dev/null @@ -1,322 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Analysis; - -import org.jf.dexlib.TypeIdItem; - -import java.io.IOException; -import java.io.Writer; -import java.util.HashMap; - -import static org.jf.dexlib.Code.Analysis.ClassPath.ClassDef; - -public class RegisterType { - private final static HashMap internedRegisterTypes = - new HashMap(); - - public final Category category; - public final ClassDef type; - - private RegisterType(Category category, ClassDef type) { - assert ((category == Category.Reference || category == Category.UninitRef || category == Category.UninitThis) && - type != null) || - ((category != Category.Reference && category != Category.UninitRef && category != Category.UninitThis) && - type == null); - - this.category = category; - this.type = type; - } - - @Override - public String toString() { - return "(" + category.name() + (type==null?"":("," + type.getClassType())) + ")"; - } - - public void writeTo(Writer writer) throws IOException { - writer.write('('); - writer.write(category.name()); - if (type != null) { - writer.write(','); - writer.write(type.getClassType()); - } - writer.write(')'); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - RegisterType that = (RegisterType) o; - - if (category != that.category) return false; - if (type != null ? !type.equals(that.type) : that.type != null) return false; - - return true; - } - - @Override - public int hashCode() { - int result = category.hashCode(); - result = 31 * result + (type != null ? type.hashCode() : 0); - return result; - } - - public static enum Category { - //the Unknown category denotes a register type that hasn't been determined yet - Unknown, - Uninit, - Null, - One, - Boolean, - Byte, - PosByte, - Short, - PosShort, - Char, - Integer, - Float, - LongLo, - LongHi, - DoubleLo, - DoubleHi, - //the UninitRef category is used after a new-instance operation, and before the corresponding is called - UninitRef, - //the UninitThis category is used the "this" register inside an method, before the superclass' - //method is called - UninitThis, - Reference, - //This is used when there are multiple incoming execution paths that have incompatible register types. For - //example if the register's type is an Integer on one incomming code path, but is a Reference type on another - //incomming code path. There is no register type that can hold either an Integer or a Reference. - Conflicted; - - //this table is used when merging register types. For example, if a particular register can be either a Byte - //or a Char, then the "merged" type of that register would be Integer, because it is the "smallest" type can - //could hold either type of value. - protected static Category[][] mergeTable = - { - /* Unknown Uninit Null One, Boolean Byte PosByte Short PosShort Char Integer, Float, LongLo LongHi DoubleLo DoubleHi UninitRef UninitThis Reference Conflicted*/ - /*Unknown*/ {Unknown, Uninit, Null, One, Boolean, Byte, PosByte, Short, PosShort, Char, Integer, Float, LongLo, LongHi, DoubleLo, DoubleHi, UninitRef, UninitThis, Reference, Conflicted}, - /*Uninit*/ {Uninit, Uninit, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted}, - /*Null*/ {Null, Conflicted, Null, Boolean, Boolean, Byte, PosByte, Short, PosShort, Char, Integer, Float, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Reference, Conflicted}, - /*One*/ {One, Conflicted, Boolean, One, Boolean, Byte, PosByte, Short, PosShort, Char, Integer, Float, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted}, - /*Boolean*/ {Boolean, Conflicted, Boolean, Boolean, Boolean, Byte, PosByte, Short, PosShort, Char, Integer, Float, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted}, - /*Byte*/ {Byte, Conflicted, Byte, Byte, Byte, Byte, Byte, Short, Short, Integer, Integer, Float, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted}, - /*PosByte*/ {PosByte, Conflicted, PosByte, PosByte, PosByte, Byte, PosByte, Short, PosShort, Char, Integer, Float, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted}, - /*Short*/ {Short, Conflicted, Short, Short, Short, Short, Short, Short, Short, Integer, Integer, Float, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted}, - /*PosShort*/ {PosShort, Conflicted, PosShort, PosShort, PosShort, Short, PosShort, Short, PosShort, Char, Integer, Float, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted}, - /*Char*/ {Char, Conflicted, Char, Char, Char, Integer, Char, Integer, Char, Char, Integer, Float, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted}, - /*Integer*/ {Integer, Conflicted, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted}, - /*Float*/ {Float, Conflicted, Float, Float, Float, Float, Float, Float, Float, Float, Integer, Float, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted}, - /*LongLo*/ {LongLo, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, LongLo, Conflicted, LongLo, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted}, - /*LongHi*/ {LongHi, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, LongHi, Conflicted, LongHi, Conflicted, Conflicted, Conflicted, Conflicted}, - /*DoubleLo*/ {DoubleLo, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, LongLo, Conflicted, DoubleLo, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted}, - /*DoubleHi*/ {DoubleHi, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, LongHi, Conflicted, DoubleHi, Conflicted, Conflicted, Conflicted, Conflicted}, - /*UninitRef*/ {UninitRef, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted}, - /*UninitThis*/ {UninitThis, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, UninitThis, Conflicted, Conflicted}, - /*Reference*/ {Reference, Conflicted, Reference, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Reference, Conflicted}, - /*Conflicted*/ {Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted, Conflicted} - }; - - //this table is used to denote whether a given value type can be assigned to a "slot" of a certain type. For - //example, to determine if you can assign a Boolean value to a particular array "slot", where the array is an - //array of Integers, you would look up assignmentTable[Boolean.ordinal()][Integer.ordinal()] - //Note that not all slot types in the table are expected to be used. For example, it doesn't make sense to - //check if a value can be assigned to an uninitialized reference slot - because there is no such thing. - protected static boolean[][] assigmentTable = - { - /* Unknown Uninit Null One, Boolean Byte PosByte Short PosShort Char Integer, Float, LongLo LongHi DoubleLo DoubleHi UninitRef UninitThis Reference Conflicted |slot type*/ - /*Unknown*/ {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}, - /*Uninit*/ {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}, - /*Null*/ {false, false, true, false, true, true, true, true, true, true, true, true, false, false, false, false, false, false, true, false}, - /*One*/ {false, false, false, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false}, - /*Boolean*/ {false, false, false, false, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false}, - /*Byte*/ {false, false, false, false, false, true, false, true, true, false, true, true, false, false, false, false, false, false, false, false}, - /*PosByte*/ {false, false, false, false, false, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false}, - /*Short*/ {false, false, false, false, false, false, false, true, false, false, true, true, false, false, false, false, false, false, false, false}, - /*PosShort*/ {false, false, false, false, false, false, false, true, true, true, true, true, false, false, false, false, false, false, false, false}, - /*Char*/ {false, false, false, false, false, false, false, false, false, true, true, true, false, false, false, false, false, false, false, false}, - /*Integer*/ {false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false, false, false}, - /*Float*/ {false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false, false, false}, - /*LongLo*/ {false, false, false, false, false, false, false, false, false, false, false, false, true, false, true, false, false, false, false, false}, - /*LongHi*/ {false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, true, false, false, false, false}, - /*DoubleLo*/ {false, false, false, false, false, false, false, false, false, false, false, false, true, false, true, false, false, false, false, false}, - /*DoubleHi*/ {false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, true, false, false, false, false}, - /*UninitRef*/ {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}, - /*UninitThis*/ {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}, - /*Reference*/ {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false}, - /*Conflicted*/ {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false} - /*----------*/ - /*value type*/ - }; - - } - - public static RegisterType getRegisterTypeForType(String type) { - switch (type.charAt(0)) { - case 'V': - throw new ValidationException("The V type can only be used as a method return type"); - case 'Z': - return getRegisterType(Category.Boolean, null); - case 'B': - return getRegisterType(Category.Byte, null); - case 'S': - return getRegisterType(Category.Short, null); - case 'C': - return getRegisterType(Category.Char, null); - case 'I': - return getRegisterType(Category.Integer, null); - case 'F': - return getRegisterType(Category.Float, null); - case 'J': - return getRegisterType(Category.LongLo, null); - case 'D': - return getRegisterType(Category.DoubleLo, null); - case 'L': - case '[': - return getRegisterType(Category.Reference, ClassPath.getClassDef(type)); - default: - throw new RuntimeException("Invalid type: " + type); - } - } - - public static RegisterType getRegisterTypeForTypeIdItem(TypeIdItem typeIdItem) { - return getRegisterTypeForType(typeIdItem.getTypeDescriptor()); - } - - public static RegisterType getWideRegisterTypeForTypeIdItem(TypeIdItem typeIdItem, boolean firstRegister) { - if (typeIdItem.getRegisterCount() == 1) { - throw new RuntimeException("Cannot use this method for non-wide register type: " + - typeIdItem.getTypeDescriptor()); - } - - switch (typeIdItem.getTypeDescriptor().charAt(0)) { - case 'J': - if (firstRegister) { - return getRegisterType(Category.LongLo, null); - } else { - return getRegisterType(Category.LongHi, null); - } - case 'D': - if (firstRegister) { - return getRegisterType(Category.DoubleLo, null); - } else { - return getRegisterType(Category.DoubleHi, null); - } - default: - throw new RuntimeException("Invalid type: " + typeIdItem.getTypeDescriptor()); - } - } - - public static RegisterType getRegisterTypeForLiteral(long literalValue) { - if (literalValue < -32768) { - return getRegisterType(Category.Integer, null); - } - if (literalValue < -128) { - return getRegisterType(Category.Short, null); - } - if (literalValue < 0) { - return getRegisterType(Category.Byte, null); - } - if (literalValue == 0) { - return getRegisterType(Category.Null, null); - } - if (literalValue == 1) { - return getRegisterType(Category.One, null); - } - if (literalValue < 128) { - return getRegisterType(Category.PosByte, null); - } - if (literalValue < 32768) { - return getRegisterType(Category.PosShort, null); - } - if (literalValue < 65536) { - return getRegisterType(Category.Char, null); - } - return getRegisterType(Category.Integer, null); - } - - public RegisterType merge(RegisterType type) { - if (type == null || type == this) { - return this; - } - - Category mergedCategory = Category.mergeTable[this.category.ordinal()][type.category.ordinal()]; - - ClassDef mergedType = null; - if (mergedCategory == Category.Reference) { - if (this.type instanceof ClassPath.UnresolvedClassDef || - type.type instanceof ClassPath.UnresolvedClassDef) { - mergedType = ClassPath.getUnresolvedObjectClassDef(); - } else { - mergedType = ClassPath.getCommonSuperclass(this.type, type.type); - } - } else if (mergedCategory == Category.UninitRef || mergedCategory == Category.UninitThis) { - if (this.category == Category.Unknown) { - return type; - } - assert type.category == Category.Unknown; - return this; - } - return RegisterType.getRegisterType(mergedCategory, mergedType); - } - - public boolean canBeAssignedTo(RegisterType slotType) { - if (Category.assigmentTable[this.category.ordinal()][slotType.category.ordinal()]) { - if (this.category == Category.Reference && slotType.category == Category.Reference) { - if (!slotType.type.isInterface()) { - return this.type.extendsClass(slotType.type); - } - //for verification, we assume all objects implement all interfaces, so we don't verify the type if - //slotType is an interface - } - return true; - } - return false; - } - - public static RegisterType getUnitializedReference(ClassDef classType) { - //We always create a new RegisterType instance for an uninit ref. Each unique uninit RegisterType instance - //is used to track a specific uninitialized reference, so that if multiple registers contain the same - //uninitialized reference, then they can all be upgraded to an initialized reference when the appropriate - // is invoked - return new RegisterType(Category.UninitRef, classType); - } - - public static RegisterType getRegisterType(Category category, ClassDef classType) { - RegisterType newRegisterType = new RegisterType(category, classType); - RegisterType internedRegisterType = internedRegisterTypes.get(newRegisterType); - if (internedRegisterType == null) { - internedRegisterTypes.put(newRegisterType, newRegisterType); - return newRegisterType; - } - return internedRegisterType; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/SyntheticAccessorResolver.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/SyntheticAccessorResolver.java deleted file mode 100644 index 5ad98fe0..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/SyntheticAccessorResolver.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2011 Ben Gruver - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Analysis; - -import org.jf.dexlib.*; -import org.jf.dexlib.Code.Format.Instruction22c; -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.InstructionWithReference; -import org.jf.dexlib.Util.AccessFlags; - -import java.util.HashMap; - -public class SyntheticAccessorResolver { - public static final int METHOD = 0; - public static final int GETTER = 1; - public static final int SETTER = 2; - - private final DexFileClassMap classMap; - private final HashMap resolvedAccessors = new HashMap(); - - public SyntheticAccessorResolver(DexFile dexFile) { - classMap = new DexFileClassMap(dexFile); - } - - public static boolean looksLikeSyntheticAccessor(MethodIdItem methodIdItem) { - return methodIdItem.getMethodName().getStringValue().startsWith("access$"); - } - - public AccessedMember getAccessedMember(MethodIdItem methodIdItem) { - AccessedMember accessedMember = resolvedAccessors.get(methodIdItem); - if (accessedMember != null) { - return accessedMember; - } - - ClassDefItem classDefItem = classMap.getClassDefByType(methodIdItem.getContainingClass()); - if (classDefItem == null) { - return null; - } - - ClassDataItem classDataItem = classDefItem.getClassData(); - if (classDataItem == null) { - return null; - } - - ClassDataItem.EncodedMethod encodedMethod = classDataItem.findDirectMethodByMethodId(methodIdItem); - if (encodedMethod == null) { - return null; - } - - //A synthetic accessor will be marked synthetic - if ((encodedMethod.accessFlags & AccessFlags.SYNTHETIC.getValue()) == 0) { - return null; - } - - Instruction[] instructions = encodedMethod.codeItem.getInstructions(); - - //TODO: add support for odexed formats - switch (instructions[0].opcode.format) { - case Format35c: - case Format3rc: { - //a synthetic method access should be either 2 or 3 instructions, depending on if the method returns - //anything or not - if (instructions.length < 2 || instructions.length > 3) { - return null; - } - InstructionWithReference instruction = (InstructionWithReference)instructions[0]; - Item referencedItem = instruction.getReferencedItem(); - if (!(referencedItem instanceof MethodIdItem)) { - return null; - } - MethodIdItem referencedMethodIdItem = (MethodIdItem)referencedItem; - - accessedMember = new AccessedMember(METHOD, referencedMethodIdItem); - resolvedAccessors.put(methodIdItem, accessedMember); - return accessedMember; - } - case Format22c: { - //a synthetic field access should be exactly 2 instructions. The set/put, and then the return - if (instructions.length != 2) { - return null; - } - Instruction22c instruction = (Instruction22c)instructions[0]; - Item referencedItem = instruction.getReferencedItem(); - if (!(referencedItem instanceof FieldIdItem)) { - return null; - } - FieldIdItem referencedFieldIdItem = (FieldIdItem)referencedItem; - - if (instruction.opcode.setsRegister() || instruction.opcode.setsWideRegister()) { - //If the instruction sets a register, that means it is a getter - it gets the field value and - //stores it in the register - accessedMember = new AccessedMember(GETTER, referencedFieldIdItem); - } else { - accessedMember = new AccessedMember(SETTER, referencedFieldIdItem); - } - - resolvedAccessors.put(methodIdItem, accessedMember); - return accessedMember; - } - default: - return null; - } - } - - public static class AccessedMember { - public final int accessedMemberType; - public final Item accessedMember; - - public AccessedMember(int accessedMemberType, Item accessedMember) { - this.accessedMemberType = accessedMemberType; - this.accessedMember = accessedMember; - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/ValidationException.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/ValidationException.java deleted file mode 100644 index dfc2174b..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/ValidationException.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Analysis; - -import org.jf.util.ExceptionWithContext; - -public class ValidationException extends ExceptionWithContext { - private int codeAddress; - - public ValidationException(int codeAddress, String errorMessage) { - super(errorMessage); - this.codeAddress = codeAddress; - } - - public ValidationException(String errorMessage) { - super(errorMessage); - } - - public void setCodeAddress(int codeAddress) { - this.codeAddress = codeAddress; - } - - public int getCodeAddress() { - return codeAddress; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/EncodedLiteralInstruction.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/EncodedLiteralInstruction.java deleted file mode 100644 index a772dfea..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/EncodedLiteralInstruction.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2012, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code; - -public interface EncodedLiteralInstruction extends LiteralInstruction { - long getDecodedLiteral(); -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/FiveRegisterInstruction.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/FiveRegisterInstruction.java deleted file mode 100644 index b9ff0661..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/FiveRegisterInstruction.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code; - -public interface FiveRegisterInstruction extends InvokeInstruction { - byte getRegisterA(); - byte getRegisterD(); - byte getRegisterE(); - byte getRegisterF(); - byte getRegisterG(); -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/ArrayDataPseudoInstruction.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/ArrayDataPseudoInstruction.java deleted file mode 100644 index 5de88f40..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/ArrayDataPseudoInstruction.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -import java.util.Iterator; - -public class ArrayDataPseudoInstruction extends Instruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private int elementWidth; - private byte[] encodedValues; - - @Override - public int getSize(int codeAddress) { - return ((encodedValues.length + 1)/2) + 4 + (codeAddress % 2); - } - - public ArrayDataPseudoInstruction(int elementWidth, byte[] encodedValues) { - super(Opcode.NOP); - - if (encodedValues.length % elementWidth != 0) { - throw new RuntimeException("There are not a whole number of " + elementWidth + " byte elements"); - } - - this.elementWidth = elementWidth; - this.encodedValues = encodedValues; - } - - public ArrayDataPseudoInstruction(byte[] buffer, int bufferIndex) { - super(Opcode.NOP); - - byte opcodeByte = buffer[bufferIndex]; - if (opcodeByte != 0x00) { - throw new RuntimeException("Invalid opcode byte for an ArrayData pseudo-instruction"); - } - - byte subopcodeByte = buffer[bufferIndex+1]; - if (subopcodeByte != 0x03) { - throw new RuntimeException("Invalid sub-opcode byte for an ArrayData pseudo-instruction"); - } - - this.elementWidth = NumberUtils.decodeUnsignedShort(buffer, bufferIndex+2); - int elementCount = NumberUtils.decodeInt(buffer, bufferIndex+4); - this.encodedValues = new byte[elementCount * elementWidth]; - System.arraycopy(buffer, bufferIndex+8, encodedValues, 0, elementCount * elementWidth); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.alignTo(4); - - int elementCount = encodedValues.length / elementWidth; - - out.writeByte(0x00); - out.writeByte(0x03); - out.writeShort(elementWidth); - out.writeInt(elementCount); - out.write(encodedValues); - - //make sure we're written out an even number of bytes - out.alignTo(2); - } - - protected void annotateInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.annotate(getSize(currentCodeAddress)*2, "[0x" + Integer.toHexString(currentCodeAddress) + "] " + - "fill-array-data instruction"); - } - - public Format getFormat() { - return Format.ArrayData; - } - - public int getElementWidth() { - return elementWidth; - } - - public int getElementCount() { - return encodedValues.length / elementWidth; - } - - public static class ArrayElement { - public final byte[] buffer; - public int bufferIndex; - public final int elementWidth; - public ArrayElement(byte[] buffer, int elementWidth) { - this.buffer = buffer; - this.elementWidth = elementWidth; - } - } - - public Iterator getElements() { - return new Iterator() { - final int elementCount = getElementCount(); - int i=0; - int position=0; - final ArrayElement arrayElement = new ArrayElement(encodedValues, getElementWidth()); - - public boolean hasNext() { - return i 127) { - throw new RuntimeException("The address offset is out of range. It must be in [-128,-1] or [1, 127]"); - } - - out.writeByte(opcode.value); - out.writeByte(targetAddressOffset); - } - - public void updateTargetAddressOffset(int targetAddressOffset) { - this.targetAddressOffset = targetAddressOffset; - } - - public Format getFormat() { - return Format.Format10t; - } - - public int getTargetAddressOffset() { - return targetAddressOffset; - } - - private static class Factory implements InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction10t(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction10x.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction10x.java deleted file mode 100644 index 46ea9686..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction10x.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; - -public class Instruction10x extends Instruction { - public static final InstructionFactory Factory = new Factory(); - - public Instruction10x(Opcode opcode) { - super(opcode); - } - - public Instruction10x(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - assert (buffer[bufferIndex] & 0xFF) == opcode.value; - assert buffer[bufferIndex + 1] == 0x00; - } - - public void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte(0); - } - - public Format getFormat() { - return Format.Format10x; - } - - private static class Factory implements InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction10x(opcode, buffer, bufferIndex); - } - } -} \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction11n.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction11n.java deleted file mode 100644 index 7fae04c3..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction11n.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.LiteralInstruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.SingleRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction11n extends Instruction implements SingleRegisterInstruction, LiteralInstruction { - public static final InstructionFactory Factory = new Factory(); - private byte regA; - private byte litB; - - public Instruction11n(Opcode opcode, byte regA, byte litB) { - super(opcode); - - if (regA >= 1 << 4) { - throw new RuntimeException("The register number must be less than v16"); - } - - if (litB < -(1 << 3) || - litB >= 1 << 3) { - throw new RuntimeException("The literal value must be between -8 and 7 inclusive"); - } - - this.regA = regA; - this.litB = litB; - } - - private Instruction11n(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - this.regA = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]); - this.litB = NumberUtils.decodeHighSignedNibble(buffer[bufferIndex + 1]); - } - - public void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte((litB << 4) | regA); - } - - public Format getFormat() { - return Format.Format11n; - } - - public int getRegisterA() { - return regA; - } - - public long getLiteral() { - return litB; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction11n(opcode, buffer, bufferIndex); - } - } -} \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction11x.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction11x.java deleted file mode 100644 index ca30c7b4..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction11x.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.SingleRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction11x extends Instruction implements SingleRegisterInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regA; - - public Instruction11x(Opcode opcode, short regA) { - super(opcode); - - if (regA >= 1 << 8) { - throw new RuntimeException("The register number must be less than v256"); - } - - this.regA = (byte)regA; - } - - private Instruction11x(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - this.regA = (byte)NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); - } - - public void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte(regA); - } - - public Format getFormat() { - return Format.Format11x; - } - - public int getRegisterA() { - return regA & 0xFF; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction11x(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction12x.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction12x.java deleted file mode 100644 index 6d8d774d..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction12x.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.TwoRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction12x extends Instruction implements TwoRegisterInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private int regA; - private int regB; - - public Instruction12x(Opcode opcode, byte regA, byte regB) { - super(opcode); - - if (regA >= 1 << 4 || - regB >= 1 << 4) { - throw new RuntimeException("The register number must be less than v16"); - } - - this.regA = regA; - this.regB = regB; - } - - private Instruction12x(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - this.regA = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]); - this.regB = NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]); - } - - public void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte((regB << 4) | regA); - } - - public Format getFormat() { - return Format.Format12x; - } - - public int getRegisterA() { - return regA; - } - - public int getRegisterB() { - return regB; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction12x(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction20bc.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction20bc.java deleted file mode 100644 index 75af9df7..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction20bc.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2011 Ben Gruver - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.*; -import org.jf.dexlib.Code.*; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction20bc extends InstructionWithReference { - public static final Instruction.InstructionFactory Factory = new Factory(); - - private VerificationErrorType validationErrorType; - - public Instruction20bc(Opcode opcode, VerificationErrorType validationErrorType, Item referencedItem) { - super(opcode, referencedItem, getReferenceType(referencedItem)); - - this.validationErrorType = validationErrorType; - } - - private static ReferenceType getReferenceType(Item item) { - if (item instanceof TypeIdItem) { - return ReferenceType.type; - } - if (item instanceof FieldIdItem) { - return ReferenceType.field; - } - if (item instanceof MethodIdItem) { - return ReferenceType.method; - } - return null; - } - - private Instruction20bc(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - super(dexFile, opcode, buffer, bufferIndex); - - short val = NumberUtils.decodeUnsignedByte(buffer[bufferIndex+1]); - validationErrorType = VerificationErrorType.getValidationErrorType(val & 0x3f); - } - - protected ReferenceType readReferenceType(Opcode opcode, byte[] buffer, int bufferIndex) { - short val = NumberUtils.decodeUnsignedByte(buffer[bufferIndex+1]); - short referenceType = (short)(val >> 6); - return ReferenceType.fromValidationErrorReferenceType(referenceType); - } - - @Override - public Format getFormat() { - return Format.Format20bc; - } - - @Override - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - if(opcode == Opcode.CONST_STRING && getReferencedItem().getIndex() > 0xFFFF) { - throw new RuntimeException("String offset is too large for const-string. Use string-const/jumbo instead."); - } - - out.writeByte(opcode.value); - out.writeByte((this.getReferenceType().getValidationErrorReferenceType() << 6) & - validationErrorType.getValue()); - - out.writeShort(getReferencedItem().getIndex()); - } - - public VerificationErrorType getValidationErrorType() { - return validationErrorType; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction20bc(dexFile, opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction20t.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction20t.java deleted file mode 100644 index f970cfb5..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction20t.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.OffsetInstruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction20t extends OffsetInstruction { - public static final InstructionFactory Factory = new Factory(); - private int targetAddressOffset; - - public Instruction20t(Opcode opcode, int offA) { - super(opcode); - this.targetAddressOffset = offA; - - if (targetAddressOffset == 0) { - throw new RuntimeException("The address offset cannot be 0. Use goto/32 instead."); - } - - //allow out of range address offsets here, so we have the option of replacing this instruction - //with goto/16 or goto/32 later - } - - private Instruction20t(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - assert buffer[bufferIndex] == opcode.value; - - this.targetAddressOffset = NumberUtils.decodeShort(buffer, bufferIndex+2); - assert targetAddressOffset != 0; - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - if (targetAddressOffset == 0) { - throw new RuntimeException("The address offset cannot be 0. Use goto/32 instead"); - } - - if (targetAddressOffset < -32768 || targetAddressOffset > 32767) { - throw new RuntimeException("The address offset is out of range. It must be in [-32768,-1] or [1, 32768]"); - } - - out.writeByte(opcode.value); - out.writeByte(0x00); - out.writeShort(targetAddressOffset); - } - - public void updateTargetAddressOffset(int targetAddressOffset) { - this.targetAddressOffset = targetAddressOffset; - } - - public Format getFormat() { - return Format.Format20t; - } - - public int getTargetAddressOffset() { - return targetAddressOffset; - } - - private static class Factory implements InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction20t(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction21c.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction21c.java deleted file mode 100644 index 411dc724..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction21c.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.InstructionWithReference; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.SingleRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Item; -import org.jf.dexlib.TypeIdItem; -import org.jf.dexlib.Util.AnnotatedOutput; - -public class Instruction21c extends InstructionWithReference implements SingleRegisterInstruction, - InstructionWithJumboVariant { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regA; - - public Instruction21c(Opcode opcode, short regA, Item referencedItem) { - super(opcode, referencedItem); - - if (regA >= 1 << 8) { - throw new RuntimeException("The register number must be less than v256"); - } - - if (opcode == Opcode.NEW_INSTANCE) { - assert referencedItem instanceof TypeIdItem; - if (((TypeIdItem)referencedItem).getTypeDescriptor().charAt(0) != 'L') { - throw new RuntimeException("Only class references can be used with the new-instance opcode"); - } - } - - this.regA = (byte)regA; - } - - private Instruction21c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - super(dexFile, opcode, buffer, bufferIndex); - - if (opcode == Opcode.NEW_INSTANCE && - ((TypeIdItem)this.getReferencedItem()).getTypeDescriptor().charAt(0) != 'L') { - - throw new RuntimeException("Only class references can be used with the new-instance opcode"); - } - - this.regA = buffer[bufferIndex + 1]; - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - if(getReferencedItem().getIndex() > 0xFFFF) { - if (opcode.hasJumboOpcode()) { - throw new RuntimeException(String.format("%s index is too large. Use the %s instruction instead.", - opcode.referenceType.name(), opcode.getJumboOpcode().name)); - } else { - throw new RuntimeException(String.format("%s index is too large", opcode.referenceType.name())); - } - } - - out.writeByte(opcode.value); - out.writeByte(regA); - out.writeShort(getReferencedItem().getIndex()); - } - - public Format getFormat() { - return Format.Format21c; - } - - public int getRegisterA() { - return regA & 0xFF; - } - - public Instruction makeJumbo() { - Opcode jumboOpcode = opcode.getJumboOpcode(); - if (jumboOpcode == null) { - return null; - } - - return new Instruction31c(jumboOpcode, (short)getRegisterA(), getReferencedItem()); - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction21c(dexFile, opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction21h.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction21h.java deleted file mode 100644 index c063b9aa..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction21h.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.EncodedLiteralInstruction; -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.SingleRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction21h extends Instruction implements SingleRegisterInstruction, EncodedLiteralInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regA; - private short litB; - - public Instruction21h(Opcode opcode, short regA, short litB) { - super(opcode); - - if (regA >= 1 << 8) { - throw new RuntimeException("The register number must be less than v256"); - } - - this.regA = (byte)regA; - this.litB = litB; - } - - private Instruction21h(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - this.regA = buffer[bufferIndex + 1]; - this.litB = NumberUtils.decodeShort(buffer, bufferIndex + 2); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte(regA); - out.writeShort(litB); - } - - public Format getFormat() { - return Format.Format21h; - } - - public int getRegisterA() { - return regA & 0xFF; - } - - public long getLiteral() { - return litB; - } - - public long getDecodedLiteral() { - if (opcode == Opcode.CONST_HIGH16) { - return litB << 16; - } else { - assert opcode == Opcode.CONST_WIDE_HIGH16; - return ((long)litB) << 48; - } - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction21h(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction21s.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction21s.java deleted file mode 100644 index ca507694..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction21s.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.LiteralInstruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.SingleRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction21s extends Instruction implements SingleRegisterInstruction, LiteralInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regA; - private short litB; - - public Instruction21s(Opcode opcode, short regA, short litB) { - super(opcode); - - if (regA >= 1 << 8) { - throw new RuntimeException("The register number must be less than v256"); - } - - this.regA = (byte)regA; - this.litB = litB; - } - - private Instruction21s(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - this.regA = buffer[bufferIndex + 1]; - this.litB = NumberUtils.decodeShort(buffer, bufferIndex + 2); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte(regA); - out.writeShort(litB); - } - - public Format getFormat() { - return Format.Format21s; - } - - public int getRegisterA() { - return regA & 0xFF; - } - - public long getLiteral() { - return litB; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction21s(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction21t.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction21t.java deleted file mode 100644 index f1cd7d27..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction21t.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.OffsetInstruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.SingleRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction21t extends OffsetInstruction implements SingleRegisterInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regA; - private short targetAddressOffset; - - public Instruction21t(Opcode opcode, short regA, short offB) { - super(opcode); - - if (regA >= 1 << 8) { - throw new RuntimeException("The register number must be less than v256"); - } - - if (offB == 0) { - throw new RuntimeException("The address offset cannot be 0."); - } - - this.regA = (byte)regA; - this.targetAddressOffset = offB; - } - - private Instruction21t(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - assert buffer[bufferIndex] == opcode.value; - - regA = buffer[bufferIndex + 1]; - targetAddressOffset = NumberUtils.decodeShort(buffer, bufferIndex + 2); - assert targetAddressOffset != 0; - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte(regA); - out.writeShort(targetAddressOffset); - } - - public void updateTargetAddressOffset(int targetAddressOffset) { - if (targetAddressOffset < Short.MIN_VALUE || targetAddressOffset > Short.MAX_VALUE) { - throw new RuntimeException("The address offset " + targetAddressOffset + - " is out of range. It must be in [-32768, 32767]"); - } - if (targetAddressOffset == 0) { - throw new RuntimeException("The address offset cannot be 0"); - } - this.targetAddressOffset = (short) targetAddressOffset; - } - - public Format getFormat() { - return Format.Format21t; - } - - public int getRegisterA() { - return regA & 0xFF; - } - - public int getTargetAddressOffset() { - return targetAddressOffset; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction21t(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22b.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22b.java deleted file mode 100644 index 19fdbd55..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22b.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.LiteralInstruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.TwoRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; - -public class Instruction22b extends Instruction implements TwoRegisterInstruction, LiteralInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regA; - private byte regB; - private byte litC; - - public Instruction22b(Opcode opcode, short regA, short regB, byte litC) { - super(opcode); - - if (regA >= 1 << 8 || - regB >= 1 << 8) { - throw new RuntimeException("The register number must be less than v256"); - } - - this.regA = (byte)regA; - this.regB = (byte)regB; - this.litC = litC; - } - - private Instruction22b(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - this.regA = buffer[bufferIndex + 1]; - this.regB = buffer[bufferIndex + 2]; - this.litC = buffer[bufferIndex + 3]; - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte(regA); - out.writeByte(regB); - out.writeByte(litC); - } - - public Format getFormat() { - return Format.Format22b; - } - - public int getRegisterA() { - return regA & 0xFF; - } - - public int getRegisterB() { - return regB & 0xFF; - } - - public long getLiteral() { - return litC; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction22b(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22c.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22c.java deleted file mode 100644 index 500ee39c..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22c.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.InstructionWithReference; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.TwoRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Item; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction22c extends InstructionWithReference implements TwoRegisterInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regA; - private byte regB; - - public Instruction22c(Opcode opcode, byte regA, byte regB, Item referencedItem) { - super(opcode, referencedItem); - - if (regA >= 1 << 4 || - regB >= 1 << 4) { - throw new RuntimeException("The register number must be less than v16"); - } - - this.regA = regA; - this.regB = regB; - } - - private Instruction22c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - super(dexFile, opcode, buffer, bufferIndex); - - this.regA = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]); - this.regB = NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - if(getReferencedItem().getIndex() > 0xFFFF) { - if (opcode.hasJumboOpcode()) { - throw new RuntimeException(String.format("%s index is too large. Use the %s instruction instead.", - opcode.referenceType.name(), opcode.getJumboOpcode().name)); - } else { - throw new RuntimeException(String.format("%s index is too large.", opcode.referenceType.name())); - } - } - - out.writeByte(opcode.value); - out.writeByte((regB << 4) | regA); - out.writeShort(getReferencedItem().getIndex()); - } - - public Format getFormat() { - return Format.Format22c; - } - - public int getRegisterA() { - return regA; - } - - public int getRegisterB() { - return regB; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction22c(dexFile, opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22cs.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22cs.java deleted file mode 100644 index 9dc62fae..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22cs.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.OdexedFieldAccess; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.TwoRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction22cs extends Instruction implements TwoRegisterInstruction, OdexedFieldAccess { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regA; - private byte regB; - private short fieldOffset; - - public Instruction22cs(Opcode opcode, byte regA, byte regB, int fieldOffset) { - super(opcode); - - if (regA >= 1 << 4 || - regB >= 1 << 4) { - throw new RuntimeException("The register number must be less than v16"); - } - - if (fieldOffset >= 1 << 16) { - throw new RuntimeException("The field offset must be less than 65536"); - } - - this.regA = regA; - this.regB = regB; - this.fieldOffset = (short)fieldOffset; - } - - private Instruction22cs(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - this.regA = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]); - this.regB = NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]); - this.fieldOffset = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte((regB << 4) | regA); - out.writeShort(fieldOffset); - } - - public Format getFormat() { - return Format.Format22cs; - } - - public int getRegisterA() { - return regA; - } - - public int getRegisterB() { - return regB; - } - - public int getFieldOffset() { - return fieldOffset & 0xFFFF; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction22cs(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22s.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22s.java deleted file mode 100644 index 434a1b20..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22s.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.LiteralInstruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.TwoRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction22s extends Instruction implements TwoRegisterInstruction, LiteralInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regA; - private byte regB; - private short litC; - - public Instruction22s(Opcode opcode, byte regA, byte regB, short litC) { - super(opcode); - - if (regA >= 1 << 4 || - regB >= 1 << 4) { - throw new RuntimeException("The register number must be less than v16"); - } - - this.regA = regA; - this.regB = regB; - this.litC = litC; - } - - private Instruction22s(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - this.regA = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]); - this.regB = NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]); - this.litC = NumberUtils.decodeShort(buffer, bufferIndex + 2); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte((regB << 4) | regA); - out.writeShort(litC); - } - - public Format getFormat() { - return Format.Format22s; - } - - public int getRegisterA() { - return regA; - } - - public int getRegisterB() { - return regB; - } - - public long getLiteral() { - return litC; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction22s(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22t.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22t.java deleted file mode 100644 index 56b8298a..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22t.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.OffsetInstruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.TwoRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction22t extends OffsetInstruction implements TwoRegisterInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regA; - private byte regB; - private short targetAddressOffset; - - public Instruction22t(Opcode opcode, byte regA, byte regB, short offC) { - super(opcode); - - if (regA >= 16 || - regB >= 16) { - throw new RuntimeException("The register number must be less than v16"); - } - - if (offC == 0) { - throw new RuntimeException("The address offset cannot be 0."); - } - - this.regA = regA; - this.regB = regB; - this.targetAddressOffset = offC; - } - - private Instruction22t(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - assert buffer[bufferIndex] == opcode.value; - - regA = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]); - regB = NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]); - targetAddressOffset = NumberUtils.decodeShort(buffer, bufferIndex + 2); - - assert targetAddressOffset != 0; - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte((regB << 4) | regA); - out.writeShort(targetAddressOffset); - } - - public void updateTargetAddressOffset(int targetAddressOffset) { - if (targetAddressOffset < -32768 || targetAddressOffset > 32767) { - throw new RuntimeException("The address offset " + targetAddressOffset + - " is out of range. It must be in [-32768, 32767]"); - } - if (targetAddressOffset == 0) { - throw new RuntimeException("The address offset cannot be 0"); - } - this.targetAddressOffset = (short)targetAddressOffset; - } - - public Format getFormat() { - return Format.Format22t; - } - - public int getRegisterA() { - return regA; - } - - public int getRegisterB() { - return regB; - } - - public int getTargetAddressOffset() { - return targetAddressOffset; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction22t(opcode, buffer, bufferIndex); - } - } -} \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22x.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22x.java deleted file mode 100644 index dc262897..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22x.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.TwoRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction22x extends Instruction implements TwoRegisterInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regA; - private short regB; - - public Instruction22x(Opcode opcode, short regA, int regB) { - super(opcode); - - if (regA >= 1 << 8) { - throw new RuntimeException("The register number must be less than v16"); - } - - if (regB >= 1 << 16) { - throw new RuntimeException("The register number must be less than v65536"); - } - - this.regA = (byte)regA; - this.regB = (short)regB; - } - - private Instruction22x(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - this.regA = buffer[bufferIndex + 1]; - this.regB = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte(regA); - out.writeShort(regB); - } - - public Format getFormat() { - return Format.Format22x; - } - - public int getRegisterA() { - return regA & 0xFF; - } - - public int getRegisterB() { - return regB & 0xFFFF; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction22x(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction23x.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction23x.java deleted file mode 100644 index b9695fcc..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction23x.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.ThreeRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; - -public class Instruction23x extends Instruction implements ThreeRegisterInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regA; - private byte regB; - private byte regC; - - public Instruction23x(Opcode opcode, short regA, short regB, short regC) { - super(opcode); - - if (regA >= 1 << 8 || - regB >= 1 << 8 || - regC >= 1 << 8) { - throw new RuntimeException("The register number must be less than v256"); - } - - this.regA = (byte)regA; - this.regB = (byte)regB; - this.regC = (byte)regC; - } - - private Instruction23x(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - this.regA = buffer[bufferIndex + 1]; - this.regB = buffer[bufferIndex + 2]; - this.regC = buffer[bufferIndex + 3]; - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte(regA); - out.writeByte(regB); - out.writeByte(regC); - } - - public Format getFormat() { - return Format.Format23x; - } - - public int getRegisterA() { - return regA & 0xFF; - } - - public int getRegisterB() { - return regB & 0xFF; - } - - public int getRegisterC() { - return regC & 0xFF; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction23x(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction30t.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction30t.java deleted file mode 100644 index fc83b222..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction30t.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.OffsetInstruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction30t extends OffsetInstruction { - public static final InstructionFactory Factory = new Factory(); - private int targetAddressOffset; - - public Instruction30t(Opcode opcode, int offA) { - super(opcode); - this.targetAddressOffset = offA; - } - - private Instruction30t(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - assert buffer[bufferIndex] == opcode.value; - - this.targetAddressOffset = NumberUtils.decodeInt(buffer, bufferIndex+2); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte(0x00); - out.writeInt(targetAddressOffset); - } - - public void updateTargetAddressOffset(int targetAddressOffset) { - this.targetAddressOffset = targetAddressOffset; - } - - public Format getFormat() { - return Format.Format30t; - } - - public int getTargetAddressOffset() { - return targetAddressOffset; - } - - private static class Factory implements InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction30t(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction31c.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction31c.java deleted file mode 100644 index 4c62c00a..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction31c.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.InstructionWithReference; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.SingleRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Item; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction31c extends InstructionWithJumboReference implements SingleRegisterInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regA; - - public Instruction31c(Opcode opcode, short regA, Item referencedItem) { - super(opcode, referencedItem); - - if (regA >= 1 << 8) { - throw new RuntimeException("The register number must be less than v256"); - } - - this.regA = (byte)regA; - } - - private Instruction31c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - super(dexFile, opcode, buffer, bufferIndex); - - this.regA = buffer[bufferIndex + 1]; - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte(regA); - out.writeInt(getReferencedItem().getIndex()); - } - - public Format getFormat() { - return Format.Format31c; - } - - public int getRegisterA() { - return regA & 0xFF; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction31c(dexFile, opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction31i.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction31i.java deleted file mode 100644 index 5c08ce48..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction31i.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.LiteralInstruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.SingleRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction31i extends Instruction implements SingleRegisterInstruction, LiteralInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regA; - private int litB; - - public Instruction31i(Opcode opcode, short regA, int litB) { - super(opcode); - - if (regA >= 1 << 8) { - throw new RuntimeException("The register number must be less than v256"); - } - - this.regA = (byte)regA; - this.litB = litB; - } - - private Instruction31i(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - this.regA = (byte)NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); - this.litB = NumberUtils.decodeInt(buffer, bufferIndex + 2); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte(regA); - out.writeInt(litB); - } - - public Format getFormat() { - return Format.Format31i; - } - - public int getRegisterA() { - return regA & 0xFF; - } - - public long getLiteral() { - return litB; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction31i(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction31t.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction31t.java deleted file mode 100644 index 55bcc6bf..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction31t.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.OffsetInstruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.SingleRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction31t extends OffsetInstruction implements SingleRegisterInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regA; - private int targetAddressOffset; - - public Instruction31t(Opcode opcode, short regA, int offB) { - super(opcode); - - if (regA >= 1 << 8) { - throw new RuntimeException("The register number must be less than v256"); - } - - this.regA = (byte)regA; - this.targetAddressOffset = offB; - } - - private Instruction31t(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - this.regA = buffer[bufferIndex + 1]; - this.targetAddressOffset = NumberUtils.decodeInt(buffer, bufferIndex + 2); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte(regA); - //align the address offset so that the absolute address is aligned on a 4-byte boundary (2 code block boundary) - out.writeInt(targetAddressOffset + ((currentCodeAddress + targetAddressOffset) % 2)); - } - - public void updateTargetAddressOffset(int targetAddressOffset) { - this.targetAddressOffset = targetAddressOffset; - } - - public Format getFormat() { - return Format.Format31t; - } - - public int getRegisterA() { - return regA & 0xFF; - } - - public int getTargetAddressOffset() { - return targetAddressOffset; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction31t(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction32x.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction32x.java deleted file mode 100644 index 841ab665..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction32x.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.TwoRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction32x extends Instruction implements TwoRegisterInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private short regA; - private short regB; - - public Instruction32x(Opcode opcode, int regA, int regB) { - super(opcode); - - if (regA >= 1<<16 || - regB >= 1<<16) { - throw new RuntimeException("The register number must be less than v65536"); - } - - this.regA = (short)regA; - this.regB = (short)regB; - } - - private Instruction32x(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - this.regA = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2); - this.regB = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 4); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte(0); - out.writeShort(regA); - out.writeShort(regB); - } - - public Format getFormat() { - return Format.Format32x; - } - - public int getRegisterA() { - return regA & 0xFFFF; - } - - public int getRegisterB() { - return regB & 0xFFFF; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction32x(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35c.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35c.java deleted file mode 100644 index dfe69fec..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35c.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.FiveRegisterInstruction; -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.InstructionWithReference; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Item; -import org.jf.dexlib.MethodIdItem; -import org.jf.dexlib.TypeIdItem; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -import static org.jf.dexlib.Code.Opcode.*; - -public class Instruction35c extends InstructionWithReference implements FiveRegisterInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regCount; - private byte regA; - private byte regD; - private byte regE; - private byte regF; - private byte regG; - - public Instruction35c(Opcode opcode, int regCount, byte regD, byte regE, byte regF, byte regG, - byte regA, Item referencedItem) { - super(opcode, referencedItem); - - if (regCount > 5) { - throw new RuntimeException("regCount cannot be greater than 5"); - } - - if (regD >= 1 << 4 || - regE >= 1 << 4 || - regF >= 1 << 4 || - regG >= 1 << 4 || - regA >= 1 << 4) { - throw new RuntimeException("All register args must fit in 4 bits"); - } - - checkItem(opcode, referencedItem, regCount); - - this.regCount = (byte)regCount; - this.regA = regA; - this.regD = regD; - this.regE = regE; - this.regF = regF; - this.regG = regG; - } - - protected Instruction35c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - super(dexFile, opcode, buffer, bufferIndex); - - this.regCount = NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]); - this.regA = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]); - this.regD = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 4]); - this.regE = NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 4]); - this.regF = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 5]); - this.regG = NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 5]); - - if (getRegCount() > 5) { - throw new RuntimeException("regCount cannot be greater than 5"); - } - - checkItem(opcode, getReferencedItem(), getRegCount()); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - if(getReferencedItem().getIndex() > 0xFFFF) { - if (opcode.hasJumboOpcode()) { - throw new RuntimeException(String.format("%s index is too large. Use the %s instruction instead.", - opcode.referenceType.name(), opcode.getJumboOpcode().name)); - } else { - throw new RuntimeException(String.format("%s index is too large.", opcode.referenceType.name())); - } - } - - out.writeByte(opcode.value); - out.writeByte((regCount << 4) | regA); - out.writeShort(getReferencedItem().getIndex()); - out.writeByte((regE << 4) | regD); - out.writeByte((regG << 4) | regF); - } - - public Format getFormat() { - return Format.Format35c; - } - - public int getRegCount() { - return regCount; - } - - public byte getRegisterA() { - return regA; - } - - public byte getRegisterD() { - return regD; - } - - public byte getRegisterE() { - return regE; - } - - public byte getRegisterF() { - return regF; - } - - public byte getRegisterG() { - return regG; - } - - private static void checkItem(Opcode opcode, Item item, int regCount) { - if (opcode == FILLED_NEW_ARRAY) { - //check data for filled-new-array opcode - String type = ((TypeIdItem) item).getTypeDescriptor(); - if (type.charAt(0) != '[') { - throw new RuntimeException("The type must be an array type"); - } - if (type.charAt(1) == 'J' || type.charAt(1) == 'D') { - throw new RuntimeException("The type cannot be an array of longs or doubles"); - } - } else if (opcode.value >= INVOKE_VIRTUAL.value && opcode.value <= INVOKE_INTERFACE.value || - opcode == INVOKE_DIRECT_EMPTY) { - //check data for invoke-* opcodes - MethodIdItem methodIdItem = (MethodIdItem) item; - int parameterRegisterCount = methodIdItem.getPrototype().getParameterRegisterCount(); - if (opcode != INVOKE_STATIC) { - parameterRegisterCount++; - } - if (parameterRegisterCount != regCount) { - throw new RuntimeException("regCount does not match the number of arguments of the method"); - } - } - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction35c(dexFile, opcode, buffer, bufferIndex); - } - } -} \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35mi.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35mi.java deleted file mode 100644 index a204cd71..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35mi.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2011, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.*; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - - -public class Instruction35mi extends Instruction implements FiveRegisterInstruction, OdexedInvokeInline { - public static final InstructionFactory Factory = new Factory(); - private byte regCount; - private byte regA; - private byte regD; - private byte regE; - private byte regF; - private byte regG; - private short inlineIndex; - - public Instruction35mi(Opcode opcode, int regCount, byte regD, byte regE, byte regF, byte regG, - byte regA, int inlineIndex) { - super(opcode); - if (regCount > 5) { - throw new RuntimeException("regCount cannot be greater than 5"); - } - - if (regD >= 1 << 4 || - regE >= 1 << 4 || - regF >= 1 << 4 || - regG >= 1 << 4 || - regA >= 1 << 4) { - throw new RuntimeException("All register args must fit in 4 bits"); - } - - if (inlineIndex >= 1 << 16) { - throw new RuntimeException("The method index must be less than 65536"); - } - - this.regCount = (byte)regCount; - this.regA = regA; - this.regD = regD; - this.regE = regE; - this.regF = regF; - this.regG = regG; - this.inlineIndex = (short)inlineIndex; - } - - private Instruction35mi(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - this.regCount = NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]); - this.regA = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]); - this.regD = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 4]); - this.regE = NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 4]); - this.regF = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 5]); - this.regG = NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 5]); - this.inlineIndex = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte((regCount << 4) | regA); - out.writeShort(inlineIndex); - out.writeByte((regE << 4) | regD); - out.writeByte((regG << 4) | regF); - } - - public Format getFormat() { - return Format.Format35mi; - } - - public int getRegCount() { - return regCount; - } - - public byte getRegisterA() { - return regA; - } - - public byte getRegisterD() { - return regD; - } - - public byte getRegisterE() { - return regE; - } - - public byte getRegisterF() { - return regF; - } - - public byte getRegisterG() { - return regG; - } - - public int getInlineIndex() { - return inlineIndex & 0xFFFF; - } - - private static class Factory implements InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction35mi(opcode, buffer, bufferIndex); - } - } -} - diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35ms.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35ms.java deleted file mode 100644 index 8e9098c1..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction35ms.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.FiveRegisterInstruction; -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.OdexedInvokeVirtual; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - - -public class Instruction35ms extends Instruction implements FiveRegisterInstruction, OdexedInvokeVirtual { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regCount; - private byte regA; - private byte regD; - private byte regE; - private byte regF; - private byte regG; - private short vtableIndex; - - public Instruction35ms(Opcode opcode, int regCount, byte regD, byte regE, byte regF, byte regG, - byte regA, int vtableIndex) { - super(opcode); - if (regCount > 5) { - throw new RuntimeException("regCount cannot be greater than 5"); - } - - if (regD >= 1 << 4 || - regE >= 1 << 4 || - regF >= 1 << 4 || - regG >= 1 << 4 || - regA >= 1 << 4) { - throw new RuntimeException("All register args must fit in 4 bits"); - } - - if (vtableIndex >= 1 << 16) { - throw new RuntimeException("The method index must be less than 65536"); - } - - this.regCount = (byte)regCount; - this.regA = regA; - this.regD = regD; - this.regE = regE; - this.regF = regF; - this.regG = regG; - this.vtableIndex = (short)vtableIndex; - } - - private Instruction35ms(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - this.regCount = NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]); - this.regA = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]); - this.regD = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 4]); - this.regE = NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 4]); - this.regF = NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 5]); - this.regG = NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 5]); - this.vtableIndex = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte((regCount << 4) | regA); - out.writeShort(vtableIndex); - out.writeByte((regE << 4) | regD); - out.writeByte((regG << 4) | regF); - } - - public Format getFormat() { - return Format.Format35ms; - } - - public int getRegCount() { - return regCount; - } - - public byte getRegisterA() { - return regA; - } - - public byte getRegisterD() { - return regD; - } - - public byte getRegisterE() { - return regE; - } - - public byte getRegisterF() { - return regF; - } - - public byte getRegisterG() { - return regG; - } - - public int getVtableIndex() { - return vtableIndex & 0xFFFF; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction35ms(opcode, buffer, bufferIndex); - } - } -} - diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rc.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rc.java deleted file mode 100644 index 5e4d35cf..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rc.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.InstructionWithReference; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.RegisterRangeInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Item; -import org.jf.dexlib.MethodIdItem; -import org.jf.dexlib.TypeIdItem; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -import static org.jf.dexlib.Code.Opcode.*; - -public class Instruction3rc extends InstructionWithReference implements RegisterRangeInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regCount; - private short startReg; - - public Instruction3rc(Opcode opcode, short regCount, int startReg, Item referencedItem) { - super(opcode, referencedItem); - - if (regCount >= 1 << 8) { - throw new RuntimeException("regCount must be less than 256"); - } - if (regCount < 0) { - throw new RuntimeException("regCount cannot be negative"); - } - - if (startReg >= 1 << 16) { - throw new RuntimeException("The beginning register of the range must be less than 65536"); - } - if (startReg < 0) { - throw new RuntimeException("The beginning register of the range cannot be negative"); - } - - this.regCount = (byte)regCount; - this.startReg = (short)startReg; - - checkItem(opcode, referencedItem, regCount); - } - - private Instruction3rc(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - super(dexFile, opcode, buffer, bufferIndex); - - this.regCount = (byte)NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); - this.startReg = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 4); - - checkItem(opcode, getReferencedItem(), getRegCount()); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - if(getReferencedItem().getIndex() > 0xFFFF) { - if (opcode.hasJumboOpcode()) { - throw new RuntimeException(String.format("%s index is too large. Use the %s instruction instead.", - opcode.referenceType.name(), opcode.getJumboOpcode().name)); - } else { - throw new RuntimeException(String.format("%s index is too large.", opcode.referenceType.name())); - } - } - - out.writeByte(opcode.value); - out.writeByte(regCount); - out.writeShort(this.getReferencedItem().getIndex()); - out.writeShort(startReg); - } - - public Format getFormat() { - return Format.Format3rc; - } - - public int getRegCount() { - return (short)(regCount & 0xFF); - } - - public int getStartRegister() { - return startReg & 0xFFFF; - } - - private static void checkItem(Opcode opcode, Item item, int regCount) { - if (opcode == FILLED_NEW_ARRAY_RANGE) { - //check data for filled-new-array/range opcode - String type = ((TypeIdItem) item).getTypeDescriptor(); - if (type.charAt(0) != '[') { - throw new RuntimeException("The type must be an array type"); - } - if (type.charAt(1) == 'J' || type.charAt(1) == 'D') { - throw new RuntimeException("The type cannot be an array of longs or doubles"); - } - } else if (opcode.value >= INVOKE_VIRTUAL_RANGE.value && opcode.value <= INVOKE_INTERFACE_RANGE.value || - opcode == INVOKE_OBJECT_INIT_RANGE) { - //check data for invoke-*/range opcodes - MethodIdItem methodIdItem = (MethodIdItem) item; - int parameterRegisterCount = methodIdItem.getPrototype().getParameterRegisterCount(); - if (opcode != INVOKE_STATIC_RANGE) { - parameterRegisterCount++; - } - if (parameterRegisterCount != regCount) { - throw new RuntimeException("regCount does not match the number of arguments of the method"); - } - } - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction3rc(dexFile, opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rmi.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rmi.java deleted file mode 100644 index 8499f6f0..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rmi.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2011, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.*; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction3rmi extends Instruction implements RegisterRangeInstruction, OdexedInvokeInline { - public static final InstructionFactory Factory = new Factory(); - private byte regCount; - private short startReg; - private short inlineIndex; - - public Instruction3rmi(Opcode opcode, short regCount, int startReg, int inlineIndex) { - super(opcode); - - if (regCount >= 1 << 8) { - throw new RuntimeException("regCount must be less than 256"); - } - if (regCount < 0) { - throw new RuntimeException("regCount cannot be negative"); - } - - if (startReg >= 1 << 16) { - throw new RuntimeException("The beginning register of the range must be less than 65536"); - } - if (startReg < 0) { - throw new RuntimeException("The beginning register of the range cannot be negative"); - } - - if (inlineIndex >= 1 << 16) { - throw new RuntimeException("The method index must be less than 65536"); - } - - this.regCount = (byte)regCount; - this.startReg = (short)startReg; - this.inlineIndex = (short)inlineIndex; - } - - private Instruction3rmi(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - this.regCount = (byte)NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); - this.inlineIndex = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2); - this.startReg = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 4); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte(regCount); - out.writeShort(inlineIndex); - out.writeShort(startReg); - } - - public Format getFormat() { - return Format.Format3rmi; - } - - public int getRegCount() { - return (short)(regCount & 0xFF); - } - - public int getStartRegister() { - return startReg & 0xFFFF; - } - - public int getInlineIndex() { - return inlineIndex & 0xFFFF; - } - - private static class Factory implements InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction3rmi(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rms.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rms.java deleted file mode 100644 index a93c9f72..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction3rms.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.OdexedInvokeVirtual; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.RegisterRangeInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction3rms extends Instruction implements RegisterRangeInstruction, OdexedInvokeVirtual { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regCount; - private short startReg; - private short vtableIndex; - - public Instruction3rms(Opcode opcode, short regCount, int startReg, int vtableIndex) { - super(opcode); - - if (regCount >= 1 << 8) { - throw new RuntimeException("regCount must be less than 256"); - } - if (regCount < 0) { - throw new RuntimeException("regCount cannot be negative"); - } - - if (startReg >= 1 << 16) { - throw new RuntimeException("The beginning register of the range must be less than 65536"); - } - if (startReg < 0) { - throw new RuntimeException("The beginning register of the range cannot be negative"); - } - - if (vtableIndex >= 1 << 16) { - throw new RuntimeException("The method index must be less than 65536"); - } - - this.regCount = (byte)regCount; - this.startReg = (short)startReg; - this.vtableIndex = (short)vtableIndex; - } - - private Instruction3rms(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - this.regCount = (byte)NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); - this.vtableIndex = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2); - this.startReg = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 4); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte(regCount); - out.writeShort(vtableIndex); - out.writeShort(startReg); - } - - public Format getFormat() { - return Format.Format3rms; - } - - public int getRegCount() { - return (short)(regCount & 0xFF); - } - - public int getStartRegister() { - return startReg & 0xFFFF; - } - - public int getVtableIndex() { - return vtableIndex & 0xFFFF; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction3rms(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction51l.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction51l.java deleted file mode 100644 index a627c7a8..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction51l.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.LiteralInstruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.SingleRegisterInstruction; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -public class Instruction51l extends Instruction implements SingleRegisterInstruction, LiteralInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private byte regA; - private long litB; - - public Instruction51l(Opcode opcode, short regA, long litB) { - super(opcode); - - if (regA >= 1 << 8) { - throw new RuntimeException("The register number must be less than v256"); - } - - this.regA = (byte)regA; - this.litB = litB; - } - - private Instruction51l(Opcode opcode, byte[] buffer, int bufferIndex) { - super(opcode); - - regA = (byte)NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); - litB = NumberUtils.decodeLong(buffer, bufferIndex + 2); - } - - protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.writeByte(opcode.value); - out.writeByte(regA); - out.writeLong(litB); - } - - public Format getFormat() { - return Format.Format51l; - } - - public int getRegisterA() { - return regA & 0xFF; - } - - public long getLiteral() { - return litB; - } - - private static class Factory implements Instruction.InstructionFactory { - public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - return new Instruction51l(opcode, buffer, bufferIndex); - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/InstructionWithJumboReference.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/InstructionWithJumboReference.java deleted file mode 100644 index c10e3bd3..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/InstructionWithJumboReference.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2011, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.InstructionWithReference; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.Code.ReferenceType; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Item; -import org.jf.dexlib.Util.NumberUtils; - -public abstract class InstructionWithJumboReference extends InstructionWithReference { - protected InstructionWithJumboReference(Opcode opcode, Item referencedItem) { - super(opcode, referencedItem); - } - - protected InstructionWithJumboReference(Opcode opcode, Item referencedItem, ReferenceType referenceType) { - super(opcode, referencedItem, referenceType); - } - - protected InstructionWithJumboReference(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { - super(dexFile, opcode, buffer, bufferIndex); - } - - protected int getReferencedItemIndex(byte[] buffer, int bufferIndex) { - return NumberUtils.decodeInt(buffer, bufferIndex + 2); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/InstructionWithJumboVariant.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/InstructionWithJumboVariant.java deleted file mode 100644 index 9557e696..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/InstructionWithJumboVariant.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2011, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; - -public interface InstructionWithJumboVariant { - Instruction makeJumbo(); -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/PackedSwitchDataPseudoInstruction.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/PackedSwitchDataPseudoInstruction.java deleted file mode 100644 index 6e88861a..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/Format/PackedSwitchDataPseudoInstruction.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code.Format; - -import org.jf.dexlib.Code.Instruction; -import org.jf.dexlib.Code.MultiOffsetInstruction; -import org.jf.dexlib.Code.Opcode; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.NumberUtils; - -import java.util.Iterator; - -public class PackedSwitchDataPseudoInstruction extends Instruction implements MultiOffsetInstruction { - public static final Instruction.InstructionFactory Factory = new Factory(); - private int firstKey; - private int[] targets; - - @Override - public int getSize(int codeAddress) { - return getTargetCount() * 2 + 4 + (codeAddress % 2); - } - - public PackedSwitchDataPseudoInstruction(int firstKey, int[] targets) { - super(Opcode.NOP); - - if (targets.length > 0xFFFF) { - throw new RuntimeException("The packed-switch data contains too many elements. " + - "The maximum number of switch elements is 65535"); - } - - this.firstKey = firstKey; - this.targets = targets; - } - - public PackedSwitchDataPseudoInstruction(byte[] buffer, int bufferIndex) { - super(Opcode.NOP); - - byte opcodeByte = buffer[bufferIndex]; - if (opcodeByte != 0x00) { - throw new RuntimeException("Invalid opcode byte for a PackedSwitchData pseudo-instruction"); - } - byte subopcodeByte = buffer[bufferIndex+1]; - if (subopcodeByte != 0x01) { - throw new RuntimeException("Invalid sub-opcode byte for a PackedSwitchData pseudo-instruction"); - } - - int targetCount = NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2); - this.firstKey = NumberUtils.decodeInt(buffer, bufferIndex + 4); - this.targets = new int[targetCount]; - - for (int i = 0; i iterateKeysAndTargets() { - return new Iterator() { - final int targetCount = getTargetCount(); - int i = 0; - int value = getFirstKey(); - - PackedSwitchTarget packedSwitchTarget = new PackedSwitchTarget(); - - public boolean hasNext() { - return i 0xFFFF) { - throw new RuntimeException("The sparse-switch data contains too many elements. " + - "The maximum number of switch elements is 65535"); - } - - this.keys = keys; - this.targets = targets; - } - - public SparseSwitchDataPseudoInstruction(byte[] buffer, int bufferIndex) { - super(Opcode.NOP); - - byte opcodeByte = buffer[bufferIndex]; - if (opcodeByte != 0x00) { - throw new RuntimeException("Invalid opcode byte for a SparseSwitchData pseudo-instruction"); - } - byte subopcodeByte = buffer[bufferIndex+1]; - if (subopcodeByte != 0x02) { - throw new RuntimeException("Invalid sub-opcode byte for a SparseSwitchData pseudo-instruction"); - } - - int targetCount = NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2); - keys = new int[targetCount]; - targets = new int[targetCount]; - - for (int i=0; i 0) { - int key = keys[0]; - - out.writeInt(key); - - for (int i = 1; i < keys.length; i++) { - key = keys[i]; - assert key >= keys[i - 1]; - out.writeInt(key); - } - - for (int target : targets) { - out.writeInt(target); - } - } - } - - protected void annotateInstruction(AnnotatedOutput out, int currentCodeAddress) { - out.annotate(getSize(currentCodeAddress)*2, "[0x" + Integer.toHexString(currentCodeAddress) + "] " + - "sparse-switch-data instruction"); - } - - public void updateTarget(int targetIndex, int targetAddressOffset) { - targets[targetIndex] = targetAddressOffset; - } - - public Format getFormat() { - return Format.SparseSwitchData; - } - - public int getTargetCount() { - return targets.length; - } - - public int[] getTargets() { - return targets; - } - - public int[] getKeys() { - return keys; - } - - public static class SparseSwitchTarget { - public int key; - public int targetAddressOffset; - } - - public Iterator iterateKeysAndTargets() { - return new Iterator() { - final int targetCount = getTargetCount(); - int i = 0; - - SparseSwitchTarget sparseSwitchTarget = new SparseSwitchTarget(); - - public boolean hasNext() { - return i opcodesByName; - - //if the instruction can throw an exception - public static final int CAN_THROW = 0x1; - //if the instruction is an odex only instruction - public static final int ODEX_ONLY = 0x2; - //if execution can continue to the next instruction - public static final int CAN_CONTINUE = 0x4; - //if the instruction sets the "hidden" result register - public static final int SETS_RESULT = 0x8; - //if the instruction sets the value of it's first register - public static final int SETS_REGISTER = 0x10; - //if the instruction sets the value of it's first register to a wide type - public static final int SETS_WIDE_REGISTER = 0x20; - //if the instruction is an odexed iget-quick/iput-quick instruction - public static final int ODEXED_INSTANCE_QUICK = 0x40; - //if the instruction is an odexed iget-volatile/iput-volatile instruction - public static final int ODEXED_INSTANCE_VOLATILE = 0x80; - //if the instruction is an odexed sget-volatile/sput-volatile instruction - public static final int ODEXED_STATIC_VOLATILE = 0x100; - //if the instruction is a jumbo instruction - public static final int JUMBO_OPCODE = 0x200; - //if the instruction can initialize an uninitialized object reference - public static final int CAN_INITIALIZE_REFERENCE = 0x400; - - static { - opcodesByValue = new Opcode[256]; - expandedOpcodesByValue = new Opcode[256]; - opcodesByName = new HashMap(); - - for (Opcode opcode: Opcode.values()) { - //INVOKE_DIRECT_EMPTY was changed to INVOKE_OBJECT_INIT_RANGE in ICS - if (opcode != INVOKE_DIRECT_EMPTY) { - if (((opcode.value >> 8) & 0xFF) == 0x00) { - opcodesByValue[opcode.value & 0xFF] = opcode; - } else { - assert ((opcode.value >> 8) & 0xFF) == 0xFF; - expandedOpcodesByValue[opcode.value & 0xFF] = opcode; - } - opcodesByName.put(opcode.name.hashCode(), opcode); - } - } - } - - public static Opcode getOpcodeByName(String opcodeName) { - return opcodesByName.get(opcodeName.toLowerCase().hashCode()); - } - - public static Opcode getOpcodeByValue(short opcodeValue) { - if (((opcodeValue >> 8) & 0xFF) == 0x00) { - return opcodesByValue[opcodeValue & 0xFF]; - } else { - assert ((opcodeValue >> 8) & 0xFF) == 0xFF; - return expandedOpcodesByValue[opcodeValue & 0xFF]; - } - } - - private static void removeOpcodes(Opcode... toRemove) { - for (Opcode opcode: toRemove) { - opcodesByName.remove(opcode.name.toLowerCase().hashCode()); - - if (((opcode.value >> 8) & 0xFF) == 0x00) { - opcodesByValue[opcode.value] = null; - } else { - expandedOpcodesByValue[opcode.value & 0xFF] = null; - } - } - } - - private static void addOpcodes(Opcode... toAdd) { - for (Opcode opcode: toAdd) { - if (((opcode.value >> 8) & 0xFF) == 0x00) { - opcodesByValue[opcode.value & 0xFF] = opcode; - } else { - assert ((opcode.value >> 8) & 0xFF) == 0xFF; - expandedOpcodesByValue[opcode.value & 0xFF] = opcode; - } - opcodesByName.put(opcode.name.hashCode(), opcode); - } - } - - /** - * This will add/remove/replace various opcodes in the value/name maps as needed, - * based on the idiosyncrasies of that api level - * @param apiLevel - */ - public static void updateMapsForApiLevel(int apiLevel) { - if (apiLevel < 5) { - removeOpcodes(THROW_VERIFICATION_ERROR); - } - if (apiLevel < 8) { - removeOpcodes(EXECUTE_INLINE_RANGE); - } - if (apiLevel < 9) { - removeOpcodes(IGET_VOLATILE, IPUT_VOLATILE, SGET_VOLATILE, SPUT_VOLATILE, IGET_OBJECT_VOLATILE, - IGET_WIDE_VOLATILE, IPUT_WIDE_VOLATILE, SGET_WIDE_VOLATILE, SPUT_WIDE_VOLATILE, - IPUT_OBJECT_VOLATILE, SGET_OBJECT_VOLATILE, SPUT_OBJECT_VOLATILE); - } - if (apiLevel < 11) { - removeOpcodes(RETURN_VOID_BARRIER); - } - if (apiLevel < 14) { - removeOpcodes(INVOKE_OBJECT_INIT_RANGE); - addOpcodes(INVOKE_DIRECT_EMPTY); - } - } - - public final short value; - public final String name; - public final ReferenceType referenceType; - public final Format format; - public final int flags; - private final short jumboOpcode; - - Opcode(short opcodeValue, String opcodeName, ReferenceType referenceType, Format format) { - this(opcodeValue, opcodeName, referenceType, format, 0); - } - - Opcode(short opcodeValue, String opcodeName, ReferenceType referenceType, Format format, int flags) { - this(opcodeValue, opcodeName, referenceType, format, flags, (short)-1); - } - - Opcode(short opcodeValue, String opcodeName, ReferenceType referenceType, Format format, int flags, short jumboOpcodeValue) { - this.value = opcodeValue; - this.name = opcodeName; - this.referenceType = referenceType; - this.format = format; - this.flags = flags; - this.jumboOpcode = jumboOpcodeValue; - } - - public final boolean canThrow() { - return (flags & CAN_THROW) != 0; - } - - public final boolean odexOnly() { - return (flags & ODEX_ONLY) != 0; - } - - public final boolean canContinue() { - return (flags & CAN_CONTINUE) != 0; - } - - public final boolean setsResult() { - return (flags & SETS_RESULT) != 0; - } - - public final boolean setsRegister() { - return (flags & SETS_REGISTER) != 0; - } - - public final boolean setsWideRegister() { - return (flags & SETS_WIDE_REGISTER) != 0; - } - - public final boolean isOdexedInstanceQuick() { - return (flags & ODEXED_INSTANCE_QUICK) != 0; - } - - public final boolean isOdexedInstanceVolatile() { - return (flags & ODEXED_INSTANCE_VOLATILE) != 0; - } - - public final boolean isOdexedStaticVolatile() { - return (flags & ODEXED_STATIC_VOLATILE) != 0; - } - - public final boolean isJumboOpcode() { - return (flags & JUMBO_OPCODE) != 0; - } - - public final boolean canInitializeReference() { - return (flags & CAN_INITIALIZE_REFERENCE) != 0; - } - - public final boolean hasJumboOpcode() { - return jumboOpcode != -1 && Opcode.getOpcodeByValue(jumboOpcode) != null; - } - - public final Opcode getJumboOpcode() { - return Opcode.getOpcodeByValue(jumboOpcode); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/ReferenceType.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/ReferenceType.java deleted file mode 100644 index f6d147ab..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/ReferenceType.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code; - -import org.jf.dexlib.*; - -public enum ReferenceType -{ - string(-1), - type(0), - field(1), - method(2), - none(-1); - - private int validationErrorReferenceType; - - private ReferenceType(int validationErrorReferenceType) { - this.validationErrorReferenceType = validationErrorReferenceType; - } - - public boolean checkItem(Item item) { - switch (this) { - case string: - return item instanceof StringIdItem; - case type: - return item instanceof TypeIdItem; - case field: - return item instanceof FieldIdItem; - case method: - return item instanceof MethodIdItem; - } - return false; - } - - public static ReferenceType fromValidationErrorReferenceType(int validationErrorReferenceType) { - switch (validationErrorReferenceType) { - case 0: - return type; - case 1: - return field; - case 2: - return method; - } - return null; - } - - public int getValidationErrorReferenceType() { - if (validationErrorReferenceType == -1) { - throw new RuntimeException("This reference type cannot be referenced from a throw-validation-error" + - " instruction"); - } - return validationErrorReferenceType; - } -} \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/RegisterRangeInstruction.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/RegisterRangeInstruction.java deleted file mode 100644 index 21e37196..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/RegisterRangeInstruction.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code; - -public interface RegisterRangeInstruction extends InvokeInstruction { - int getStartRegister(); -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/SingleRegisterInstruction.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/SingleRegisterInstruction.java deleted file mode 100644 index 0cc46561..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/SingleRegisterInstruction.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code; - -public interface SingleRegisterInstruction { - int getRegisterA(); -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/ThreeRegisterInstruction.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/ThreeRegisterInstruction.java deleted file mode 100644 index 83bbb808..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/ThreeRegisterInstruction.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code; - -public interface ThreeRegisterInstruction extends TwoRegisterInstruction { - int getRegisterC(); -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/TwoRegisterInstruction.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/TwoRegisterInstruction.java deleted file mode 100644 index 022a1458..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/TwoRegisterInstruction.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code; - -public interface TwoRegisterInstruction extends SingleRegisterInstruction { - int getRegisterA(); - int getRegisterB(); - -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/VerificationErrorType.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/VerificationErrorType.java deleted file mode 100644 index 622be5d3..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Code/VerificationErrorType.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2011 Ben Gruver - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Code; - -import java.util.HashMap; - -public enum VerificationErrorType { - None(0, "no-error"), - Generic(1, "generic-error"), - NoClass(2, "no-such-class"), - NoField(3, "no-such-field"), - NoMethod(4, "no-such-method"), - AccessClass(5, "illegal-class-access"), - AccessField(6, "illegal-field-access"), - AccessMethod(7, "illegal-method-access"), - ClassChange(8, "class-change-error"), - Instantiation(9, "instantiation-error"); - - private static HashMap verificationErrorTypesByName; - - static { - verificationErrorTypesByName = new HashMap(); - - for (VerificationErrorType verificationErrorType: VerificationErrorType.values()) { - verificationErrorTypesByName.put(verificationErrorType.getName(), verificationErrorType); - } - } - - private int value; - private String name; - private VerificationErrorType(int value, String name) { - this.value = value; - this.name = name; - } - - public int getValue() { - return value; - } - - public String getName() { - return name; - } - - public static VerificationErrorType fromString(String validationErrorType) { - return verificationErrorTypesByName.get(validationErrorType); - } - - public static VerificationErrorType getValidationErrorType(int validationErrorType) { - switch (validationErrorType) { - case 0: - return None; - case 1: - return Generic; - case 2: - return NoClass; - case 3: - return NoField; - case 4: - return NoMethod; - case 5: - return AccessClass; - case 6: - return AccessField; - case 7: - return AccessMethod; - case 8: - return ClassChange; - case 9: - return Instantiation; - } - return null; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/CodeItem.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/CodeItem.java deleted file mode 100644 index 0c2a6ba0..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/CodeItem.java +++ /dev/null @@ -1,1085 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.dexlib.Code.Format.*; -import org.jf.dexlib.Code.*; -import org.jf.dexlib.Debug.DebugInstructionIterator; -import org.jf.dexlib.Debug.DebugOpcode; -import org.jf.dexlib.Util.*; -import org.jf.util.AlignmentUtils; -import org.jf.util.ExceptionWithContext; - -import java.util.ArrayList; -import java.util.List; - -public class CodeItem extends Item { - private int registerCount; - private int inWords; - private int outWords; - private DebugInfoItem debugInfo; - private Instruction[] instructions; - private TryItem[] tries; - private EncodedCatchHandler[] encodedCatchHandlers; - - private ClassDataItem.EncodedMethod parent; - - /** - * Creates a new uninitialized CodeItem - * @param dexFile The DexFile that this item belongs to - */ - public CodeItem(DexFile dexFile) { - super(dexFile); - } - - /** - * Creates a new CodeItem with the given values. - * @param dexFile The DexFile that this item belongs to - * @param registerCount the number of registers that the method containing this code uses - * @param inWords the number of 2-byte words that the parameters to the method containing this code take - * @param outWords the maximum number of 2-byte words for the arguments of any method call in this code - * @param debugInfo the debug information for this code/method - * @param instructions the instructions for this code item - * @param tries an array of the tries defined for this code/method - * @param encodedCatchHandlers an array of the exception handlers defined for this code/method - */ - private CodeItem(DexFile dexFile, - int registerCount, - int inWords, - int outWords, - DebugInfoItem debugInfo, - Instruction[] instructions, - TryItem[] tries, - EncodedCatchHandler[] encodedCatchHandlers) { - super(dexFile); - - this.registerCount = registerCount; - this.inWords = inWords; - this.outWords = outWords; - this.debugInfo = debugInfo; - if (debugInfo != null) { - debugInfo.setParent(this); - } - - this.instructions = instructions; - this.tries = tries; - this.encodedCatchHandlers = encodedCatchHandlers; - } - - /** - * Returns a new CodeItem with the given values. - * @param dexFile The DexFile that this item belongs to - * @param registerCount the number of registers that the method containing this code uses - * @param inWords the number of 2-byte words that the parameters to the method containing this code take - * @param outWords the maximum number of 2-byte words for the arguments of any method call in this code - * @param debugInfo the debug information for this code/method - * @param instructions the instructions for this code item - * @param tries a list of the tries defined for this code/method or null if none - * @param encodedCatchHandlers a list of the exception handlers defined for this code/method or null if none - * @return a new CodeItem with the given values. - */ - public static CodeItem internCodeItem(DexFile dexFile, - int registerCount, - int inWords, - int outWords, - DebugInfoItem debugInfo, - List instructions, - List tries, - List encodedCatchHandlers) { - TryItem[] triesArray = null; - EncodedCatchHandler[] encodedCatchHandlersArray = null; - Instruction[] instructionsArray = null; - - if (tries != null && tries.size() > 0) { - triesArray = new TryItem[tries.size()]; - tries.toArray(triesArray); - } - - if (encodedCatchHandlers != null && encodedCatchHandlers.size() > 0) { - encodedCatchHandlersArray = new EncodedCatchHandler[encodedCatchHandlers.size()]; - encodedCatchHandlers.toArray(encodedCatchHandlersArray); - } - - if (instructions != null && instructions.size() > 0) { - instructionsArray = new Instruction[instructions.size()]; - instructions.toArray(instructionsArray); - } - - CodeItem codeItem = new CodeItem(dexFile, registerCount, inWords, outWords, debugInfo, instructionsArray, - triesArray, encodedCatchHandlersArray); - return dexFile.CodeItemsSection.intern(codeItem); - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - this.registerCount = in.readShort(); - this.inWords = in.readShort(); - this.outWords = in.readShort(); - int triesCount = in.readShort(); - this.debugInfo = (DebugInfoItem)readContext.getOptionalOffsettedItemByOffset(ItemType.TYPE_DEBUG_INFO_ITEM, - in.readInt()); - if (this.debugInfo != null) { - this.debugInfo.setParent(this); - } - - int instructionCount = in.readInt(); - - final ArrayList instructionList = new ArrayList(); - - byte[] encodedInstructions = in.readBytes(instructionCount * 2); - InstructionIterator.IterateInstructions(dexFile, encodedInstructions, - new InstructionIterator.ProcessInstructionDelegate() { - public void ProcessInstruction(int codeAddress, Instruction instruction) { - instructionList.add(instruction); - } - }); - - this.instructions = new Instruction[instructionList.size()]; - instructionList.toArray(instructions); - - if (triesCount > 0) { - in.alignTo(4); - - //we need to read in the catch handlers first, so save the offset to the try items for future reference - int triesOffset = in.getCursor(); - in.setCursor(triesOffset + 8 * triesCount); - - //read in the encoded catch handlers - int encodedHandlerStart = in.getCursor(); - int handlerCount = in.readUnsignedLeb128(); - SparseArray handlerMap = new SparseArray(handlerCount); - encodedCatchHandlers = new EncodedCatchHandler[handlerCount]; - for (int i=0; i 0) { - offset = AlignmentUtils.alignOffset(offset, 4); - - offset += tries.length * 8; - int encodedCatchHandlerBaseOffset = offset; - offset += Leb128Utils.unsignedLeb128Size(encodedCatchHandlers.length); - for (EncodedCatchHandler encodedCatchHandler: encodedCatchHandlers) { - offset = encodedCatchHandler.place(offset, encodedCatchHandlerBaseOffset); - } - } - return offset; - } - - /** {@inheritDoc} */ - protected void writeItem(final AnnotatedOutput out) { - int instructionsLength = getInstructionsLength(); - - if (out.annotates()) { - out.annotate(0, parent.method.getMethodString()); - out.annotate(2, "registers_size: 0x" + Integer.toHexString(registerCount) + " (" + registerCount + ")"); - out.annotate(2, "ins_size: 0x" + Integer.toHexString(inWords) + " (" + inWords + ")"); - out.annotate(2, "outs_size: 0x" + Integer.toHexString(outWords) + " (" + outWords + ")"); - int triesLength = tries==null?0:tries.length; - out.annotate(2, "tries_size: 0x" + Integer.toHexString(triesLength) + " (" + triesLength + ")"); - if (debugInfo == null) { - out.annotate(4, "debug_info_off:"); - } else { - out.annotate(4, "debug_info_off: 0x" + Integer.toHexString(debugInfo.getOffset())); - } - out.annotate(4, "insns_size: 0x" + Integer.toHexString(instructionsLength) + " (" + - (instructionsLength) + ")"); - } - - out.writeShort(registerCount); - out.writeShort(inWords); - out.writeShort(outWords); - if (tries == null) { - out.writeShort(0); - } else { - out.writeShort(tries.length); - } - if (debugInfo == null) { - out.writeInt(0); - } else { - out.writeInt(debugInfo.getOffset()); - } - - out.writeInt(instructionsLength); - - int currentCodeAddress = 0; - for (Instruction instruction: instructions) { - currentCodeAddress = instruction.write(out, currentCodeAddress); - } - - if (tries != null && tries.length > 0) { - if (out.annotates()) { - if ((currentCodeAddress % 2) != 0) { - out.annotate("padding"); - out.writeShort(0); - } - - int index = 0; - for (TryItem tryItem: tries) { - out.annotate(0, "[0x" + Integer.toHexString(index++) + "] try_item"); - out.indent(); - tryItem.writeTo(out); - out.deindent(); - } - - out.annotate("handler_count: 0x" + Integer.toHexString(encodedCatchHandlers.length) + "(" + - encodedCatchHandlers.length + ")"); - out.writeUnsignedLeb128(encodedCatchHandlers.length); - - index = 0; - for (EncodedCatchHandler encodedCatchHandler: encodedCatchHandlers) { - out.annotate(0, "[" + Integer.toHexString(index++) + "] encoded_catch_handler"); - out.indent(); - encodedCatchHandler.writeTo(out); - out.deindent(); - } - } else { - if ((currentCodeAddress % 2) != 0) { - out.writeShort(0); - } - - for (TryItem tryItem: tries) { - tryItem.writeTo(out); - } - - out.writeUnsignedLeb128(encodedCatchHandlers.length); - - for (EncodedCatchHandler encodedCatchHandler: encodedCatchHandlers) { - encodedCatchHandler.writeTo(out); - } - } - } - } - - /** {@inheritDoc} */ - public ItemType getItemType() { - return ItemType.TYPE_CODE_ITEM; - } - - /** {@inheritDoc} */ - public String getConciseIdentity() { - if (this.parent == null) { - return "code_item @0x" + Integer.toHexString(getOffset()); - } - return "code_item @0x" + Integer.toHexString(getOffset()) + " (" + parent.method.getMethodString() + ")"; - } - - /** {@inheritDoc} */ - public int compareTo(CodeItem other) { - if (parent == null) { - if (other.parent == null) { - return 0; - } - return -1; - } - if (other.parent == null) { - return 1; - } - return parent.method.compareTo(other.parent.method); - } - - /** - * @return the register count - */ - public int getRegisterCount() { - return registerCount; - } - - /** - * @return an array of the instructions in this code item - */ - public Instruction[] getInstructions() { - return instructions; - } - - /** - * @return an array of the TryItem objects in this CodeItem - */ - public TryItem[] getTries() { - return tries; - } - - /** - * @return an array of the EncodedCatchHandler objects in this CodeItem - */ - public EncodedCatchHandler[] getHandlers() { - return encodedCatchHandlers; - } - - /** - * @return the DebugInfoItem associated with this CodeItem - */ - public DebugInfoItem getDebugInfo() { - return debugInfo; - } - - /** - * @return the number of 2-byte words that the parameters to the method containing this code take - */ - public int getInWords() { - return inWords; - } - - /** - * @return the maximum number of 2-byte words for the arguments of any method call in this code - */ - public int getOutWords() { - return outWords; - } - - /** - * Sets the MethodIdItem of the method that this CodeItem is associated with - * @param encodedMethod the EncodedMethod of the method that this CodeItem is associated - * with - */ - protected void setParent(ClassDataItem.EncodedMethod encodedMethod) { - this.parent = encodedMethod; - } - - /** - * @return the MethodIdItem of the method that this CodeItem belongs to - */ - public ClassDataItem.EncodedMethod getParent() { - return parent; - } - - /** - * Used by OdexUtil to update this CodeItem with a deodexed version of the instructions - * @param newInstructions the new instructions to use for this code item - */ - public void updateCode(Instruction[] newInstructions) { - this.instructions = newInstructions; - } - - /** - * @return The length of the instructions in this CodeItem, in 2-byte code blocks - */ - private int getInstructionsLength() { - int currentCodeAddress = 0; - for (Instruction instruction: instructions) { - currentCodeAddress += instruction.getSize(currentCodeAddress); - } - return currentCodeAddress; - } - - /** - * Go through the instructions and perform any of the following fixes that are applicable - * - Replace const-string instruction with const-string/jumbo, when the string index is too big - * - Replace goto and goto/16 with a larger version of goto, when the target is too far away - * TODO: we should be able to replace if-* instructions with targets that are too far away with a negated if followed by a goto/32 to the original target - * TODO: remove multiple nops that occur before a switch/array data pseudo instruction. In some cases, multiple smali-baksmali cycles with changes in between could cause nops to start piling up - * TODO: in case of non-range invoke with a jumbo-sized method reference, we could check if the registers are sequential, and replace it with the jumbo variant (which only takes a register range) - * - * The above fixes are applied iteratively, until no more fixes have been performed - */ - public void fixInstructions(boolean fixJumbo, boolean fixGoto) { - try { - boolean didSomething = false; - - do - { - didSomething = false; - - int currentCodeAddress = 0; - for (int i=0; i 0xFFFF) { - - InstructionWithJumboVariant instructionWithJumboVariant = - (InstructionWithJumboVariant)referenceInstruction; - - Instruction jumboInstruction = instructionWithJumboVariant.makeJumbo(); - if (jumboInstruction != null) { - replaceInstructionAtAddress(currentCodeAddress, - instructionWithJumboVariant.makeJumbo()); - didSomething = true; - break; - } - } - } - - currentCodeAddress += instruction.getSize(currentCodeAddress); - } catch (Exception ex) { - throw ExceptionWithContext.withContext(ex, "Error while attempting to fix " + - instruction.opcode.name + " instruction at address " + currentCodeAddress); - } - } - }while(didSomething); - } catch (Exception ex) { - throw this.addExceptionContext(ex); - } - } - - private void replaceInstructionAtAddress(int codeAddress, Instruction replacementInstruction) { - Instruction originalInstruction = null; - - int[] originalInstructionCodeAddresses = new int[instructions.length+1]; - SparseIntArray originalSwitchAddressByOriginalSwitchDataAddress = new SparseIntArray(); - - int currentCodeAddress = 0; - int instructionIndex = 0; - int i; - for (i=0; i= 0; - int originalAddress = originalAddressByNewAddress.get(currentCodeAddress); - - int originalInstructionTarget = originalAddress + offsetInstruction.getTargetAddressOffset(); - - assert newAddressByOriginalAddress.indexOfKey(originalInstructionTarget) >= 0; - int newInstructionTarget = newAddressByOriginalAddress.get(originalInstructionTarget); - - int newCodeAddress = (newInstructionTarget - currentCodeAddress); - - if (newCodeAddress != offsetInstruction.getTargetAddressOffset()) { - offsetInstruction.updateTargetAddressOffset(newCodeAddress); - } - } else if (instruction instanceof MultiOffsetInstruction) { - MultiOffsetInstruction multiOffsetInstruction = (MultiOffsetInstruction)instruction; - - assert originalAddressByNewAddress.indexOfKey(currentCodeAddress) >= 0; - int originalDataAddress = originalAddressByNewAddress.get(currentCodeAddress); - - int originalSwitchAddress = - originalSwitchAddressByOriginalSwitchDataAddress.get(originalDataAddress, -1); - if (originalSwitchAddress == -1) { - //TODO: maybe we could just remove the unreferenced switch data? - throw new RuntimeException("This method contains an unreferenced switch data block at address " + - + currentCodeAddress + " and can't be automatically fixed."); - } - - assert newAddressByOriginalAddress.indexOfKey(originalSwitchAddress) >= 0; - int newSwitchAddress = newAddressByOriginalAddress.get(originalSwitchAddress); - - int[] targets = multiOffsetInstruction.getTargets(); - for (int t=0; t= 0; - int newTargetCodeAddress = newAddressByOriginalAddress.get(originalTargetCodeAddress); - int newCodeAddress = newTargetCodeAddress - newSwitchAddress; - if (newCodeAddress != targets[t]) { - multiOffsetInstruction.updateTarget(t, newCodeAddress); - } - } - } - currentCodeAddress += instruction.getSize(currentCodeAddress); - } - - if (debugInfo != null) { - final byte[] encodedDebugInfo = debugInfo.getEncodedDebugInfo(); - - ByteArrayInput debugInput = new ByteArrayInput(encodedDebugInfo); - - DebugInstructionFixer debugInstructionFixer = new DebugInstructionFixer(encodedDebugInfo, - newAddressByOriginalAddress); - DebugInstructionIterator.IterateInstructions(debugInput, debugInstructionFixer); - - if (debugInstructionFixer.result != null) { - debugInfo.setEncodedDebugInfo(debugInstructionFixer.result); - } - } - - if (encodedCatchHandlers != null) { - for (EncodedCatchHandler encodedCatchHandler: encodedCatchHandlers) { - if (encodedCatchHandler.catchAllHandlerAddress != -1) { - assert newAddressByOriginalAddress.indexOfKey(encodedCatchHandler.catchAllHandlerAddress) >= 0; - encodedCatchHandler.catchAllHandlerAddress = - newAddressByOriginalAddress.get(encodedCatchHandler.catchAllHandlerAddress); - } - - for (EncodedTypeAddrPair handler: encodedCatchHandler.handlers) { - assert newAddressByOriginalAddress.indexOfKey(handler.handlerAddress) >= 0; - handler.handlerAddress = newAddressByOriginalAddress.get(handler.handlerAddress); - } - } - } - - if (this.tries != null) { - for (TryItem tryItem: tries) { - int startAddress = tryItem.startCodeAddress; - int endAddress = tryItem.startCodeAddress + tryItem.tryLength; - - assert newAddressByOriginalAddress.indexOfKey(startAddress) >= 0; - tryItem.startCodeAddress = newAddressByOriginalAddress.get(startAddress); - - assert newAddressByOriginalAddress.indexOfKey(endAddress) >= 0; - tryItem.tryLength = newAddressByOriginalAddress.get(endAddress) - tryItem.startCodeAddress; - } - } - } - - private class DebugInstructionFixer extends DebugInstructionIterator.ProcessRawDebugInstructionDelegate { - private int currentCodeAddress = 0; - private SparseIntArray newAddressByOriginalAddress; - private final byte[] originalEncodedDebugInfo; - public byte[] result = null; - - public DebugInstructionFixer(byte[] originalEncodedDebugInfo, SparseIntArray newAddressByOriginalAddress) { - this.newAddressByOriginalAddress = newAddressByOriginalAddress; - this.originalEncodedDebugInfo = originalEncodedDebugInfo; - } - - - @Override - public void ProcessAdvancePC(int startDebugOffset, int debugInstructionLength, int codeAddressDelta) { - currentCodeAddress += codeAddressDelta; - - if (result != null) { - return; - } - - int newCodeAddress = newAddressByOriginalAddress.get(currentCodeAddress, -1); - - //The address might not point to an actual instruction in some cases, for example, if an AdvancePC - //instruction was inserted just before a "special" instruction, to fix up the addresses for a previous - //instruction replacement. - //In this case, it should be safe to skip, because there will be another AdvancePC/SpecialOpcode that will - //bump up the address to point to a valid instruction before anything (line/local/etc.) is emitted - if (newCodeAddress == -1) { - return; - } - - if (newCodeAddress != currentCodeAddress) { - int newCodeAddressDelta = newCodeAddress - (currentCodeAddress - codeAddressDelta); - assert newCodeAddressDelta > 0; - int codeAddressDeltaLeb128Size = Leb128Utils.unsignedLeb128Size(newCodeAddressDelta); - - //if the length of the new code address delta is the same, we can use the existing buffer - if (codeAddressDeltaLeb128Size + 1 == debugInstructionLength) { - result = originalEncodedDebugInfo; - Leb128Utils.writeUnsignedLeb128(newCodeAddressDelta, result, startDebugOffset+1); - } else { - //The length of the new code address delta is different, so create a new buffer with enough - //additional space to accomodate the new code address delta value. - result = new byte[originalEncodedDebugInfo.length + codeAddressDeltaLeb128Size - - (debugInstructionLength - 1)]; - - System.arraycopy(originalEncodedDebugInfo, 0, result, 0, startDebugOffset); - - result[startDebugOffset] = DebugOpcode.DBG_ADVANCE_PC.value; - Leb128Utils.writeUnsignedLeb128(newCodeAddressDelta, result, startDebugOffset+1); - - System.arraycopy(originalEncodedDebugInfo, startDebugOffset + debugInstructionLength, result, - startDebugOffset + codeAddressDeltaLeb128Size + 1, - originalEncodedDebugInfo.length - (startDebugOffset + codeAddressDeltaLeb128Size + 1)); - } - } - } - - @Override - public void ProcessSpecialOpcode(int startDebugOffset, int debugOpcode, int lineDelta, - int codeAddressDelta) { - currentCodeAddress += codeAddressDelta; - if (result != null) { - return; - } - - int newCodeAddress = newAddressByOriginalAddress.get(currentCodeAddress, -1); - assert newCodeAddress != -1; - - if (newCodeAddress != currentCodeAddress) { - int newCodeAddressDelta = newCodeAddress - (currentCodeAddress - codeAddressDelta); - assert newCodeAddressDelta > 0; - - //if the new code address delta won't fit in the special opcode, we need to insert - //an additional DBG_ADVANCE_PC opcode - if (lineDelta < 2 && newCodeAddressDelta > 16 || lineDelta > 1 && newCodeAddressDelta > 15) { - int additionalCodeAddressDelta = newCodeAddress - currentCodeAddress; - int additionalCodeAddressDeltaLeb128Size = Leb128Utils.signedLeb128Size(additionalCodeAddressDelta); - - //create a new buffer with enough additional space for the new opcode - result = new byte[originalEncodedDebugInfo.length + additionalCodeAddressDeltaLeb128Size + 1]; - - System.arraycopy(originalEncodedDebugInfo, 0, result, 0, startDebugOffset); - result[startDebugOffset] = 0x01; //DBG_ADVANCE_PC - Leb128Utils.writeUnsignedLeb128(additionalCodeAddressDelta, result, startDebugOffset+1); - System.arraycopy(originalEncodedDebugInfo, startDebugOffset, result, - startDebugOffset+additionalCodeAddressDeltaLeb128Size+1, - result.length - (startDebugOffset+additionalCodeAddressDeltaLeb128Size+1)); - } else { - result = originalEncodedDebugInfo; - result[startDebugOffset] = DebugInfoBuilder.calculateSpecialOpcode(lineDelta, - newCodeAddressDelta); - } - } - } - } - - public static class TryItem { - /** - * The address (in 2-byte words) within the code where the try block starts - */ - private int startCodeAddress; - - /** - * The number of 2-byte words that the try block covers - */ - private int tryLength; - - /** - * The associated exception handler - */ - public final EncodedCatchHandler encodedCatchHandler; - - /** - * Construct a new TryItem with the given values - * @param startCodeAddress the code address within the code where the try block starts - * @param tryLength the number of code blocks that the try block covers - * @param encodedCatchHandler the associated exception handler - */ - public TryItem(int startCodeAddress, int tryLength, EncodedCatchHandler encodedCatchHandler) { - this.startCodeAddress = startCodeAddress; - this.tryLength = tryLength; - this.encodedCatchHandler = encodedCatchHandler; - } - - /** - * This is used internally to construct a new TryItem while reading in a DexFile - * @param in the Input object to read the TryItem from - * @param encodedCatchHandlers a SparseArray of the EncodedCatchHandlers for this CodeItem. The - * key should be the offset of the EncodedCatchHandler from the beginning of the encoded_catch_handler_list - * structure. - */ - private TryItem(Input in, SparseArray encodedCatchHandlers) { - startCodeAddress = in.readInt(); - tryLength = in.readShort(); - - encodedCatchHandler = encodedCatchHandlers.get(in.readShort()); - if (encodedCatchHandler == null) { - throw new RuntimeException("Could not find the EncodedCatchHandler referenced by this TryItem"); - } - } - - /** - * Writes the TryItem to the given AnnotatedOutput object - * @param out the AnnotatedOutput object to write to - */ - private void writeTo(AnnotatedOutput out) { - if (out.annotates()) { - out.annotate(4, "start_addr: 0x" + Integer.toHexString(startCodeAddress)); - out.annotate(2, "try_length: 0x" + Integer.toHexString(tryLength) + " (" + tryLength + - ")"); - out.annotate(2, "handler_off: 0x" + Integer.toHexString(encodedCatchHandler.getOffsetInList())); - } - - out.writeInt(startCodeAddress); - out.writeShort(tryLength); - out.writeShort(encodedCatchHandler.getOffsetInList()); - } - - /** - * @return The address (in 2-byte words) within the code where the try block starts - */ - public int getStartCodeAddress() { - return startCodeAddress; - } - - /** - * @return The number of code blocks that the try block covers - */ - public int getTryLength() { - return tryLength; - } - } - - public static class EncodedCatchHandler { - /** - * An array of the individual exception handlers - */ - public final EncodedTypeAddrPair[] handlers; - - /** - * The address within the code (in 2-byte words) for the catch all handler, or -1 if there is no catch all - * handler - */ - private int catchAllHandlerAddress; - - private int baseOffset; - private int offset; - - /** - * Constructs a new EncodedCatchHandler with the given values - * @param handlers an array of the individual exception handlers - * @param catchAllHandlerAddress The address within the code (in 2-byte words) for the catch all handler, or -1 - * if there is no catch all handler - */ - public EncodedCatchHandler(EncodedTypeAddrPair[] handlers, int catchAllHandlerAddress) { - this.handlers = handlers; - this.catchAllHandlerAddress = catchAllHandlerAddress; - } - - /** - * This is used internally to construct a new EncodedCatchHandler while reading in a - * DexFile - * @param dexFile the DexFile that is being read in - * @param in the Input object to read the EncodedCatchHandler from - */ - private EncodedCatchHandler(DexFile dexFile, Input in) { - int handlerCount = in.readSignedLeb128(); - - if (handlerCount < 0) { - handlers = new EncodedTypeAddrPair[-1 * handlerCount]; - } else { - handlers = new EncodedTypeAddrPair[handlerCount]; - } - - for (int i=0; iEncodedCatchHandler, or -1 if there - * is no "Catch All" handler - */ - public int getCatchAllHandlerAddress() { - return catchAllHandlerAddress; - } - - /** - * @return the offset of this EncodedCatchHandler from the beginning of the - * encoded_catch_handler_list structure - */ - private int getOffsetInList() { - return offset-baseOffset; - } - - /** - * Places the EncodedCatchHandler, storing the offset and baseOffset, and returning the offset - * immediately following this EncodedCatchHandler - * @param offset the offset of this EncodedCatchHandler in the DexFile - * @param baseOffset the offset of the beginning of the encoded_catch_handler_list structure in the - * DexFile - * @return the offset immediately following this EncodedCatchHandler - */ - private int place(int offset, int baseOffset) { - this.offset = offset; - this.baseOffset = baseOffset; - - int size = handlers.length; - if (catchAllHandlerAddress > -1) { - size *= -1; - offset += Leb128Utils.unsignedLeb128Size(catchAllHandlerAddress); - } - offset += Leb128Utils.signedLeb128Size(size); - - for (EncodedTypeAddrPair handler: handlers) { - offset += handler.getSize(); - } - return offset; - } - - /** - * Writes the EncodedCatchHandler to the given AnnotatedOutput object - * @param out the AnnotatedOutput object to write to - */ - private void writeTo(AnnotatedOutput out) { - if (out.annotates()) { - out.annotate("size: 0x" + Integer.toHexString(handlers.length) + " (" + handlers.length + ")"); - - int size = handlers.length; - if (catchAllHandlerAddress > -1) { - size = size * -1; - } - out.writeSignedLeb128(size); - - int index = 0; - for (EncodedTypeAddrPair handler: handlers) { - out.annotate(0, "[" + index++ + "] encoded_type_addr_pair"); - out.indent(); - handler.writeTo(out); - out.deindent(); - } - - if (catchAllHandlerAddress > -1) { - out.annotate("catch_all_addr: 0x" + Integer.toHexString(catchAllHandlerAddress)); - out.writeUnsignedLeb128(catchAllHandlerAddress); - } - } else { - int size = handlers.length; - if (catchAllHandlerAddress > -1) { - size = size * -1; - } - out.writeSignedLeb128(size); - - for (EncodedTypeAddrPair handler: handlers) { - handler.writeTo(out); - } - - if (catchAllHandlerAddress > -1) { - out.writeUnsignedLeb128(catchAllHandlerAddress); - } - } - } - - @Override - public int hashCode() { - int hash = 0; - for (EncodedTypeAddrPair handler: handlers) { - hash = hash * 31 + handler.hashCode(); - } - hash = hash * 31 + catchAllHandlerAddress; - return hash; - } - - @Override - public boolean equals(Object o) { - if (this==o) { - return true; - } - if (o==null || !this.getClass().equals(o.getClass())) { - return false; - } - - EncodedCatchHandler other = (EncodedCatchHandler)o; - if (handlers.length != other.handlers.length || catchAllHandlerAddress != other.catchAllHandlerAddress) { - return false; - } - - for (int i=0; iException that this handler handles - */ - public final TypeIdItem exceptionType; - - /** - * The address (in 2-byte words) in the code of the handler - */ - private int handlerAddress; - - /** - * Constructs a new EncodedTypeAddrPair with the given values - * @param exceptionType the type of the Exception that this handler handles - * @param handlerAddress the address (in 2-byte words) in the code of the handler - */ - public EncodedTypeAddrPair(TypeIdItem exceptionType, int handlerAddress) { - this.exceptionType = exceptionType; - this.handlerAddress = handlerAddress; - } - - /** - * This is used internally to construct a new EncodedTypeAddrPair while reading in a - * DexFile - * @param dexFile the DexFile that is being read in - * @param in the Input object to read the EncodedCatchHandler from - */ - private EncodedTypeAddrPair(DexFile dexFile, Input in) { - exceptionType = dexFile.TypeIdsSection.getItemByIndex(in.readUnsignedLeb128()); - handlerAddress = in.readUnsignedLeb128(); - } - - /** - * @return the size of this EncodedTypeAddrPair - */ - private int getSize() { - return Leb128Utils.unsignedLeb128Size(exceptionType.getIndex()) + - Leb128Utils.unsignedLeb128Size(handlerAddress); - } - - /** - * Writes the EncodedTypeAddrPair to the given AnnotatedOutput object - * @param out the AnnotatedOutput object to write to - */ - private void writeTo(AnnotatedOutput out) { - if (out.annotates()) { - out.annotate("exception_type: " + exceptionType.getTypeDescriptor()); - out.writeUnsignedLeb128(exceptionType.getIndex()); - - out.annotate("handler_addr: 0x" + Integer.toHexString(handlerAddress)); - out.writeUnsignedLeb128(handlerAddress); - } else { - out.writeUnsignedLeb128(exceptionType.getIndex()); - out.writeUnsignedLeb128(handlerAddress); - } - } - - public int getHandlerAddress() { - return handlerAddress; - } - - @Override - public int hashCode() { - return exceptionType.hashCode() * 31 + handlerAddress; - } - - @Override - public boolean equals(Object o) { - if (this==o) { - return true; - } - if (o==null || !this.getClass().equals(o.getClass())) { - return false; - } - - EncodedTypeAddrPair other = (EncodedTypeAddrPair)o; - return exceptionType == other.exceptionType && handlerAddress == other.handlerAddress; - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Convertible.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Convertible.java deleted file mode 100644 index f227621b..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Convertible.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2012, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -/** - * Describes an object that can be converted to a different type - */ -public interface Convertible { - T convert(); -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Debug/DebugInstructionIterator.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Debug/DebugInstructionIterator.java deleted file mode 100644 index b61f399d..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Debug/DebugInstructionIterator.java +++ /dev/null @@ -1,364 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Debug; - -import org.jf.dexlib.DebugInfoItem; -import org.jf.dexlib.DexFile; -import org.jf.dexlib.StringIdItem; -import org.jf.dexlib.TypeIdItem; -import org.jf.dexlib.Util.ByteArrayInput; -import org.jf.dexlib.Util.Input; - -public class DebugInstructionIterator { - /** - * This method decodes the debug instructions in the given byte array and iterates over them, calling - * the ProcessDebugInstructionDelegate.ProcessDebugInstruction method for each instruction - * @param in an Input object that the debug instructions can be read from - * @param processDebugInstruction a ProcessDebugInstructionDelegate object that gets called - * for each instruction that is encountered - */ - public static void IterateInstructions(Input in, ProcessRawDebugInstructionDelegate processDebugInstruction) { - int startDebugOffset; - - while(true) - { - startDebugOffset = in.getCursor(); - byte debugOpcode = in.readByte(); - - switch (debugOpcode) { - case 0x00: - { - processDebugInstruction.ProcessEndSequence(startDebugOffset); - return; - } - case 0x01: - { - int codeAddressDiff = in.readUnsignedLeb128(); - processDebugInstruction.ProcessAdvancePC(startDebugOffset, in.getCursor() - startDebugOffset, - codeAddressDiff); - break; - } - case 0x02: - { - int lineDiff = in.readSignedLeb128(); - processDebugInstruction.ProcessAdvanceLine(startDebugOffset, in.getCursor() - startDebugOffset, - lineDiff); - break; - } - case 0x03: - { - int registerNum = in.readUnsignedOrSignedLeb128(); - boolean isSignedRegister = false; - if (registerNum < 0) { - isSignedRegister = true; - registerNum = ~registerNum; - } - int nameIndex = in.readUnsignedLeb128() - 1; - int typeIndex = in.readUnsignedLeb128() - 1; - processDebugInstruction.ProcessStartLocal(startDebugOffset, in.getCursor() - startDebugOffset, - registerNum, nameIndex, typeIndex, isSignedRegister); - break; - } - case 0x04: - { - int registerNum = in.readUnsignedOrSignedLeb128(); - boolean isSignedRegister = false; - if (registerNum < 0) { - isSignedRegister = true; - registerNum = ~registerNum; - } - int nameIndex = in.readUnsignedLeb128() - 1; - int typeIndex = in.readUnsignedLeb128() - 1; - int signatureIndex = in.readUnsignedLeb128() - 1; - processDebugInstruction.ProcessStartLocalExtended(startDebugOffset, - in.getCursor() - startDebugOffset, registerNum, nameIndex, typeIndex, signatureIndex, - isSignedRegister); - break; - } - case 0x05: - { - int registerNum = in.readUnsignedOrSignedLeb128(); - boolean isSignedRegister = false; - if (registerNum < 0) { - isSignedRegister = true; - registerNum = ~registerNum; - } - processDebugInstruction.ProcessEndLocal(startDebugOffset, in.getCursor() - startDebugOffset, - registerNum, isSignedRegister); - break; - } - case 0x06: - { - int registerNum = in.readUnsignedOrSignedLeb128(); - boolean isSignedRegister = false; - if (registerNum < 0) { - isSignedRegister = true; - registerNum = ~registerNum; - } - processDebugInstruction.ProcessRestartLocal(startDebugOffset, in.getCursor() - startDebugOffset, - registerNum, isSignedRegister); - break; - } - case 0x07: - { - processDebugInstruction.ProcessSetPrologueEnd(startDebugOffset); - break; - } - case 0x08: - { - processDebugInstruction.ProcessSetEpilogueBegin(startDebugOffset); - break; - } - case 0x09: - { - int nameIndex = in.readUnsignedLeb128(); - processDebugInstruction.ProcessSetFile(startDebugOffset, in.getCursor() - startDebugOffset, - nameIndex); - break; - } - default: - { - int base = ((debugOpcode & 0xFF) - 0x0A); - processDebugInstruction.ProcessSpecialOpcode(startDebugOffset, debugOpcode, (base % 15) - 4, base / 15); - } - } - } - } - - /** - * This method decodes the debug instructions in the given byte array and iterates over them, calling - * the ProcessDebugInstructionDelegate.ProcessDebugInstruction method for each instruction - * @param debugInfoItem the DebugInfoItem to iterate over - * @param registerCount the number of registers in the method that the given debug info is for - * @param processDecodedDebugInstruction a ProcessDebugInstructionDelegate object that gets called - * for each instruction that is encountered - */ - public static void DecodeInstructions(DebugInfoItem debugInfoItem, int registerCount, - ProcessDecodedDebugInstructionDelegate processDecodedDebugInstruction) { - int startDebugOffset; - int currentCodeAddress = 0; - int line = debugInfoItem.getLineStart(); - Input in = new ByteArrayInput(debugInfoItem.getEncodedDebugInfo()); - DexFile dexFile = debugInfoItem.getDexFile(); - - Local[] locals = new Local[registerCount]; - - while(true) - { - startDebugOffset = in.getCursor(); - byte debugOpcode = in.readByte(); - - switch (DebugOpcode.getDebugOpcodeByValue(debugOpcode)) { - case DBG_END_SEQUENCE: - { - return; - } - case DBG_ADVANCE_PC: - { - int codeAddressDiff = in.readUnsignedLeb128(); - currentCodeAddress += codeAddressDiff; - break; - } - case DBG_ADVANCE_LINE: - { - int lineDiff = in.readSignedLeb128(); - line += lineDiff; - break; - } - case DBG_START_LOCAL: - { - int registerNum = in.readUnsignedLeb128(); - StringIdItem name = dexFile.StringIdsSection.getOptionalItemByIndex(in.readUnsignedLeb128() - 1); - TypeIdItem type = dexFile.TypeIdsSection.getOptionalItemByIndex(in.readUnsignedLeb128() - 1); - locals[registerNum] = new Local(registerNum, name, type, null); - processDecodedDebugInstruction.ProcessStartLocal(currentCodeAddress, - in.getCursor() - startDebugOffset, registerNum, name, type); - break; - } - case DBG_START_LOCAL_EXTENDED: - { - int registerNum = in.readUnsignedLeb128(); - StringIdItem name = dexFile.StringIdsSection.getOptionalItemByIndex(in.readUnsignedLeb128() - 1); - TypeIdItem type = dexFile.TypeIdsSection.getOptionalItemByIndex(in.readUnsignedLeb128() - 1); - StringIdItem signature = - dexFile.StringIdsSection.getOptionalItemByIndex(in.readUnsignedLeb128() - 1); - locals[registerNum] = new Local(registerNum, name, type, signature); - processDecodedDebugInstruction.ProcessStartLocalExtended(currentCodeAddress, - in.getCursor() - startDebugOffset, registerNum, name, type, signature); - break; - } - case DBG_END_LOCAL: - { - int registerNum = in.readUnsignedLeb128(); - Local local = locals[registerNum]; - if (local == null) { - processDecodedDebugInstruction.ProcessEndLocal(currentCodeAddress, in.getCursor() - startDebugOffset, registerNum, - null, null, null); - } else { - processDecodedDebugInstruction.ProcessEndLocal(currentCodeAddress, in.getCursor() - startDebugOffset, registerNum, - local.name, local.type, local.signature); - } - break; - } - case DBG_RESTART_LOCAL: - { - int registerNum = in.readUnsignedLeb128(); - Local local = locals[registerNum]; - if (local == null) { - processDecodedDebugInstruction.ProcessRestartLocal(currentCodeAddress, in.getCursor() - startDebugOffset, - registerNum, null, null, null); - } else { - processDecodedDebugInstruction.ProcessRestartLocal(currentCodeAddress, in.getCursor() - startDebugOffset, - registerNum, local.name, local.type, local.signature); - } - - break; - } - case DBG_SET_PROLOGUE_END: - { - processDecodedDebugInstruction.ProcessSetPrologueEnd(currentCodeAddress); - break; - } - case DBG_SET_EPILOGUE_BEGIN: - { - processDecodedDebugInstruction.ProcessSetEpilogueBegin(currentCodeAddress); - break; - } - case DBG_SET_FILE: - { - StringIdItem name = dexFile.StringIdsSection.getOptionalItemByIndex(in.readUnsignedLeb128() - 1); - processDecodedDebugInstruction.ProcessSetFile(currentCodeAddress, in.getCursor() - startDebugOffset, name); - break; - } - case DBG_SPECIAL_OPCODE: - { - int base = ((debugOpcode & 0xFF) - 0x0A); - currentCodeAddress += base / 15; - line += (base % 15) - 4; - processDecodedDebugInstruction.ProcessLineEmit(currentCodeAddress, line); - } - } - } - } - - public static class ProcessRawDebugInstructionDelegate - { - //TODO: add javadocs - public void ProcessEndSequence(int startDebugOffset) { - ProcessStaticOpcode(DebugOpcode.DBG_END_SEQUENCE, startDebugOffset, 1); - } - - public void ProcessAdvancePC(int startDebugOffset, int length, int codeAddressDiff) { - ProcessStaticOpcode(DebugOpcode.DBG_ADVANCE_PC, startDebugOffset, length); - } - - public void ProcessAdvanceLine(int startDebugOffset, int length, int lineDiff) { - ProcessStaticOpcode(DebugOpcode.DBG_ADVANCE_LINE, startDebugOffset, length); - } - - public void ProcessStartLocal(int startDebugOffset, int length, int registerNum, int nameIndex, int typeIndex, - boolean registerIsSigned) { - } - - public void ProcessStartLocalExtended(int startDebugOffset, int length, int registerNum, int nameIndex, - int typeIndex,int signatureIndex, boolean registerIsSigned) { - } - - public void ProcessEndLocal(int startDebugOffset, int length, int registerNum, boolean registerIsSigned) { - ProcessStaticOpcode(DebugOpcode.DBG_END_LOCAL, startDebugOffset, length); - } - - public void ProcessRestartLocal(int startDebugOffset, int length, int registerNum, boolean registerIsSigned) { - ProcessStaticOpcode(DebugOpcode.DBG_RESTART_LOCAL, startDebugOffset, length); - } - - public void ProcessSetPrologueEnd(int startDebugOffset) { - ProcessStaticOpcode(DebugOpcode.DBG_SET_PROLOGUE_END, startDebugOffset, 1); - } - - public void ProcessSetEpilogueBegin(int startDebugOffset) { - ProcessStaticOpcode(DebugOpcode.DBG_SET_EPILOGUE_BEGIN, startDebugOffset, 1); - } - - public void ProcessSetFile(int startDebugOffset, int length, int nameIndex) { - } - - public void ProcessSpecialOpcode(int startDebugOffset, int debugOpcode, int lineDiff, int codeAddressDiff) { - ProcessStaticOpcode(DebugOpcode.DBG_SPECIAL_OPCODE, startDebugOffset, 1); - } - - public void ProcessStaticOpcode(DebugOpcode debugOpcode, int startDebugOffset, int length) { - } - } - - public static class ProcessDecodedDebugInstructionDelegate - { - public void ProcessStartLocal(int codeAddress, int length, int registerNum, StringIdItem name, - TypeIdItem type) { - } - - public void ProcessStartLocalExtended(int codeAddress, int length, int registerNum, StringIdItem name, - TypeIdItem type, StringIdItem signature) { - } - - public void ProcessEndLocal(int codeAddress, int length, int registerNum, StringIdItem name, TypeIdItem type, - StringIdItem signature) { - } - - public void ProcessRestartLocal(int codeAddress, int length, int registerNum, StringIdItem name, - TypeIdItem type, StringIdItem signature) { - } - - public void ProcessSetPrologueEnd(int codeAddress) { - } - - public void ProcessSetEpilogueBegin(int codeAddress) { - } - - public void ProcessSetFile(int codeAddress, int length, StringIdItem name) { - } - - public void ProcessLineEmit(int codeAddress, int line) { - } - } - - private static class Local { - public final int register; - public final StringIdItem name; - public final TypeIdItem type; - public final StringIdItem signature; - public Local(int register, StringIdItem name, TypeIdItem type, StringIdItem signature) { - this.register = register; - this.name = name; - this.type = type; - this.signature = signature; - } - - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Debug/DebugOpcode.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Debug/DebugOpcode.java deleted file mode 100644 index d219ee33..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Debug/DebugOpcode.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Debug; - -public enum DebugOpcode { - DBG_END_SEQUENCE((byte)0x00), - DBG_ADVANCE_PC((byte)0x01), - DBG_ADVANCE_LINE((byte)0x02), - DBG_START_LOCAL((byte)0x03), - DBG_START_LOCAL_EXTENDED((byte)0x04), - DBG_END_LOCAL((byte)0x05), - DBG_RESTART_LOCAL((byte)0x06), - DBG_SET_PROLOGUE_END((byte)0x07), - DBG_SET_EPILOGUE_BEGIN((byte)0x08), - DBG_SET_FILE((byte)0x09), - DBG_SPECIAL_OPCODE((byte)0x0A); - - private static DebugOpcode[] opcodesByValue; - - static { - opcodesByValue = new DebugOpcode[11]; - - for (DebugOpcode debugOpcode: DebugOpcode.values()) { - opcodesByValue[debugOpcode.value & 0xFF] = debugOpcode; - } - } - - public static DebugOpcode getDebugOpcodeByValue(byte debugOpcodeValue) { - debugOpcodeValue = (byte)Math.min(debugOpcodeValue & 0xFF, 0x0A); - return opcodesByValue[debugOpcodeValue]; - } - - public final byte value; - - DebugOpcode(byte value) { - this.value = value; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/DebugInfoItem.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/DebugInfoItem.java deleted file mode 100644 index 81e023de..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/DebugInfoItem.java +++ /dev/null @@ -1,620 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.dexlib.Debug.DebugInstructionIterator; -import org.jf.dexlib.Debug.DebugOpcode; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.ByteArrayInput; -import org.jf.dexlib.Util.Input; -import org.jf.dexlib.Util.Leb128Utils; - -import java.util.ArrayList; -import java.util.List; - -public class DebugInfoItem extends Item { - private int lineStart; - private StringIdItem[] parameterNames; - private byte[] encodedDebugInfo; - private Item[] referencedItems; - - private CodeItem parent = null; - - /** - * Creates a new uninitialized DebugInfoInfo - * @param dexFile The DexFile that this item belongs to - */ - public DebugInfoItem(DexFile dexFile) { - super(dexFile); - } - - /** - * Creates a new DebugInfoItem with the given values - * @param dexFile The DexFile that this item belongs to - * @param lineStart the initial value for the line number register for the debug info machine - * @param parameterNames an array of the names of the associated method's parameters. The entire parameter - * can be null if no parameter info is available, or any element can be null to indicate no info for that parameter - * @param encodedDebugInfo the debug info, encoded as a byte array - * @param referencedItems an array of the items referenced by instructions, in order of occurance in the encoded - * debug info - */ - private DebugInfoItem(DexFile dexFile, - int lineStart, - StringIdItem[] parameterNames, - byte[] encodedDebugInfo, - Item[] referencedItems) { - super(dexFile); - this.lineStart = lineStart; - this.parameterNames = parameterNames; - this.encodedDebugInfo = encodedDebugInfo; - this.referencedItems = referencedItems; - } - - /** - * Returns a new DebugInfoItem with the given values - * @param dexFile The DexFile that this item belongs to - * @param lineStart the initial value for the line number register for the debug info machine - * @param parameterNames an array of the names of the associated method's parameters. The entire parameter - * can be null if no parameter info is available, or any element can be null to indicate no info for that parameter - * @param encodedDebugInfo the debug info, encoded as a byte array - * @param referencedItems an array of the items referenced by instructions, in order of occurance in the encoded - * debug info - * @return a new DebugInfoItem with the given values - */ - public static DebugInfoItem internDebugInfoItem(DexFile dexFile, - int lineStart, - StringIdItem[] parameterNames, - byte[] encodedDebugInfo, - Item[] referencedItems) { - DebugInfoItem debugInfoItem = new DebugInfoItem(dexFile, lineStart, parameterNames, encodedDebugInfo, - referencedItems); - return dexFile.DebugInfoItemsSection.intern(debugInfoItem); - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - lineStart = in.readUnsignedLeb128(); - parameterNames = new StringIdItem[in.readUnsignedLeb128()]; - IndexedSection stringIdSection = dexFile.StringIdsSection; - for (int i=0; i referencedItemsList = new ArrayList(50); - DebugInstructionIterator.IterateInstructions(in, - new DebugInstructionIterator.ProcessRawDebugInstructionDelegate() { - @Override - public void ProcessStartLocal(int startDebugOffset, int length, int registerNum, int nameIndex, - int typeIndex, boolean registerIsSigned) { - if (nameIndex != -1) { - referencedItemsList.add(dexFile.StringIdsSection.getItemByIndex(nameIndex)); - } - if (typeIndex != -1) { - referencedItemsList.add(dexFile.TypeIdsSection.getItemByIndex(typeIndex)); - } - } - - @Override - public void ProcessStartLocalExtended(int startDebugOffset, int length, int registerNume, - int nameIndex, int typeIndex, int signatureIndex, - boolean registerIsSigned) { - if (nameIndex != -1) { - referencedItemsList.add(dexFile.StringIdsSection.getItemByIndex(nameIndex)); - } - if (typeIndex != -1) { - referencedItemsList.add(dexFile.TypeIdsSection.getItemByIndex(typeIndex)); - } - if (signatureIndex != -1) { - referencedItemsList.add(dexFile.StringIdsSection.getItemByIndex(signatureIndex)); - } - } - - @Override - public void ProcessSetFile(int startDebugOffset, int length, int nameIndex) { - if (nameIndex != -1) { - referencedItemsList.add(dexFile.StringIdsSection.getItemByIndex(nameIndex)); - } - } - }); - - referencedItems = new Item[referencedItemsList.size()]; - referencedItemsList.toArray(referencedItems); - - int length = in.getCursor() - start; - in.setCursor(start); - encodedDebugInfo = in.readBytes(length); - } - - - - /** {@inheritDoc} */ - protected int placeItem(int offset) { - offset += Leb128Utils.unsignedLeb128Size(lineStart); - offset += Leb128Utils.unsignedLeb128Size(parameterNames.length); - for (StringIdItem parameterName: parameterNames) { - int indexp1; - if (parameterName == null) { - indexp1 = 0; - } else { - indexp1 = parameterName.getIndex() + 1; - } - offset += Leb128Utils.unsignedLeb128Size(indexp1); - } - - //make a subclass so we can keep track of and access the computed length - class ProcessDebugInstructionDelegateWithLength extends - DebugInstructionIterator.ProcessRawDebugInstructionDelegate { - public int length = 0; - } - ProcessDebugInstructionDelegateWithLength pdidwl; - - //final referencedItems = this.referencedItems; - - DebugInstructionIterator.IterateInstructions(new ByteArrayInput(encodedDebugInfo), - pdidwl = new ProcessDebugInstructionDelegateWithLength() { - private int referencedItemsPosition = 0; - - @Override - public void ProcessStaticOpcode(DebugOpcode opcode, int startDebugOffset, int length) { - this.length+=length; - } - - @Override - public void ProcessStartLocal(int startDebugOffset, int length, int registerNum, int nameIndex, - int typeIndex, boolean registerIsSigned) { - this.length++; - if (dexFile.getPreserveSignedRegisters() && registerIsSigned) { - this.length += Leb128Utils.signedLeb128Size(registerNum); - } else { - this.length+=Leb128Utils.unsignedLeb128Size(registerNum); - } - if (nameIndex != -1) { - this.length+= - Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); - } else { - this.length++; - } - if (typeIndex != -1) { - this.length+= - Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); - } else { - this.length++; - } - - } - - @Override - public void ProcessStartLocalExtended(int startDebugOffset, int length, int registerNum, int nameIndex, - int typeIndex, int signatureIndex, - boolean registerIsSigned) { - this.length++; - if (dexFile.getPreserveSignedRegisters() && registerIsSigned) { - this.length += Leb128Utils.signedLeb128Size(registerNum); - } else { - this.length+=Leb128Utils.unsignedLeb128Size(registerNum); - } - if (nameIndex != -1) { - this.length+= - Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); - } else { - this.length++; - } - if (typeIndex != -1) { - this.length+= - Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); - } else { - this.length++; - } - if (signatureIndex != -1) { - this.length+= - Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); - } else { - this.length++; - } - } - - @Override - public void ProcessSetFile(int startDebugOffset, int length, int nameIndex) { - this.length++; - if (nameIndex != -1) { - this.length+= - Leb128Utils.unsignedLeb128Size(referencedItems[referencedItemsPosition++].getIndex()+1); - } else { - this.length++; - } - } - }); - return offset + pdidwl.length; - } - - /** {@inheritDoc} */ - protected void writeItem(final AnnotatedOutput out) { - if (out.annotates()) { - writeItemWithAnnotations(out); - } else { - writeItemWithNoAnnotations(out); - } - } - - /** - * Replaces the encoded debug info for this DebugInfoItem. It is expected that the new debug info is compatible - * with the existing information, i.e. lineStart, referencedItems, parameterNames - * @param encodedDebugInfo the new encoded debug info - */ - protected void setEncodedDebugInfo(byte[] encodedDebugInfo) { - //TODO: I would rather replace this method with some way of saying "The (code) instruction at address changed from A bytes to B bytes. Fixup the debug info accordingly" - - this.encodedDebugInfo = encodedDebugInfo; - } - - /** - * Helper method that writes the item, without writing annotations - * @param out the AnnotatedOutput object - */ - private void writeItemWithNoAnnotations(final AnnotatedOutput out) { - out.writeUnsignedLeb128(lineStart); - out.writeUnsignedLeb128(parameterNames.length); - for (StringIdItem parameterName: parameterNames) { - int indexp1; - if (parameterName == null) { - indexp1 = 0; - } else { - indexp1 = parameterName.getIndex() + 1; - } - out.writeUnsignedLeb128(indexp1); - } - - DebugInstructionIterator.IterateInstructions(new ByteArrayInput(encodedDebugInfo), - new DebugInstructionIterator.ProcessRawDebugInstructionDelegate() { - private int referencedItemsPosition = 0; - - @Override - public void ProcessStaticOpcode(DebugOpcode opcode, int startDebugOffset, int length) { - out.write(encodedDebugInfo, startDebugOffset, length); - } - - @Override - public void ProcessStartLocal(int startDebugOffset, int length, int registerNum, int nameIndex, - int typeIndex, boolean registerIsSigned) { - out.writeByte(DebugOpcode.DBG_START_LOCAL.value); - if (dexFile.getPreserveSignedRegisters() && registerIsSigned) { - out.writeSignedLeb128(registerNum); - } else { - out.writeUnsignedLeb128(registerNum); - } - if (nameIndex != -1) { - out.writeUnsignedLeb128(referencedItems[referencedItemsPosition++].getIndex() + 1); - } else { - out.writeByte(0); - } - if (typeIndex != -1) { - out.writeUnsignedLeb128(referencedItems[referencedItemsPosition++].getIndex() + 1); - } else { - out.writeByte(0); - } - } - - @Override - public void ProcessStartLocalExtended(int startDebugOffset, int length, int registerNum, int nameIndex, - int typeIndex, int signatureIndex, - boolean registerIsSigned) { - out.writeByte(DebugOpcode.DBG_START_LOCAL_EXTENDED.value); - if (dexFile.getPreserveSignedRegisters() && registerIsSigned) { - out.writeSignedLeb128(registerNum); - } else { - out.writeUnsignedLeb128(registerNum); - } - if (nameIndex != -1) { - out.writeUnsignedLeb128(referencedItems[referencedItemsPosition++].getIndex() + 1); - } else { - out.writeByte(0); - } - if (typeIndex != -1) { - out.writeUnsignedLeb128(referencedItems[referencedItemsPosition++].getIndex() + 1); - } else { - out.writeByte(0); - } - if (signatureIndex != -1) { - out.writeUnsignedLeb128(referencedItems[referencedItemsPosition++].getIndex() + 1); - } else { - out.writeByte(0); - } - } - - @Override - public void ProcessSetFile(int startDebugOffset, int length, int nameIndex) { - out.writeByte(DebugOpcode.DBG_SET_FILE.value); - if (nameIndex != -1) { - out.writeUnsignedLeb128(referencedItems[referencedItemsPosition++].getIndex() + 1); - } else { - out.writeByte(0); - } - } - }); - } - - /** - * Helper method that writes and annotates the item - * @param out the AnnotatedOutput object - */ - private void writeItemWithAnnotations(final AnnotatedOutput out) { - out.annotate(0, parent.getParent().method.getMethodString()); - out.annotate("line_start: 0x" + Integer.toHexString(lineStart) + " (" + lineStart + ")"); - out.writeUnsignedLeb128(lineStart); - out.annotate("parameters_size: 0x" + Integer.toHexString(parameterNames.length) + " (" + parameterNames.length - + ")"); - out.writeUnsignedLeb128(parameterNames.length); - int index = 0; - for (StringIdItem parameterName: parameterNames) { - int indexp1; - if (parameterName == null) { - out.annotate("[" + index++ +"] parameterName: "); - indexp1 = 0; - } else { - out.annotate("[" + index++ +"] parameterName: " + parameterName.getStringValue()); - indexp1 = parameterName.getIndex() + 1; - } - out.writeUnsignedLeb128(indexp1); - } - - DebugInstructionIterator.IterateInstructions(new ByteArrayInput(encodedDebugInfo), - new DebugInstructionIterator.ProcessRawDebugInstructionDelegate() { - private int referencedItemsPosition = 0; - - @Override - public void ProcessEndSequence(int startDebugOffset) { - out.annotate("DBG_END_SEQUENCE"); - out.writeByte(DebugOpcode.DBG_END_SEQUENCE.value); - } - - @Override - public void ProcessAdvancePC(int startDebugOffset, int length, int addressDiff) { - out.annotate("DBG_ADVANCE_PC"); - out.writeByte(DebugOpcode.DBG_ADVANCE_PC.value); - out.indent(); - out.annotate("addr_diff: 0x" + Integer.toHexString(addressDiff) + " (" + addressDiff + ")"); - out.writeUnsignedLeb128(addressDiff); - out.deindent(); - } - - @Override - public void ProcessAdvanceLine(int startDebugOffset, int length, int lineDiff) { - out.annotate("DBG_ADVANCE_LINE"); - out.writeByte(DebugOpcode.DBG_ADVANCE_LINE.value); - out.indent(); - out.annotate("line_diff: 0x" + Integer.toHexString(lineDiff) + " (" + lineDiff + ")"); - out.writeSignedLeb128(lineDiff); - out.deindent(); - } - - @Override - public void ProcessStartLocal(int startDebugOffset, int length, int registerNum, int nameIndex, - int typeIndex, boolean registerIsSigned) { - out.annotate("DBG_START_LOCAL"); - out.writeByte(DebugOpcode.DBG_START_LOCAL.value); - out.indent(); - out.annotate("register_num: 0x" + Integer.toHexString(registerNum) + " (" + registerNum + ")"); - if (dexFile.getPreserveSignedRegisters() && registerIsSigned) { - out.writeSignedLeb128(registerNum); - } else { - out.writeUnsignedLeb128(registerNum); - } - if (nameIndex != -1) { - Item nameItem = referencedItems[referencedItemsPosition++]; - assert nameItem instanceof StringIdItem; - out.annotate("name: " + ((StringIdItem)nameItem).getStringValue()); - out.writeUnsignedLeb128(nameItem.getIndex() + 1); - } else { - out.annotate("name: "); - out.writeByte(0); - } - if (typeIndex != -1) { - Item typeItem = referencedItems[referencedItemsPosition++]; - assert typeItem instanceof TypeIdItem; - out.annotate("type: " + ((TypeIdItem)typeItem).getTypeDescriptor()); - out.writeUnsignedLeb128(typeItem.getIndex() + 1); - } else { - out.annotate("type: "); - out.writeByte(0); - } - out.deindent(); - } - - @Override - public void ProcessStartLocalExtended(int startDebugOffset, int length, int registerNum, - int nameIndex, int typeIndex, int signatureIndex, - boolean registerIsSigned) { - out.annotate("DBG_START_LOCAL_EXTENDED"); - out.writeByte(DebugOpcode.DBG_START_LOCAL_EXTENDED.value); - out.indent(); - out.annotate("register_num: 0x" + Integer.toHexString(registerNum) + " (" + registerNum + ")"); - if (dexFile.getPreserveSignedRegisters() && registerIsSigned) { - out.writeSignedLeb128(registerNum); - } else { - out.writeUnsignedLeb128(registerNum); - } - if (nameIndex != -1) { - Item nameItem = referencedItems[referencedItemsPosition++]; - assert nameItem instanceof StringIdItem; - out.annotate("name: " + ((StringIdItem)nameItem).getStringValue()); - out.writeUnsignedLeb128(nameItem.getIndex() + 1); - } else { - out.annotate("name: "); - out.writeByte(0); - } - if (typeIndex != -1) { - Item typeItem = referencedItems[referencedItemsPosition++]; - assert typeItem instanceof TypeIdItem; - out.annotate("type: " + ((TypeIdItem)typeItem).getTypeDescriptor()); - out.writeUnsignedLeb128(typeItem.getIndex() + 1); - } else { - out.annotate("type: "); - out.writeByte(0); - } - if (signatureIndex != -1) { - Item signatureItem = referencedItems[referencedItemsPosition++]; - assert signatureItem instanceof StringIdItem; - out.annotate("signature: " + ((StringIdItem)signatureItem).getStringValue()); - out.writeUnsignedLeb128(signatureItem.getIndex() + 1); - } else { - out.annotate("signature: "); - out.writeByte(0); - } - out.deindent(); - } - - @Override - public void ProcessEndLocal(int startDebugOffset, int length, int registerNum, - boolean registerIsSigned) { - out.annotate("DBG_END_LOCAL"); - out.writeByte(DebugOpcode.DBG_END_LOCAL.value); - out.annotate("register_num: 0x" + Integer.toHexString(registerNum) + " (" + registerNum + ")"); - if (registerIsSigned) { - out.writeSignedLeb128(registerNum); - } else { - out.writeUnsignedLeb128(registerNum); - } - } - - @Override - public void ProcessRestartLocal(int startDebugOffset, int length, int registerNum, - boolean registerIsSigned) { - out.annotate("DBG_RESTART_LOCAL"); - out.writeByte(DebugOpcode.DBG_RESTART_LOCAL.value); - out.annotate("register_num: 0x" + Integer.toHexString(registerNum) + " (" + registerNum + ")"); - if (registerIsSigned) { - out.writeSignedLeb128(registerNum); - } else { - out.writeUnsignedLeb128(registerNum); - } - } - - @Override - public void ProcessSetPrologueEnd(int startDebugOffset) { - out.annotate("DBG_SET_PROLOGUE_END"); - out.writeByte(DebugOpcode.DBG_SET_PROLOGUE_END.value); - } - - @Override - public void ProcessSetEpilogueBegin(int startDebugOffset) { - out.annotate("DBG_SET_EPILOGUE_BEGIN"); - out.writeByte(DebugOpcode.DBG_SET_EPILOGUE_BEGIN.value); - } - - @Override - public void ProcessSetFile(int startDebugOffset, int length, int nameIndex) { - out.annotate("DBG_SET_FILE"); - out.writeByte(DebugOpcode.DBG_SET_FILE.value); - if (nameIndex != -1) { - Item sourceItem = referencedItems[referencedItemsPosition++]; - assert sourceItem instanceof StringIdItem; - out.annotate("source_file: \"" + ((StringIdItem)sourceItem).getStringValue() + "\""); - out.writeUnsignedLeb128(sourceItem.getIndex() + 1); - } else { - out.annotate("source_file: "); - out.writeByte(0); - } - } - - @Override - public void ProcessSpecialOpcode(int startDebugOffset, int debugOpcode, int lineDiff, - int addressDiff) { - out.annotate("DBG_SPECIAL_OPCODE: line_diff=0x" + Integer.toHexString(lineDiff) + "(" + - lineDiff +"),addressDiff=0x" + Integer.toHexString(addressDiff) + "(" + addressDiff + - ")"); - out.writeByte(debugOpcode); - } - }); - } - - - - - /** {@inheritDoc} */ - public ItemType getItemType() { - return ItemType.TYPE_DEBUG_INFO_ITEM; - } - - /** {@inheritDoc} */ - public String getConciseIdentity() { - return "debug_info_item @0x" + Integer.toHexString(getOffset()); - } - - /** {@inheritDoc} */ - public int compareTo(DebugInfoItem other) { - if (parent == null) { - if (other.parent == null) { - return 0; - } - return -1; - } - if (other.parent == null) { - return 1; - } - return parent.compareTo(other.parent); - } - - /** - * Set the CodeItem that this DebugInfoItem is associated with - * @param codeItem the CodeItem that this DebugInfoItem is associated with - */ - protected void setParent(CodeItem codeItem) { - this.parent = codeItem; - } - - /** - * @return the initial value for the line number register for the debug info machine - */ - public int getLineStart() { - return lineStart; - } - - /** - * @return the debug info, encoded as a byte array - */ - public byte[] getEncodedDebugInfo() { - return encodedDebugInfo; - } - - /** - * @return an array of the items referenced by instructions, in order of occurance in the encoded debug info - */ - public Item[] getReferencedItems() { - return referencedItems; - } - - /** - * @return an array of the names of the associated method's parameters. The array can be null if no parameter info - * is available, or any element can be null to indicate no info for that parameter - */ - public StringIdItem[] getParameterNames() { - return parameterNames; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/DexFile.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/DexFile.java deleted file mode 100644 index 38a1e6f5..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/DexFile.java +++ /dev/null @@ -1,904 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.dexlib.Util.*; -import org.jf.util.AlignmentUtils; -import org.jf.util.ExceptionWithContext; -import org.jf.util.Hex; - -import java.io.*; -import java.security.DigestException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.zip.Adler32; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -/** - *

Main use cases

- * - *

These are the main use cases that drove the design of this library

- * - *
    - *
  1. Annotate an existing dex file - In this case, the intent is to document the structure of - * an existing dex file. We want to be able to read in the dex file, and then write out a dex file - * that is exactly the same (while adding annotation information to an AnnotatedOutput object)

  2. - * - *
  3. Canonicalize an existing dex file - In this case, the intent is to rewrite an existing dex file - * so that it is in a canonical form. There is a certain amount of leeway in how various types of - * tems in a dex file are ordered or represented. It is sometimes useful to be able to easily - * compare a disassebled and reassembled dex file with the original dex file. If both dex-files are - * written canonically, they "should" match exactly, barring any explicit changes to the reassembled - * file.

    - * - *

    Currently, there are a couple of pieces of information that probably won't match exactly - *

      - *
    • the order of exception handlers in the EncodedCatchHandlerList for a method
    • - *
    • the ordering of some of the debug info in the {@link org.jf.dexlib.DebugInfoItem} for a method
    • - *

    - * - * - *

    Note that the above discrepancies should typically only be "intra-item" differences. They - * shouldn't change the size of the item, or affect how anything else is placed or laid out

  4. - * - *
  5. Creating a dex file from scratch - In this case, a blank dex file is created and then classes - * are added to it incrementally by calling the {@link org.jf.dexlib.Section#intern intern} method of - * {@link DexFile#ClassDefsSection}, which will add all the information necessary to represent the given - * class. For example, when assembling a dex file from a set of assembly text files.

    - * - *

    In this case, we can choose to write the dex file in a canonical form or not. It is somewhat - * slower to write it in a canonical format, due to the extra sorting and calculations that are - * required.

  6. - * - * - *
  7. Reading in the dex file - In this case, the intent is to read in a dex file and expose all the - * data to the calling application. For example, when disassembling a dex file into a text based - * assembly format, or doing other misc processing of the dex file.

  8. - * - * - *

    Other use cases

    - * - *

    These are other use cases that are possible, but did not drive the design of the library. - * No effort was made to test these use cases or ensure that they work. Some of these could - * probably be better achieved with a disassemble - modify - reassemble type process, using - * smali/baksmali or another assembler/disassembler pair that are compatible with each other

    - * - *
      - *
    • deleting classes/methods/etc. from a dex file
    • - *
    • merging 2 dex files
    • - *
    • splitting a dex file
    • - *
    • moving classes from 1 dex file to another
    • - *
    • removing the debug information from a dex file
    • - *
    • obfustication of a dex file
    • - *
    - */ -public class DexFile -{ - /** - * A mapping from ItemType to the section that contains items of the given type - */ - private final Section[] sectionsByType; - - /** - * Ordered lists of the indexed and offsetted sections. The order of these lists specifies the order - * that the sections will be written in - */ - private final IndexedSection[] indexedSections; - private final OffsettedSection[] offsettedSections; - - /** - * dalvik had a bug where it wrote the registers for certain types of debug info in a signed leb - * format, instead of an unsigned leb format. There are no negative registers of course, but - * certain positive values have a different encoding depending on whether they are encoded as - * an unsigned leb128 or a signed leb128. Specifically, the signed leb128 is 1 byte longer in some cases. - * - * This determine whether we should keep any signed registers as signed, or force all register to - * unsigned. By default we don't keep track of whether they were signed or not, and write them back - * out as unsigned. This option only has an effect when reading an existing dex file. It has no - * effect when a dex file is created from scratch - * - * The 2 main use-cases in play are - * 1. Annotate an existing dex file - In this case, preserveSignedRegisters should be false, so that we keep - * track of any signed registers and write them back out as signed Leb128 values. - * - * 2. Canonicalize an existing dex file - In this case, fixRegisters should be true, so that all - * registers in the debug info are written as unsigned Leb128 values regardless of how they were - * originally encoded - */ - private final boolean preserveSignedRegisters; - - /** - * When true, any instructions in a code item are skipped over instead of being read in. This is useful when - * you only need the information about the classes and their methods, for example, when loading the BOOTCLASSPATH - * jars in order to analyze a dex file - */ - private final boolean skipInstructions; - - /** - * When true, this prevents any sorting of the items during placement of the dex file. This - * should *only* be set to true when this dex file was read in from an existing (valid) dex file, - * and no modifications were made (i.e. no items added or deleted). Otherwise it is likely that - * an invalid dex file will be generated. - * - * This is useful for the first use case (annotating an existing dex file). This ensures the items - * retain the same order as in the original dex file. - */ - private boolean inplace = false; - - /** - * When true, this imposes an full ordering on all the items, to force them into a (possibly - * arbitrary) canonical order. When false, only the items that the dex format specifies - * an order for are sorted. The rest of the items are not ordered. - * - * This is useful for the second use case (canonicalizing an existing dex file) or possibly for - * the third use case (creating a dex file from scratch), if there is a need to write the new - * dex file in a canonical form. - */ - private boolean sortAllItems = false; - - /** - * Is this file an odex file? This is only set when reading in an odex file - */ - private boolean isOdex = false; - - private OdexHeader odexHeader; - private OdexDependencies odexDependencies; - - private int dataOffset; - private int dataSize; - private int fileSize; - - /** - * A private constructor containing common code to initialize the section maps and lists - * @param preserveSignedRegisters If true, keep track of any registers in the debug information - * @param skipInstructions If true, skip the instructions in any code item. - * that are signed, so they will be written in the same format. See - * getPreserveSignedRegisters() - */ - private DexFile(boolean preserveSignedRegisters, boolean skipInstructions) { - this.preserveSignedRegisters = preserveSignedRegisters; - this.skipInstructions = skipInstructions; - - sectionsByType = new Section[] { - StringIdsSection, - TypeIdsSection, - ProtoIdsSection, - FieldIdsSection, - MethodIdsSection, - ClassDefsSection, - TypeListsSection, - AnnotationSetRefListsSection, - AnnotationSetsSection, - ClassDataSection, - CodeItemsSection, - AnnotationDirectoriesSection, - StringDataSection, - DebugInfoItemsSection, - AnnotationsSection, - EncodedArraysSection, - null, - null - }; - - indexedSections = new IndexedSection[] { - StringIdsSection, - TypeIdsSection, - ProtoIdsSection, - FieldIdsSection, - MethodIdsSection, - ClassDefsSection - }; - - offsettedSections = new OffsettedSection[] { - AnnotationSetRefListsSection, - AnnotationSetsSection, - CodeItemsSection, - AnnotationDirectoriesSection, - TypeListsSection, - StringDataSection, - AnnotationsSection, - EncodedArraysSection, - ClassDataSection, - DebugInfoItemsSection - }; - } - - - /** - * Construct a new DexFile instance by reading in the given dex file. - * @param file The dex file to read in - * @throws IOException if an IOException occurs - */ - public DexFile(String file) - throws IOException { - this(new File(file), true, false); - } - - /** - * Construct a new DexFile instance by reading in the given dex file, - * and optionally keep track of any registers in the debug information that are signed, - * so they will be written in the same format. - * @param file The dex file to read in - * @param preserveSignedRegisters If true, keep track of any registers in the debug information - * that are signed, so they will be written in the same format. See - * @param skipInstructions If true, skip the instructions in any code item. - * getPreserveSignedRegisters() - * @throws IOException if an IOException occurs - */ - public DexFile(String file, boolean preserveSignedRegisters, boolean skipInstructions) - throws IOException { - this(new File(file), preserveSignedRegisters, skipInstructions); - } - - /** - * Construct a new DexFile instance by reading in the given dex file. - * @param file The dex file to read in - * @throws IOException if an IOException occurs - */ - public DexFile(File file) - throws IOException { - this(file, true, false); - } - - /** - * Construct a new DexFile instance by reading in the given dex file, - * and optionally keep track of any registers in the debug information that are signed, - * so they will be written in the same format. - * @param file The dex file to read in - * @param preserveSignedRegisters If true, keep track of any registers in the debug information - * that are signed, so they will be written in the same format. - * @param skipInstructions If true, skip the instructions in any code item. - * @see #getPreserveSignedRegisters - * @throws IOException if an IOException occurs - */ - public DexFile(File file, boolean preserveSignedRegisters, boolean skipInstructions) - throws IOException { - this(preserveSignedRegisters, skipInstructions); - - long fileLength; - byte[] magic = FileUtils.readFile(file, 0, 8); - - InputStream inputStream = null; - Input in = null; - ZipFile zipFile = null; - - try { - //do we have a zip file? - if (magic[0] == 0x50 && magic[1] == 0x4B) { - zipFile = new ZipFile(file); - ZipEntry zipEntry = zipFile.getEntry("classes.dex"); - if (zipEntry == null) { - throw new NoClassesDexException("zip file " + file.getName() + " does not contain a classes.dex " + - "file"); - } - fileLength = zipEntry.getSize(); - if (fileLength < 40) { - throw new RuntimeException("The classes.dex file in " + file.getName() + " is too small to be a" + - " valid dex file"); - } else if (fileLength > Integer.MAX_VALUE) { - throw new RuntimeException("The classes.dex file in " + file.getName() + " is too large to read in"); - } - inputStream = new BufferedInputStream(zipFile.getInputStream(zipEntry)); - - inputStream.mark(8); - for (int i=0; i<8; i++) { - magic[i] = (byte)inputStream.read(); - } - inputStream.reset(); - } else { - fileLength = file.length(); - if (fileLength < 40) { - throw new RuntimeException(file.getName() + " is too small to be a valid dex file"); - } - if (fileLength < 40) { - throw new RuntimeException(file.getName() + " is too small to be a valid dex file"); - } else if (fileLength > Integer.MAX_VALUE) { - throw new RuntimeException(file.getName() + " is too large to read in"); - } - inputStream = new FileInputStream(file); - } - - byte[] dexMagic, odexMagic; - boolean isDex = false; - this.isOdex = false; - - for (int i=0; i 40) { - FileUtils.readStream(inputStream, odexHeader.dexOffset - 40); - } - - in = new ByteArrayInput(FileUtils.readStream(inputStream, odexHeader.dexLength)); - - if (dependencySkip > 0) { - FileUtils.readStream(inputStream, dependencySkip); - } - - odexDependencies = new OdexDependencies( - new ByteArrayInput(FileUtils.readStream(inputStream, odexHeader.depsLength))); - } else if (isDex) { - in = new ByteArrayInput(FileUtils.readStream(inputStream, (int)fileLength)); - } else { - StringBuffer sb = new StringBuffer("bad magic value:"); - for (int i=0; i<8; i++) { - sb.append(" "); - sb.append(Hex.u1(magic[i])); - } - throw new RuntimeException(sb.toString()); - } - } finally { - if (inputStream != null) { - inputStream.close(); - } - if (zipFile != null) { - zipFile.close(); - } - } - - ReadContext readContext = new ReadContext(); - - HeaderItem.readFrom(in, 0, readContext); - - //the map offset was set while reading in the header item - int mapOffset = readContext.getSectionOffset(ItemType.TYPE_MAP_LIST); - - in.setCursor(mapOffset); - MapItem.readFrom(in, 0, readContext); - - //the sections are ordered in such a way that the item types - Section sections[] = new Section[] { - StringDataSection, - StringIdsSection, - TypeIdsSection, - TypeListsSection, - ProtoIdsSection, - FieldIdsSection, - MethodIdsSection, - AnnotationsSection, - AnnotationSetsSection, - AnnotationSetRefListsSection, - AnnotationDirectoriesSection, - DebugInfoItemsSection, - CodeItemsSection, - ClassDataSection, - EncodedArraysSection, - ClassDefsSection - }; - - for (Section section: sections) { - if (section == null) { - continue; - } - - if (skipInstructions && (section == CodeItemsSection || section == DebugInfoItemsSection)) { - continue; - } - - int sectionOffset = readContext.getSectionOffset(section.ItemType); - if (sectionOffset > 0) { - int sectionSize = readContext.getSectionSize(section.ItemType); - in.setCursor(sectionOffset); - section.readFrom(sectionSize, in, readContext); - } - } - } - - /** - * Constructs a new, blank dex file. Classes can be added to this dex file by calling - * the Section.intern() method of ClassDefsSection - */ - public DexFile() { - this(true, false); - } - - /** - * Get the Section containing items of the same type as the given item - * @param item Get the Section that contains items of this type - * @param The specific item subclass - inferred from the passed item - * @return the Section containing items of the same type as the given item - */ - public Section getSectionForItem(T item) { - return (Section)sectionsByType[item.getItemType().SectionIndex]; - } - - /** - * Get the Section containing items of the given type - * @param itemType the type of item - * @return the Section containing items of the given type - */ - public Section getSectionForType(ItemType itemType) { - return sectionsByType[itemType.SectionIndex]; - } - - /** - * Get a boolean value indicating whether this dex file preserved any signed - * registers in the debug info as it read the dex file in. By default, the dex file - * doesn't check whether the registers are encoded as unsigned or signed values. - * - * This does *not* affect the actual register value that is read in. The value is - * read correctly regardless - * - * This does affect whether any signed registers will retain the same encoding or be - * forced to the (correct) unsigned encoding when the dex file is written back out. - * - * See the discussion about signed register values in the documentation for - * DexFile - * @return a boolean indicating whether this dex file preserved any signed registers - * as it was read in - */ - public boolean getPreserveSignedRegisters() { - return preserveSignedRegisters; - } - - /** - * Get a boolean value indicating whether to skip any instructions in a code item while reading in the dex file. - * This is useful when you only need the information about the classes and their methods, for example, when - * loading the BOOTCLASSPATH jars in order to analyze a dex file - * @return a boolean value indicating whether to skip any instructions in a code item - */ - public boolean skipInstructions() { - return skipInstructions; - } - - /** - * Get a boolean value indicating whether all items should be placed into a - * (possibly arbitrary) "canonical" ordering. If false, then only the items - * that must be ordered per the dex specification are sorted. - * - * When true, writing the dex file involves somewhat more overhead - * - * If both SortAllItems and Inplace are true, Inplace takes precedence - * @return a boolean value indicating whether all items should be sorted - */ - public boolean getSortAllItems() { - return this.sortAllItems; - } - - /** - * Set a boolean value indicating whether all items should be placed into a - * (possibly arbitrary) "canonical" ordering. If false, then only the items - * that must be ordered per the dex specification are sorted. - * - * When true, writing the dex file involves somewhat more overhead - * - * If both SortAllItems and Inplace are true, Inplace takes precedence - * @param value a boolean value indicating whether all items should be sorted - */ - public void setSortAllItems(boolean value) { - this.sortAllItems = value; - } - - /** - * @return a boolean value indicating whether this dex file was created by reading in an odex file - */ - public boolean isOdex() { - return this.isOdex; - } - - /** - * @return an OdexDependencies object that contains the dependencies for this odex, or null if this - * DexFile represents a dex file instead of an odex file - */ - public OdexDependencies getOdexDependencies() { - return odexDependencies; - } - - /** - * @return An OdexHeader object containing the information from the odex header in this dex file, or null if there - * is no odex header - */ - public OdexHeader getOdexHeader() { - return odexHeader; - } - - /** - * Get a boolean value indicating whether items in this dex file should be - * written back out "in-place", or whether the normal layout logic should be - * applied. - * - * This should only be used for a dex file that has been read from an existing - * dex file, and no modifications have been made to the dex file. Otherwise, - * there is a good chance that the resulting dex file will be invalid due to - * items that aren't placed correctly - * - * If both SortAllItems and Inplace are true, Inplace takes precedence - * @return a boolean value indicating whether items in this dex file should be - * written back out in-place. - */ - public boolean getInplace() { - return this.inplace; - } - - /** - * @return the size of the file, in bytes - */ - public int getFileSize() { - return fileSize; - } - - /** - * @return the size of the data section, in bytes - */ - public int getDataSize() { - return dataSize; - } - - /** - * @return the offset where the data section begins - */ - public int getDataOffset() { - return dataOffset; - } - - /** - * Set a boolean value indicating whether items in this dex file should be - * written back out "in-place", or whether the normal layout logic should be - * applied. - * - * This should only be used for a dex file that has been read from an existing - * dex file, and no modifications have been made to the dex file. Otherwise, - * there is a good chance that the resulting dex file will be invalid due to - * items that aren't placed correctly - * - * If both SortAllItems and Inplace are true, Inplace takes precedence - * @param value a boolean value indicating whether items in this dex file should be - * written back out in-place. - */ - public void setInplace(boolean value) { - this.inplace = value; - } - - /** - * Get an array of Section objects that are sorted by offset. - * @return an array of Section objects that are sorted by offset. - */ - protected Section[] getOrderedSections() { - int sectionCount = 0; - - for (Section section: sectionsByType) { - if (section != null && section.getItems().size() > 0) { - sectionCount++; - } - } - - Section[] sections = new Section[sectionCount]; - sectionCount = 0; - for (Section section: sectionsByType) { - if (section != null && section.getItems().size() > 0) { - sections[sectionCount++] = section; - } - } - - Arrays.sort(sections, new Comparator
    () { - public int compare(Section a, Section b) { - return a.getOffset() - b.getOffset(); - } - }); - - return sections; - } - - /** - * This method should be called before writing a dex file. It sorts the sections - * as needed or as indicated by getSortAllItems() and getInplace(), - * and then performs a pass through all of the items, finalizing the position (i.e. - * index and/or offset) of each item in the dex file. - * - * This step is needed primarily so that the indexes and offsets of all indexed and - * offsetted items are available when writing references to those items elsewhere. - */ - public void place() { - int offset = HeaderItem.placeAt(0, 0); - - int sectionsPosition = 0; - Section[] sections; - if (this.inplace) { - sections = this.getOrderedSections(); - } else { - sections = new Section[indexedSections.length + offsettedSections.length]; - System.arraycopy(indexedSections, 0, sections, 0, indexedSections.length); - System.arraycopy(offsettedSections, 0, sections, indexedSections.length, offsettedSections.length); - } - - while (sectionsPosition < sections.length && sections[sectionsPosition].ItemType.isIndexedItem()) { - Section section = sections[sectionsPosition]; - if (!this.inplace) { - section.sortSection(); - } - - offset = section.placeAt(offset); - - sectionsPosition++; - } - - dataOffset = offset; - - while (sectionsPosition < sections.length) { - Section section = sections[sectionsPosition]; - if (this.sortAllItems && !this.inplace) { - section.sortSection(); - } - offset = section.placeAt(offset); - - sectionsPosition++; - } - - offset = AlignmentUtils.alignOffset(offset, ItemType.TYPE_MAP_LIST.ItemAlignment); - offset = MapItem.placeAt(offset, 0); - - fileSize = offset; - dataSize = offset - dataOffset; - } - - /** - * Writes the dex file to the give AnnotatedOutput object. If - * out.Annotates() is true, then annotations that document the format - * of the dex file are written. - * - * You must call place() on this dex file, before calling this method - * @param out the AnnotatedOutput object to write the dex file and annotations to - * - * After calling this method, you should call calcSignature() and - * then calcChecksum() on the resulting byte array, to calculate the - * signature and checksum in the header - */ - public void writeTo(AnnotatedOutput out) { - - out.annotate(0, "-----------------------------"); - out.annotate(0, "header item"); - out.annotate(0, "-----------------------------"); - out.annotate(0, " "); - HeaderItem.writeTo(out); - - out.annotate(0, " "); - - int sectionsPosition = 0; - Section[] sections; - if (this.inplace) { - sections = this.getOrderedSections(); - } else { - sections = new Section[indexedSections.length + offsettedSections.length]; - System.arraycopy(indexedSections, 0, sections, 0, indexedSections.length); - System.arraycopy(offsettedSections, 0, sections, indexedSections.length, offsettedSections.length); - } - - while (sectionsPosition < sections.length) { - sections[sectionsPosition].writeTo(out); - sectionsPosition++; - } - - out.alignTo(MapItem.getItemType().ItemAlignment); - - out.annotate(0, " "); - out.annotate(0, "-----------------------------"); - out.annotate(0, "map item"); - out.annotate(0, "-----------------------------"); - out.annotate(0, " "); - MapItem.writeTo(out); - } - - public final HeaderItem HeaderItem = new HeaderItem(this); - public final MapItem MapItem = new MapItem(this); - - /** - * The IndexedSection containing StringIdItem items - */ - public final IndexedSection StringIdsSection = - new IndexedSection(this, ItemType.TYPE_STRING_ID_ITEM); - - /** - * The IndexedSection containing TypeIdItem items - */ - public final IndexedSection TypeIdsSection = - new IndexedSection(this, ItemType.TYPE_TYPE_ID_ITEM); - - /** - * The IndexedSection containing ProtoIdItem items - */ - public final IndexedSection ProtoIdsSection = - new IndexedSection(this, ItemType.TYPE_PROTO_ID_ITEM); - - /** - * The IndexedSection containing FieldIdItem items - */ - public final IndexedSection FieldIdsSection = - new IndexedSection(this, ItemType.TYPE_FIELD_ID_ITEM); - - /** - * The IndexedSection containing MethodIdItem items - */ - public final IndexedSection MethodIdsSection = - new IndexedSection(this, ItemType.TYPE_METHOD_ID_ITEM); - - /** - * The IndexedSection containing ClassDefItem items - */ - public final IndexedSection ClassDefsSection = - new IndexedSection(this, ItemType.TYPE_CLASS_DEF_ITEM) { - - public int placeAt(int offset) { - if (DexFile.this.getInplace()) { - return super.placeAt(offset); - } - - int ret = ClassDefItem.placeClassDefItems(this, offset); - - Collections.sort(this.items); - - this.offset = items.get(0).getOffset(); - return ret; - } - - protected void sortSection() { - // Do nothing. Sorting is handled by ClassDefItem.ClassDefPlacer, during placement - } - }; - - /** - * The OffsettedSection containing TypeListItem items - */ - public final OffsettedSection TypeListsSection = - new OffsettedSection(this, ItemType.TYPE_TYPE_LIST); - - /** - * The OffsettedSection containing AnnotationSetRefList items - */ - public final OffsettedSection AnnotationSetRefListsSection = - new OffsettedSection(this, ItemType.TYPE_ANNOTATION_SET_REF_LIST); - - /** - * The OffsettedSection containing AnnotationSetItem items - */ - public final OffsettedSection AnnotationSetsSection = - new OffsettedSection(this, ItemType.TYPE_ANNOTATION_SET_ITEM); - - /** - * The OffsettedSection containing ClassDataItem items - */ - public final OffsettedSection ClassDataSection = - new OffsettedSection(this, ItemType.TYPE_CLASS_DATA_ITEM); - - /** - * The OffsettedSection containing CodeItem items - */ - public final OffsettedSection CodeItemsSection = - new OffsettedSection(this, ItemType.TYPE_CODE_ITEM); - - /** - * The OffsettedSection containing StringDataItem items - */ - public final OffsettedSection StringDataSection = - new OffsettedSection(this, ItemType.TYPE_STRING_DATA_ITEM); - - /** - * The OffsettedSection containing DebugInfoItem items - */ - public final OffsettedSection DebugInfoItemsSection = - new OffsettedSection(this, ItemType.TYPE_DEBUG_INFO_ITEM); - - /** - * The OffsettedSection containing AnnotationItem items - */ - public final OffsettedSection AnnotationsSection = - new OffsettedSection(this, ItemType.TYPE_ANNOTATION_ITEM); - - /** - * The OffsettedSection containing EncodedArrayItem items - */ - public final OffsettedSection EncodedArraysSection = - new OffsettedSection(this, ItemType.TYPE_ENCODED_ARRAY_ITEM); - - /** - * The OffsettedSection containing AnnotationDirectoryItem items - */ - public final OffsettedSection AnnotationDirectoriesSection = - new OffsettedSection(this, ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM); - - - /** - * Calculates the signature for the dex file in the given byte array, - * and then writes the signature to the appropriate location in the header - * containing in the array - * - * @param bytes non-null; the bytes of the file - */ - public static void calcSignature(byte[] bytes) { - MessageDigest md; - - try { - md = MessageDigest.getInstance("SHA-1"); - } catch (NoSuchAlgorithmException ex) { - throw new RuntimeException(ex); - } - - md.update(bytes, 32, bytes.length - 32); - - try { - int amt = md.digest(bytes, 12, 20); - if (amt != 20) { - throw new RuntimeException("unexpected digest write: " + amt + - " bytes"); - } - } catch (DigestException ex) { - throw new RuntimeException(ex); - } - } - - /** - * Calculates the checksum for the .dex file in the - * given array, and modify the array to contain it. - * - * @param bytes non-null; the bytes of the file - */ - public static void calcChecksum(byte[] bytes) { - Adler32 a32 = new Adler32(); - - a32.update(bytes, 12, bytes.length - 12); - - int sum = (int) a32.getValue(); - - bytes[8] = (byte) sum; - bytes[9] = (byte) (sum >> 8); - bytes[10] = (byte) (sum >> 16); - bytes[11] = (byte) (sum >> 24); - } - - public static class NoClassesDexException extends ExceptionWithContext { - public NoClassesDexException(String message) { - super(message); - } - } -} \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedArrayItem.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedArrayItem.java deleted file mode 100644 index 6eb917cb..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedArrayItem.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.dexlib.EncodedValue.ArrayEncodedSubValue; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; - -public class EncodedArrayItem extends Item { - private int hashCode = 0; - - private ArrayEncodedSubValue encodedArray; - - /** - * Creates a new uninitialized EncodedArrayItem - * @param dexFile The DexFile that this item belongs to - */ - protected EncodedArrayItem(DexFile dexFile) { - super(dexFile); - } - - /** - * Creates a new EncodedArrayItem with the given values - * @param dexFile The DexFile that this item belongs to - * @param encodedArray The encoded array value - */ - private EncodedArrayItem(DexFile dexFile, ArrayEncodedSubValue encodedArray) { - super(dexFile); - this.encodedArray = encodedArray; - } - - /** - * Returns an EncodedArrayItem for the given values, and that has been interned into the given - * DexFile - * @param dexFile The DexFile that this item belongs to - * @param encodedArray The encoded array value - * @return an EncodedArrayItem for the given values, and that has been interned into the given - */ - public static EncodedArrayItem internEncodedArrayItem(DexFile dexFile, ArrayEncodedSubValue encodedArray) { - EncodedArrayItem encodedArrayItem = new EncodedArrayItem(dexFile, encodedArray); - return dexFile.EncodedArraysSection.intern(encodedArrayItem); - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - encodedArray = new ArrayEncodedSubValue(dexFile, in); - } - - /** {@inheritDoc} */ - protected int placeItem(int offset) { - return encodedArray.placeValue(offset); - } - - /** {@inheritDoc} */ - protected void writeItem(AnnotatedOutput out) { - encodedArray.writeValue(out); - } - - /** {@inheritDoc} */ - public ItemType getItemType() { - return ItemType.TYPE_ENCODED_ARRAY_ITEM; - } - - /** {@inheritDoc} */ - public String getConciseIdentity() { - return "encoded_array @0x" + Integer.toHexString(getOffset()); - } - - /** {@inheritDoc} */ - public int compareTo(EncodedArrayItem encodedArrayItem) { - return encodedArray.compareTo(encodedArrayItem.encodedArray); - } - - /** - * @return The encoded array value - */ - public ArrayEncodedSubValue getEncodedArray() { - return encodedArray; - } - - /** - * calculate and cache the hashcode - */ - private void calcHashCode() { - hashCode = encodedArray.hashCode(); - } - - @Override - public int hashCode() { - //there's a small possibility that the actual hash code will be 0. If so, we'll - //just end up recalculating it each time - if (hashCode == 0) - calcHashCode(); - return hashCode; - } - - @Override - public boolean equals(Object o) { - if (this==o) { - return true; - } - if (o==null || !this.getClass().equals(o.getClass())) { - return false; - } - - EncodedArrayItem other = (EncodedArrayItem)o; - return (encodedArray.compareTo(other.encodedArray) == 0); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/AnnotationEncodedSubValue.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/AnnotationEncodedSubValue.java deleted file mode 100644 index acd59961..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/AnnotationEncodedSubValue.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.DexFile; -import org.jf.dexlib.StringIdItem; -import org.jf.dexlib.TypeIdItem; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; -import org.jf.dexlib.Util.Leb128Utils; - -/** - * An AnnotationEncodedSubValue is identical to an AnnotationEncodedValue, except that it - * doesn't have the initial valueType/valueArg byte. This is used in the AnnotationItem object - */ -public class AnnotationEncodedSubValue extends EncodedValue { - private int hashCode = 0; - - public final TypeIdItem annotationType; - public final StringIdItem[] names; - public final EncodedValue[] values; - - /** - * Constructs a new AnnotationEncodedSubValue by reading the value from the given Input - * object. - * @param dexFile The DexFile that is being read in - * @param in The Input object to read from - */ - public AnnotationEncodedSubValue(DexFile dexFile, Input in) { - annotationType = dexFile.TypeIdsSection.getItemByIndex(in.readUnsignedLeb128()); - names = new StringIdItem[in.readUnsignedLeb128()]; - values = new EncodedValue[names.length]; - - for (int i=0; iAnnotationEncodedValue with the given values. names and values must be the same - * length, and must be sorted according to the name - * @param annotationType The type of the annotation - * @param names An array of the names of the elements of the annotation - * @param values An array of the values of the elements on the annotation - */ - public AnnotationEncodedSubValue(TypeIdItem annotationType, StringIdItem[] names, EncodedValue[] values) { - this.annotationType = annotationType; - if (names.length != values.length) { - throw new RuntimeException("The names and values parameters must be the same length"); - } - this.names = names; - this.values = values; - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - out.annotate("annotation_type: " + annotationType.getTypeDescriptor()); - out.writeUnsignedLeb128(annotationType.getIndex()); - out.annotate("element_count: 0x" + Integer.toHexString(names.length) + " (" + names.length + ")"); - out.writeUnsignedLeb128(names.length); - - for (int i=0; iAnnotationEncodedValue by reading the value from the given Input - * object. The Input's cursor should be set to the 2nd byte of the encoded value - * @param dexFile The DexFile that is being read in - * @param in The Input object to read from - */ - protected AnnotationEncodedValue(DexFile dexFile, Input in) { - super(dexFile, in); - } - - /** - * Constructs a new AnnotationEncodedValue with the given values. names and values must be the same - * length, and must be sorted according to the name - * @param annotationType The type of the annotation - * @param names An array of the names of the elements of the annotation - * @param values An array of the values of the elements on the annotation - */ - public AnnotationEncodedValue(TypeIdItem annotationType, StringIdItem[] names, EncodedValue[] values) { - super(annotationType, names, values); - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - if (out.annotates()) { - out.annotate("value_type=" + ValueType.VALUE_ANNOTATION.name() + ",value_arg=0"); - } - out.writeByte(ValueType.VALUE_ANNOTATION.value); - super.writeValue(out); - } - - /** {@inheritDoc} */ - public int placeValue(int offset) { - return super.placeValue(offset + 1); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/ArrayEncodedSubValue.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/ArrayEncodedSubValue.java deleted file mode 100644 index f79db736..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/ArrayEncodedSubValue.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; -import org.jf.dexlib.Util.Leb128Utils; - -/** - * An ArrayEncodedSubValue is identical to an ArrayEncodedValue, except that it - * doesn't have the initial valueType/valueArg byte. This is used in the EncodedArrayItem object - */ -public class ArrayEncodedSubValue extends EncodedValue { - private int hashCode = 0; - - public final EncodedValue[] values; - - /** - * Constructs a new ArrayEncodedSubValue by reading the value from the given Input object. - * The Input's cursor should be set to the 2nd byte of the encoded value - * @param dexFile The DexFile that is being read in - * @param in The Input object to read from - */ - public ArrayEncodedSubValue(DexFile dexFile, Input in) { - values = new EncodedValue[in.readUnsignedLeb128()]; - - for (int i=0; iArrayEncodedSubValue with the given values - * @param values The array values - */ - public ArrayEncodedSubValue(EncodedValue[] values) { - this.values = values; - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - if (out.annotates()) - { - out.annotate("array_size: 0x" + Integer.toHexString(values.length) + " (" + values.length + ")"); - out.writeUnsignedLeb128(values.length); - int index = 0; - for (EncodedValue encodedValue: values) { - out.annotate(0, "[" + index++ + "] array_element"); - out.indent(); - encodedValue.writeValue(out); - out.deindent(); - } - } else { - out.writeUnsignedLeb128(values.length); - for (EncodedValue encodedValue: values) { - encodedValue.writeValue(out); - } - } - } - - /** {@inheritDoc} */ - public int placeValue(int offset) { - offset = offset + Leb128Utils.unsignedLeb128Size(values.length); - for (EncodedValue encodedValue: values) { - offset = encodedValue.placeValue(offset); - } - - return offset; - } - - /** {@inheritDoc} */ - protected int compareValue(EncodedValue o) { - ArrayEncodedSubValue other = (ArrayEncodedSubValue)o; - - int comp = values.length - other.values.length; - if (comp != 0) { - return comp; - } - - for (int i=0; iArrayEncodedValue by reading the value from the given Input object. - * The Input's cursor should be set to the 2nd byte of the encoded value - * @param dexFile The DexFile that is being read in - * @param in The Input object to read from - */ - protected ArrayEncodedValue(DexFile dexFile, Input in) { - super(dexFile, in); - } - - /** - * Constructs a new ArrayEncodedValue with the given values - * @param values The array values - */ - public ArrayEncodedValue(EncodedValue[] values) { - super(values); - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - if (out.annotates()) { - out.annotate("value_type=" + ValueType.VALUE_ARRAY.name() + ",value_arg=0"); - } - out.writeByte(ValueType.VALUE_ARRAY.value); - super.writeValue(out); - } - - /** {@inheritDoc} */ - public int placeValue(int offset) { - return super.placeValue(offset + 1); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/BooleanEncodedValue.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/BooleanEncodedValue.java deleted file mode 100644 index 507e58fe..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/BooleanEncodedValue.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.Util.AnnotatedOutput; - -public class BooleanEncodedValue extends EncodedValue { - /** - * The dupliton values - */ - public static final BooleanEncodedValue TrueValue = new BooleanEncodedValue(true); - public static final BooleanEncodedValue FalseValue = new BooleanEncodedValue(false); - - public final boolean value; - - /** - * Constructs a new BooleanEncodedValue with the given value - * @param value The value - */ - private BooleanEncodedValue(boolean value) { - this.value = value; - } - - /** - * Gets the BooleanEncodedValue for the given valueArg value. The high 3 bits of the first byte should - * be passed as the valueArg parameter - * @param valueArg The high 3 bits of the first byte of this encoded value - * @return the BooleanEncodedValue for the given valueArg value - */ - protected static BooleanEncodedValue getBooleanEncodedValue(byte valueArg) { - if (valueArg == 0) { - return FalseValue; - } else if (valueArg == 1) { - return TrueValue; - } - throw new RuntimeException("valueArg must be either 0 or 1"); - } - - /** - * Gets the BooleanEncodedValue for the given boolean value - * @param value the boolean value - * @return the BooleanEncodedValue for the given boolean value - */ - public static BooleanEncodedValue getBooleanEncodedValue(boolean value) { - if (value) { - return TrueValue; - } - return FalseValue; - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - if (out.annotates()) { - out.annotate("value_type=" + ValueType.VALUE_BOOLEAN.name() + ",value=" + Boolean.toString(value)); - } - out.writeByte(ValueType.VALUE_BOOLEAN.value | ((value?1:0) << 5)); - } - - /** {@inheritDoc} */ - public int placeValue(int offset) { - return offset + 1; - } - - /** {@inheritDoc} */ - protected int compareValue(EncodedValue o) { - BooleanEncodedValue other = (BooleanEncodedValue)o; - if (value == other.value) - return 0; - if (value) - return 1; - return -1; - } - - /** {@inheritDoc} */ - public ValueType getValueType() { - return ValueType.VALUE_BOOLEAN; - } - - @Override - public int hashCode() { - return value?1:0; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/ByteEncodedValue.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/ByteEncodedValue.java deleted file mode 100644 index 683d547e..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/ByteEncodedValue.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.EncodedValueUtils; -import org.jf.dexlib.Util.Input; - -public class ByteEncodedValue extends EncodedValue { - public final byte value; - - /** - * Constructs a new ByteEncodedValue by reading the value from the given Input object. - * The Input's cursor should be set to the 2nd byte of the encoded value - * @param in The Input object to read from - */ - protected ByteEncodedValue(Input in) { - value = (byte)EncodedValueUtils.decodeSignedIntegralValue(in.readBytes(1)); - } - - /** - * Constructs a new ByteEncodedValue with the given value - * @param value The value - */ - public ByteEncodedValue(byte value) { - this.value = value; - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - if (out.annotates()) { - out.annotate(1, "value_type=" + ValueType.VALUE_BYTE.name() + ",value_arg=0"); - out.annotate(1, "value: 0x" + Integer.toHexString(value) + " (" + value + ")"); - } - out.writeByte(ValueType.VALUE_BYTE.value); - out.writeByte(value); - } - - /** {@inheritDoc} */ - public int placeValue(int offset) { - return offset + 2; - } - - /** {@inheritDoc} */ - protected int compareValue(EncodedValue o) { - ByteEncodedValue other = (ByteEncodedValue)o; - - return (valueother.value?1:0)); - } - - /** {@inheritDoc} */ - public ValueType getValueType() { - return ValueType.VALUE_BYTE; - } - - @Override - public int hashCode() { - return value; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/CharEncodedValue.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/CharEncodedValue.java deleted file mode 100644 index 25646612..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/CharEncodedValue.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.EncodedValueUtils; -import org.jf.dexlib.Util.Input; - -public class CharEncodedValue extends EncodedValue { - public final char value; - - /** - * Constructs a new CharEncodedValue by reading the value from the given Input object. - * The Input's cursor should be set to the 2nd byte of the encoded value, and the high 3 bits of - * the first byte should be passed as the valueArg parameter - * @param in The Input object to read from - * @param valueArg The high 3 bits of the first byte of this encoded value - */ - protected CharEncodedValue(Input in, byte valueArg) { - value = (char)EncodedValueUtils.decodeUnsignedIntegralValue(in.readBytes(valueArg+1)); - } - - /** - * Constructs a new CharEncodedValue with the given value - * @param value The value - */ - public CharEncodedValue(char value) { - this.value = value; - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value); - - if (out.annotates()) { - out.annotate(1, "value_type=" + ValueType.VALUE_CHAR.name() + ",value_arg=" + (bytes.length - 1)); - char[] c = Character.toChars(value); - assert c.length > 0; - out.annotate(bytes.length, "value: 0x" + Integer.toHexString(value) + " '" + c[0] + "'"); - } - - out.writeByte(ValueType.VALUE_CHAR.value | ((bytes.length - 1) << 5)); - out.write(bytes); - } - - /** {@inheritDoc} */ - public int placeValue(int offset) { - return offset + EncodedValueUtils.getRequiredBytesForUnsignedIntegralValue(value) + 1; - } - - /** {@inheritDoc} */ - protected int compareValue(EncodedValue o) { - CharEncodedValue other = (CharEncodedValue)o; - - return (valueother.value?1:0)); - } - - /** {@inheritDoc} */ - public ValueType getValueType() { - return ValueType.VALUE_CHAR; - } - - @Override - public int hashCode() { - return value; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/DoubleEncodedValue.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/DoubleEncodedValue.java deleted file mode 100644 index 6b8bcc37..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/DoubleEncodedValue.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.EncodedValueUtils; -import org.jf.dexlib.Util.Input; - -public class DoubleEncodedValue extends EncodedValue { - public final double value; - - /** - * Constructs a new DoubleEncodedValue by reading the value from the given Input object. - * The Input's cursor should be set to the 2nd byte of the encoded value, and the high 3 bits of - * the first byte should be passed as the valueArg parameter - * @param in The Input object to read from - * @param valueArg The high 3 bits of the first byte of this encoded value - */ - protected DoubleEncodedValue(Input in, byte valueArg) { - long longValue = EncodedValueUtils.decodeRightZeroExtendedValue(in.readBytes(valueArg + 1)); - value = Double.longBitsToDouble(longValue); - } - - /** - * Constructs a new DoubleEncodedValue with the given value - * @param value The value - */ - public DoubleEncodedValue(double value) { - this.value = value; - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - byte[] bytes = EncodedValueUtils.encodeRightZeroExtendedValue(Double.doubleToRawLongBits(value)); - - if (out.annotates()) { - out.annotate(1, "value_type=" + ValueType.VALUE_DOUBLE.name() + ",value_arg=" + (bytes.length - 1)); - out.annotate(bytes.length, "value: " + value); - } - - out.writeByte(ValueType.VALUE_DOUBLE.value | ((bytes.length - 1) << 5)); - out.write(bytes); - } - - /** {@inheritDoc} */ - public int placeValue(int offset) { - return offset + 1 + EncodedValueUtils.getRequiredBytesForRightZeroExtendedValue( - Double.doubleToRawLongBits(value)); - } - - /** {@inheritDoc} */ - protected int compareValue(EncodedValue o) { - DoubleEncodedValue other = (DoubleEncodedValue)o; - - return Double.compare(value, other.value); - } - - /** {@inheritDoc} */ - public ValueType getValueType() { - return ValueType.VALUE_DOUBLE; - } - - @Override - public int hashCode() { - return (int)Double.doubleToRawLongBits(value); - } -} - diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/EncodedValue.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/EncodedValue.java deleted file mode 100644 index 4c00faf2..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/EncodedValue.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.DexFile; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; - -public abstract class EncodedValue implements Comparable { - /** - * Writes this EncodedValue to the given AnnotatedOutput object - * @param out the AnnotatedOutput object to write to - */ - public abstract void writeValue(AnnotatedOutput out); - - /** - * Calculates the size of this encoded value and returns offset + size; - * @param offset The offset to place this encoded value - * @return the offset immediately after this encoded value - */ - public abstract int placeValue(int offset); - - - public static EncodedValue readEncodedValue(DexFile dexFile, Input in) { - Byte b = in.readByte(); - ValueType valueType = ValueType.fromByte((byte)(b & 0x1f)); - byte valueArg = (byte)((b & 0xFF) >> 5); - - switch (valueType) { - case VALUE_BYTE: - return new ByteEncodedValue(in); - case VALUE_SHORT: - return new ShortEncodedValue(in, valueArg); - case VALUE_CHAR: - return new CharEncodedValue(in, valueArg); - case VALUE_INT: - return new IntEncodedValue(in, valueArg); - case VALUE_LONG: - return new LongEncodedValue(in, valueArg); - case VALUE_FLOAT: - return new FloatEncodedValue(in, valueArg); - case VALUE_DOUBLE: - return new DoubleEncodedValue(in, valueArg); - case VALUE_STRING: - return new StringEncodedValue(dexFile, in, valueArg); - case VALUE_TYPE: - return new TypeEncodedValue(dexFile, in, valueArg); - case VALUE_FIELD: - return new FieldEncodedValue(dexFile, in, valueArg); - case VALUE_METHOD: - return new MethodEncodedValue(dexFile, in, valueArg); - case VALUE_ENUM: - return new EnumEncodedValue(dexFile, in, valueArg); - case VALUE_ARRAY: - return new ArrayEncodedValue(dexFile, in); - case VALUE_ANNOTATION: - return new AnnotationEncodedValue(dexFile, in); - case VALUE_NULL: - return NullEncodedValue.NullValue; - case VALUE_BOOLEAN: - return BooleanEncodedValue.getBooleanEncodedValue(valueArg); - } - return null; - } - - /** {@inheritDoc} */ - public int compareTo(EncodedValue o) { - int comp = getValueType().compareTo(o.getValueType()); - if (comp == 0) { - comp = compareValue(o); - } - return comp; - } - - /** - * Compare the value of this EncodedValue against the value of the given , which - * is guaranteed to be of the same type as this EncodedValue - * @param o The EncodedValue to compare against - * @return A standard comparison integer value - */ - protected abstract int compareValue(EncodedValue o); - - /** - * @return the ValueType representing the type of this EncodedValue - */ - public abstract ValueType getValueType(); - - @Override - public boolean equals(Object o) { - if (this==o) { - return true; - } - if (o==null || !(o instanceof EncodedValue)) { - return false; - } - - return this.compareTo((EncodedValue)o) == 0; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/EnumEncodedValue.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/EnumEncodedValue.java deleted file mode 100644 index 7cd1f45a..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/EnumEncodedValue.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.DexFile; -import org.jf.dexlib.FieldIdItem; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.EncodedValueUtils; -import org.jf.dexlib.Util.Input; - -public class EnumEncodedValue extends EncodedValue { - public final FieldIdItem value; - - /** - * Constructs a new EnumEncodedValue by reading the field index from the given Input - * object. The Input's cursor should be set to the 2nd byte of the encoded value, and the high 3 bits - * of the first byte should be passed as the valueArg parameter - * @param dexFile The DexFile that is being read in - * @param in The Input object to read from - * @param valueArg The high 3 bits of the first byte of this encoded value - */ - protected EnumEncodedValue(DexFile dexFile, Input in, byte valueArg) { - int index = (int) EncodedValueUtils.decodeUnsignedIntegralValue(in.readBytes(valueArg+1)); - value = dexFile.FieldIdsSection.getItemByIndex(index); - } - - /** - * Constructs a new EnumEncodedValue with the given FieldIdItem value - * @param value The FieldIdItem value - */ - public EnumEncodedValue(FieldIdItem value) { - this.value = value; - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex()); - - if (out.annotates()) { - out.annotate(1, "value_type=" + ValueType.VALUE_ENUM.name() + ",value_arg=" + (bytes.length - 1)); - out.annotate(bytes.length, "value: " + value.getFieldString()); - } - - out.writeByte(ValueType.VALUE_ENUM.value | ((bytes.length - 1) << 5)); - out.write(bytes); - } - - /** {@inheritDoc} */ - public int placeValue(int offset) { - return offset + EncodedValueUtils.getRequiredBytesForUnsignedIntegralValue(value.getIndex()) + 1; - } - - /** {@inheritDoc} */ - protected int compareValue(EncodedValue o) { - EnumEncodedValue other = (EnumEncodedValue)o; - - return value.compareTo(other.value); - } - - /** {@inheritDoc} */ - public ValueType getValueType() { - return ValueType.VALUE_ENUM; - } - - @Override - public int hashCode() { - return value.hashCode(); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/FieldEncodedValue.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/FieldEncodedValue.java deleted file mode 100644 index 6aafc621..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/FieldEncodedValue.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.DexFile; -import org.jf.dexlib.FieldIdItem; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.EncodedValueUtils; -import org.jf.dexlib.Util.Input; - -public class FieldEncodedValue extends EncodedValue { - public final FieldIdItem value; - - /** - * Constructs a new FieldEncodedValue by reading the field index from the given Input - * object. The Input's cursor should be set to the 2nd byte of the encoded value, and the high 3 bits - * of the first byte should be passed as the valueArg parameter - * @param dexFile The DexFile that is being read in - * @param in The Input object to read from - * @param valueArg The high 3 bits of the first byte of this encoded value - */ - protected FieldEncodedValue(DexFile dexFile, Input in, byte valueArg) { - int index = (int) EncodedValueUtils.decodeUnsignedIntegralValue(in.readBytes(valueArg+1)); - value = dexFile.FieldIdsSection.getItemByIndex(index); - } - - /** - * Constructs a new FieldEncodedValue with the given FieldIdItem value - * @param value The FieldIdItem value - */ - public FieldEncodedValue(FieldIdItem value) { - this.value = value; - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex()); - - if (out.annotates()) { - out.annotate(1, "value_type=" + ValueType.VALUE_FIELD.name() + ",value_arg=" + (bytes.length - 1)); - out.annotate(bytes.length, "value: " + value.getFieldString()); - } - - out.writeByte(ValueType.VALUE_FIELD.value | ((bytes.length - 1) << 5)); - out.write(bytes); - } - - /** {@inheritDoc} */ - public int placeValue(int offset) { - return offset + EncodedValueUtils.getRequiredBytesForUnsignedIntegralValue(value.getIndex()) + 1; - } - - /** {@inheritDoc} */ - protected int compareValue(EncodedValue o) { - FieldEncodedValue other = (FieldEncodedValue)o; - - return value.compareTo(other.value); - } - - /** {@inheritDoc} */ - public ValueType getValueType() { - return ValueType.VALUE_FIELD; - } - - @Override - public int hashCode() { - return value.hashCode(); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/FloatEncodedValue.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/FloatEncodedValue.java deleted file mode 100644 index af514f4f..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/FloatEncodedValue.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.EncodedValueUtils; -import org.jf.dexlib.Util.Input; - -public class FloatEncodedValue extends EncodedValue { - public final float value; - - /** - * Constructs a new FloatEncodedValue by reading the value from the given Input object. - * The Input's cursor should be set to the 2nd byte of the encoded value, and the high 3 bits of - * the first byte should be passed as the valueArg parameter - * @param in The Input object to read from - * @param valueArg The high 3 bits of the first byte of this encoded value - */ - protected FloatEncodedValue(Input in, byte valueArg) { - long longValue = EncodedValueUtils.decodeRightZeroExtendedValue(in.readBytes(valueArg + 1)); - value = Float.intBitsToFloat((int)((longValue >> 32) & 0xFFFFFFFFL)); - } - - /** - * Constructs a new FloatEncodedValue with the given value - * @param value The value - */ - public FloatEncodedValue(float value) { - this.value = value; - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - byte[] bytes = EncodedValueUtils.encodeRightZeroExtendedValue(((long)Float.floatToRawIntBits(value)) << 32); - - if (out.annotates()) { - out.annotate(1, "value_type=" + ValueType.VALUE_FLOAT.name() + ",value_arg=" + (bytes.length - 1)); - out.annotate(bytes.length, "value: " + value); - } - - out.writeByte(ValueType.VALUE_FLOAT.value | ((bytes.length - 1) << 5)); - out.write(bytes); - } - - /** {@inheritDoc} */ - public int placeValue(int offset) { - return offset + 1 + EncodedValueUtils.getRequiredBytesForRightZeroExtendedValue( - ((long)Float.floatToRawIntBits(value)) << 32); - } - - /** {@inheritDoc} */ - protected int compareValue(EncodedValue o) { - FloatEncodedValue other = (FloatEncodedValue)o; - - return Float.compare(value, other.value); - } - - /** {@inheritDoc} */ - public ValueType getValueType() { - return ValueType.VALUE_FLOAT; - } - - @Override - public int hashCode() { - return Float.floatToRawIntBits(value); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/IntEncodedValue.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/IntEncodedValue.java deleted file mode 100644 index 7da5b021..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/IntEncodedValue.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.EncodedValueUtils; -import org.jf.dexlib.Util.Input; - -public class IntEncodedValue extends EncodedValue { - public final int value; - - /** - * Constructs a new IntEncodedValue by reading the value from the given Input object. - * The Input's cursor should be set to the 2nd byte of the encoded value, and the high 3 bits of - * the first byte should be passed as the valueArg parameter - * @param in The Input object to read from - * @param valueArg The high 3 bits of the first byte of this encoded value - */ - protected IntEncodedValue(Input in, byte valueArg) { - value = (int)EncodedValueUtils.decodeSignedIntegralValue(in.readBytes(valueArg+1)); - } - - /** - * Constructs a new IntEncodedValue with the given value - * @param value The value - */ - public IntEncodedValue(int value) { - this.value = value; - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - byte[] bytes = EncodedValueUtils.encodeSignedIntegralValue(value); - - if (out.annotates()) { - out.annotate(1, "value_type=" + ValueType.VALUE_INT.name() + ",value_arg=" + (bytes.length - 1)); - out.annotate(bytes.length, "value: 0x" + Integer.toHexString(value) + " (" + value + ")"); - } - - out.writeByte(ValueType.VALUE_INT.value | ((bytes.length - 1) << 5)); - out.write(bytes); - } - - /** {@inheritDoc} */ - public int placeValue(int offset) { - return offset + EncodedValueUtils.getRequiredBytesForSignedIntegralValue(value) + 1; - } - - /** {@inheritDoc} */ - protected int compareValue(EncodedValue o) { - IntEncodedValue other = (IntEncodedValue)o; - - return (valueother.value?1:0)); - } - - /** {@inheritDoc} */ - public ValueType getValueType() { - return ValueType.VALUE_INT; - } - - @Override - public int hashCode() { - return value; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/LongEncodedValue.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/LongEncodedValue.java deleted file mode 100644 index 7db6ed13..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/LongEncodedValue.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.EncodedValueUtils; -import org.jf.dexlib.Util.Input; - -public class LongEncodedValue extends EncodedValue { - public final long value; - - /** - * Constructs a new LongEncodedValue by reading the value from the given Input object. - * The Input's cursor should be set to the 2nd byte of the encoded value, and the high 3 bits of - * the first byte should be passed as the valueArg parameter - * @param in The Input object to read from - * @param valueArg The high 3 bits of the first byte of this encoded value - */ - protected LongEncodedValue(Input in, byte valueArg) { - value = EncodedValueUtils.decodeSignedIntegralValue(in.readBytes(valueArg+1)); - } - - /** - * Constructs a new LongEncodedValue with the given value - * @param value The value - */ - public LongEncodedValue(long value) { - this.value = value; - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - byte[] bytes = EncodedValueUtils.encodeSignedIntegralValue(value); - - if (out.annotates()) { - out.annotate(1, "value_type=" + ValueType.VALUE_LONG.name() + ",value_arg=" + (bytes.length - 1)); - out.annotate(bytes.length, "value: 0x" + Long.toHexString(value) + " (" + value + ")"); - } - - out.writeByte(ValueType.VALUE_LONG.value | ((bytes.length - 1) << 5)); - out.write(bytes); - } - - /** {@inheritDoc} */ - public int placeValue(int offset) { - return offset + EncodedValueUtils.getRequiredBytesForSignedIntegralValue(value) + 1; - } - - /** {@inheritDoc} */ - protected int compareValue(EncodedValue o) { - LongEncodedValue other = (LongEncodedValue)o; - - return (valueother.value?1:0)); - } - - /** {@inheritDoc} */ - public ValueType getValueType() { - return ValueType.VALUE_LONG; - } - - @Override - public int hashCode() { - return (int)value; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/MethodEncodedValue.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/MethodEncodedValue.java deleted file mode 100644 index e23450a2..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/MethodEncodedValue.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.DexFile; -import org.jf.dexlib.MethodIdItem; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.EncodedValueUtils; -import org.jf.dexlib.Util.Input; - -public class MethodEncodedValue extends EncodedValue { - public final MethodIdItem value; - - /** - * Constructs a new MethodEncodedValue by reading the method index from the given Input - * object. The Input's cursor should be set to the 2nd byte of the encoded value, and the high 3 bits - * of the first byte should be passed as the valueArg parameter - * @param dexFile The DexFile that is being read in - * @param in The Input object to read from - * @param valueArg The high 3 bits of the first byte of this encoded value - */ - protected MethodEncodedValue(DexFile dexFile, Input in, byte valueArg) { - int index = (int) EncodedValueUtils.decodeUnsignedIntegralValue(in.readBytes(valueArg+1)); - value = dexFile.MethodIdsSection.getItemByIndex(index); - } - - /** - * Constructs a new MethodEncodedValue with the given MethodIdItem value - * @param value The MethodIdItem value - */ - public MethodEncodedValue(MethodIdItem value) { - this.value = value; - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex()); - - if (out.annotates()) { - out.annotate(1, "value_type=" + ValueType.VALUE_METHOD.name() + ",value_arg=" + (bytes.length - 1)); - out.annotate(bytes.length, "value: " + value.getMethodString()); - } - - out.writeByte(ValueType.VALUE_METHOD.value | ((bytes.length - 1) << 5)); - out.write(bytes); - } - - /** {@inheritDoc} */ - public int placeValue(int offset) { - return offset + EncodedValueUtils.getRequiredBytesForUnsignedIntegralValue(value.getIndex()) + 1; - } - - /** {@inheritDoc} */ - protected int compareValue(EncodedValue o) { - MethodEncodedValue other = (MethodEncodedValue)o; - - return value.compareTo(other.value); - } - - /** {@inheritDoc} */ - public ValueType getValueType() { - return ValueType.VALUE_METHOD; - } - - @Override - public int hashCode() { - return value.hashCode(); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/NullEncodedValue.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/NullEncodedValue.java deleted file mode 100644 index 334b82a3..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/NullEncodedValue.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.Util.AnnotatedOutput; - -public class NullEncodedValue extends EncodedValue { - /** - * The singleton value - */ - public static final NullEncodedValue NullValue = new NullEncodedValue(); - - /** - * Constructs a new NullEncodedValue - */ - private NullEncodedValue() { - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - if (out.annotates()) { - out.annotate("value_type=" + ValueType.VALUE_NULL.name() + ",value_arg=0"); - } - out.writeByte(ValueType.VALUE_NULL.value); - } - - /** {@inheritDoc} */ - public int placeValue(int offset) { - return offset + 1; - } - - /** {@inheritDoc} */ - protected int compareValue(EncodedValue o) { - return 0; - } - - /** {@inheritDoc} */ - public ValueType getValueType() { - return ValueType.VALUE_NULL; - } - - @Override - public int hashCode() { - return 1; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/ShortEncodedValue.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/ShortEncodedValue.java deleted file mode 100644 index 66d80e17..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/ShortEncodedValue.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.EncodedValueUtils; -import org.jf.dexlib.Util.Input; - -public class ShortEncodedValue extends EncodedValue { - public final short value; - - /** - * Constructs a new ShortEncodedValue by reading the value from the given Input object. - * The Input's cursor should be set to the 2nd byte of the encoded value, and the high 3 bits of - * the first byte should be passed as the valueArg parameter - * @param in The Input object to read from - * @param valueArg The high 3 bits of the first byte of this encoded value - */ - protected ShortEncodedValue(Input in, byte valueArg) { - value = (short) EncodedValueUtils.decodeSignedIntegralValue(in.readBytes(valueArg+1)); - } - - /** - * Constructs a new ShortEncodedValue with the given value - * @param value The value - */ - public ShortEncodedValue(short value) { - this.value = value; - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - byte[] bytes = EncodedValueUtils.encodeSignedIntegralValue(value); - - if (out.annotates()) { - out.annotate(1, "value_type=" + ValueType.VALUE_SHORT.name() + ",value_arg=" + (bytes.length - 1)); - out.annotate(bytes.length, "value: 0x" + Integer.toHexString(value) + " (" + value + ")"); - } - - out.writeByte(ValueType.VALUE_SHORT.value | ((bytes.length - 1) << 5)); - out.write(bytes); - } - - /** {@inheritDoc} */ - public int placeValue(int offset) { - return offset + EncodedValueUtils.getRequiredBytesForSignedIntegralValue(value) + 1; - } - - /** {@inheritDoc} */ - protected int compareValue(EncodedValue o) { - ShortEncodedValue other = (ShortEncodedValue)o; - - return (valueother.value?1:0)); - } - - /** {@inheritDoc} */ - public ValueType getValueType() { - return ValueType.VALUE_SHORT; - } - - @Override - public int hashCode() { - return value; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/StringEncodedValue.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/StringEncodedValue.java deleted file mode 100644 index 97b81b92..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/StringEncodedValue.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.DexFile; -import org.jf.dexlib.StringIdItem; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.EncodedValueUtils; -import org.jf.dexlib.Util.Input; -import org.jf.util.StringUtils; - -public class StringEncodedValue extends EncodedValue { - public final StringIdItem value; - - /** - * Constructs a new StringEncodedValue by reading the string index from the given Input - * object. The Input's cursor should be set to the 2nd byte of the encoded value, and the high 3 bits - * of the first byte should be passed as the valueArg parameter - * @param dexFile The DexFile that is being read in - * @param in The Input object to read from - * @param valueArg The high 3 bits of the first byte of this encoded value - */ - protected StringEncodedValue(DexFile dexFile, Input in, byte valueArg) { - int index = (int)EncodedValueUtils.decodeUnsignedIntegralValue(in.readBytes(valueArg+1)); - value = dexFile.StringIdsSection.getItemByIndex(index); - } - - /** - * Constructs a new StringEncodedValue with the given StringIdItem value - * @param value The StringIdItem value - */ - public StringEncodedValue(StringIdItem value) { - this.value = value; - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex()); - - if (out.annotates()) { - out.annotate(1, "value_type=" + ValueType.VALUE_STRING.name() + ",value_arg=" + (bytes.length - 1)); - out.annotate(bytes.length, "value: \"" + StringUtils.escapeString(value.getStringValue()) + "\""); - } - - out.writeByte(ValueType.VALUE_STRING.value | ((bytes.length - 1) << 5)); - out.write(bytes); - } - - /** {@inheritDoc} */ - public int placeValue(int offset) { - return offset + EncodedValueUtils.getRequiredBytesForUnsignedIntegralValue(value.getIndex()) + 1; - } - - /** {@inheritDoc} */ - protected int compareValue(EncodedValue o) { - StringEncodedValue other = (StringEncodedValue)o; - - return value.compareTo(other.value); - } - - /** {@inheritDoc} */ - public ValueType getValueType() { - return ValueType.VALUE_STRING; - } - - @Override - public int hashCode() { - return value.hashCode(); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/TypeEncodedValue.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/TypeEncodedValue.java deleted file mode 100644 index 335aab65..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/TypeEncodedValue.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.DexFile; -import org.jf.dexlib.TypeIdItem; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.EncodedValueUtils; -import org.jf.dexlib.Util.Input; - -public class TypeEncodedValue extends EncodedValue { - public final TypeIdItem value; - - /** - * Constructs a new TypeEncodedValue by reading the type index from the given Input - * object. The Input's cursor should be set to the 2nd byte of the encoded value, and the high 3 bits - * of the first byte should be passed as the valueArg parameter - * @param dexFile The DexFile that is being read in - * @param in The Input object to read from - * @param valueArg The high 3 bits of the first byte of this encoded value - */ - protected TypeEncodedValue(DexFile dexFile, Input in, byte valueArg) { - int index = (int) EncodedValueUtils.decodeUnsignedIntegralValue(in.readBytes(valueArg+1)); - value = dexFile.TypeIdsSection.getItemByIndex(index); - } - - /** - * Constructs a new TypeEncodedValue with the given TypeIdItem value - * @param value The TypeIdItem value - */ - public TypeEncodedValue(TypeIdItem value) { - this.value = value; - } - - /** {@inheritDoc} */ - public void writeValue(AnnotatedOutput out) { - byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex()); - - if (out.annotates()) { - out.annotate(1, "value_type=" + ValueType.VALUE_TYPE.name() + ",value_arg=" + (bytes.length - 1)); - out.annotate(bytes.length, "value: " + value.getTypeDescriptor()); - } - - out.writeByte(ValueType.VALUE_TYPE.value | ((bytes.length - 1) << 5)); - out.write(bytes); - } - - /** {@inheritDoc} */ - public int placeValue(int offset) { - return offset + EncodedValueUtils.getRequiredBytesForUnsignedIntegralValue(value.getIndex()) + 1; - } - - /** {@inheritDoc} */ - protected int compareValue(EncodedValue o) { - TypeEncodedValue other = (TypeEncodedValue)o; - - return value.compareTo(other.value); - } - - /** {@inheritDoc} */ - public ValueType getValueType() { - return ValueType.VALUE_TYPE; - } - - @Override - public int hashCode() { - return value.hashCode(); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/ValueType.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/ValueType.java deleted file mode 100644 index d33b0ac2..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/EncodedValue/ValueType.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.EncodedValue; - -import org.jf.dexlib.Util.SparseArray; - -public enum ValueType { - - VALUE_BYTE((byte) 0x00), - VALUE_SHORT((byte) 0x02), - VALUE_CHAR((byte) 0x03), - VALUE_INT((byte) 0x04), - VALUE_LONG((byte) 0x06), - VALUE_FLOAT((byte) 0x10), - VALUE_DOUBLE((byte) 0x11), - VALUE_STRING((byte) 0x17), - VALUE_TYPE((byte) 0x18), - VALUE_FIELD((byte) 0x19), - VALUE_METHOD((byte) 0x1a), - VALUE_ENUM((byte) 0x1b), - VALUE_ARRAY((byte) 0x1c), - VALUE_ANNOTATION((byte) 0x1d), - VALUE_NULL((byte) 0x1e), - VALUE_BOOLEAN((byte) 0x1f); - - /** - * A map to facilitate looking up a ValueType by byte value - */ - private final static SparseArray valueTypeIntegerMap; - - static { - /** build the valueTypeIntegerMap object */ - valueTypeIntegerMap = new SparseArray(16); - - for (ValueType valueType : ValueType.values()) { - valueTypeIntegerMap.put(valueType.value, valueType); - } - } - - /** - * The byte value for this ValueType - */ - public final byte value; - - private ValueType(byte value) { - this.value = value; - } - - /** - * Converts a byte value to the corresponding ValueType enum value, - * or null if the value isn't a valid ValueType value - * - * @param valueType the byte value to convert to a ValueType - * @return the ValueType enum value corresponding to valueType, or null - * if not a valid ValueType value - */ - public static ValueType fromByte(byte valueType) { - return valueTypeIntegerMap.get(valueType); - } -} \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/FieldIdItem.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/FieldIdItem.java deleted file mode 100644 index c9fe05f0..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/FieldIdItem.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; - -public class FieldIdItem extends Item implements Convertible { - private int hashCode = 0; - - private TypeIdItem classType; - private TypeIdItem fieldType; - private StringIdItem fieldName; - - /** - * Creates a new uninitialized FieldIdItem - * @param dexFile The DexFile that this item belongs to - */ - protected FieldIdItem(DexFile dexFile) { - super(dexFile); - } - - /** - * Creates a new FieldIdItem for the given class, type and name - * @param dexFile The DexFile that this item belongs to - * @param classType the class that the field is a member of - * @param fieldType the type of the field - * @param fieldName the name of the field - */ - private FieldIdItem(DexFile dexFile, TypeIdItem classType, TypeIdItem fieldType, StringIdItem fieldName) { - this(dexFile); - - assert classType.dexFile == dexFile; - assert fieldType.dexFile == dexFile; - assert fieldName.dexFile == dexFile; - - this.classType = classType; - this.fieldType = fieldType; - this.fieldName = fieldName; - } - - /** - * Returns a FieldIdItem for the given values, and that has been interned into - * the given DexFile - * @param dexFile The DexFile that this item belongs to - * @param classType the class that the field is a member of - * @param fieldType the type of the field - * @param fieldName the name of the field - * @return a FieldIdItem for the given values, and that has been interned into - * the given DexFile - */ - public static FieldIdItem internFieldIdItem(DexFile dexFile, TypeIdItem classType, TypeIdItem fieldType, - StringIdItem fieldName) { - FieldIdItem fieldIdItem = new FieldIdItem(dexFile, classType, fieldType, fieldName); - return dexFile.FieldIdsSection.intern(fieldIdItem); - } - - /** - * Looks up a FieldIdItem from the given DexFile for the given - * values - * @param dexFile The DexFile that this item belongs to - * @param classType the class that the field is a member of - * @param fieldType the type of the field - * @param fieldName the name of the field - * @return a FieldIdItem from the given DexFile for the given - * values, or null if it doesn't exist - */ - public static FieldIdItem lookupFieldIdItem(DexFile dexFile, TypeIdItem classType, TypeIdItem fieldType, - StringIdItem fieldName) { - FieldIdItem fieldIdItem = new FieldIdItem(dexFile, classType, fieldType, fieldName); - return dexFile.FieldIdsSection.getInternedItem(fieldIdItem); - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - classType = dexFile.TypeIdsSection.getItemByIndex(in.readShort()); - fieldType = dexFile.TypeIdsSection.getItemByIndex(in.readShort()); - fieldName = dexFile.StringIdsSection.getItemByIndex(in.readInt()); - } - - /** {@inheritDoc} */ - protected int placeItem(int offset) { - return offset + 8; - } - - /** {@inheritDoc} */ - protected void writeItem(AnnotatedOutput out) { - if (out.annotates()) { - out.annotate(2, "class_type: " + classType.getTypeDescriptor()); - out.annotate(2, "field_type: " + fieldType.getTypeDescriptor()); - out.annotate(4, "field_name: " + fieldName.getStringValue()); - } - - int classIndex = classType.getIndex(); - if (classIndex > 0xffff) { - throw new RuntimeException(String.format("Error writing field_id_item for %s. The type index of " + - "defining class %s is too large", getFieldString(), classType.getTypeDescriptor())); - } - out.writeShort(classIndex); - - int typeIndex = fieldType.getIndex(); - if (typeIndex > 0xffff) { - throw new RuntimeException(String.format("Error writing field_id_item for %s. The type index of field " + - "type %s is too large", getFieldString(), fieldType.getTypeDescriptor())); - } - out.writeShort(typeIndex); - - out.writeInt(fieldName.getIndex()); - } - - /** {@inheritDoc} */ - public ItemType getItemType() { - return ItemType.TYPE_FIELD_ID_ITEM; - } - - /** {@inheritDoc} */ - public String getConciseIdentity() { - return getFieldString(); - } - - /** {@inheritDoc} */ - public int compareTo(FieldIdItem o) { - int result = classType.compareTo(o.classType); - if (result != 0) { - return result; - } - - result = fieldName.compareTo(o.fieldName); - if (result != 0) { - return result; - } - - return fieldType.compareTo(o.fieldType); - } - - /** - * @return the class that this field is a member of - */ - public TypeIdItem getContainingClass() { - return classType; - } - - /** - * @return the type of this field - */ - public TypeIdItem getFieldType() { - return fieldType; - } - - /** - * @return the field name - */ - public StringIdItem getFieldName() { - return fieldName; - } - - String cachedFieldString = null; - /** - * @return a string formatted like LclassName;->fieldName:fieldType - */ - public String getFieldString() { - if (cachedFieldString == null) { - String typeDescriptor = classType.getTypeDescriptor(); - String fieldName = this.fieldName.getStringValue(); - String fieldType = this.fieldType.getTypeDescriptor(); - - StringBuffer sb = new StringBuffer(typeDescriptor.length() + fieldName.length() + fieldType.length() + 3); - sb.append(typeDescriptor); - sb.append("->"); - sb.append(fieldName); - sb.append(":"); - sb.append(fieldType); - cachedFieldString = sb.toString(); - } - return cachedFieldString; - } - - String cachedShortFieldString = null; - /** - * @return a "short" string containing just the field name and type, formatted like fieldName:fieldType - */ - public String getShortFieldString() { - if (cachedShortFieldString == null) { - String fieldName = this.fieldName.getStringValue(); - String fieldType = this.fieldType.getTypeDescriptor(); - - StringBuffer sb = new StringBuffer(fieldName.length() + fieldType.length() + 1); - sb.append(fieldName); - sb.append(":"); - sb.append(fieldType); - cachedShortFieldString = sb.toString(); - } - return cachedShortFieldString; - } - - - /** - * calculate and cache the hashcode - */ - private void calcHashCode() { - hashCode = classType.hashCode(); - hashCode = 31 * hashCode + fieldType.hashCode(); - hashCode = 31 * hashCode + fieldName.hashCode(); - } - - @Override - public int hashCode() { - //there's a small possibility that the actual hash code will be 0. If so, we'll - //just end up recalculating it each time - if (hashCode == 0) - calcHashCode(); - return hashCode; - } - - @Override - public boolean equals(Object o) { - if (this==o) { - return true; - } - if (o==null || !this.getClass().equals(o.getClass())) { - return false; - } - - //This assumes that the referenced items have been interned in both objects. - //This is a valid assumption because all outside code must use the static - //"getInterned..." style methods to make new items, and any item created - //internally is guaranteed to be interned - FieldIdItem other = (FieldIdItem)o; - return (classType == other.classType && - fieldType == other.fieldType && - fieldName == other.fieldName); - } - - public FieldIdItem convert() { - return this; - } -} \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/HeaderItem.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/HeaderItem.java deleted file mode 100644 index 266d14a3..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/HeaderItem.java +++ /dev/null @@ -1,301 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import com.google.common.base.Preconditions; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; -import org.jf.util.StringUtils; - -public class HeaderItem extends Item { - /** - * the file format magic number, represented as the - * low-order bytes of a string - */ - public static final byte[][] MAGIC_VALUES = new byte[][] { - new byte[] {0x64, 0x65, 0x78, 0x0A, 0x30, 0x33, 0x35, 0x00}, //"dex\n035" + '\0'; - new byte[] {0x64, 0x65, 0x78, 0x0A, 0x30, 0x33, 0x36, 0x00}}; //"dex\n036" + '\0'; - - - /** size of this section, in bytes */ - private static final int HEADER_SIZE = 0x70; - - /** the endianness constants */ - private static final int LITTLE_ENDIAN = 0x12345678; - private static final int BIG_ENDIAN = 0x78563412; - - /* Which magic value to use when writing out the header item */ - private int magic_index = 0; - - private boolean checksumSignatureSet = false; - private int checksum; - private byte[] signature; - - /** - * Create a new uninitialized HeaderItem - * @param dexFile The DexFile containing this HeaderItem - */ - protected HeaderItem(final DexFile dexFile) { - super(dexFile); - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - byte[] readMagic = in.readBytes(8); - - boolean success = false; - for (int i=0; i extends Section { - - /** - * Create a new indexed section - * @param dexFile The DexFile that this section belongs to - * @param itemType The itemType that this section will hold - */ - public IndexedSection(DexFile dexFile, ItemType itemType) { - super(dexFile, itemType); - } - - /** {@inheritDoc} */ - protected void readItems(Input in, ReadContext readContext) { - for (int i = 0; i < items.size(); i++) { - T item = (T)ItemFactory.makeItem(ItemType, DexFile); - items.set(i, item); - item.readFrom(in, i, readContext); - } - } - - /** - * Gets the item at the specified index in this section, or null if the index is -1 - * @param index the index of the item to get - * @return the item at the specified index in this section, or null if the index is -1 - */ - public T getOptionalItemByIndex(int index) { - if (index == -1) { - return null; - } - - return getItemByIndex(index); - } - - /** - * Gets the item at the specified index in this section - * @param index the index of the item to get - * @return the item at the specified index in this section - */ - public T getItemByIndex(int index) { - try { - //if index is out of bounds, just let it throw an exception - return items.get(index); - } catch (Exception ex) { - throw ExceptionWithContext.withContext(ex, "Error occured while retrieving the " + this.ItemType.TypeName + - " item at index " + index); - } - } -} \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Item.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Item.java deleted file mode 100644 index d54aa436..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Item.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import com.google.common.base.Preconditions; -import org.jf.util.AlignmentUtils; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.util.ExceptionWithContext; -import org.jf.dexlib.Util.Input; - -public abstract class Item implements Comparable { - /** - * The offset of this item in the dex file, or -1 if not known - */ - protected int offset = -1; - - /** - * The index of this item in the containing section, or -1 if not known - */ - protected int index = -1; - - /** - * The DexFile that this item is associatedr with - */ - protected final DexFile dexFile; - - /** - * The constructor that is used when reading in a DexFile - * @param dexFile the DexFile that this item is associated with - */ - protected Item(DexFile dexFile) { - assert dexFile != null; - - this.dexFile = dexFile; - } - - /** - * Read in the item from the given input stream, and initialize the index - * @param in the Input object to read from - * @param index the index within the containing section of the item being read in - * @param readContext a ReadContext object to hold information that is - * only needed while reading in a file - */ - protected void readFrom(Input in, int index, ReadContext readContext) { - try { - assert AlignmentUtils.isAligned(in.getCursor(), getItemType().ItemAlignment); - - this.offset = in.getCursor(); - this.index = index; - - this.readItem(in, readContext); - } catch (Exception ex) { - throw addExceptionContext(ex); - } - } - - /** - * Place the item at the given offset and index, and return the offset of the byte following this item - * @param offset The offset to place the item at - * @param index The index of the item within the containing section - * @return The offset of the byte following this item - */ - protected int placeAt(int offset, int index) { - try { - assert AlignmentUtils.isAligned(offset, getItemType().ItemAlignment); - assert !dexFile.getInplace() || (offset == this.offset && this.index == index); - - this.offset = offset; - this.index = index; - return this.placeItem(offset); - } catch (Exception ex) { - throw addExceptionContext(ex); - } - } - - /** - * Write and annotate this item to the output stream - * @param out The output stream to write and annotate to - */ - protected void writeTo(AnnotatedOutput out) { - try { - assert AlignmentUtils.isAligned(offset, getItemType().ItemAlignment); - //ensure that it is being written to the same offset where it was previously placed - assert out.getCursor() == offset; - - if (out.annotates()) { - out.annotate(0, "[" + index + "] " + this.getItemType().TypeName); - } - - out.indent(); - writeItem(out); - out.deindent(); - } catch (Exception ex) { - throw addExceptionContext(ex); - } - } - - /** - * Returns a human readable form of this item - * @return a human readable form of this item - */ - public String toString() { - return getConciseIdentity(); - } - - /** - * The method in the concrete item subclass that actually reads in the data for the item - * - * The logic in this method can assume that the given Input object is valid and is - * aligned as neccessary. - * - * This method is for internal use only - * @param in the Input object to read from - * @param readContext a ReadContext object to hold information that is - * only needed while reading in a file - */ - protected abstract void readItem(Input in, ReadContext readContext); - - /** - * The method should finalize the layout of the item and return the offset of the byte - * immediately following the item. - * - * The implementation of this method can assume that the offset argument has already been - * aligned based on the item's alignment requirements - * - * This method is for internal use only - * @param offset the (pre-aligned) offset to place the item at - * @return the size of the item, in bytes - */ - protected abstract int placeItem(int offset); - - /** - * The method in the concrete item subclass that actually writes and annotates the data - * for the item. - * - * The logic in this method can assume that the given Output object is valid and is - * aligned as neccessary - * - * @param out The AnnotatedOutput object to write/annotate to - */ - protected abstract void writeItem(AnnotatedOutput out); - - /** - * This method is called to add item specific context information to an exception, to identify the "current item" - * when the exception occured. It adds the value returned by getConciseIdentity as context for the - * exception - * @param ex The exception that occured - * @return A RuntimeException with additional details about the item added - */ - protected final RuntimeException addExceptionContext(Exception ex) { - return ExceptionWithContext.withContext(ex, getConciseIdentity()); - } - - /** - * @return An ItemType enum that represents the item type of this item - */ - public abstract ItemType getItemType(); - - /** - * @return A concise (human-readable) string value that conveys the identity of this item - */ - public abstract String getConciseIdentity(); - - - /** - * Note that the item must have been placed before calling this method (See DexFile.place()) - * @return the offset in the dex file where this item is located - */ - public int getOffset() { - Preconditions.checkState(offset != -1, - "The offset is not set until the DexFile containing this item is placed."); - return offset; - } - - /** - * Note that the item must have been placed before calling this method (See DexFile.place()) - * @return the index of this item within the item's containing section. - */ - public int getIndex() { - Preconditions.checkState(index != -1, - "The index is not set until the DexFile containing this item is placed."); - return index; - } - - /** - * @return True if this item has been placed, otherwise False - */ - public boolean isPlaced() { - return offset != -1; - } - - /** - * @return the DexFile that contains this item - */ - public DexFile getDexFile() { - return dexFile; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ItemFactory.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ItemFactory.java deleted file mode 100644 index 553d1898..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ItemFactory.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -class ItemFactory { - protected static Item makeItem(ItemType itemType, DexFile dexFile) { - switch (itemType) { - case TYPE_STRING_ID_ITEM: - return new StringIdItem(dexFile); - case TYPE_TYPE_ID_ITEM: - return new TypeIdItem(dexFile); - case TYPE_PROTO_ID_ITEM: - return new ProtoIdItem(dexFile); - case TYPE_FIELD_ID_ITEM: - return new FieldIdItem(dexFile); - case TYPE_METHOD_ID_ITEM: - return new MethodIdItem(dexFile); - case TYPE_CLASS_DEF_ITEM: - return new ClassDefItem(dexFile); - case TYPE_TYPE_LIST: - return new TypeListItem(dexFile); - case TYPE_ANNOTATION_SET_REF_LIST: - return new AnnotationSetRefList(dexFile); - case TYPE_ANNOTATION_SET_ITEM: - return new AnnotationSetItem(dexFile); - case TYPE_CLASS_DATA_ITEM: - return new ClassDataItem(dexFile); - case TYPE_CODE_ITEM: - return new CodeItem(dexFile); - case TYPE_STRING_DATA_ITEM: - return new StringDataItem(dexFile); - case TYPE_DEBUG_INFO_ITEM: - return new DebugInfoItem(dexFile); - case TYPE_ANNOTATION_ITEM: - return new AnnotationItem(dexFile); - case TYPE_ENCODED_ARRAY_ITEM: - return new EncodedArrayItem(dexFile); - case TYPE_ANNOTATIONS_DIRECTORY_ITEM: - return new AnnotationDirectoryItem(dexFile); - default: - assert false; - } - return null; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ItemType.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ItemType.java deleted file mode 100644 index a8c7868f..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ItemType.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import java.util.TreeMap; - -/** - * Enumeration of all the top-level item types. - */ -public enum ItemType { - TYPE_HEADER_ITEM( 0x0000, 17, 4, "header_item"), - TYPE_STRING_ID_ITEM( 0x0001, 0, 4, "string_id_item"), - TYPE_TYPE_ID_ITEM( 0x0002, 1, 4, "type_id_item"), - TYPE_PROTO_ID_ITEM( 0x0003, 2, 4, "proto_id_item"), - TYPE_FIELD_ID_ITEM( 0x0004, 3, 4, "field_id_item"), - TYPE_METHOD_ID_ITEM( 0x0005, 4, 4, "method_id_item"), - TYPE_CLASS_DEF_ITEM( 0x0006, 5, 4, "class_def_item"), - TYPE_MAP_LIST( 0x1000, 16, 4, "map_list"), - TYPE_TYPE_LIST( 0x1001, 6, 4, "type_list"), - TYPE_ANNOTATION_SET_REF_LIST( 0x1002, 7, 4, "annotation_set_ref_list"), - TYPE_ANNOTATION_SET_ITEM( 0x1003, 8, 4, "annotation_set_item"), - TYPE_CLASS_DATA_ITEM( 0x2000, 9, 1, "class_data_item"), - TYPE_CODE_ITEM( 0x2001, 10, 4, "code_item"), - TYPE_STRING_DATA_ITEM( 0x2002, 11, 1, "string_data_item"), - TYPE_DEBUG_INFO_ITEM( 0x2003, 12, 1, "debug_info_item"), - TYPE_ANNOTATION_ITEM( 0x2004, 13, 1, "annotation_item"), - TYPE_ENCODED_ARRAY_ITEM( 0x2005, 14, 1, "encoded_array_item"), - TYPE_ANNOTATIONS_DIRECTORY_ITEM(0x2006, 15, 4, "annotations_directory_item"); - - /** A map to facilitate looking up an ItemType by ordinal */ - private final static TreeMap itemTypeIntegerMap; - - /** builds the itemTypeIntegerMap object */ - static { - itemTypeIntegerMap = new TreeMap(); - - for (ItemType itemType: ItemType.values()) { - itemTypeIntegerMap.put(itemType.MapValue, itemType); - } - } - - - - /** - * value when represented in a MapItem - */ - public final int MapValue; - - /** - * name of the type - */ - public final String TypeName; - - /** - * index for this item's section - */ - public final int SectionIndex; - - /** - * the alignment for this item type - */ - public final int ItemAlignment; - /** - * Constructs an instance. - * - * @param mapValue value when represented in a MapItem - * @param sectionIndex index for this item's section - * @param itemAlignment the byte alignment required by this item - * @param typeName non-null; name of the type - */ - private ItemType(int mapValue, int sectionIndex, int itemAlignment, String typeName) { - this.MapValue = mapValue; - this.SectionIndex = sectionIndex; - this.ItemAlignment = itemAlignment; - this.TypeName = typeName; - } - - /** - * Converts an int value to the corresponding ItemType enum value, - * or null if the value isn't a valid ItemType value - * - * @param itemType the int value to convert to an ItemType - * @return the ItemType enum value corresponding to itemType, or null - * if not a valid ItemType value - */ - public static ItemType fromInt(int itemType) { - return itemTypeIntegerMap.get(itemType); - } - - /** - * Returns true if this is an indexed item, or false if its an offsetted item - * @return true if this is an indexed item, or false if its an offsetted item - */ - public boolean isIndexedItem() { - return MapValue <= 0x1000; - } -} \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/MapItem.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/MapItem.java deleted file mode 100644 index e69a33a4..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/MapItem.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; - -/** - * This item represents a map_list item from the dex specification. It contains a - * SectionInfo instance for every section in the DexFile, with the number of items - * in and offset of that section. - */ -public class MapItem extends Item { - /** - * This item is read in immediately after the HeaderItem, and the section info contained - * by this item is added to the ReadContext object, which is used when reading in the other - * sections in the dex file. - * - * This item should be placed last. It depends on the fact that the other sections - * in the file have been placed. - */ - - /** - * Create a new uninitialized MapItem - * @param dexFile The DexFile that this item belongs to - */ - protected MapItem(final DexFile dexFile) { - super(dexFile); - } - - /** {@inheritDoc} */ - protected int placeItem(int offset) { - Section[] sections = dexFile.getOrderedSections(); - //the list returned by getOrderedSections doesn't contain the header - //or map section, so add 2 to the length - return offset + 4 + (sections.length + 2) * 12; - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - int size = in.readInt(); - - for (int i=0; i 0; - Section[] sections = dexFile.getOrderedSections(); - - out.annotate("map_size: 0x" + Integer.toHexString(sections.length + 2) + " (" + - Integer.toString(sections.length + 2) + ")"); - out.writeInt(sections.length + 2); - - int index = 0; - out.annotate(0, "[" + index++ + "]"); - out.indent(); - writeSectionInfo(out, ItemType.TYPE_HEADER_ITEM, 1, 0); - out.deindent(); - - for (Section section: dexFile.getOrderedSections()) { - out.annotate(0, "[" + index++ + "]"); - out.indent(); - writeSectionInfo(out, section.ItemType, section.getItems().size(), section.getOffset()); - out.deindent(); - } - - out.annotate(0, "[" + index++ + "]"); - out.indent(); - writeSectionInfo(out, ItemType.TYPE_MAP_LIST, 1, dexFile.MapItem.getOffset()); - out.deindent(); - } - - private void writeSectionInfo(AnnotatedOutput out, ItemType itemType, int sectionSize, int sectionOffset) { - if (out.annotates()) { - out.annotate(2, "item_type: " + itemType); - out.annotate(2, "unused"); - out.annotate(4, "section_size: 0x" + Integer.toHexString(sectionSize) + " (" + sectionSize + ")"); - out.annotate(4, "section_off: 0x" + Integer.toHexString(sectionOffset)); - } - - out.writeShort(itemType.MapValue); - out.writeShort(0); - out.writeInt(sectionSize); - out.writeInt(sectionOffset); - } - - /** {@inheritDoc} */ - public ItemType getItemType() { - return ItemType.TYPE_MAP_LIST; - } - - /** {@inheritDoc} */ - public int compareTo(MapItem o) { - return 0; - } - - /** {@inheritDoc} */ - public String getConciseIdentity() { - return "map_item"; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/MethodIdItem.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/MethodIdItem.java deleted file mode 100644 index c3522c5e..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/MethodIdItem.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; - -public class MethodIdItem extends Item implements Convertible { - private int hashCode = 0; - - private TypeIdItem classType; - private ProtoIdItem methodPrototype; - private StringIdItem methodName; - - /** - * Creates a new uninitialized MethodIdItem - * @param dexFile The DexFile that this item belongs to - */ - protected MethodIdItem(DexFile dexFile) { - super(dexFile); - } - - /** - * Creates a new MethodIdItem for the given class, type and name - * @param dexFile The DexFile that this item belongs to - * @param classType the class that the method is a member of - * @param methodPrototype the type of the method - * @param methodName the name of the method - */ - private MethodIdItem(DexFile dexFile, TypeIdItem classType, ProtoIdItem methodPrototype, StringIdItem methodName) { - this(dexFile); - this.classType = classType; - this.methodPrototype = methodPrototype; - this.methodName = methodName; - } - - /** - * Returns a MethodIdItem for the given values, and that has been interned into - * the given DexFile - * @param dexFile The DexFile that this item belongs to - * @param classType the class that the method is a member of - * @param methodPrototype the type of the method - * @param methodName the name of the method - * @return a MethodIdItem for the given values, and that has been interned into - * the given DexFile - */ - public static MethodIdItem internMethodIdItem(DexFile dexFile, TypeIdItem classType, - ProtoIdItem methodPrototype, StringIdItem methodName) { - MethodIdItem methodIdItem = new MethodIdItem(dexFile, classType, methodPrototype, methodName); - return dexFile.MethodIdsSection.intern(methodIdItem); - } - - /** - * Looks up a MethodIdItem from the given DexFile for the given - * values - * @param dexFile The DexFile that this item belongs to - * @param classType the class that the method is a member of - * @param methodPrototype the type of the method - * @param methodName the name of the method - * @return a MethodIdItem from the given DexFile for the given - * values, or null if it doesn't exist - */ - public static MethodIdItem lookupMethodIdItem(DexFile dexFile, TypeIdItem classType, - ProtoIdItem methodPrototype, StringIdItem methodName) { - MethodIdItem methodIdItem = new MethodIdItem(dexFile, classType, methodPrototype, methodName); - return dexFile.MethodIdsSection.getInternedItem(methodIdItem); - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - classType = dexFile.TypeIdsSection.getItemByIndex(in.readShort()); - methodPrototype = dexFile.ProtoIdsSection.getItemByIndex(in.readShort()); - methodName = dexFile.StringIdsSection.getItemByIndex(in.readInt()); - } - - /** {@inheritDoc} */ - protected int placeItem(int offset) { - return offset + 8; - } - - /** {@inheritDoc} */ - protected void writeItem(AnnotatedOutput out) { - if (out.annotates()) { - out.annotate(2, "class_type: " + classType.getTypeDescriptor()); - out.annotate(2, "method_prototype: " + methodPrototype.getPrototypeString()); - out.annotate(4, "method_name: " + methodName.getStringValue()); - } - - int classIndex = classType.getIndex(); - if (classIndex > 0xffff) { - throw new RuntimeException(String.format("Error writing method_id_item for %s. The type index of " + - "defining class %s is too large", getMethodString(), classType.getTypeDescriptor())); - } - out.writeShort(classIndex); - - int prototypeIndex = methodPrototype.getIndex(); - if (prototypeIndex > 0xffff) { - throw new RuntimeException(String.format("Error writing method_id_item for %0. The prototype index of " + - "method prototype %s is too large", getMethodString(), methodPrototype.getPrototypeString())); - } - out.writeShort(prototypeIndex); - - out.writeInt(methodName.getIndex()); - } - - /** {@inheritDoc} */ - public ItemType getItemType() { - return ItemType.TYPE_METHOD_ID_ITEM; - } - - /** {@inheritDoc} */ - public String getConciseIdentity() { - return "method_id_item: " + getMethodString(); - } - - /** {@inheritDoc} */ - public int compareTo(MethodIdItem o) { - int result = classType.compareTo(o.classType); - if (result != 0) { - return result; - } - - result = methodName.compareTo(o.methodName); - if (result != 0) { - return result; - } - - return methodPrototype.compareTo(o.methodPrototype); - } - - private String cachedMethodString = null; - /** - * @return a string formatted like LclassName;->methodName(TTTT..)R - */ - public String getMethodString() { - if (cachedMethodString == null) { - String classType = this.classType.getTypeDescriptor(); - String methodName = this.methodName.getStringValue(); - String prototypeString = methodPrototype.getPrototypeString(); - - StringBuilder sb = new StringBuilder(classType.length() + methodName.length() + prototypeString.length() + - 2); - sb.append(classType); - sb.append("->"); - sb.append(methodName); - sb.append(prototypeString); - cachedMethodString = sb.toString(); - } - return cachedMethodString; - } - - private String cachedShortMethodString = null; - /** - * @return a string formatted like methodName(TTTT..)R - */ - public String getShortMethodString() { - if (cachedShortMethodString == null) { - String methodName = this.methodName.getStringValue(); - String prototypeString = methodPrototype.getPrototypeString(); - - StringBuilder sb = new StringBuilder(methodName.length() + prototypeString.length()); - sb.append(methodName); - sb.append(prototypeString); - cachedShortMethodString = sb.toString(); - } - return cachedShortMethodString; - } - - /** - * @return the method prototype - */ - public ProtoIdItem getPrototype() { - return methodPrototype; - } - - /** - * @return the name of the method - */ - public StringIdItem getMethodName() { - return methodName; - } - - /** - * @return the class this method is a member of - */ - public TypeIdItem getContainingClass() { - return classType; - } - - /** - * calculate and cache the hashcode - */ - private void calcHashCode() { - hashCode = classType.hashCode(); - hashCode = 31 * hashCode + methodPrototype.hashCode(); - hashCode = 31 * hashCode + methodName.hashCode(); - } - - @Override - public int hashCode() { - //there's a small possibility that the actual hash code will be 0. If so, we'll - //just end up recalculating it each time - if (hashCode == 0) - calcHashCode(); - return hashCode; - } - - @Override - public boolean equals(Object o) { - if (this==o) { - return true; - } - if (o==null || !this.getClass().equals(o.getClass())) { - return false; - } - - //This assumes that the referenced items have been interned in both objects. - //This is a valid assumption because all outside code must use the static - //"getInterned..." style methods to make new items, and any item created - //internally is guaranteed to be interned - MethodIdItem other = (MethodIdItem)o; - return (classType == other.classType && - methodPrototype == other.methodPrototype && - methodName == other.methodName); - } - - public MethodIdItem convert() { - return this; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/OdexDependencies.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/OdexDependencies.java deleted file mode 100644 index 581b8acc..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/OdexDependencies.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.dexlib.Util.Input; - -import java.io.UnsupportedEncodingException; - -public class OdexDependencies { - public final int modificationTime; - public final int crc; - public final int dalvikBuild; - - private final String[] dependencies; - private final byte[][] dependencyChecksums; - - public OdexDependencies (Input in) { - modificationTime = in.readInt(); - crc = in.readInt(); - dalvikBuild = in.readInt(); - - int dependencyCount = in.readInt(); - - dependencies = new String[dependencyCount]; - dependencyChecksums = new byte[dependencyCount][]; - - for (int i=0; i extends Section { - public OffsettedSection(DexFile dexFile, ItemType itemType) { - super(dexFile, itemType); - } - - public void readItems(Input in, ReadContext readContext) { - - for (int i = 0; i < items.size(); i++) { - assert items.get(i) == null; - - in.alignTo(ItemType.ItemAlignment); - - T item = (T)ItemFactory.makeItem(ItemType, DexFile); - - items.set(i, item); - item.readFrom(in, i, readContext); - } - - readContext.setItemsForSection(ItemType, items); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ProtoIdItem.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ProtoIdItem.java deleted file mode 100644 index a7b4a0a1..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ProtoIdItem.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; - -public class ProtoIdItem extends Item { - private int hashCode = 0; - - private StringIdItem shortyDescriptor; - private TypeIdItem returnType; - private TypeListItem parameters; - - /** - * Creates a new uninitialized ProtoIdItem - * @param dexFile The DexFile that this item belongs to - */ - protected ProtoIdItem(DexFile dexFile) { - super(dexFile); - } - - /** - * Creates a new ProtoIdItem with the given values - * @param dexFile The DexFile that this item belongs to - * @param returnType the return type - * @param parameters a TypeListItem containing a list of the parameter types - */ - private ProtoIdItem(DexFile dexFile, TypeIdItem returnType, TypeListItem parameters) { - this(dexFile); - - String shortyString = returnType.toShorty(); - if (parameters != null) { - shortyString += parameters.getShortyString(); - } - this.shortyDescriptor = StringIdItem.internStringIdItem(dexFile, shortyString); - this.returnType = returnType; - this.parameters = parameters; - } - - /** - * Returns a ProtoIdItem for the given values, and that has been interned into - * the given DexFile - * @param dexFile The DexFile that this item belongs to - * @param returnType the return type - * @param parameters a TypeListItem containing a list of the parameter types - * @return a ProtoIdItem for the given values, and that has been interned into - * the given DexFile - */ - public static ProtoIdItem internProtoIdItem(DexFile dexFile, TypeIdItem returnType, TypeListItem parameters) { - ProtoIdItem protoIdItem = new ProtoIdItem(dexFile, returnType, parameters); - return dexFile.ProtoIdsSection.intern(protoIdItem); - } - - /** - * Looks up the ProtoIdItem from the given DexFile for the given - * values - * @param dexFile the Dexfile to find the type in - * @param returnType the return type - * @param parameters a TypeListItem containing a list of the parameter types - * @return a ProtoIdItem from the given DexFile for the given - * values, or null if it doesn't exist - */ - public static ProtoIdItem lookupProtoIdItem(DexFile dexFile, TypeIdItem returnType, TypeListItem parameters) { - ProtoIdItem protoIdItem = new ProtoIdItem(dexFile, returnType, parameters); - return dexFile.ProtoIdsSection.getInternedItem(protoIdItem); - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - shortyDescriptor = dexFile.StringIdsSection.getItemByIndex(in.readInt()); - returnType = dexFile.TypeIdsSection.getItemByIndex(in.readInt()); - parameters = (TypeListItem)readContext.getOptionalOffsettedItemByOffset(ItemType.TYPE_TYPE_LIST, in.readInt()); - } - - /** {@inheritDoc} */ - protected int placeItem(int offset) { - return offset + 12; - } - - /** {@inheritDoc} */ - protected void writeItem(AnnotatedOutput out) { - if (out.annotates()) { - out.annotate(4, "shorty_descriptor: " + shortyDescriptor.getStringValue()); - out.annotate(4, "return_type: " + returnType.getTypeDescriptor()); - - if (parameters == null) { - out.annotate(4, "parameters:"); - } else { - out.annotate(4, "parameters: " + parameters.getTypeListString("")); - } - } - - out.writeInt(shortyDescriptor.getIndex()); - out.writeInt(returnType.getIndex()); - out.writeInt(parameters == null?0:parameters.getOffset()); - } - - /** {@inheritDoc} */ - public ItemType getItemType() { - return ItemType.TYPE_PROTO_ID_ITEM; - } - - /** {@inheritDoc} */ - public int compareTo(ProtoIdItem o) { - int result = returnType.compareTo(o.returnType); - if (result != 0) { - return result; - } - - if (parameters == null) { - if (o.parameters == null) { - return 0; - } - return -1; - } else if (o.parameters == null) { - return 1; - } - - return parameters.compareTo(o.parameters); - } - - /** {@inheritDoc} */ - public String getConciseIdentity() { - return "proto_id_item: " + getPrototypeString(); - } - - private String cachedPrototypeString = null; - /** - * @return a string in the format (TTTT..)R where TTTT.. are the parameter types and R is the return type - */ - public String getPrototypeString() { - if (cachedPrototypeString == null) { - StringBuilder sb = new StringBuilder("("); - if (parameters != null) { - sb.append(parameters.getTypeListString("")); - } - sb.append(")"); - sb.append(returnType.getTypeDescriptor()); - - cachedPrototypeString = sb.toString(); - } - return cachedPrototypeString; - } - - /** - * @return the return type of the method - */ - public TypeIdItem getReturnType() { - return returnType; - } - - /** - * @return a TypeListItem containing the method parameter types - */ - public TypeListItem getParameters() { - return parameters; - } - - /** - * @return the number of registers required for the parameters of this ProtoIdItem - */ - public int getParameterRegisterCount() { - if (parameters == null) { - return 0; - } else { - return parameters.getRegisterCount(); - } - } - - /** - * calculate and cache the hashcode - */ - private void calcHashCode() { - hashCode = returnType.hashCode(); - hashCode = 31 * hashCode + (parameters==null?0:parameters.hashCode()); - } - - @Override - public int hashCode() { - //there's a small possibility that the actual hash code will be 0. If so, we'll - //just end up recalculating it each time - if (hashCode == 0) - calcHashCode(); - return hashCode; - } - - @Override - public boolean equals(Object o) { - if (this==o) { - return true; - } - if (o==null || !this.getClass().equals(o.getClass())) { - return false; - } - - //This assumes that the referenced items have been interned in both objects. - //This is a valid assumption because all outside code must use the static - //"getInterned..." style methods to make new items, and any item created - //internally is guaranteed to be interned - ProtoIdItem other = (ProtoIdItem)o; - return (returnType == other.returnType && - parameters == other.parameters); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ReadContext.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ReadContext.java deleted file mode 100644 index 0ee7587f..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/ReadContext.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.util.ExceptionWithContext; -import org.jf.dexlib.Util.SparseArray; - -import java.util.List; - - -/** - * This class stores context information that is only needed when reading in a dex file - * Namely, it handles "pre-creating" items when an item needs to resolve some other item - * that it references, and keeps track of those pre-created items, so the corresponding section - * for the pre-created items uses them, instead of creating new items - */ -public class ReadContext { - private SparseArray typeListItems = new SparseArray(0); - private SparseArray annotationSetRefLists = new SparseArray(0); - private SparseArray annotationSetItems = new SparseArray(0); - private SparseArray classDataItems = new SparseArray(0); - private SparseArray codeItems = new SparseArray(0); - private SparseArray stringDataItems = new SparseArray(0); - private SparseArray debugInfoItems = new SparseArray(0); - private SparseArray annotationItems = new SparseArray(0); - private SparseArray encodedArrayItems = new SparseArray(0); - private SparseArray annotationDirectoryItems = new SparseArray(0); - - private SparseArray[] itemsByType = new SparseArray[] { - null, //string_id_item - null, //type_id_item - null, //proto_id_item - null, //field_id_item - null, //method_id_item - null, //class_def_item - typeListItems, - annotationSetRefLists, - annotationSetItems, - classDataItems, - codeItems, - stringDataItems, - debugInfoItems, - annotationItems, - encodedArrayItems, - annotationDirectoryItems, - null, //map_list - null //header_item - }; - - - /** - * The section sizes that are passed in while reading HeaderItem/MapItem, via the - * addSection method. - */ - private int[] sectionSizes = new int[18]; - - /** - * The section offsets that are passed in while reading MapItem/HeaderItem, via the - * addSection method. - */ - private int[] sectionOffsets = new int[18]; - - /** - * Creates a new ReadContext instance. - */ - public ReadContext() { - for (int i=0; i<18; i++) { - sectionSizes[i] = -1; - sectionOffsets[i] = -1; - } - } - - /** - * Gets the offsetted item of the specified type for the given offset. This method does not support retrieving an - * optional item where a value of 0 indicates "not present". Use getOptionalOffsettedItemByOffset instead. - * - * @param itemType The type of item to get - * @param offset The offset of the item - * @return the offsetted item of the specified type at the specified offset - */ - public Item getOffsettedItemByOffset(ItemType itemType, int offset) { - assert !itemType.isIndexedItem(); - - SparseArray sa = itemsByType[itemType.SectionIndex]; - Item item = sa.get(offset); - if (item == null) { - throw new ExceptionWithContext(String.format("Could not find the %s item at offset %#x", - itemType.TypeName, offset)); - } - return item; - } - - /** - * Gets the optional offsetted item of the specified type for the given offset - * - * @param itemType The type of item to get - * @param offset The offset of the item - * @return the offsetted item of the specified type at the specified offset, or null if the offset is 0 - */ - public Item getOptionalOffsettedItemByOffset(ItemType itemType, int offset) { - assert !itemType.isIndexedItem(); - - assert !itemType.isIndexedItem(); - - SparseArray sa = itemsByType[itemType.SectionIndex]; - Item item = sa.get(offset); - if (item == null && offset != 0) { - throw new ExceptionWithContext(String.format("Could not find the %s item at offset %#x", - itemType.TypeName, offset)); - } - return item; - } - - /** - * Adds the size and offset information for the given offset - * @param itemType the item type of the section - * @param sectionSize the size of the section - * @param sectionOffset the offset of the section - */ - public void addSection(final ItemType itemType, int sectionSize, int sectionOffset) { - int storedSectionSize = sectionSizes[itemType.SectionIndex]; - if (storedSectionSize == -1) { - sectionSizes[itemType.SectionIndex] = sectionSize; - } else { - if (storedSectionSize != sectionSize) { - throw new RuntimeException("The section size in the header and map for item type " - + itemType + " do not match"); - } - } - - int storedSectionOffset = sectionOffsets[itemType.SectionIndex]; - if (storedSectionOffset == -1) { - sectionOffsets[itemType.SectionIndex] = sectionOffset; - } else { - if (storedSectionOffset != sectionOffset) { - throw new RuntimeException("The section offset in the header and map for item type " - + itemType + " do not match"); - } - } - } - - /** - * Sets the items for the specified section. This should be called by an offsetted section - * after it is finished reading in all its items. - * @param itemType the item type of the section. This must be an offsetted item type - * @param items the full list of items in the section, ordered by offset - */ - public void setItemsForSection(ItemType itemType, List items) { - assert !itemType.isIndexedItem(); - - SparseArray sa = itemsByType[itemType.SectionIndex]; - - sa.ensureCapacity(items.size()); - for (Item item: items) { - sa.append(item.getOffset(), item); - } - } - - /** - * @param itemType the item type of the section - * @return the size of the given section as it was read in from the map item - */ - public int getSectionSize(ItemType itemType) { - return sectionSizes[itemType.SectionIndex]; - } - - /** - * @param itemType the item type of the section - * @return the offset of the given section as it was read in from the map item - */ - public int getSectionOffset(ItemType itemType) { - return sectionOffsets[itemType.SectionIndex]; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Section.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Section.java deleted file mode 100644 index 61cee0ea..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Section.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.util.AlignmentUtils; -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; - -public abstract class Section { - /** - * A list of the items that this section contains. - * If the section has been placed, this list should be in the order that the items - * will written to the dex file - */ - protected final ArrayList items; - - /** - * A HashMap of the items in this section. This is used when interning items, to determine - * if this section already has an item equivalent to the one that is being interned. - * Both the key and the value should be the same object - */ - protected HashMap uniqueItems = null; - - /** - * The offset of this section within the DexFile - */ - protected int offset = 0; - - /** - * The type of item that this section holds - */ - public final ItemType ItemType; - - /** - * The DexFile that this section belongs to - */ - public final DexFile DexFile; - - /** - * Create a new section - * @param dexFile The DexFile that this section belongs to - * @param itemType The itemType that this section will hold - */ - protected Section(DexFile dexFile, ItemType itemType) { - this.DexFile = dexFile; - items = new ArrayList(); - this.ItemType = itemType; - } - - /** - * Finalize the location of all items, and place them starting at the given offset - * @param offset The offset where this section should be placed - * @return the offset of the byte immediate after the last item in this section - */ - protected int placeAt(int offset) { - if (items.size() > 0) { - offset = AlignmentUtils.alignOffset(offset, ItemType.ItemAlignment); - assert !DexFile.getInplace() || offset == this.offset; - this.offset = offset; - - for (int i=0; i < items.size(); i++) { - T item = items.get(i); - assert item != null; - offset = AlignmentUtils.alignOffset(offset, ItemType.ItemAlignment); - offset = item.placeAt(offset, i); - } - } else { - this.offset = 0; - } - - return offset; - } - - /** - * Write the items to the given AnnotatedOutput - * @param out the AnnotatedOutput object to write to - */ - protected void writeTo(AnnotatedOutput out) { - out.annotate(0, " "); - out.annotate(0, "-----------------------------"); - out.annotate(0, this.ItemType.TypeName + " section"); - out.annotate(0, "-----------------------------"); - out.annotate(0, " "); - - for (Item item: items) { - assert item!=null; - out.alignTo(ItemType.ItemAlignment); - item.writeTo(out); - out.annotate(0, " "); - } - } - - /** - * Read the specified number of items from the given Input object - * @param size The number of items to read - * @param in The Input object to read from - * @param readContext a ReadContext object to hold information that is - * only needed while reading in a file - */ - protected void readFrom(int size, Input in, ReadContext readContext) { - //readItems() expects that the list will already be the correct size, so add null items - //until we reach the specified size - items.ensureCapacity(size); - for (int i = items.size(); i < size; i++) { - items.add(null); - } - - in.alignTo(ItemType.ItemAlignment); - offset = in.getCursor(); - - //call the subclass's method that actually reads in the items - readItems(in, readContext); - } - - /** - * This method in the concrete item subclass should read in all the items from the given Input - * object, using any pre-created items as applicable (i.e. items that were created prior to reading in the - * section, by other items requesting items from this section that they reference by index/offset) - * @param in the Input - * @param readContext a ReadContext object to hold information that is - * only needed while reading in a file - */ - protected abstract void readItems(Input in, ReadContext readContext); - - /** - * Gets the offset where the first item in this section is placed - * @return the ofset where the first item in this section is placed - */ - public int getOffset() { - return offset; - } - - /** - * Gets a the items contained in this section as a read-only list - * @return A read-only List object containing the items in this section - */ - public List getItems() { - return Collections.unmodifiableList(items); - } - - /** - * This method checks if an item that is equivalent to the given item has already been added. If found, - * it returns that item. If not found, it adds the given item to this section and returns it. - * @param item the item to intern - * @return An item from this section that is equivalent to the given item. It may or may not be the same - * as the item passed to this method. - */ - protected T intern(T item) { - if (item == null) { - return null; - } - T internedItem = getInternedItem(item); - if (internedItem == null) { - uniqueItems.put(item, item); - items.add(item); - return item; - } - return internedItem; - } - - /** - * Returns the interned item that is equivalent to the given item, or null - * @param item the item to check - * @return the interned item that is equivalent to the given item, or null - */ - protected T getInternedItem(T item) { - if (uniqueItems == null) { - buildInternedItemMap(); - } - return uniqueItems.get(item); - } - - /** - * Builds the interned item map from the items that are in this section - */ - private void buildInternedItemMap() { - uniqueItems = new HashMap(); - for (T item: items) { - assert item != null; - uniqueItems.put(item, item); - } - } - - /** - * Sorts the items in the section - */ - protected void sortSection() { - Collections.sort(items); - } -} \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/StringDataItem.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/StringDataItem.java deleted file mode 100644 index bb0e79e1..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/StringDataItem.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; -import org.jf.dexlib.Util.Leb128Utils; -import org.jf.util.StringUtils; -import org.jf.util.Utf8Utils; - -public class StringDataItem extends Item { - private int hashCode = 0; - - private String stringValue; - - /** - * Creates a new uninitialized StringDataItem - * @param dexFile The DexFile that this item belongs to - */ - protected StringDataItem(DexFile dexFile) { - super(dexFile); - } - - /** - * Creates a new StringDataItem for the given string - * @param dexFile The DexFile that this item belongs to - * @param stringValue The string value that this item represents - */ - private StringDataItem(DexFile dexFile, String stringValue) { - super(dexFile); - - this.stringValue = stringValue; - } - - /** - * Returns a StringDataItem for the given values, and that has been interned into - * the given DexFile - * @param dexFile The DexFile that this item belongs to - * @param value The string value that this item represents - * @return a StringDataItem for the given values, and that has been interned into - * the given DexFile - */ - public static StringDataItem internStringDataItem(DexFile dexFile, String value) { - StringDataItem StringDataItem = new StringDataItem(dexFile, value); - return dexFile.StringDataSection.intern(StringDataItem); - } - - /** - * Looks up the StringDataItem from the given DexFile for the given - * string value - * @param dexFile the Dexfile to find the string value in - * @param value The string value to look up - * @return a StringDataItem from the given DexFile for the given - * string value, or null if it doesn't exist - **/ - public static StringDataItem lookupStringDataItem(DexFile dexFile, String value) { - StringDataItem StringDataItem = new StringDataItem(dexFile, value); - return dexFile.StringDataSection.getInternedItem(StringDataItem); - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - in.readUnsignedLeb128(); //string length - stringValue = in.realNullTerminatedUtf8String(); - } - - /** {@inheritDoc} */ - protected int placeItem(int offset) { - return offset + Leb128Utils.unsignedLeb128Size(stringValue.length()) + - Utf8Utils.stringToUtf8Bytes(stringValue).length + 1; - } - - /** {@inheritDoc} */ - protected void writeItem(AnnotatedOutput out) { - byte[] encodedValue = Utf8Utils.stringToUtf8Bytes(stringValue); - if (out.annotates()) { - out.annotate("string_size: 0x" + Integer.toHexString(stringValue.length()) + " (" + stringValue.length() + - ")"); - out.writeUnsignedLeb128(stringValue.length()); - - out.annotate(encodedValue.length + 1, "string_data: \"" + StringUtils.escapeString(stringValue) + "\""); - } else { - out.writeUnsignedLeb128(stringValue.length()); - } - out.write(encodedValue); - out.writeByte(0); - } - - /** {@inheritDoc} */ - public ItemType getItemType() { - return ItemType.TYPE_STRING_DATA_ITEM; - } - - /** {@inheritDoc} */ - public String getConciseIdentity() { - return "string_data_item: \"" + StringUtils.escapeString(getStringValue()) + "\""; - } - - /** {@inheritDoc} */ - public int compareTo(StringDataItem o) { - return getStringValue().compareTo(o.getStringValue()); - } - - /** - * Get the string value of this item as a String - * @return the string value of this item as a String - */ - public String getStringValue() { - return stringValue; - } - - /** - * calculate and cache the hashcode - */ - private void calcHashCode() { - hashCode = getStringValue().hashCode(); - } - - @Override - public int hashCode() { - //there's a small possibility that the actual hash code will be 0. If so, we'll - //just end up recalculating it each time - if (hashCode == 0) - calcHashCode(); - return hashCode; - } - - @Override - public boolean equals(Object o) { - if (this==o) { - return true; - } - if (o==null || !this.getClass().equals(o.getClass())) { - return false; - } - - //This assumes that the referenced items have been interned in both objects. - //This is a valid assumption because all outside code must use the static - //"getInterned..." style methods to make new items, and any item created - //internally is guaranteed to be interned - StringDataItem other = (StringDataItem)o; - return getStringValue().equals(other.getStringValue()); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/StringIdItem.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/StringIdItem.java deleted file mode 100644 index b63050a4..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/StringIdItem.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; -import org.jf.util.StringUtils; - -import javax.annotation.Nullable; - -public class StringIdItem extends Item { - private StringDataItem stringDataItem; - - /** - * Creates a new uninitialized StringIdItem - * @param dexFile The DexFile that this item belongs to - */ - protected StringIdItem(DexFile dexFile) { - super(dexFile); - } - - /** - * Creates a new StringIdItem for the given StringDataItem - * @param dexFile The DexFile that this item belongs to - * @param stringDataItem The StringDataItem that this StringIdItem represents - */ - protected StringIdItem(DexFile dexFile, StringDataItem stringDataItem) { - super(dexFile); - this.stringDataItem = stringDataItem; - } - - /** - * Returns a StringIdItem for the given values, and that has been interned into - * the given DexFile - * @param dexFile The DexFile that this item will belong to - * @param stringValue The string value that this item represents - * @return a StringIdItem for the given values, and that has been interned into - * the given DexFile - */ - public static StringIdItem internStringIdItem(DexFile dexFile, String stringValue) { - StringDataItem stringDataItem = StringDataItem.internStringDataItem(dexFile, stringValue); - if (stringDataItem == null) { - return null; - } - StringIdItem stringIdItem = new StringIdItem(dexFile, stringDataItem); - return dexFile.StringIdsSection.intern(stringIdItem); - } - - /** - * Looks up the StringIdItem from the given DexFile for the given - * string value - * @param dexFile the Dexfile to find the string value in - * @param stringValue The string value to look up - * @return a StringIdItem from the given DexFile for the given - * string value, or null if it doesn't exist - */ - public static StringIdItem lookupStringIdItem(DexFile dexFile, String stringValue) { - StringDataItem stringDataItem = StringDataItem.lookupStringDataItem(dexFile, stringValue); - if (stringDataItem == null) { - return null; - } - StringIdItem stringIdItem = new StringIdItem(dexFile, stringDataItem); - return dexFile.StringIdsSection.getInternedItem(stringIdItem); - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - int stringDataOffset = in.readInt(); - - stringDataItem = (StringDataItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_STRING_DATA_ITEM, - stringDataOffset); - } - - /** {@inheritDoc} */ - protected int placeItem(int offset) { - return offset + 4; - } - - /** {@inheritDoc} */ - protected void writeItem(AnnotatedOutput out) { - if (out.annotates()) { - out.annotate(4, stringDataItem.getConciseIdentity()); - } - - out.writeInt(stringDataItem.getOffset()); - } - - /** {@inheritDoc} */ - public ItemType getItemType() { - return ItemType.TYPE_STRING_ID_ITEM; - } - - /** {@inheritDoc} */ - public String getConciseIdentity() { - return "string_id_item: " + StringUtils.escapeString(getStringValue()); - } - - /** {@inheritDoc} */ - public int compareTo(StringIdItem o) { - //sort by the string value - return getStringValue().compareTo(o.getStringValue()); - } - - /** - * Get the String value that this StringIdItem represents - * @return the String value that this StringIdItem represents - */ - public String getStringValue() { - return stringDataItem.getStringValue(); - } - - /** - * Get the String value that the given StringIdItem represents - * @param stringIdItem The StringIdItem to get the string value of - * @return the String value that the given StringIdItem represents - */ - @Nullable - public static String getStringValue(@Nullable StringIdItem stringIdItem) { - return stringIdItem==null?null:stringIdItem.getStringValue(); - } - - /** - * Get the StringDataItem that this StringIdItem references - * @return the StringDataItem that this StringIdItem references - */ - public StringDataItem getStringDataItem() { - return stringDataItem; - } - - @Override - public int hashCode() { - return stringDataItem.hashCode(); - } - - @Override - public boolean equals(Object o) { - if (this==o) { - return true; - } - if (o==null || !this.getClass().equals(o.getClass())) { - return false; - } - - //This assumes that the referenced items have been interned in both objects. - //This is a valid assumption because all outside code must use the static - //"getInterned..." style methods to make new items, and any item created - //internally is guaranteed to be interned - StringIdItem other = (StringIdItem)o; - return stringDataItem == other.stringDataItem; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/TypeIdItem.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/TypeIdItem.java deleted file mode 100644 index 6cc2b968..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/TypeIdItem.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; - -import javax.annotation.Nullable; - -public class TypeIdItem extends Item { - private StringIdItem typeDescriptor; - - /** - * Creates a new uninitialized TypeIdItem - * @param dexFile The DexFile that this item belongs to - */ - protected TypeIdItem(DexFile dexFile) { - super(dexFile); - } - - /** - * Creates a new TypeIdItem for the given StringIdItem - * @param dexFile The DexFile that this item will belong to - * @param typeDescriptor The StringIdItem containing the type descriptor that - * this TypeIdItem represents - */ - private TypeIdItem(DexFile dexFile, StringIdItem typeDescriptor) { - super(dexFile); - this.typeDescriptor = typeDescriptor; - } - - /** - * Returns a TypeIdItem for the given values, and that has been interned into - * the given DexFile - * @param dexFile The DexFile that this item will belong to - * @param typeDescriptor The StringIdItem containing the type descriptor that - * this TypeIdItem represents - * @return a TypeIdItem for the given values, and that has been interned into - * the given DexFile - */ - public static TypeIdItem internTypeIdItem(DexFile dexFile, StringIdItem typeDescriptor) { - TypeIdItem typeIdItem = new TypeIdItem(dexFile, typeDescriptor); - return dexFile.TypeIdsSection.intern(typeIdItem); - } - - /** - * Returns a TypeIdItem for the given values, and that has been interned into - * the given DexFile - * @param dexFile The DexFile that this item will belong to - * @param typeDescriptor The string containing the type descriptor that this - * TypeIdItem represents - * @return a TypeIdItem for the given values, and that has been interned into - * the given DexFile - */ - public static TypeIdItem internTypeIdItem(DexFile dexFile, String typeDescriptor) { - StringIdItem stringIdItem = StringIdItem.internStringIdItem(dexFile, typeDescriptor); - if (stringIdItem == null) { - return null; - } - TypeIdItem typeIdItem = new TypeIdItem(dexFile, stringIdItem); - return dexFile.TypeIdsSection.intern(typeIdItem); - } - - /** - * Looks up the TypeIdItem from the given DexFile for the given - * type descriptor - * @param dexFile the Dexfile to find the type in - * @param typeDescriptor The string containing the type descriptor to look up - * @return a TypeIdItem from the given DexFile for the given - * type descriptor, or null if it doesn't exist - */ - public static TypeIdItem lookupTypeIdItem(DexFile dexFile, String typeDescriptor) { - StringIdItem stringIdItem = StringIdItem.lookupStringIdItem(dexFile, typeDescriptor); - if (stringIdItem == null) { - return null; - } - TypeIdItem typeIdItem = new TypeIdItem(dexFile, stringIdItem); - return dexFile.TypeIdsSection.getInternedItem(typeIdItem); - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - int stringIdIndex = in.readInt(); - this.typeDescriptor = dexFile.StringIdsSection.getItemByIndex(stringIdIndex); - } - - /** {@inheritDoc} */ - protected int placeItem(int offset) { - return offset + 4; - } - - /** {@inheritDoc} */ - protected void writeItem(AnnotatedOutput out) { - if (out.annotates()) { - out.annotate(4, typeDescriptor.getConciseIdentity()); - } - - out.writeInt(typeDescriptor.getIndex()); - } - - /** {@inheritDoc} */ - public ItemType getItemType() { - return ItemType.TYPE_TYPE_ID_ITEM; - } - - /** {@inheritDoc} */ - public String getConciseIdentity() { - return "type_id_item: " + getTypeDescriptor(); - } - - /** {@inheritDoc} */ - public int compareTo(TypeIdItem o) { - //sort by the index of the StringIdItem - return typeDescriptor.compareTo(o.typeDescriptor); - } - - /** - * Returns the type descriptor as a String for this type - * @return the type descriptor as a String for this type - */ - public String getTypeDescriptor() { - return typeDescriptor.getStringValue(); - } - - /** - * Returns the type descriptor as a String for the given type - * @param typeIdItem The TypeIdItem to get the type descriptor of - * @return the type descriptor as a String for the gvien type - */ - @Nullable - public static String getTypeDescriptor(@Nullable TypeIdItem typeIdItem) { - return typeIdItem==null?null:typeIdItem.getTypeDescriptor(); - } - - /** - * Returns the "shorty" representation of this type, used to create the shorty prototype string for a method - * @return the "shorty" representation of this type, used to create the shorty prototype string for a method - */ - public String toShorty() { - String type = getTypeDescriptor(); - if (type.length() > 1) { - return "L"; - } else { - return type; - } - } - - /** - * Calculates the number of 2-byte registers that an instance of this type requires - * @return The number of 2-byte registers that an instance of this type requires - */ - public int getRegisterCount() { - String type = this.getTypeDescriptor(); - /** Only the long and double primitive types are 2 words, - * everything else is a single word - */ - if (type.charAt(0) == 'J' || type.charAt(0) == 'D') { - return 2; - } else { - return 1; - } - } - - @Override - public int hashCode() { - return typeDescriptor.hashCode(); - } - - @Override - public boolean equals(Object o) { - if (this==o) { - return true; - } - if (o==null || !this.getClass().equals(o.getClass())) { - return false; - } - - //This assumes that the referenced items have been interned in both objects. - //This is a valid assumption because all outside code must use the static - //"getInterned..." style methods to make new items, and any item created - //internally is guaranteed to be interned - TypeIdItem other = (TypeIdItem)o; - return typeDescriptor == other.typeDescriptor; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/TypeListItem.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/TypeListItem.java deleted file mode 100644 index 50262ea1..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/TypeListItem.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib; - -import org.jf.dexlib.Util.AnnotatedOutput; -import org.jf.dexlib.Util.Input; -import org.jf.dexlib.Util.ReadOnlyArrayList; - -import java.util.List; - -public class TypeListItem extends Item { - private int hashCode = 0; - - private TypeIdItem[] typeList; - - /** - * Creates a new uninitialized TypeListItem - * @param dexFile The DexFile that this item belongs to - */ - protected TypeListItem(DexFile dexFile) { - super(dexFile); - } - - /** - * Creates a new TypeListItem for the given string - * @param dexFile The DexFile that this item belongs to - * @param typeList A list of the types that this TypeListItem represents - */ - private TypeListItem(DexFile dexFile, TypeIdItem[] typeList) { - super(dexFile); - - this.typeList = typeList; - } - - /** - * Returns a TypeListItem for the given values, and that has been interned into - * the given DexFile - * @param dexFile The DexFile that this item belongs to - * @param typeList A list of the types that this TypeListItem represents - * @return a TypeListItem for the given values, and that has been interned into - * the given DexFile - */ - public static TypeListItem internTypeListItem(DexFile dexFile, List typeList) { - TypeIdItem[] typeArray = new TypeIdItem[typeList.size()]; - typeList.toArray(typeArray); - TypeListItem typeListItem = new TypeListItem(dexFile, typeArray); - return dexFile.TypeListsSection.intern(typeListItem); - } - - /** - * Looks up the TypeListItem from the given DexFile for the given - * list of types - * @param dexFile the Dexfile to find the type in - * @param typeList A list of the types that the TypeListItem represents - * @return a TypeListItem from the given DexFile for the given - * list of types, or null if it doesn't exist - */ - public static TypeListItem lookupTypeListItem(DexFile dexFile, List typeList) { - TypeIdItem[] typeArray = new TypeIdItem[typeList.size()]; - typeList.toArray(typeArray); - TypeListItem typeListItem = new TypeListItem(dexFile, typeArray); - return dexFile.TypeListsSection.getInternedItem(typeListItem); - } - - /** {@inheritDoc} */ - protected void readItem(Input in, ReadContext readContext) { - int size = in.readInt(); - typeList = new TypeIdItem[size]; - for (int i=0; i 0xffff) { - throw new RuntimeException(String.format("Error writing type_list entry. The type index of " + - "type %s is too large", typeIdItem.getTypeDescriptor())); - } - out.writeShort(typeIndex); - } - } - - /** {@inheritDoc} */ - public ItemType getItemType() { - return ItemType.TYPE_TYPE_LIST; - } - - /** {@inheritDoc} */ - public String getConciseIdentity() { - return "type_list: " + getTypeListString(""); - } - - /** {@inheritDoc} */ - public int compareTo(TypeListItem o) { - if (o == null) { - return 1; - } - - int thisSize = typeList.length; - int otherSize = o.typeList.length; - int size = Math.min(thisSize, otherSize); - - for (int i = 0; i < size; i++) { - int result = typeList[i].compareTo(o.typeList[i]); - if (result != 0) { - return result; - } - } - - if (thisSize < otherSize) { - return -1; - } else if (thisSize > otherSize) { - return 1; - } else { - return 0; - } - } - - /** - * @return the number of registers required for this TypeListItem - */ - public int getRegisterCount() { - int wordCount = 0; - for (TypeIdItem typeIdItem: typeList) { - wordCount += typeIdItem.getRegisterCount(); - } - return wordCount; - } - - /** - * @return a string consisting of the type descriptors in this TypeListItem - * that are separated by the given separator - * @param separator the separator between each type - */ - public String getTypeListString(String separator) { - int size = 0; - for (TypeIdItem typeIdItem: typeList) { - size += typeIdItem.getTypeDescriptor().length(); - size += separator.length(); - } - - StringBuilder sb = new StringBuilder(size); - for (TypeIdItem typeIdItem: typeList) { - sb.append(typeIdItem.getTypeDescriptor()); - sb.append(separator); - } - if (typeList.length > 0) { - sb.delete(sb.length() - separator.length(), sb.length()); - } - return sb.toString(); - } - - /** - * @return a string consisting of the shorty form of the type descriptors in this - * TypeListItem that are directly concatenated together - */ - public String getShortyString() { - StringBuilder sb = new StringBuilder(); - for (TypeIdItem typeIdItem: typeList) { - sb.append(typeIdItem.toShorty()); - } - return sb.toString(); - } - - /** - * @param index the index of the TypeIdItem to get - * @return the TypeIdItem at the given index - */ - public TypeIdItem getTypeIdItem(int index) { - return typeList[index]; - } - - /** - * @return the number of types in this TypeListItem - */ - public int getTypeCount() { - return typeList.length; - } - - /** - * @return an array of the TypeIdItems in this TypeListItem - */ - public List getTypes() { - return new ReadOnlyArrayList(typeList); - } - - /** - * Helper method to allow easier "inline" retrieval of of the list of TypeIdItems - * @param typeListItem the typeListItem to return the types of (can be null) - * @return an array of the TypeIdItems in the specified TypeListItem, or null if the - * TypeListItem is null - */ - public static List getTypes(TypeListItem typeListItem) { - return typeListItem==null?null:typeListItem.getTypes(); - } - - /** - * calculate and cache the hashcode - */ - private void calcHashCode() { - int hashCode = 1; - - for (TypeIdItem typeIdItem: typeList) { - hashCode = 31 * hashCode + typeIdItem.hashCode(); - } - this.hashCode = hashCode; - } - - @Override - public int hashCode() { - //there's a small possibility that the actual hash code will be 0. If so, we'll - //just end up recalculating it each time - if (hashCode == 0) - calcHashCode(); - return hashCode; - } - - @Override - public boolean equals(Object o) { - if (this==o) { - return true; - } - if (o==null || !this.getClass().equals(o.getClass())) { - return false; - } - - //This assumes that the referenced items have been interned in both objects. - //This is a valid assumption because all outside code must use the static - //"getInterned..." style methods to make new items, and any item created - //internally is guaranteed to be interned - TypeListItem other = (TypeListItem)o; - if (typeList.length != other.typeList.length) { - return false; - } - - for (int i=0; i accessFlagsByName; - - static { - allFlags = AccessFlags.values(); - - accessFlagsByName = new HashMap(); - for (AccessFlags accessFlag: allFlags) { - accessFlagsByName.put(accessFlag.accessFlagName, accessFlag); - } - } - - private AccessFlags(int value, String accessFlagName, boolean validForClass, boolean validForMethod, - boolean validForField) { - this.value = value; - this.accessFlagName = accessFlagName; - this.validForClass = validForClass; - this.validForMethod = validForMethod; - this.validForField = validForField; - } - - public static AccessFlags[] getAccessFlagsForClass(int accessFlagValue) { - int size = 0; - for (AccessFlags accessFlag: allFlags) { - if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) { - size++; - } - } - - AccessFlags[] accessFlags = new AccessFlags[size]; - int accessFlagsPosition = 0; - for (AccessFlags accessFlag: allFlags) { - if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) { - accessFlags[accessFlagsPosition++] = accessFlag; - } - } - return accessFlags; - } - - private static String formatAccessFlags(AccessFlags[] accessFlags) { - int size = 0; - for (AccessFlags accessFlag: accessFlags) { - size += accessFlag.toString().length() + 1; - } - - StringBuilder sb = new StringBuilder(size); - for (AccessFlags accessFlag: accessFlags) { - sb.append(accessFlag.toString()); - sb.append(" "); - } - if (accessFlags.length > 0) { - sb.delete(sb.length() - 1, sb.length()); - } - return sb.toString(); - } - - public static String formatAccessFlagsForClass(int accessFlagValue) { - return formatAccessFlags(getAccessFlagsForClass(accessFlagValue)); - } - - public static AccessFlags[] getAccessFlagsForMethod(int accessFlagValue) { - int size = 0; - for (AccessFlags accessFlag: allFlags) { - if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) { - size++; - } - } - - AccessFlags[] accessFlags = new AccessFlags[size]; - int accessFlagsPosition = 0; - for (AccessFlags accessFlag: allFlags) { - if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) { - accessFlags[accessFlagsPosition++] = accessFlag; - } - } - return accessFlags; - } - - public static String formatAccessFlagsForMethod(int accessFlagValue) { - return formatAccessFlags(getAccessFlagsForMethod(accessFlagValue)); - } - - public static AccessFlags[] getAccessFlagsForField(int accessFlagValue) { - int size = 0; - for (AccessFlags accessFlag: allFlags) { - if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) { - size++; - } - } - - AccessFlags[] accessFlags = new AccessFlags[size]; - int accessFlagsPosition = 0; - for (AccessFlags accessFlag: allFlags) { - if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) { - accessFlags[accessFlagsPosition++] = accessFlag; - } - } - return accessFlags; - } - - public static String formatAccessFlagsForField(int accessFlagValue) { - return formatAccessFlags(getAccessFlagsForField(accessFlagValue)); - } - - public static AccessFlags getAccessFlag(String accessFlag) { - return accessFlagsByName.get(accessFlag); - } - - public int getValue() { - return value; - } - - public String toString() { - return accessFlagName; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/AnnotatedOutput.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/AnnotatedOutput.java deleted file mode 100644 index 928b2008..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/AnnotatedOutput.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * 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. - */ - -/* - * As per the Apache license requirements, this file has been modified - * from its original state. - * - * Such modifications are Copyright (C) 2010 Ben Gruver, and are released - * under the original license - */ - -package org.jf.dexlib.Util; - -/** - * Interface for a binary output destination that may be augmented - * with textual annotations. - */ -public interface AnnotatedOutput - extends Output { - /** - * Get whether this instance will actually keep annotations. - * - * @return true iff annotations are being kept - */ - public boolean annotates(); - - /** - * Get whether this instance is intended to keep verbose annotations. - * Annotators may use the result of calling this method to inform their - * annotation activity. - * - * @return true iff annotations are to be verbose - */ - public boolean isVerbose(); - - /** - * Add an annotation for the subsequent output. Any previously - * open annotation will be closed by this call, and the new - * annotation marks all subsequent output until another annotation - * call. - * - * @param msg non-null; the annotation message - */ - public void annotate(String msg); - - /** - * Add an annotation for a specified amount of subsequent - * output. Any previously open annotation will be closed by this - * call. If there is already pending annotation from one or more - * previous calls to this method, the new call "consumes" output - * after all the output covered by the previous calls. - * - * @param amt >= 0; the amount of output for this annotation to - * cover - * @param msg non-null; the annotation message - */ - public void annotate(int amt, String msg); - - /** - * End the most recent annotation. Subsequent output will be unannotated, - * until the next call to {@link #annotate}. - */ - public void endAnnotation(); - - /** - * Get the maximum width of the annotated output. This is advisory: - * Implementations of this interface are encouraged to deal with too-wide - * output, but annotaters are encouraged to attempt to avoid exceeding - * the indicated width. - * - * @return >= 1; the maximum width - */ - public int getAnnotationWidth(); - - public void setIndentAmount(int indentAmount); - public void indent(); - public void deindent(); -} \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ArrayUtils.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ArrayUtils.java deleted file mode 100644 index dab08372..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ArrayUtils.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Util; - -import java.util.Arrays; -import java.util.Comparator; - -public class ArrayUtils { - /** - * Utility method to sort two related arrays - that is, two arrays where the elements are related to each other - * by their position in the array. i.e. firstArray[0] is related to secondArray[0], firstArray[1] is related to - * secondArray[1], and so on. The first array is sorted based on its implementation of Comparable, and the 2nd - * array is sorted by it's related item in the first array, so that the same elements are still related to each - * other after the sort - * @param firstArray The first array, which contains the values to sort - * @param secondArray The second array, which will be sorted based on the values in the first array - * @param The type of element in the first array - * @param the type of element in the second array - */ - public static , B> void sortTwoArrays(A[] firstArray, B[] secondArray) - { - if (firstArray.length != secondArray.length) { - throw new RuntimeException("Both arrays must be of the same length"); - } - - class element - { - public A first; - public B second; - } - - element[] elements = new element[firstArray.length]; - - Arrays.sort(elements, new Comparator(){ - public int compare(element a, element b) { - return a.first.compareTo(b.first); - } - }); - - for (int i=0; ibyte[], which provides read-only access and - * can "reveal" a partial slice of the underlying array. - * - * Note: Multibyte accessors all use big-endian order. - */ -public final class ByteArray { - /** non-null; underlying array */ - private final byte[] bytes; - - /** >= 0; start index of the slice (inclusive) */ - private final int start; - - /** >= 0, <= bytes.length; size computed as - * end - start (in the constructor) */ - private final int size; - - /** - * Constructs an instance. - * - * @param bytes non-null; the underlying array - * @param start >= 0; start index of the slice (inclusive) - * @param end >= start, <= bytes.length; end index of - * the slice (exclusive) - */ - public ByteArray(byte[] bytes, int start, int end) { - if (bytes == null) { - throw new NullPointerException("bytes == null"); - } - - if (start < 0) { - throw new IllegalArgumentException("start < 0"); - } - - if (end < start) { - throw new IllegalArgumentException("end < start"); - } - - if (end > bytes.length) { - throw new IllegalArgumentException("end > bytes.length"); - } - - this.bytes = bytes; - this.start = start; - this.size = end - start; - } - - /** - * Constructs an instance from an entire byte[]. - * - * @param bytes non-null; the underlying array - */ - public ByteArray(byte[] bytes) { - this(bytes, 0, bytes.length); - } - - /** - * Gets the size of the array, in bytes. - * - * @return >= 0; the size - */ - public int size() { - return size; - } - - /** - * Returns a slice (that is, a sub-array) of this instance. - * - * @param start >= 0; start index of the slice (inclusive) - * @param end >= start, <= size(); end index of - * the slice (exclusive) - * @return non-null; the slice - */ - public ByteArray slice(int start, int end) { - checkOffsets(start, end); - return new ByteArray(bytes, start + this.start, end + this.start); - } - - /** - * Returns the offset into the given array represented by the given - * offset into this instance. - * - * @param offset offset into this instance - * @param bytes non-null; (alleged) underlying array - * @return corresponding offset into bytes - * @throws IllegalArgumentException thrown if bytes is - * not the underlying array of this instance - */ - public int underlyingOffset(int offset, byte[] bytes) { - if (bytes != this.bytes) { - throw new IllegalArgumentException("wrong bytes"); - } - - return start + offset; - } - - /** - * Gets the signed byte value at a particular offset. - * - * @param off >= 0, < size(); offset to fetch - * @return signed byte at that offset - */ - public int getByte(int off) { - checkOffsets(off, off + 1); - return getByte0(off); - } - - /** - * Gets the signed short value at a particular offset. - * - * @param off >= 0, < (size() - 1); offset to fetch - * @return signed short at that offset - */ - public int getShort(int off) { - checkOffsets(off, off + 2); - return (getByte0(off) << 8) | getUnsignedByte0(off + 1); - } - - /** - * Gets the signed int value at a particular offset. - * - * @param off >= 0, < (size() - 3); offset to fetch - * @return signed int at that offset - */ - public int getInt(int off) { - checkOffsets(off, off + 4); - return (getByte0(off) << 24) | - (getUnsignedByte0(off + 1) << 16) | - (getUnsignedByte0(off + 2) << 8) | - getUnsignedByte0(off + 3); - } - - /** - * Gets the signed long value at a particular offset. - * - * @param off >= 0, < (size() - 7); offset to fetch - * @return signed int at that offset - */ - public long getLong(int off) { - checkOffsets(off, off + 8); - int part1 = (getByte0(off) << 24) | - (getUnsignedByte0(off + 1) << 16) | - (getUnsignedByte0(off + 2) << 8) | - getUnsignedByte0(off + 3); - int part2 = (getByte0(off + 4) << 24) | - (getUnsignedByte0(off + 5) << 16) | - (getUnsignedByte0(off + 6) << 8) | - getUnsignedByte0(off + 7); - - return (part2 & 0xffffffffL) | ((long) part1) << 32; - } - - /** - * Gets the unsigned byte value at a particular offset. - * - * @param off >= 0, < size(); offset to fetch - * @return unsigned byte at that offset - */ - public int getUnsignedByte(int off) { - checkOffsets(off, off + 1); - return getUnsignedByte0(off); - } - - /** - * Gets the unsigned short value at a particular offset. - * - * @param off >= 0, < (size() - 1); offset to fetch - * @return unsigned short at that offset - */ - public int getUnsignedShort(int off) { - checkOffsets(off, off + 2); - return (getUnsignedByte0(off) << 8) | getUnsignedByte0(off + 1); - } - - /** - * Copies the contents of this instance into the given raw - * byte[] at the given offset. The given array must be - * large enough. - * - * @param out non-null; array to hold the output - * @param offset non-null; index into out for the first - * byte of output - */ - public void getBytes(byte[] out, int offset) { - if ((out.length - offset) < size) { - throw new IndexOutOfBoundsException("(out.length - offset) < " + - "size()"); - } - - System.arraycopy(bytes, start, out, offset, size); - } - - /** - * Checks a range of offsets for validity, throwing if invalid. - * - * @param s start offset (inclusive) - * @param e end offset (exclusive) - */ - private void checkOffsets(int s, int e) { - if ((s < 0) || (e < s) || (e > size)) { - throw new IllegalArgumentException("bad range: " + s + ".." + e + - "; actual size " + size); - } - } - - /** - * Gets the signed byte value at the given offset, - * without doing any argument checking. - * - * @param off offset to fetch - * @return byte at that offset - */ - private int getByte0(int off) { - return bytes[start + off]; - } - - /** - * Gets the unsigned byte value at the given offset, - * without doing any argument checking. - * - * @param off offset to fetch - * @return byte at that offset - */ - private int getUnsignedByte0(int off) { - return bytes[start + off] & 0xff; - } -} \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ByteArrayAnnotatedOutput.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ByteArrayAnnotatedOutput.java deleted file mode 100644 index ffd3476e..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ByteArrayAnnotatedOutput.java +++ /dev/null @@ -1,681 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * 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. - */ - -/* - * As per the Apache license requirements, this file has been modified - * from its original state. - * - * Such modifications are Copyright (C) 2010 Ben Gruver, and are released - * under the original license - */ - -package org.jf.dexlib.Util; - -import org.jf.util.ExceptionWithContext; -import org.jf.util.Hex; - -import java.io.IOException; -import java.io.Writer; -import java.util.ArrayList; - -/** - * Implementation of {@link AnnotatedOutput} which stores the written data - * into a byte[]. - * - *

    Note: As per the {@link Output} interface, multi-byte - * writes all use little-endian order.

    - */ -public final class ByteArrayAnnotatedOutput - implements AnnotatedOutput { - /** default size for stretchy instances */ - private static final int DEFAULT_SIZE = 1000; - - /** - * whether the instance is stretchy, that is, whether its array - * may be resized to increase capacity - */ - private final boolean stretchy; - - /** non-null; the data itself */ - private byte[] data; - - /** >= 0; current output cursor */ - private int cursor; - - /** whether annotations are to be verbose */ - private boolean verbose; - - /** - * null-ok; list of annotations, or null if this instance - * isn't keeping them - */ - private ArrayList annotations; - - /** >= 40 (if used); the desired maximum annotation width */ - private int annotationWidth; - - /** - * >= 8 (if used); the number of bytes of hex output to use - * in annotations - */ - private int hexCols; - - private int currentIndent = 0; - private int indentAmount = 2; - - /** - * Constructs an instance with a fixed maximum size. Note that the - * given array is the only one that will be used to store data. In - * particular, no reallocation will occur in order to expand the - * capacity of the resulting instance. Also, the constructed - * instance does not keep annotations by default. - * - * @param data non-null; data array to use for output - */ - public ByteArrayAnnotatedOutput(byte[] data) { - this(data, false); - } - - /** - * Constructs a "stretchy" instance. The underlying array may be - * reallocated. The constructed instance does not keep annotations - * by default. - */ - public ByteArrayAnnotatedOutput() { - this(new byte[DEFAULT_SIZE], true); - } - - /** - * Internal constructor. - * - * @param data non-null; data array to use for output - * @param stretchy whether the instance is to be stretchy - */ - private ByteArrayAnnotatedOutput(byte[] data, boolean stretchy) { - if (data == null) { - throw new NullPointerException("data == null"); - } - - this.stretchy = stretchy; - this.data = data; - this.cursor = 0; - this.verbose = false; - this.annotations = null; - this.annotationWidth = 0; - this.hexCols = 0; - } - - /** - * Gets the underlying byte[] of this instance, which - * may be larger than the number of bytes written - * - * @see #toByteArray - * - * @return non-null; the byte[] - */ - public byte[] getArray() { - return data; - } - - /** - * Constructs and returns a new byte[] that contains - * the written contents exactly (that is, with no extra unwritten - * bytes at the end). - * - * @see #getArray - * - * @return non-null; an appropriately-constructed array - */ - public byte[] toByteArray() { - byte[] result = new byte[cursor]; - System.arraycopy(data, 0, result, 0, cursor); - return result; - } - - /** {@inheritDoc} */ - public int getCursor() { - return cursor; - } - - /** {@inheritDoc} */ - public void assertCursor(int expectedCursor) { - if (cursor != expectedCursor) { - throw new ExceptionWithContext("expected cursor " + - expectedCursor + "; actual value: " + cursor); - } - } - - /** {@inheritDoc} */ - public void writeByte(int value) { - int writeAt = cursor; - int end = writeAt + 1; - - if (stretchy) { - ensureCapacity(end); - } else if (end > data.length) { - throwBounds(); - return; - } - - data[writeAt] = (byte) value; - cursor = end; - } - - /** {@inheritDoc} */ - public void writeShort(int value) { - int writeAt = cursor; - int end = writeAt + 2; - - if (stretchy) { - ensureCapacity(end); - } else if (end > data.length) { - throwBounds(); - return; - } - - data[writeAt] = (byte) value; - data[writeAt + 1] = (byte) (value >> 8); - cursor = end; - } - - /** {@inheritDoc} */ - public void writeInt(int value) { - int writeAt = cursor; - int end = writeAt + 4; - - if (stretchy) { - ensureCapacity(end); - } else if (end > data.length) { - throwBounds(); - return; - } - - data[writeAt] = (byte) value; - data[writeAt + 1] = (byte) (value >> 8); - data[writeAt + 2] = (byte) (value >> 16); - data[writeAt + 3] = (byte) (value >> 24); - cursor = end; - } - - /** {@inheritDoc} */ - public void writeLong(long value) { - int writeAt = cursor; - int end = writeAt + 8; - - if (stretchy) { - ensureCapacity(end); - } else if (end > data.length) { - throwBounds(); - return; - } - - int half = (int) value; - data[writeAt] = (byte) half; - data[writeAt + 1] = (byte) (half >> 8); - data[writeAt + 2] = (byte) (half >> 16); - data[writeAt + 3] = (byte) (half >> 24); - - half = (int) (value >> 32); - data[writeAt + 4] = (byte) half; - data[writeAt + 5] = (byte) (half >> 8); - data[writeAt + 6] = (byte) (half >> 16); - data[writeAt + 7] = (byte) (half >> 24); - - cursor = end; - } - - /** {@inheritDoc} */ - public int writeUnsignedLeb128(int value) { - long remaining = (value & 0xFFFFFFFFL) >> 7; - long lValue = value; - int count = 0; - - while (remaining != 0) { - writeByte((int)(lValue & 0x7f) | 0x80); - lValue = remaining; - remaining >>= 7; - count++; - } - - writeByte((int)(lValue & 0x7f)); - return count + 1; - } - - /** {@inheritDoc} */ - public int writeSignedLeb128(int value) { - int remaining = value >> 7; - int count = 0; - boolean hasMore = true; - int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1; - - while (hasMore) { - hasMore = (remaining != end) - || ((remaining & 1) != ((value >> 6) & 1)); - - writeByte((value & 0x7f) | (hasMore ? 0x80 : 0)); - value = remaining; - remaining >>= 7; - count++; - } - - return count; - } - - /** {@inheritDoc} */ - public void write(ByteArray bytes) { - int blen = bytes.size(); - int writeAt = cursor; - int end = writeAt + blen; - - if (stretchy) { - ensureCapacity(end); - } else if (end > data.length) { - throwBounds(); - return; - } - - bytes.getBytes(data, writeAt); - cursor = end; - } - - /** {@inheritDoc} */ - public void write(byte[] bytes, int offset, int length) { - int writeAt = cursor; - int end = writeAt + length; - int bytesEnd = offset + length; - - // twos-complement math trick: ((x < 0) || (y < 0)) <=> ((x|y) < 0) - if (((offset | length | end) < 0) || (bytesEnd > bytes.length)) { - throw new IndexOutOfBoundsException("bytes.length " + - bytes.length + "; " + - offset + "..!" + end); - } - - if (stretchy) { - ensureCapacity(end); - } else if (end > data.length) { - throwBounds(); - return; - } - - System.arraycopy(bytes, offset, data, writeAt, length); - cursor = end; - } - - /** {@inheritDoc} */ - public void write(byte[] bytes) { - write(bytes, 0, bytes.length); - } - - /** {@inheritDoc} */ - public void writeZeroes(int count) { - if (count < 0) { - throw new IllegalArgumentException("count < 0"); - } - - int end = cursor + count; - - if (stretchy) { - ensureCapacity(end); - } else if (end > data.length) { - throwBounds(); - return; - } - - /* - * There is no need to actually write zeroes, since the array is - * already preinitialized with zeroes. - */ - - cursor = end; - } - - /** {@inheritDoc} */ - public void alignTo(int alignment) { - int mask = alignment - 1; - - if ((alignment < 0) || ((mask & alignment) != 0)) { - throw new IllegalArgumentException("bogus alignment"); - } - - int end = (cursor + mask) & ~mask; - - if (stretchy) { - ensureCapacity(end); - } else if (end > data.length) { - throwBounds(); - return; - } - - /* - * There is no need to actually write zeroes, since the array is - * already preinitialized with zeroes. - */ - - cursor = end; - } - - /** {@inheritDoc} */ - public boolean annotates() { - return (annotations != null); - } - - /** {@inheritDoc} */ - public boolean isVerbose() { - return verbose; - } - - /** {@inheritDoc} */ - public void annotate(String msg) { - if (annotations == null) { - return; - } - - endAnnotation(); - annotations.add(new Annotation(cursor, msg, currentIndent)); - } - - public void indent() { - currentIndent++; - } - - public void deindent() { - currentIndent--; - if (currentIndent < 0) { - currentIndent = 0; - } - } - - public void setIndentAmount(int indentAmount) { - this.indentAmount = indentAmount; - } - - /** {@inheritDoc} */ - public void annotate(int amt, String msg) { - if (annotations == null) { - return; - } - - endAnnotation(); - - int asz = annotations.size(); - int lastEnd = (asz == 0) ? 0 : annotations.get(asz - 1).getEnd(); - int startAt; - - if (lastEnd <= cursor) { - startAt = cursor; - } else { - startAt = lastEnd; - } - - annotations.add(new Annotation(startAt, startAt + amt, msg, currentIndent)); - } - - /** {@inheritDoc} */ - public void endAnnotation() { - if (annotations == null) { - return; - } - - int sz = annotations.size(); - - if (sz != 0) { - annotations.get(sz - 1).setEndIfUnset(cursor); - } - } - - /** {@inheritDoc} */ - public int getAnnotationWidth() { - int leftWidth = 8 + (hexCols * 2) + (hexCols / 2); - - return annotationWidth - leftWidth; - } - - /** - * Indicates that this instance should keep annotations. This method may - * be called only once per instance, and only before any data has been - * written to the it. - * - * @param annotationWidth >= 40; the desired maximum annotation width - * @param verbose whether or not to indicate verbose annotations - */ - public void enableAnnotations(int annotationWidth, boolean verbose) { - if ((annotations != null) || (cursor != 0)) { - throw new RuntimeException("cannot enable annotations"); - } - - if (annotationWidth < 40) { - throw new IllegalArgumentException("annotationWidth < 40"); - } - - int hexCols = (((annotationWidth - 7) / 15) + 1) & ~1; - if (hexCols < 6) { - hexCols = 6; - } else if (hexCols > 10) { - hexCols = 10; - } - - this.annotations = new ArrayList(1000); - this.annotationWidth = annotationWidth; - this.hexCols = hexCols; - this.verbose = verbose; - } - - /** - * Finishes up annotation processing. This closes off any open - * annotations and removes annotations that don't refer to written - * data. - */ - public void finishAnnotating() { - // Close off the final annotation, if any. - endAnnotation(); - - // Remove annotations that refer to unwritten data. - if (annotations != null) { - int asz = annotations.size(); - while (asz > 0) { - Annotation last = annotations.get(asz - 1); - if (last.getStart() > cursor) { - annotations.remove(asz - 1); - asz--; - } else if (last.getEnd() > cursor) { - last.setEnd(cursor); - break; - } else { - break; - } - } - } - } - - /** - * Writes the annotated content of this instance to the given writer. - * - * @param out non-null; where to write to - */ - public void writeAnnotationsTo(Writer out) throws IOException { - int width2 = getAnnotationWidth(); - int width1 = annotationWidth - width2 - 1; - - StringBuilder padding = new StringBuilder(); - for (int i=0; i<1000; i++) { - padding.append(' '); - } - - TwoColumnOutput twoc = new TwoColumnOutput(out, width1, width2, "|"); - Writer left = twoc.getLeft(); - Writer right = twoc.getRight(); - int leftAt = 0; // left-hand byte output cursor - int rightAt = 0; // right-hand annotation index - int rightSz = annotations.size(); - - while ((leftAt < cursor) && (rightAt < rightSz)) { - Annotation a = annotations.get(rightAt); - int start = a.getStart(); - int end; - String text; - - if (leftAt < start) { - // This is an area with no annotation. - end = start; - start = leftAt; - text = ""; - } else { - // This is an area with an annotation. - end = a.getEnd(); - text = padding.substring(0, a.getIndent() * this.indentAmount) + a.getText(); - rightAt++; - } - - left.write(Hex.dump(data, start, end - start, start, hexCols, 6)); - right.write(text); - twoc.flush(); - leftAt = end; - } - - if (leftAt < cursor) { - // There is unannotated output at the end. - left.write(Hex.dump(data, leftAt, cursor - leftAt, leftAt, - hexCols, 6)); - } - - while (rightAt < rightSz) { - // There are zero-byte annotations at the end. - right.write(annotations.get(rightAt).getText()); - rightAt++; - } - - twoc.flush(); - } - - /** - * Throws the excpetion for when an attempt is made to write past the - * end of the instance. - */ - private static void throwBounds() { - throw new IndexOutOfBoundsException("attempt to write past the end"); - } - - /** - * Reallocates the underlying array if necessary. Calls to this method - * should be guarded by a test of {@link #stretchy}. - * - * @param desiredSize >= 0; the desired minimum total size of the array - */ - private void ensureCapacity(int desiredSize) { - if (data.length < desiredSize) { - byte[] newData = new byte[desiredSize * 2 + 1000]; - System.arraycopy(data, 0, newData, 0, cursor); - data = newData; - } - } - - /** - * Annotation on output. - */ - private static class Annotation { - /** >= 0; start of annotated range (inclusive) */ - private final int start; - - /** - * >= 0; end of annotated range (exclusive); - * Integer.MAX_VALUE if unclosed - */ - private int end; - - /** non-null; annotation text */ - private final String text; - - private int indent; - - /** - * Constructs an instance. - * - * @param start >= 0; start of annotated range - * @param end >= start; end of annotated range (exclusive) or - * Integer.MAX_VALUE if unclosed - * @param text non-null; annotation text - */ - public Annotation(int start, int end, String text, int indent) { - this.start = start; - this.end = end; - this.text = text; - this.indent = indent; - } - - /** - * Constructs an instance. It is initally unclosed. - * - * @param start >= 0; start of annotated range - * @param text non-null; annotation text - */ - public Annotation(int start, String text, int indent) { - this(start, Integer.MAX_VALUE, text, indent); - } - - /** - * Sets the end as given, but only if the instance is unclosed; - * otherwise, do nothing. - * - * @param end >= start; the end - */ - public void setEndIfUnset(int end) { - if (this.end == Integer.MAX_VALUE) { - this.end = end; - } - } - - /** - * Sets the end as given. - * - * @param end >= start; the end - */ - public void setEnd(int end) { - this.end = end; - } - - /** - * Gets the start. - * - * @return the start - */ - public int getStart() { - return start; - } - - /** - * Gets the end. - * - * @return the end - */ - public int getEnd() { - return end; - } - - /** - * Gets the text. - * - * @return non-null; the text - */ - public String getText() { - return text; - } - - public int getIndent() { - return indent; - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ByteArrayInput.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ByteArrayInput.java deleted file mode 100644 index 122ccc38..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ByteArrayInput.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * 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. - */ - -/* - * As per the Apache license requirements, this file has been modified - * from its original state. - * - * Such modifications are Copyright (C) 2010 Ben Gruver, and are released - * under the original license - */ - -package org.jf.dexlib.Util; - -import org.jf.util.AlignmentUtils; -import org.jf.util.ExceptionWithContext; -import org.jf.util.Utf8Utils; - -/** - * Implementation of {@link Input} which reads the data from a - * byte[] instance. - * - *

    Note: As per the {@link Input } interface, multi-byte - * reads all use little-endian order.

    - */ -public class ByteArrayInput - implements Input { - - /** non-null; the data itself */ - private byte[] data; - - /** >= 0; current read cursor */ - private int cursor; - - /** - * Constructs an instance with the given data - * - * @param data non-null; data array to use for input - */ - public ByteArrayInput(byte[] data) { - if (data == null) { - throw new NullPointerException("data == null"); - } - - this.data = data; - this.cursor = 0; - } - - /** - * Gets the underlying byte[] of this instance - * - * @return non-null; the byte[] - */ - public byte[] getArray() { - return data; - } - - /** {@inheritDoc} */ - public int getCursor() { - return cursor; - } - - /** {@inheritDoc} */ - public void setCursor(int cursor) { - if (cursor < 0 || cursor >= data.length) - throw new IndexOutOfBoundsException("The provided cursor value " + - "is not within the bounds of this instance's data array"); - this.cursor = cursor; - } - - /** {@inheritDoc} */ - public void assertCursor(int expectedCursor) { - if (cursor != expectedCursor) { - throw new ExceptionWithContext("expected cursor " + - expectedCursor + "; actual value: " + cursor); - } - } - - /** {@inheritDoc} */ - public byte readByte() { - return data[cursor++]; - } - - /** {@inheritDoc} */ - public int readShort() { - int readAt = cursor; - int result = ((data[readAt++] & 0xff) + - ((data[readAt++] & 0xff) << 8)); - cursor = readAt; - return result; - } - - /** {@inheritDoc} */ - public int readInt() { - int readAt = cursor; - int result = (data[readAt++] & 0xff) + - ((data[readAt++] & 0xff) << 8) + - ((data[readAt++] & 0xff) << 16) + - ((data[readAt++] & 0xff) << 24); - cursor = readAt; - return result; - } - - /** {@inheritDoc} */ - public long readLong() { - int readAt = cursor; - - long result = (data[readAt++] & 0xffL) | - ((data[readAt++] & 0xffL) << 8) | - ((data[readAt++] & 0xffL) << 16) | - ((data[readAt++] & 0xffL) << 24) | - ((data[readAt++] & 0xffL) << 32) | - ((data[readAt++] & 0xffL) << 40) | - ((data[readAt++] & 0xffL) << 48) | - ((data[readAt++] & 0xffL) << 56); - cursor = readAt; - return result; - } - - - /** {@inheritDoc} */ - public int readUnsignedOrSignedLeb128() { - int end = cursor; - int currentByteValue; - int result; - - result = data[end++] & 0xff; - if (result > 0x7f) { - currentByteValue = data[end++] & 0xff; - result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7); - if (currentByteValue > 0x7f) { - currentByteValue = data[end++] & 0xff; - result |= (currentByteValue & 0x7f) << 14; - if (currentByteValue > 0x7f) { - currentByteValue = data[end++] & 0xff; - result |= (currentByteValue & 0x7f) << 21; - if (currentByteValue > 0x7f) { - currentByteValue = data[end++] & 0xff; - if (currentByteValue > 0x0f) { - throwInvalidLeb(); - } - result |= currentByteValue << 28; - } - } - } - } else { - cursor = end; - return result; - } - - cursor = end; - - //If the last byte is 0, then this was an unsigned value (incorrectly) written in a signed format - //The caller wants to know if this is the case, so we'll return the negated value instead - //If there was only a single byte that had a value of 0, then we would have returned in the above - //"else" - if (data[end-1] == 0) { - return ~result; - } - return result; - } - - - - - /** {@inheritDoc} */ - public int readUnsignedLeb128() { - int end = cursor; - int currentByteValue; - int result; - - result = data[end++] & 0xff; - if (result > 0x7f) { - currentByteValue = data[end++] & 0xff; - result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7); - if (currentByteValue > 0x7f) { - currentByteValue = data[end++] & 0xff; - result |= (currentByteValue & 0x7f) << 14; - if (currentByteValue > 0x7f) { - currentByteValue = data[end++] & 0xff; - result |= (currentByteValue & 0x7f) << 21; - if (currentByteValue > 0x7f) { - currentByteValue = data[end++] & 0xff; - if (currentByteValue > 0x0f) { - throwInvalidLeb(); - } - result |= currentByteValue << 28; - } - } - } - } - - cursor = end; - return result; - } - - /** {@inheritDoc} */ - public int readSignedLeb128() { - int end = cursor; - int currentByteValue; - int result; - - result = data[end++] & 0xff; - if (result <= 0x7f) { - result = (result << 25) >> 25; - } else { - currentByteValue = data[end++] & 0xff; - result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7); - if (currentByteValue <= 0x7f) { - result = (result << 18) >> 18; - } else { - currentByteValue = data[end++] & 0xff; - result |= (currentByteValue & 0x7f) << 14; - if (currentByteValue <= 0x7f) { - result = (result << 11) >> 11; - } else { - currentByteValue = data[end++] & 0xff; - result |= (currentByteValue & 0x7f) << 21; - if (currentByteValue <= 0x7f) { - result = (result << 4) >> 4; - } else { - currentByteValue = data[end++] & 0xff; - if (currentByteValue > 0x0f) { - throwInvalidLeb(); - } - result |= currentByteValue << 28; - } - } - } - } - - cursor = end; - return result; - } - - /** {@inheritDoc} */ - public void read(byte[] bytes, int offset, int length) { - int end = cursor + length; - - if (end > data.length) { - throwBounds(); - } - - System.arraycopy(data, cursor, bytes, offset, length); - cursor = end; - } - - /** {@inheritDoc} */ - public void read(byte[] bytes) { - int length = bytes.length; - int end = cursor + length; - - if (end > data.length) { - throwBounds(); - } - - System.arraycopy(data, cursor, bytes, 0, length); - cursor = end; - } - - /** {@inheritDoc} */ - public byte[] readBytes(int length) { - int end = cursor + length; - - if (end > data.length) { - throwBounds(); - } - - byte[] result = new byte[length]; - System.arraycopy(data, cursor, result, 0, length); - cursor = end; - return result; - } - - /** {@inheritDoc} */ - public String realNullTerminatedUtf8String() { - int startPosition = cursor; - while (data[cursor] != 0) { - cursor++; - } - int byteCount = cursor - startPosition; - - //skip the terminating null - cursor++; - - return Utf8Utils.utf8BytesToString(data, startPosition, byteCount); - } - - /** {@inheritDoc} */ - public void skipBytes(int count) { - cursor += count; - } - - /** {@inheritDoc} */ - public void alignTo(int alignment) { - cursor = AlignmentUtils.alignOffset(cursor, alignment); - } - - /** - * Throws the excpetion for when an attempt is made to read past the - * end of the instance. - */ - private static void throwBounds() { - throw new IndexOutOfBoundsException("attempt to read past the end"); - } - - /** - * Throws the exception for when an invalid LEB128 value is encountered - */ - private static void throwInvalidLeb() { - throw new RuntimeException("invalid LEB128 integer encountered"); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ByteArrayOutput.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ByteArrayOutput.java deleted file mode 100644 index 67bc427b..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ByteArrayOutput.java +++ /dev/null @@ -1,581 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * 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. - */ - -/* - * As per the Apache license requirements, this file has been modified - * from its original state. - * - * Such modifications are Copyright (C) 2010 Ben Gruver, and are released - * under the original license - */ - -package org.jf.dexlib.Util; - -import org.jf.util.AlignmentUtils; -import org.jf.util.ExceptionWithContext; - -import java.util.ArrayList; - -/** - * Implementation of {@link AnnotatedOutput} which stores the written data - * into a byte[]. - * - *

    Note: As per the {@link Output} interface, multi-byte - * writes all use little-endian order.

    - */ -public final class ByteArrayOutput implements Output -{ - /** default size for stretchy instances */ - private static final int DEFAULT_SIZE = 1000; - - /** - * whether the instance is stretchy, that is, whether its array - * may be resized to increase capacity - */ - private final boolean stretchy; - - /** non-null; the data itself */ - private byte[] data; - - /** >= 0; current output cursor */ - private int cursor; - - /** whether annotations are to be verbose */ - private boolean verbose; - - /** - * null-ok; list of annotations, or null if this instance - * isn't keeping them - */ - private ArrayList annotations; - - /** >= 40 (if used); the desired maximum annotation width */ - private int annotationWidth; - - /** - * >= 8 (if used); the number of bytes of hex output to use - * in annotations - */ - private int hexCols; - - /** - * Constructs an instance with a fixed maximum size. Note that the - * given array is the only one that will be used to store data. In - * particular, no reallocation will occur in order to expand the - * capacity of the resulting instance. Also, the constructed - * instance does not keep annotations by default. - * - * @param data non-null; data array to use for output - */ - public ByteArrayOutput(byte[] data) { - this(data, false); - } - - /** - * Constructs a "stretchy" instance. The underlying array may be - * reallocated. The constructed instance does not keep annotations - * by default. - */ - public ByteArrayOutput() { - this(new byte[DEFAULT_SIZE], true); - } - - /** - * Internal constructor. - * - * @param data non-null; data array to use for output - * @param stretchy whether the instance is to be stretchy - */ - private ByteArrayOutput(byte[] data, boolean stretchy) { - if (data == null) { - throw new NullPointerException("data == null"); - } - - this.stretchy = stretchy; - this.data = data; - this.cursor = 0; - this.verbose = false; - this.annotations = null; - this.annotationWidth = 0; - this.hexCols = 0; - } - - /** - * Gets the underlying byte[] of this instance, which - * may be larger than the number of bytes written - * - * @see #toByteArray - * - * @return non-null; the byte[] - */ - public byte[] getArray() { - return data; - } - - /** - * Constructs and returns a new byte[] that contains - * the written contents exactly (that is, with no extra unwritten - * bytes at the end). - * - * @see #getArray - * - * @return non-null; an appropriately-constructed array - */ - public byte[] toByteArray() { - byte[] result = new byte[cursor]; - System.arraycopy(data, 0, result, 0, cursor); - return result; - } - - /** {@inheritDoc} */ - public int getCursor() { - return cursor; - } - - /** {@inheritDoc} */ - public void assertCursor(int expectedCursor) { - if (cursor != expectedCursor) { - throw new ExceptionWithContext("expected cursor " + - expectedCursor + "; actual value: " + cursor); - } - } - - /** {@inheritDoc} */ - public void writeByte(int value) { - int writeAt = cursor; - int end = writeAt + 1; - - if (stretchy) { - ensureCapacity(end); - } else if (end > data.length) { - throwBounds(); - return; - } - - data[writeAt] = (byte) value; - cursor = end; - } - - /** {@inheritDoc} */ - public void writeShort(int value) { - int writeAt = cursor; - int end = writeAt + 2; - - if (stretchy) { - ensureCapacity(end); - } else if (end > data.length) { - throwBounds(); - return; - } - - data[writeAt] = (byte) value; - data[writeAt + 1] = (byte) (value >> 8); - cursor = end; - } - - /** {@inheritDoc} */ - public void writeInt(int value) { - int writeAt = cursor; - int end = writeAt + 4; - - if (stretchy) { - ensureCapacity(end); - } else if (end > data.length) { - throwBounds(); - return; - } - - data[writeAt] = (byte) value; - data[writeAt + 1] = (byte) (value >> 8); - data[writeAt + 2] = (byte) (value >> 16); - data[writeAt + 3] = (byte) (value >> 24); - cursor = end; - } - - /** {@inheritDoc} */ - public void writeLong(long value) { - int writeAt = cursor; - int end = writeAt + 8; - - if (stretchy) { - ensureCapacity(end); - } else if (end > data.length) { - throwBounds(); - return; - } - - int half = (int) value; - data[writeAt] = (byte) half; - data[writeAt + 1] = (byte) (half >> 8); - data[writeAt + 2] = (byte) (half >> 16); - data[writeAt + 3] = (byte) (half >> 24); - - half = (int) (value >> 32); - data[writeAt + 4] = (byte) half; - data[writeAt + 5] = (byte) (half >> 8); - data[writeAt + 6] = (byte) (half >> 16); - data[writeAt + 7] = (byte) (half >> 24); - - cursor = end; - } - - /** {@inheritDoc} */ - public int writeUnsignedLeb128(int value) { - int remaining = value >>> 7; - int count = 0; - - while (remaining != 0) { - writeByte((value & 0x7f) | 0x80); - value = remaining; - remaining >>>= 7; - count++; - } - - writeByte(value & 0x7f); - return count + 1; - } - - /** {@inheritDoc} */ - public int writeSignedLeb128(int value) { - int remaining = value >> 7; - int count = 0; - boolean hasMore = true; - int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1; - - while (hasMore) { - hasMore = (remaining != end) - || ((remaining & 1) != ((value >> 6) & 1)); - - writeByte((value & 0x7f) | (hasMore ? 0x80 : 0)); - value = remaining; - remaining >>= 7; - count++; - } - - return count; - } - - /** {@inheritDoc} */ - public void write(ByteArray bytes) { - int blen = bytes.size(); - int writeAt = cursor; - int end = writeAt + blen; - - if (stretchy) { - ensureCapacity(end); - } else if (end > data.length) { - throwBounds(); - return; - } - - bytes.getBytes(data, writeAt); - cursor = end; - } - - /** {@inheritDoc} */ - public void write(byte[] bytes, int offset, int length) { - int writeAt = cursor; - int end = writeAt + length; - int bytesEnd = offset + length; - - // twos-complement math trick: ((x < 0) || (y < 0)) <=> ((x|y) < 0) - if (((offset | length | end) < 0) || (bytesEnd > bytes.length)) { - throw new IndexOutOfBoundsException("bytes.length " + - bytes.length + "; " + - offset + "..!" + end); - } - - if (stretchy) { - ensureCapacity(end); - } else if (end > data.length) { - throwBounds(); - return; - } - - System.arraycopy(bytes, offset, data, writeAt, length); - cursor = end; - } - - /** {@inheritDoc} */ - public void write(byte[] bytes) { - write(bytes, 0, bytes.length); - } - - /** {@inheritDoc} */ - public void writeZeroes(int count) { - if (count < 0) { - throw new IllegalArgumentException("count < 0"); - } - - int end = cursor + count; - - if (stretchy) { - ensureCapacity(end); - } else if (end > data.length) { - throwBounds(); - return; - } - - /* - * There is no need to actually write zeroes, since the array is - * already preinitialized with zeroes. - */ - - cursor = end; - } - - /** {@inheritDoc} */ - public void alignTo(int alignment) { - int end = AlignmentUtils.alignOffset(cursor, alignment); - - if (stretchy) { - ensureCapacity(end); - } else if (end > data.length) { - throwBounds(); - return; - } - cursor = end; - } - - /** {@inheritDoc} */ - public boolean annotates() { - return (annotations != null); - } - - /** {@inheritDoc} */ - public boolean isVerbose() { - return verbose; - } - - /** {@inheritDoc} */ - public void annotate(String msg) { - if (annotations == null) { - return; - } - - endAnnotation(); - annotations.add(new Annotation(cursor, msg)); - } - - /** {@inheritDoc} */ - public void annotate(int amt, String msg) { - if (annotations == null) { - return; - } - - endAnnotation(); - - int asz = annotations.size(); - int lastEnd = (asz == 0) ? 0 : annotations.get(asz - 1).getEnd(); - int startAt; - - if (lastEnd <= cursor) { - startAt = cursor; - } else { - startAt = lastEnd; - } - - annotations.add(new Annotation(startAt, startAt + amt, msg)); - } - - /** {@inheritDoc} */ - public void endAnnotation() { - if (annotations == null) { - return; - } - - int sz = annotations.size(); - - if (sz != 0) { - annotations.get(sz - 1).setEndIfUnset(cursor); - } - } - - /** {@inheritDoc} */ - public int getAnnotationWidth() { - int leftWidth = 8 + (hexCols * 2) + (hexCols / 2); - - return annotationWidth - leftWidth; - } - - /** - * Indicates that this instance should keep annotations. This method may - * be called only once per instance, and only before any data has been - * written to the it. - * - * @param annotationWidth >= 40; the desired maximum annotation width - * @param verbose whether or not to indicate verbose annotations - */ - public void enableAnnotations(int annotationWidth, boolean verbose) { - if ((annotations != null) || (cursor != 0)) { - throw new RuntimeException("cannot enable annotations"); - } - - if (annotationWidth < 40) { - throw new IllegalArgumentException("annotationWidth < 40"); - } - - int hexCols = (((annotationWidth - 7) / 15) + 1) & ~1; - if (hexCols < 6) { - hexCols = 6; - } else if (hexCols > 10) { - hexCols = 10; - } - - this.annotations = new ArrayList(1000); - this.annotationWidth = annotationWidth; - this.hexCols = hexCols; - this.verbose = verbose; - } - - /** - * Finishes up annotation processing. This closes off any open - * annotations and removes annotations that don't refer to written - * data. - */ - public void finishAnnotating() { - // Close off the final annotation, if any. - endAnnotation(); - - // Remove annotations that refer to unwritten data. - if (annotations != null) { - int asz = annotations.size(); - while (asz > 0) { - Annotation last = annotations.get(asz - 1); - if (last.getStart() > cursor) { - annotations.remove(asz - 1); - asz--; - } else if (last.getEnd() > cursor) { - last.setEnd(cursor); - break; - } else { - break; - } - } - } - } - - /** - * Throws the excpetion for when an attempt is made to write past the - * end of the instance. - */ - private static void throwBounds() { - throw new IndexOutOfBoundsException("attempt to write past the end"); - } - - /** - * Reallocates the underlying array if necessary. Calls to this method - * should be guarded by a test of {@link #stretchy}. - * - * @param desiredSize >= 0; the desired minimum total size of the array - */ - private void ensureCapacity(int desiredSize) { - if (data.length < desiredSize) { - byte[] newData = new byte[desiredSize * 2 + 1000]; - System.arraycopy(data, 0, newData, 0, cursor); - data = newData; - } - } - - /** - * Annotation on output. - */ - private static class Annotation { - /** >= 0; start of annotated range (inclusive) */ - private final int start; - - /** - * >= 0; end of annotated range (exclusive); - * Integer.MAX_VALUE if unclosed - */ - private int end; - - /** non-null; annotation text */ - private final String text; - - /** - * Constructs an instance. - * - * @param start >= 0; start of annotated range - * @param end >= start; end of annotated range (exclusive) or - * Integer.MAX_VALUE if unclosed - * @param text non-null; annotation text - */ - public Annotation(int start, int end, String text) { - this.start = start; - this.end = end; - this.text = text; - } - - /** - * Constructs an instance. It is initally unclosed. - * - * @param start >= 0; start of annotated range - * @param text non-null; annotation text - */ - public Annotation(int start, String text) { - this(start, Integer.MAX_VALUE, text); - } - - /** - * Sets the end as given, but only if the instance is unclosed; - * otherwise, do nothing. - * - * @param end >= start; the end - */ - public void setEndIfUnset(int end) { - if (this.end == Integer.MAX_VALUE) { - this.end = end; - } - } - - /** - * Sets the end as given. - * - * @param end >= start; the end - */ - public void setEnd(int end) { - this.end = end; - } - - /** - * Gets the start. - * - * @return the start - */ - public int getStart() { - return start; - } - - /** - * Gets the end. - * - * @return the end - */ - public int getEnd() { - return end; - } - - /** - * Gets the text. - * - * @return non-null; the text - */ - public String getText() { - return text; - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/DebugInfoBuilder.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/DebugInfoBuilder.java deleted file mode 100644 index 2bfd8cd6..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/DebugInfoBuilder.java +++ /dev/null @@ -1,451 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Util; - -import org.jf.dexlib.*; - -import java.util.ArrayList; -import java.util.List; - -/** - * This class is intended to provide an easy to use container to build up a method's debug info. You can easily add - * an "event" at a specific address, where an event is something like a line number, start/end local, etc. - * The events must be added such that the code addresses increase monotonically. This matches how a parser would - * generally behave, and is intended to increase performance. - */ -public class DebugInfoBuilder -{ - private static final int LINE_BASE = -4; - private static final int LINE_RANGE = 15; - private static final int FIRST_SPECIAL = 0x0a; - - private int lineStart = 0; - private ArrayList parameterNames = new ArrayList(); - private ArrayList events = new ArrayList(); - private int lastAddress = 0; - - private boolean hasData; - - private int currentAddress; - private int currentLine; - - public DebugInfoBuilder() { - } - - private void checkAddress(int address) { - if (lastAddress > address) { - throw new RuntimeException("Cannot add an event with an address before the address of the prior event"); - } - } - - public void addParameterName(String parameterName) { - if (parameterName != null) { - hasData = true; - } - - parameterNames.add(parameterName); - } - - public void addLine(int address, int line) { - hasData = true; - - checkAddress(address); - - if (lineStart == 0) { - lineStart = line; - } - - events.add(new LineEvent(address, line)); - } - - public void addLocal(int address, int registerNumber, String localName, String localType) { - hasData = true; - - checkAddress(address); - - events.add(new StartLocalEvent(address, registerNumber, localName, localType)); - } - - public void addLocalExtended(int address, int registerNumber, String localName, String localType, - String signature) { - hasData = true; - - checkAddress(address); - - events.add(new StartLocalExtendedEvent(address, registerNumber, localName, localType, signature)); - } - - public void addEndLocal(int address, int registerNumber) { - hasData = true; - - checkAddress(address); - - events.add(new EndLocalEvent(address, registerNumber)); - } - - public void addRestartLocal(int address, int registerNumber) { - hasData = true; - - checkAddress(address); - - events.add(new RestartLocalEvent(address, registerNumber)); - } - - public void addPrologue(int address) { - hasData = true; - - checkAddress(address); - - events.add(new PrologueEvent(address)); - } - - public void addEpilogue(int address) { - hasData = true; - - checkAddress(address); - - events.add(new EpilogueEvent(address)); - } - - public void addSetFile(int address, String fileName) { - hasData = true; - - checkAddress(address); - - events.add(new SetFileEvent(address, fileName)); - } - - public int getParameterNameCount() { - return parameterNames.size(); - } - - public DebugInfoItem encodeDebugInfo(DexFile dexFile) { - if (!hasData) { - return null; - } - - ByteArrayOutput out = new ByteArrayOutput(); - StringIdItem[] parameterNamesArray = new StringIdItem[parameterNames.size()]; - ArrayList referencedItems = new ArrayList(); - - if (lineStart == 0) { - lineStart = 1; - } - - currentLine = lineStart; - - for (Event event: events) { - event.emit(dexFile, out, referencedItems); - } - emitEndSequence(out); - - int index = 0; - for (String parameterName: parameterNames) { - if (parameterName == null) { - parameterNamesArray[index++] = null; - } else { - parameterNamesArray[index++] = StringIdItem.internStringIdItem(dexFile, parameterName); - } - } - - Item[] referencedItemsArray = new Item[referencedItems.size()]; - referencedItems.toArray(referencedItemsArray); - return DebugInfoItem.internDebugInfoItem(dexFile, lineStart, parameterNamesArray, out.toByteArray(), - referencedItemsArray); - } - - public static byte calculateSpecialOpcode(int lineDelta, int addressDelta) { - return (byte)(FIRST_SPECIAL + (addressDelta * LINE_RANGE) + (lineDelta - LINE_BASE)); - } - - private interface Event - { - int getAddress(); - void emit(DexFile dexFile, Output out, List referencedItems); - } - - private void emitEndSequence(Output out) { - out.writeByte(0); - } - - private void emitAdvancePC(Output out, int address) { - int addressDelta = address-currentAddress; - - if (addressDelta > 0) { - out.writeByte(1); - out.writeUnsignedLeb128(addressDelta); - currentAddress = address; - } - } - - private void emitAdvanceLine(Output out, int lineDelta) { - out.writeByte(2); - out.writeSignedLeb128(lineDelta); - } - - private void emitStartLocal(Output out, int registerNum) { - out.writeByte(3); - out.writeUnsignedLeb128(registerNum); - out.writeByte(1); - out.writeByte(1); - } - - private void emitStartLocalExtended(Output out, int registerNum) { - out.writeByte(4); - out.writeUnsignedLeb128(registerNum); - out.writeByte(1); - out.writeByte(1); - out.writeByte(1); - } - - private void emitEndLocal(Output out, int registerNum) { - out.writeByte(5); - out.writeUnsignedLeb128(registerNum); - } - - private void emitRestartLocal(Output out, int registerNum) { - out.writeByte(6); - out.writeUnsignedLeb128(registerNum); - } - - private void emitSetPrologueEnd(Output out) { - out.writeByte(7); - } - - private void emitSetEpilogueBegin(Output out) { - out.writeByte(8); - } - - private void emitSetFile(Output out) { - out.writeByte(9); - out.writeByte(1); - } - - private void emitSpecialOpcode(Output out, byte opcode) { - out.writeByte(opcode); - } - - private class LineEvent implements Event - { - private final int address; - private final int line; - - public LineEvent(int address, int line) { - this.address = address; - this.line = line; - } - - public int getAddress() { - return address; - } - - public void emit(DexFile dexFile, Output out, List referencedItems) { - int lineDelta = line - currentLine; - int addressDelta = address - currentAddress; - - if (lineDelta < -4 || lineDelta > 10) { - emitAdvanceLine(out, lineDelta); - lineDelta = 0; - } - if (lineDelta < 2 && addressDelta > 16 || lineDelta > 1 && addressDelta > 15) { - emitAdvancePC(out, address); - addressDelta = 0; - } - - //TODO: need to handle the case when the line delta is larger than a signed int - emitSpecialOpcode(out, calculateSpecialOpcode(lineDelta, addressDelta)); - - currentAddress = address; - currentLine = line; - } - } - - private class StartLocalEvent implements Event - { - private final int address; - private final int registerNum; - private final String localName; - private final String localType; - - public StartLocalEvent(int address, int registerNum, String localName, String localType) { - this.address = address; - this.registerNum = registerNum; - this.localName = localName; - this.localType = localType; - } - - public int getAddress() { - return address; - } - - public void emit(DexFile dexFile, Output out, List referencedItems) { - emitAdvancePC(out, address); - emitStartLocal(out, registerNum); - referencedItems.add(localName==null?null:StringIdItem.internStringIdItem(dexFile, localName)); - referencedItems.add(localType==null?null:TypeIdItem.internTypeIdItem(dexFile, - StringIdItem.internStringIdItem(dexFile, localType))); - } - } - - private class StartLocalExtendedEvent implements Event - { - private final int address; - private final int registerNum; - private final String localName; - private final String localType; - private final String signature; - - public StartLocalExtendedEvent(int address, int registerNum, String localName, String localType, - String signature) { - this.address = address; - this.registerNum = registerNum; - this.localName = localName; - this.localType = localType; - this.signature = signature; - } - - public int getAddress() { - return address; - } - - public void emit(DexFile dexFile, Output out, List referencedItems) { - emitAdvancePC(out, address); - emitStartLocalExtended(out, registerNum); - if (localName != null) { - referencedItems.add(StringIdItem.internStringIdItem(dexFile, localName)); - } - if (localType != null) { - referencedItems.add(TypeIdItem.internTypeIdItem(dexFile, - StringIdItem.internStringIdItem(dexFile, localType))); - } - if (signature != null) { - referencedItems.add(StringIdItem.internStringIdItem(dexFile, signature)); - } - } - } - - private class EndLocalEvent implements Event - { - private final int address; - private final int registerNum; - - public EndLocalEvent(int address, int registerNum) { - this.address = address; - this.registerNum = registerNum; - } - - public int getAddress() { - return address; - } - - public void emit(DexFile dexFile, Output out, List referencedItems) { - emitAdvancePC(out, address); - emitEndLocal(out, registerNum); - } - } - - private class RestartLocalEvent implements Event - { - private final int address; - private final int registerNum; - - public RestartLocalEvent(int address, int registerNum) { - this.address = address; - this.registerNum = registerNum; - } - - public int getAddress() { - return address; - } - - public void emit(DexFile dexFile, Output out, List referencedItems) { - emitAdvancePC(out, address); - emitRestartLocal(out, registerNum); - } - } - - private class PrologueEvent implements Event - { - private final int address; - - public PrologueEvent(int address) { - this.address = address; - } - - public int getAddress() { - return address; - } - - public void emit(DexFile dexFile, Output out, List referencedItems) { - emitAdvancePC(out, address); - emitSetPrologueEnd(out); - } - } - - private class EpilogueEvent implements Event - { - private final int address; - - public EpilogueEvent(int address) { - this.address = address; - } - - public int getAddress() { - return address; - } - - public void emit(DexFile dexFile, Output out, List referencedItems) { - emitAdvancePC(out, address); - emitSetEpilogueBegin(out); - } - } - - private class SetFileEvent implements Event - { - private final int address; - private final String fileName; - - public SetFileEvent(int address, String fileName) { - this.address = address; - this.fileName = fileName; - } - - public int getAddress() { - return address; - } - - public void emit(DexFile dexFile, Output out, List referencedItems) { - emitAdvancePC(out, address); - emitSetFile(out); - if (fileName != null) { - referencedItems.add(StringIdItem.internStringIdItem(dexFile, fileName)); - } - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/EncodedValueUtils.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/EncodedValueUtils.java deleted file mode 100644 index 91f14072..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/EncodedValueUtils.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Util; - -public class EncodedValueUtils { - public static byte getRequiredBytesForSignedIntegralValue(long value) { - /* - * Figure out how many bits are needed to represent the value, - * including a sign bit: The bit count is subtracted from 65 - * and not 64 to account for the sign bit. The xor operation - * has the effect of leaving non-negative values alone and - * unary complementing negative values (so that a leading zero - * count always returns a useful number for our present - * purpose). - */ - int requiredBits = - 65 - Long.numberOfLeadingZeros(value ^ (value >> 63)); - - // Round up the requiredBits to a number of bytes. - return (byte)((requiredBits + 0x07) >> 3); - } - - public static long decodeSignedIntegralValue(byte[] bytes) { - long value = 0; - for (int i = 0; i < bytes.length; i++) { - value |= (((long)(bytes[i] & 0xFF)) << (i * 8)); - } - - int shift = (8 - bytes.length) * 8; - return value << shift >> shift; - } - - public static byte[] encodeSignedIntegralValue(long value) { - int requiredBytes = getRequiredBytesForSignedIntegralValue(value); - - byte[] bytes = new byte[requiredBytes]; - - for (int i = 0; i < requiredBytes; i++) { - bytes[i] = (byte) value; - value >>= 8; - } - return bytes; - } - - - - - - public static byte getRequiredBytesForUnsignedIntegralValue(long value) { - // Figure out how many bits are needed to represent the value. - int requiredBits = 64 - Long.numberOfLeadingZeros(value); - if (requiredBits == 0) { - requiredBits = 1; - } - - // Round up the requiredBits to a number of bytes. - return (byte)((requiredBits + 0x07) >> 3); - } - - public static long decodeUnsignedIntegralValue(byte[] bytes) { - long value = 0; - for (int i = 0; i < bytes.length; i++) { - value |= (((long)(bytes[i] & 0xFF)) << i * 8); - } - return value; - } - - public static byte[] encodeUnsignedIntegralValue(long value) { - int requiredBytes = getRequiredBytesForUnsignedIntegralValue(value); - - byte[] bytes = new byte[requiredBytes]; - - for (int i = 0; i < requiredBytes; i++) { - bytes[i] = (byte) value; - value >>= 8; - } - return bytes; - } - - - - - - public static int getRequiredBytesForRightZeroExtendedValue(long value) { - // Figure out how many bits are needed to represent the value. - int requiredBits = 64 - Long.numberOfTrailingZeros(value); - if (requiredBits == 0) { - requiredBits = 1; - } - - // Round up the requiredBits to a number of bytes. - return (requiredBits + 0x07) >> 3; - } - - public static long decodeRightZeroExtendedValue(byte[] bytes) { - long value = 0; - for (int i = 0; i < bytes.length; i++) { - value |= (((long)(bytes[i] & 0xFF)) << (i * 8)); - } - return value << (8 - bytes.length) * 8; - } - - public static byte[] encodeRightZeroExtendedValue(long value) { - int requiredBytes = getRequiredBytesForRightZeroExtendedValue(value); - - // Scootch the first bits to be written down to the low-order bits. - value >>= 64 - (requiredBytes * 8); - - byte[] bytes = new byte[requiredBytes]; - - for(int i = 0; i < requiredBytes; i++) { - bytes[i] = (byte)value; - value >>= 8; - } - return bytes; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/FileUtils.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/FileUtils.java deleted file mode 100644 index d8cd9bc8..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/FileUtils.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * 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. - */ - -/* - * As per the Apache license requirements, this file has been modified - * from its original state. - * - * Such modifications are Copyright (C) 2010 Ben Gruver, and are released - * under the original license - */ - -package org.jf.dexlib.Util; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * File I/O utilities. - */ -public final class FileUtils { - /** - * This class is uninstantiable. - */ - private FileUtils() { - // This space intentionally left blank. - } - - /** - * Reads the named file, translating {@link IOException} to a - * {@link RuntimeException} of some sort. - * - * @param fileName non-null; name of the file to read - * @return non-null; contents of the file - */ - public static byte[] readFile(String fileName) - throws IOException { - File file = new File(fileName); - return readFile(file); - } - - /** - * Reads the given file, translating {@link IOException} to a - * {@link RuntimeException} of some sort. - * - * @param file non-null; the file to read - * @return non-null; contents of the file - */ - public static byte[] readFile(File file) - throws IOException { - return readFile(file, 0, -1); - } - - /** - * Reads the specified block from the given file, translating - * {@link IOException} to a {@link RuntimeException} of some sort. - * - * @param file non-null; the file to read - * @param offset the offset to begin reading - * @param length the number of bytes to read, or -1 to read to the - * end of the file - * @return non-null; contents of the file - */ - public static byte[] readFile(File file, int offset, int length) - throws IOException { - if (!file.exists()) { - throw new RuntimeException(file + ": file not found"); - } - - if (!file.isFile()) { - throw new RuntimeException(file + ": not a file"); - } - - if (!file.canRead()) { - throw new RuntimeException(file + ": file not readable"); - } - - long longLength = file.length(); - int fileLength = (int) longLength; - if (fileLength != longLength) { - throw new RuntimeException(file + ": file too long"); - } - - if (length == -1) { - length = fileLength - offset; - } - - if (offset + length > fileLength) { - throw new RuntimeException(file + ": file too short"); - } - - FileInputStream in = new FileInputStream(file); - - int at = offset; - while(at > 0) { - long amt = in.skip(at); - if (amt == -1) { - throw new RuntimeException(file + ": unexpected EOF"); - } - at -= amt; - } - - byte[] result = readStream(in, length); - - in.close(); - - return result; - } - - public static byte[] readStream(InputStream in, int length) - throws IOException { - byte[] result = new byte[length]; - int at=0; - - while (length > 0) { - int amt = in.read(result, at, length); - if (amt == -1) { - throw new RuntimeException("unexpected EOF"); - } - at += amt; - length -= amt; - } - - return result; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/IndentingWriter.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/IndentingWriter.java deleted file mode 100644 index e8b85e09..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/IndentingWriter.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * 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. - */ - -/* - * As per the Apache license requirements, this file has been modified - * from its original state. - * - * Such modifications are Copyright (C) 2010 Ben Gruver, and are released - * under the original license - */ - -package org.jf.dexlib.Util; - -import java.io.FilterWriter; -import java.io.IOException; -import java.io.Writer; - -/** - * Writer that wraps another writer and passes width-limited and - * optionally-prefixed output to its subordinate. When lines are - * wrapped they are automatically indented based on the start of the - * line. - */ -public final class IndentingWriter extends FilterWriter { - /** null-ok; optional prefix for every line */ - private final String prefix; - - /** > 0; the maximum output width */ - private final int width; - - /** > 0; the maximum indent */ - private final int maxIndent; - - /** >= 0; current output column (zero-based) */ - private int column; - - /** whether indent spaces are currently being collected */ - private boolean collectingIndent; - - /** >= 0; current indent amount */ - private int indent; - - /** - * Constructs an instance. - * - * @param out non-null; writer to send final output to - * @param width >= 0; the maximum output width (not including - * prefix), or 0 for no maximum - * @param prefix non-null; the prefix for each line - */ - public IndentingWriter(Writer out, int width, String prefix) { - super(out); - - if (out == null) { - throw new NullPointerException("out == null"); - } - - if (width < 0) { - throw new IllegalArgumentException("width < 0"); - } - - if (prefix == null) { - throw new NullPointerException("prefix == null"); - } - - this.width = (width != 0) ? width : Integer.MAX_VALUE; - this.maxIndent = width >> 1; - this.prefix = (prefix.length() == 0) ? null : prefix; - - bol(); - } - - /** - * Constructs a no-prefix instance. - * - * @param out non-null; writer to send final output to - * @param width >= 0; the maximum output width (not including - * prefix), or 0 for no maximum - */ - public IndentingWriter(Writer out, int width) { - this(out, width, ""); - } - - /** {@inheritDoc} */ - @Override - public void write(int c) throws IOException { - synchronized (lock) { - if (collectingIndent) { - if (c == ' ') { - indent++; - if (indent >= maxIndent) { - indent = maxIndent; - collectingIndent = false; - } - } else { - collectingIndent = false; - } - } - - if ((column == width) && (c != '\n')) { - out.write('\n'); - column = 0; - /* - * Note: No else, so this should fall through to the next - * if statement. - */ - } - - if (column == 0) { - if (prefix != null) { - out.write(prefix); - } - - if (!collectingIndent) { - for (int i = 0; i < indent; i++) { - out.write(' '); - } - column = indent; - } - } - - out.write(c); - - if (c == '\n') { - bol(); - } else { - column++; - } - } - } - - /** {@inheritDoc} */ - @Override - public void write(char[] cbuf, int off, int len) throws IOException { - synchronized (lock) { - while (len > 0) { - write(cbuf[off]); - off++; - len--; - } - } - } - - /** {@inheritDoc} */ - @Override - public void write(String str, int off, int len) throws IOException { - synchronized (lock) { - while (len > 0) { - write(str.charAt(off)); - off++; - len--; - } - } - } - - /** - * Indicates that output is at the beginning of a line. - */ - private void bol() { - column = 0; - collectingIndent = (maxIndent != 0); - indent = 0; - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/Input.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/Input.java deleted file mode 100644 index 2364fabf..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/Input.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * 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. - */ - -/* - * As per the Apache license requirements, this file has been modified - * from its original state. - * - * Such modifications are Copyright (C) 2010 Ben Gruver, and are released - * under the original license - */ - -package org.jf.dexlib.Util; - -/** - * Interface for a source for binary input. This is similar to - * java.util.DataInput, but no IOExceptions - * are declared, and multibyte input is defined to be little-endian. - */ -public interface Input { - /** - * Gets the current cursor position. This is the same as the number of - * bytes read from this instance. - * - * @return >= 0; the cursor position - */ - public int getCursor(); - - /** - * Sets the current cursor position. - * - * @return >= 0; the cursor position - */ - public void setCursor(int cursor); - - /** - * Asserts that the cursor is the given value. - * - * @param expectedCursor the expected cursor value - * @throws RuntimeException thrown if getCursor() != - * expectedCursor - */ - public void assertCursor(int expectedCursor); - - /** - * Reads a byte from this instance. - * - * @return the byte value that was read - */ - public byte readByte(); - - /** - * Reads a short from this instance. - * - * @return the short value that was read, as an int - */ - public int readShort(); - - /** - * Reads an int from this instance. - * - * @return the unsigned int value that was read - */ - public int readInt(); - - /** - * Reads a long from this instance. - * - * @return the long value that was read - */ - public long readLong(); - - - /** - * Reads a DWARFv3-style signed LEB128 integer. For details, - * see the "Dalvik Executable Format" document or DWARF v3 section - * 7.6. - * - * @return the integer value that was read - */ - public int readSignedLeb128(); - - /** - * Reads a DWARFv3-style unsigned LEB128 integer. For details, - * see the "Dalvik Executable Format" document or DWARF v3 section - * 7.6. - * - * @return the integer value that was read - */ - public int readUnsignedLeb128(); - - - /** - * Reads a unsigned value as a DWARFv3-style LEB128 integer. It specifically - * checks for the case when the value was incorrectly formatted as a signed - * LEB128, and returns the appropriate unsigned value, but negated - * @return If the value was formatted as a ULEB128, it returns the actual unsigned - * value. Otherwise, if the value was formatted as a signed LEB128, it negates the - * "correct" unsigned value and returns that - */ - public int readUnsignedOrSignedLeb128(); - - /** - * reads a byte[] from this instance. - * - * @param bytes non-null; the buffer to read the data into - * @param offset >= 0; offset into bytes for the first - * byte to write - * @param length >= 0; number of bytes to read - */ - public void read(byte[] bytes, int offset, int length); - - /** - * reads a byte[] from this instance. This is just - * a convenient shorthand for read(bytes, 0, bytes.length). - * - * @param bytes non-null; the buffer to read the data into - */ - public void read(byte[] bytes); - - - /** - * reads a byte[] from this instance - * - * @param length >= 0; number of bytes to read - * @return a byte array containing length bytes - */ - public byte[] readBytes(int length); - - /** - * reads and decodes a null terminated utf8 string from the current cursor up to but not including - * the next null (0) byte. The terminating null byte is read and discarded, so that after the read, - * the cursor is positioned at the byte immediately after the terminating null - * - * @return a string representing the decoded value - */ - public String realNullTerminatedUtf8String(); - - /** - * Skips the given number of bytes. - * - * @param count >= 0; the number of bytes to skip - */ - public void skipBytes(int count); - - /** - * Skip extra bytes if necessary to force alignment of the output - * cursor as given. - * - * @param alignment > 0; the alignment; must be a power of two - */ - public void alignTo(int alignment); -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/Leb128Utils.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/Leb128Utils.java deleted file mode 100644 index a5aafe68..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/Leb128Utils.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * 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. - */ - -/* - * As per the Apache license requirements, this file has been modified - * from its original state. - * - * Such modifications are Copyright (C) 2010 Ben Gruver, and are released - * under the original license - */ - -package org.jf.dexlib.Util; - -/** - * LEB128 (little-endian base 128) utilities. - */ -public final class Leb128Utils { - /** - * This class is uninstantiable. - */ - private Leb128Utils() { - // This space intentionally left blank. - } - - /** - * Gets the number of bytes in the unsigned LEB128 encoding of the - * given value. - * - * @param value the value in question - * @return its write size, in bytes - */ - public static int unsignedLeb128Size(int value) { - // TODO: This could be much cleverer. - - int remaining = value >>> 7; - int count = 0; - - while (remaining != 0) { - value = remaining; - remaining >>>= 7; - count++; - } - - return count + 1; - } - - /** - * Gets the number of bytes in the signed LEB128 encoding of the - * given value. - * - * @param value the value in question - * @return its write size, in bytes - */ - public static int signedLeb128Size(int value) { - // TODO: This could be much cleverer. - - int remaining = value >> 7; - int count = 0; - boolean hasMore = true; - int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1; - - while (hasMore) { - hasMore = (remaining != end) - || ((remaining & 1) != ((value >> 6) & 1)); - - value = remaining; - remaining >>= 7; - count++; - } - - return count; - } - - /** - * Writes an unsigned leb128 to the buffer at the specified location - * @param value the value to write as an unsigned leb128 - * @param buffer the buffer to write to - * @param bufferIndex the index to start writing at - */ - public static void writeUnsignedLeb128(int value, byte[] buffer, int bufferIndex) { - int remaining = value >>> 7; - int count = 0; - - while (remaining != 0) { - buffer[bufferIndex] = (byte)((value & 0x7f) | 0x80); - bufferIndex++; - value = remaining; - remaining >>>= 7; - count++; - } - - buffer[bufferIndex] = (byte)(value & 0x7f); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/NumberUtils.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/NumberUtils.java deleted file mode 100644 index 2e97f512..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/NumberUtils.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Util; - -public class NumberUtils { - - /** - * Decodes the high signed 4-bit nibble from the given byte - * @param b the byte to decode - * @return the decoded signed nibble - */ - public static byte decodeHighSignedNibble(byte b) { - return (byte)(b >> 4); - } - - /** - * Decodes the low signed 4-bit nibble from the given byte - * @param b the byte to decode - * @return the decoded signed nibble - */ - public static byte decodeLowSignedNibble(byte b) { - return (byte)(((byte)(b << 4)) >> 4); - } - - /** - * Decodes the high unsigned 4-bit nibble from the given byte - * @param b the byte to decode - * @return the decoded unsigned nibble - */ - public static byte decodeHighUnsignedNibble(byte b) { - return (byte)((b & 0xFF) >>> 4); - } - - /** - * Decodes the low unsigned 4-bit nibble from the given byte - * @param b the byte to decode - * @return the decoded unsigned nibble - */ - public static byte decodeLowUnsignedNibble(byte b) { - return (byte)(b & 0x0F); - } - - /** - * Decodes an unsigned byte from a signed byte - * @param b the signed byte to decode - * @return the decoded unsigned byte as a short - */ - public static short decodeUnsignedByte(byte b) { - return (short)(b & 0xFF); - } - - /** - * Decodes a signed short value from 2 individual bytes - * The parameters are in order from least significant byte to most significant byte - * @param lsb the least significant byte - * @param msb the most significant byte - * @return the decoded signed short value - */ - public static short decodeShort(byte lsb, byte msb) { - return (short) - ( (lsb & 0xFF) | - (msb << 8) - ); - } - - /** - * Decodes a signed short value in little endian format from the given byte array at the given index. - * @param bytes the byte array - * @param index the index of the first byte of the signed short value to decode - * @return the decoded signed short value - */ - public static short decodeShort(byte[] bytes, int index) { - return (short) - ( (bytes[index++] & 0xFF) | - (bytes[index] << 8) - ); - } - - /** - * Decodes an unsigned short value from 2 individual bytes - * The parameters are in order from least significant byte to most significant byte - * @param lsb the least significant byte - * @param msb the most significant byte - * @return the decoded unsigned short value as an int - */ - public static int decodeUnsignedShort(byte lsb, byte msb) { - return ( (lsb & 0xFF) | - ((msb & 0xFF) << 8) - ); - } - - /** - * Decodes an unsigned short value in little endian format from the given byte array at the given index. - * @param bytes the byte array - * @param index the index of the first byte of the unsigned short value to decode - * @return the decoded unsigned short value as an int - */ - public static int decodeUnsignedShort(byte[] bytes, int index) { - return ( (bytes[index++] & 0xFF) | - ((bytes[index] & 0xFF) << 8) - ); - } - - /** - * Decodes a signed integer value from 4 individual bytes - * The parameters are in order from least significant byte to most significant byte - * @param lsb the least significant byte - * @param mlsb the middle least significant byte - * @param mmsb the middle most significant byte - * @param msb the most significant byte - * @return the decoded signed integer value - */ - public static int decodeInt(byte lsb, byte mlsb, byte mmsb, byte msb) { - return (lsb & 0xFF) | - ((mlsb & 0xFF) << 8) | - ((mmsb & 0xFF) << 16) | - (msb << 24); - } - - /** - * Decodes a signed integer value in little endian format from the given byte array at the given index. - * @param bytes the byte array - * @param index the index of the first byte of the signed integer value to decode - * @return the decoded signed integer value - */ - public static int decodeInt(byte[] bytes, int index) { - return (bytes[index++] & 0xFF) | - ((bytes[index++] & 0xFF) << 8) | - ((bytes[index++] & 0xFF) << 16) | - (bytes[index] << 24); - } - - /** - * Decodes a signed long value from 8 individual bytes - * The parameters are in order from least significant byte to most significant byte - * @param llsb the lower least significant byte - * @param lmlsb the lower middle least significant byte - * @param lmmsb the lower middle most significant byte - * @param lgsb the lower greater significant byte - * @param glsb the greater least significant byte - * @param gmlsb the greater middle least significant byte - * @param gmmsb the greater middle most significant byte - * @param gmsb the greater most significant byte - * @return the decoded signed long value - */ - public static long decodeLong(byte llsb, byte lmlsb, byte lmmsb, byte lgsb, byte glsb, byte gmlsb, byte gmmsb, - byte gmsb) { - return (llsb & 0xFFL) | - ((lmlsb & 0xFFL) << 8) | - ((lmmsb & 0xFFL) << 16) | - ((lgsb & 0xFFL) << 24) | - ((glsb & 0xFFL) << 32) | - ((gmlsb & 0xFFL) << 40) | - ((gmmsb & 0xFFL) << 48) | - (((long)gmsb) << 56); - } - - /** - * Decodes a signed long value in little endian format from the given byte array at the given index. - * @param bytes the byte array - * @param index the index of the first byte of the signed long value to decode - * @return the decoded signed long value - */ - public static long decodeLong(byte[] bytes, int index) { - return (bytes[index++] & 0xFFL) | - ((bytes[index++] & 0xFFL) << 8) | - ((bytes[index++] & 0xFFL) << 16) | - ((bytes[index++] & 0xFFL) << 24) | - ((bytes[index++] & 0xFFL) << 32) | - ((bytes[index++] & 0xFFL) << 40) | - ((bytes[index++] & 0xFFL) << 48) | - (((long)bytes[index]) << 56); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/Output.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/Output.java deleted file mode 100644 index 49b41336..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/Output.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Util; - -/** - * Interface for a sink for binary output. This is similar to - * java.util.DataOutput, but no IOExceptions - * are declared, and multibyte output is defined to be little-endian. - */ -public interface Output { - /** - * Gets the current cursor position. This is the same as the number of - * bytes written to this instance. - * - * @return >= 0; the cursor position - */ - public int getCursor(); - - /** - * Asserts that the cursor is the given value. - * - * @param expectedCursor the expected cursor value - * @throws RuntimeException thrown if getCursor() != - * expectedCursor - */ - public void assertCursor(int expectedCursor); - - /** - * Writes a byte to this instance. - * - * @param value the value to write; all but the low 8 bits are ignored - */ - public void writeByte(int value); - - /** - * Writes a short to this instance. - * - * @param value the value to write; all but the low 16 bits are ignored - */ - public void writeShort(int value); - - /** - * Writes an int to this instance. - * - * @param value the value to write - */ - public void writeInt(int value); - - /** - * Writes a long to this instance. - * - * @param value the value to write - */ - public void writeLong(long value); - - /** - * Writes a DWARFv3-style unsigned LEB128 integer. For details, - * see the "Dalvik Executable Format" document or DWARF v3 section - * 7.6. - * - * @param value value to write, treated as an unsigned value - * @return 1..5; the number of bytes actually written - */ - public int writeUnsignedLeb128(int value); - - /** - * Writes a DWARFv3-style unsigned LEB128 integer. For details, - * see the "Dalvik Executable Format" document or DWARF v3 section - * 7.6. - * - * @param value value to write - * @return 1..5; the number of bytes actually written - */ - public int writeSignedLeb128(int value); - - /** - * Writes a {@link org.jf.dexlib.Util.ByteArray} to this instance. - * - * @param bytes non-null; the array to write - */ - public void write(ByteArray bytes); - - /** - * Writes a portion of a byte[] to this instance. - * - * @param bytes non-null; the array to write - * @param offset >= 0; offset into bytes for the first - * byte to write - * @param length >= 0; number of bytes to write - */ - public void write(byte[] bytes, int offset, int length); - - /** - * Writes a byte[] to this instance. This is just - * a convenient shorthand for write(bytes, 0, bytes.length). - * - * @param bytes non-null; the array to write - */ - public void write(byte[] bytes); - - /** - * Writes the given number of 0 bytes. - * - * @param count >= 0; the number of zeroes to write - */ - public void writeZeroes(int count); - - /** - * Adds extra bytes if necessary (with value 0) to - * force alignment of the output cursor as given. - * - * @param alignment > 0; the alignment; must be a power of two - */ - public void alignTo(int alignment); -} \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/Pair.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/Pair.java deleted file mode 100644 index f246c999..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/Pair.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Util; - -public class Pair { - public final A first; - public final B second; - - public Pair(A first, B second) { - this.first = first; - this.second = second; - } -} - diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ReadOnlyArrayList.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ReadOnlyArrayList.java deleted file mode 100644 index 2667979d..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/ReadOnlyArrayList.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Util; - -import java.util.AbstractList; -import java.util.RandomAccess; - -public class ReadOnlyArrayList extends AbstractList implements RandomAccess { - private final T[] arr; - - public ReadOnlyArrayList(T[] arr) { - this.arr = arr; - } - - public int size() { - return arr.length; - } - - public T get(int i) { - return arr[i]; - } - - public static ReadOnlyArrayList of(T... items) { - return new ReadOnlyArrayList(items); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/SparseArray.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/SparseArray.java deleted file mode 100644 index 25fb7b46..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/SparseArray.java +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * 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. - */ - -/* - * As per the Apache license requirements, this file has been modified - * from its original state. - * - * Such modifications are Copyright (C) 2010 Ben Gruver, and are released - * under the original license - */ - -package org.jf.dexlib.Util; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * SparseArrays map integers to Objects. Unlike a normal array of Objects, - * there can be gaps in the indices. It is intended to be more efficient - * than using a HashMap to map Integers to Objects. - */ -public class SparseArray { - private static final Object DELETED = new Object(); - private boolean mGarbage = false; - - /** - * Creates a new SparseArray containing no mappings. - */ - public SparseArray() { - this(10); - } - - /** - * Creates a new SparseArray containing no mappings that will not - * require any additional memory allocation to store the specified - * number of mappings. - */ - public SparseArray(int initialCapacity) { - mKeys = new int[initialCapacity]; - mValues = new Object[initialCapacity]; - mSize = 0; - } - - /** - * Gets the Object mapped from the specified key, or null - * if no such mapping has been made. - */ - public E get(int key) { - return get(key, null); - } - - /** - * Gets the Object mapped from the specified key, or the specified Object - * if no such mapping has been made. - */ - public E get(int key, E valueIfKeyNotFound) { - int i = binarySearch(mKeys, 0, mSize, key); - - if (i < 0 || mValues[i] == DELETED) { - return valueIfKeyNotFound; - } else { - return (E) mValues[i]; - } - } - - /** - * Removes the mapping from the specified key, if there was any. - */ - public void delete(int key) { - int i = binarySearch(mKeys, 0, mSize, key); - - if (i >= 0) { - if (mValues[i] != DELETED) { - mValues[i] = DELETED; - mGarbage = true; - } - } - } - - /** - * Alias for {@link #delete(int)}. - */ - public void remove(int key) { - delete(key); - } - - private void gc() { - // Log.e("SparseArray", "gc start with " + mSize); - - int n = mSize; - int o = 0; - int[] keys = mKeys; - Object[] values = mValues; - - for (int i = 0; i < n; i++) { - Object val = values[i]; - - if (val != DELETED) { - if (i != o) { - keys[o] = keys[i]; - values[o] = val; - } - - o++; - } - } - - mGarbage = false; - mSize = o; - - // Log.e("SparseArray", "gc end with " + mSize); - } - - /** - * Adds a mapping from the specified key to the specified value, - * replacing the previous mapping from the specified key if there - * was one. - */ - public void put(int key, E value) { - int i = binarySearch(mKeys, 0, mSize, key); - - if (i >= 0) { - mValues[i] = value; - } else { - i = ~i; - - if (i < mSize && mValues[i] == DELETED) { - mKeys[i] = key; - mValues[i] = value; - return; - } - - if (mGarbage && mSize >= mKeys.length) { - gc(); - - // Search again because indices may have changed. - i = ~binarySearch(mKeys, 0, mSize, key); - } - - if (mSize >= mKeys.length) { - int n = Math.max(mSize + 1, mKeys.length * 2); - - int[] nkeys = new int[n]; - Object[] nvalues = new Object[n]; - - // Log.e("SparseArray", "grow " + mKeys.length + " to " + n); - System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length); - System.arraycopy(mValues, 0, nvalues, 0, mValues.length); - - mKeys = nkeys; - mValues = nvalues; - } - - if (mSize - i != 0) { - // Log.e("SparseArray", "move " + (mSize - i)); - System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i); - System.arraycopy(mValues, i, mValues, i + 1, mSize - i); - } - - mKeys[i] = key; - mValues[i] = value; - mSize++; - } - } - - /** - * Returns the number of key-value mappings that this SparseArray - * currently stores. - */ - public int size() { - if (mGarbage) { - gc(); - } - - return mSize; - } - - /** - * Given an index in the range 0...size()-1, returns - * the key from the indexth key-value mapping that this - * SparseArray stores. - */ - public int keyAt(int index) { - if (mGarbage) { - gc(); - } - - return mKeys[index]; - } - - /** - * Given an index in the range 0...size()-1, returns - * the value from the indexth key-value mapping that this - * SparseArray stores. - */ - public E valueAt(int index) { - if (mGarbage) { - gc(); - } - - return (E) mValues[index]; - } - - /** - * Given an index in the range 0...size()-1, sets a new - * value for the indexth key-value mapping that this - * SparseArray stores. - */ - public void setValueAt(int index, E value) { - if (mGarbage) { - gc(); - } - - mValues[index] = value; - } - - /** - * Returns the index for which {@link #keyAt} would return the - * specified key, or a negative number if the specified - * key is not mapped. - */ - public int indexOfKey(int key) { - if (mGarbage) { - gc(); - } - - return binarySearch(mKeys, 0, mSize, key); - } - - /** - * Returns an index for which {@link #valueAt} would return the - * specified key, or a negative number if no keys map to the - * specified value. - * Beware that this is a linear search, unlike lookups by key, - * and that multiple keys can map to the same value and this will - * find only one of them. - */ - public int indexOfValue(E value) { - if (mGarbage) { - gc(); - } - - for (int i = 0; i < mSize; i++) - if (mValues[i] == value) - return i; - - return -1; - } - - /** - * Removes all key-value mappings from this SparseArray. - */ - public void clear() { - int n = mSize; - Object[] values = mValues; - - for (int i = 0; i < n; i++) { - values[i] = null; - } - - mSize = 0; - mGarbage = false; - } - - /** - * Puts a key/value pair into the array, optimizing for the case where - * the key is greater than all existing keys in the array. - */ - public void append(int key, E value) { - if (mSize != 0 && key <= mKeys[mSize - 1]) { - put(key, value); - return; - } - - if (mGarbage && mSize >= mKeys.length) { - gc(); - } - - int pos = mSize; - if (pos >= mKeys.length) { - int n = Math.max(pos + 1, mKeys.length * 2); - - int[] nkeys = new int[n]; - Object[] nvalues = new Object[n]; - - // Log.e("SparseArray", "grow " + mKeys.length + " to " + n); - System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length); - System.arraycopy(mValues, 0, nvalues, 0, mValues.length); - - mKeys = nkeys; - mValues = nvalues; - } - - mKeys[pos] = key; - mValues[pos] = value; - mSize = pos + 1; - } - - /** - * Increases the size of the underlying storage if needed, to ensure that it can - * hold the specified number of items without having to allocate additional memory - * @param capacity the number of items - */ - public void ensureCapacity(int capacity) { - if (mGarbage && mSize >= mKeys.length) { - gc(); - } - - if (mKeys.length < capacity) { - int[] nkeys = new int[capacity]; - Object[] nvalues = new Object[capacity]; - - System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length); - System.arraycopy(mValues, 0, nvalues, 0, mValues.length); - - mKeys = nkeys; - mValues = nvalues; - } - } - - private static int binarySearch(int[] a, int start, int len, int key) { - int high = start + len, low = start - 1, guess; - - while (high - low > 1) { - guess = (high + low) / 2; - - if (a[guess] < key) - low = guess; - else - high = guess; - } - - if (high == start + len) - return ~(start + len); - else if (a[high] == key) - return high; - else - return ~high; - } - - /** - * @return a read-only list of the values in this SparseArray which are in ascending order, based on their - * associated key - */ - public List getValues() { - return Collections.unmodifiableList(Arrays.asList((E[])mValues)); - } - - private int[] mKeys; - private Object[] mValues; - private int mSize; -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/SparseIntArray.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/SparseIntArray.java deleted file mode 100644 index 4e687f19..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/SparseIntArray.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * 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. - */ - -/* - * As per the Apache license requirements, this file has been modified - * from its original state. - * - * Such modifications are Copyright (C) 2010 Ben Gruver, and are released - * under the original license - */ - -package org.jf.dexlib.Util; - -/** - * SparseIntArrays map integers to integers. Unlike a normal array of integers, - * there can be gaps in the indices. It is intended to be more efficient - * than using a HashMap to map Integers to Integers. - */ -public class SparseIntArray { - /** - * Creates a new SparseIntArray containing no mappings. - */ - public SparseIntArray() { - this(10); - } - - /** - * Creates a new SparseIntArray containing no mappings that will not - * require any additional memory allocation to store the specified - * number of mappings. - */ - public SparseIntArray(int initialCapacity) { - mKeys = new int[initialCapacity]; - mValues = new int[initialCapacity]; - mSize = 0; - } - - /** - * Gets the int mapped from the specified key, or 0 - * if no such mapping has been made. - */ - public int get(int key) { - return get(key, 0); - } - - /** - * Gets the int mapped from the specified key, or the specified value - * if no such mapping has been made. - */ - public int get(int key, int valueIfKeyNotFound) { - int i = binarySearch(mKeys, 0, mSize, key); - - if (i < 0) { - return valueIfKeyNotFound; - } else { - return mValues[i]; - } - } - - /** - * Gets the int mapped from the specified key, or if not present, the - * closest key that is less than the specified key. - */ - public int getClosestSmaller(int key) { - int i = binarySearch(mKeys, 0, mSize, key); - - if (i < 0) { - i = ~i; - if (i > 0) { - i--; - } - return mValues[i]; - } else { - return mValues[i]; - } - } - - /** - * Removes the mapping from the specified key, if there was any. - */ - public void delete(int key) { - int i = binarySearch(mKeys, 0, mSize, key); - - if (i >= 0) { - removeAt(i); - } - } - - /** - * Removes the mapping at the given index. - */ - public void removeAt(int index) { - System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1)); - System.arraycopy(mValues, index + 1, mValues, index, mSize - (index + 1)); - mSize--; - } - - /** - * Adds a mapping from the specified key to the specified value, - * replacing the previous mapping from the specified key if there - * was one. - */ - public void put(int key, int value) { - int i = binarySearch(mKeys, 0, mSize, key); - - if (i >= 0) { - mValues[i] = value; - } else { - i = ~i; - - if (mSize >= mKeys.length) { - int n = Math.max(mSize + 1, mKeys.length * 2); - - int[] nkeys = new int[n]; - int[] nvalues = new int[n]; - - // Log.e("SparseIntArray", "grow " + mKeys.length + " to " + n); - System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length); - System.arraycopy(mValues, 0, nvalues, 0, mValues.length); - - mKeys = nkeys; - mValues = nvalues; - } - - if (mSize - i != 0) { - // Log.e("SparseIntArray", "move " + (mSize - i)); - System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i); - System.arraycopy(mValues, i, mValues, i + 1, mSize - i); - } - - mKeys[i] = key; - mValues[i] = value; - mSize++; - } - } - - /** - * Returns the number of key-value mappings that this SparseIntArray - * currently stores. - */ - public int size() { - return mSize; - } - - /** - * Given an index in the range 0...size()-1, returns - * the key from the indexth key-value mapping that this - * SparseIntArray stores. - */ - public int keyAt(int index) { - return mKeys[index]; - } - - /** - * Given an index in the range 0...size()-1, returns - * the value from the indexth key-value mapping that this - * SparseIntArray stores. - */ - public int valueAt(int index) { - return mValues[index]; - } - - /** - * Returns the index for which {@link #keyAt} would return the - * specified key, or a negative number if the specified - * key is not mapped. - */ - public int indexOfKey(int key) { - return binarySearch(mKeys, 0, mSize, key); - } - - /** - * Returns an index for which {@link #valueAt} would return the - * specified key, or a negative number if no keys map to the - * specified value. - * Beware that this is a linear search, unlike lookups by key, - * and that multiple keys can map to the same value and this will - * find only one of them. - */ - public int indexOfValue(int value) { - for (int i = 0; i < mSize; i++) - if (mValues[i] == value) - return i; - - return -1; - } - - /** - * Removes all key-value mappings from this SparseIntArray. - */ - public void clear() { - mSize = 0; - } - - /** - * Puts a key/value pair into the array, optimizing for the case where - * the key is greater than all existing keys in the array. - */ - public void append(int key, int value) { - if (mSize != 0 && key <= mKeys[mSize - 1]) { - put(key, value); - return; - } - - int pos = mSize; - if (pos >= mKeys.length) { - int n = Math.max(pos + 1, mKeys.length * 2); - - int[] nkeys = new int[n]; - int[] nvalues = new int[n]; - - // Log.e("SparseIntArray", "grow " + mKeys.length + " to " + n); - System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length); - System.arraycopy(mValues, 0, nvalues, 0, mValues.length); - - mKeys = nkeys; - mValues = nvalues; - } - - mKeys[pos] = key; - mValues[pos] = value; - mSize = pos + 1; - } - - private static int binarySearch(int[] a, int start, int len, int key) { - int high = start + len, low = start - 1, guess; - - while (high - low > 1) { - guess = (high + low) / 2; - - if (a[guess] < key) - low = guess; - else - high = guess; - } - - if (high == start + len) - return ~(start + len); - else if (a[high] == key) - return high; - else - return ~high; - } - - private int[] mKeys; - private int[] mValues; - private int mSize; -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/TryListBuilder.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/TryListBuilder.java deleted file mode 100644 index aadcaa7a..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/TryListBuilder.java +++ /dev/null @@ -1,347 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Util; - -import org.jf.dexlib.CodeItem; -import org.jf.dexlib.TypeIdItem; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; - -public class TryListBuilder -{ - /*TODO: add logic to merge adjacent, identical try blocks, and remove superflous handlers - Also provide a "strict" mode, where the above isn't performed, which will be useful to be able to - exactly reproduce the original .dex file (for testing/verification purposes)*/ - - - private TryRange firstTryRange = new TryRange(0,0); - private TryRange lastTryRange = new TryRange(0,0); - - public TryListBuilder() { - firstTryRange.next = lastTryRange; - lastTryRange.previous = firstTryRange; - } - - private class TryRange - { - public TryRange previous = null; - public TryRange next = null; - - public int startAddress; - public int endAddress; - public LinkedList handlers; - - public int catchAllHandlerAddress; - - public TryRange(int startAddress, int endAddress) { - this.startAddress = startAddress; - this.endAddress = endAddress; - this.handlers = new LinkedList(); - this.previous = null; - this.next = null; - catchAllHandlerAddress = -1; - } - - public void append(TryRange tryRange) { - /*we use a dummy last item, so this.next will always - have a value*/ - this.next.previous = tryRange; - tryRange.next = this.next; - - this.next = tryRange; - tryRange.previous = this; - } - - public void prepend(TryRange tryRange){ - /*we use a dummy first item, so this.previous will always - have a value*/ - this.previous.next = tryRange; - tryRange.previous = this.previous; - - this.previous = tryRange; - tryRange.next = this; - } - - /** - * This splits the current range into two ranges at the given - * address. The existing range will be shortened to the first - * half, and a new range will be created and returned for the - * 2nd half. - * @param address The address to split at - * @return The 2nd half of the - */ - public TryRange split(int address) { - //this is a private class, so address is assumed - //to be valid - - TryRange tryRange = new TryRange(address, endAddress); - tryRange.catchAllHandlerAddress = this.catchAllHandlerAddress; - tryRange.handlers.addAll(this.handlers); - append(tryRange); - - this.endAddress = address; - - return tryRange; - } - - public void appendHandler(Handler handler) { - handlers.addLast(handler); - } - - public void prependHandler(Handler handler) { - handlers.addFirst(handler); - } - } - - private class Handler - { - public final TypeIdItem type; - public final int handlerAddress; - - public Handler(TypeIdItem type, int handlerAddress) { - this.type = type; - this.handlerAddress = handlerAddress; - } - } - - public Pair, List> encodeTries() { - if (firstTryRange.next == lastTryRange) { - return new Pair, List>(null, null); - } - - ArrayList tries = new ArrayList(); - ArrayList handlers = new ArrayList(); - - HashMap handlerDict = - new HashMap(); - - TryRange tryRange = firstTryRange.next; - - while (tryRange != lastTryRange) { - CodeItem.EncodedTypeAddrPair[] encodedTypeAddrPairs = - new CodeItem.EncodedTypeAddrPair[tryRange.handlers.size()]; - - int index = 0; - for (Handler handler: tryRange.handlers) { - CodeItem.EncodedTypeAddrPair encodedTypeAddrPair = new CodeItem.EncodedTypeAddrPair( - handler.type, - handler.handlerAddress); - encodedTypeAddrPairs[index++] = encodedTypeAddrPair; - } - - CodeItem.EncodedCatchHandler encodedCatchHandler = new CodeItem.EncodedCatchHandler( - encodedTypeAddrPairs, - tryRange.catchAllHandlerAddress); - CodeItem.EncodedCatchHandler internedEncodedCatchHandler = handlerDict.get(encodedCatchHandler); - if (internedEncodedCatchHandler == null) { - handlerDict.put(encodedCatchHandler, encodedCatchHandler); - handlers.add(encodedCatchHandler); - } else { - encodedCatchHandler = internedEncodedCatchHandler; - } - - CodeItem.TryItem tryItem = new CodeItem.TryItem( - tryRange.startAddress, - tryRange.endAddress - tryRange.startAddress, - encodedCatchHandler); - tries.add(tryItem); - - tryRange = tryRange.next; - } - - return new Pair, List>(tries, handlers); - } - - public void addCatchAllHandler(int startAddress, int endAddress, int handlerAddress) { - TryRange startRange; - TryRange endRange; - - Pair ranges = getBoundingRanges(startAddress, endAddress); - startRange = ranges.first; - endRange = ranges.second; - - int previousEnd = startAddress; - TryRange tryRange = startRange; - - /*Now we have the start and end ranges that exactly match the start and end - of the range being added. We need to iterate over all the ranges from the start - to end range inclusively, and append the handler to the end of each range's handler - list. We also need to create a new range for any "holes" in the existing ranges*/ - do - { - //is there a hole? If so, add a new range to fill the hole - if (tryRange.startAddress > previousEnd) { - TryRange newRange = new TryRange(previousEnd, tryRange.startAddress); - tryRange.prepend(newRange); - tryRange = newRange; - } - - if (tryRange.catchAllHandlerAddress == -1) { - tryRange.catchAllHandlerAddress = handlerAddress; - } - - previousEnd = tryRange.endAddress; - tryRange = tryRange.next; - } while (tryRange.previous != endRange); - } - - public Pair getBoundingRanges(int startAddress, int endAddress) { - TryRange startRange = null; - TryRange endRange = null; - - TryRange tryRange = firstTryRange.next; - while (tryRange != lastTryRange) { - if (startAddress == tryRange.startAddress) { - //|-----| - //^------ - /*Bam. We hit the start of the range right on the head*/ - startRange = tryRange; - break; - } else if (startAddress > tryRange.startAddress && startAddress < tryRange.endAddress) { - //|-----| - // ^---- - /*Almost. The start of the range being added is in the middle - of an existing try range. We need to split the existing range - at the start address of the range being added*/ - startRange = tryRange.split(startAddress); - break; - }else if (startAddress < tryRange.startAddress) { - if (endAddress <= tryRange.startAddress) { - // |-----| - //^--^ - /*Oops, totally too far! The new range doesn't overlap any existing - ones, so we just add it and return*/ - startRange = new TryRange(startAddress, endAddress); - tryRange.prepend(startRange); - return new Pair(startRange, startRange); - } else { - // |-----| - //^--------- - /*Oops, too far! We've passed the start of the range being added, but - the new range does overlap this one. We need to add a new range just - before this one*/ - startRange = new TryRange(startAddress, tryRange.startAddress); - tryRange.prepend(startRange); - break; - } - } - - tryRange = tryRange.next; - } - - //|-----| - // ^----- - /*Either the list of tries is blank, or all the tries in the list - end before the range being added starts. In either case, we just need - to add a new range at the end of the list*/ - if (startRange == null) { - startRange = new TryRange(startAddress, endAddress); - lastTryRange.prepend(startRange); - return new Pair(startRange, startRange); - } - - tryRange = startRange; - while (tryRange != lastTryRange) { - if (tryRange.endAddress == endAddress) { - //|-----| - //------^ - /*Bam! We hit the end right on the head.*/ - endRange = tryRange; - break; - } else if (tryRange.startAddress < endAddress && tryRange.endAddress > endAddress) { - //|-----| - //--^ - /*Almost. The range being added ends in the middle of an - existing range. We need to split the existing range - at the end of the range being added.*/ - tryRange.split(endAddress); - endRange = tryRange; - break; - } else if (tryRange.startAddress >= endAddress) { - //|-----| |-----| - //-----------^ - /*Oops, too far! The current range starts after the range being added - ends. We need to create a new range that starts at the end of the - previous range, and ends at the end of the range being added*/ - endRange = new TryRange(tryRange.previous.endAddress, endAddress); - tryRange.prepend(endRange); - break; - } - tryRange = tryRange.next; - } - - //|-----| - //--------^ - /*The last range in the list ended before the end of the range being added. - We need to add a new range that starts at the end of the last range in the - list, and ends at the end of the range being added.*/ - if (endRange == null) { - endRange = new TryRange(lastTryRange.previous.endAddress, endAddress); - lastTryRange.prepend(endRange); - } - - return new Pair(startRange, endRange); - } - - public void addHandler(TypeIdItem type, int startAddress, int endAddress, int handlerAddress) { - TryRange startRange; - TryRange endRange; - - //TODO: need to check for pre-existing exception types in the handler list? - - Pair ranges = getBoundingRanges(startAddress, endAddress); - startRange = ranges.first; - endRange = ranges.second; - Handler handler = new Handler(type, handlerAddress); - - int previousEnd = startAddress; - TryRange tryRange = startRange; - - /*Now we have the start and end ranges that exactly match the start and end - of the range being added. We need to iterate over all the ranges from the start - to end range inclusively, and append the handler to the end of each range's handler - list. We also need to create a new range for any "holes" in the existing ranges*/ - do - { - //is there a hole? If so, add a new range to fill the hole - if (tryRange.startAddress > previousEnd) { - TryRange newRange = new TryRange(previousEnd, tryRange.startAddress); - tryRange.prepend(newRange); - tryRange = newRange; - } - - tryRange.appendHandler(handler); - previousEnd = tryRange.endAddress; - tryRange = tryRange.next; - } while (tryRange.previous != endRange); - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/TwoColumnOutput.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/TwoColumnOutput.java deleted file mode 100644 index d064a4da..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/TwoColumnOutput.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * 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. - */ - -/* - * As per the Apache license requirements, this file has been modified - * from its original state. - * - * Such modifications are Copyright (C) 2010 Ben Gruver, and are released - * under the original license - */ - -package org.jf.dexlib.Util; - -import java.io.*; - -/** - * Class that takes a combined output destination and provides two - * output writers, one of which ends up writing to the left column and - * one which goes on the right. - */ -public final class TwoColumnOutput { - /** non-null; underlying writer for final output */ - private final Writer out; - - /** > 0; the left column width */ - private final int leftWidth; - - /** non-null; pending left column output */ - private final StringBuffer leftBuf; - - /** non-null; pending right column output */ - private final StringBuffer rightBuf; - - /** non-null; left column writer */ - private final IndentingWriter leftColumn; - - /** non-null; right column writer */ - private final IndentingWriter rightColumn; - - /** - * Turns the given two strings (with widths) and spacer into a formatted - * two-column string. - * - * @param s1 non-null; first string - * @param width1 > 0; width of the first column - * @param spacer non-null; spacer string - * @param s2 non-null; second string - * @param width2 > 0; width of the second column - * @return non-null; an appropriately-formatted string - */ - public static String toString(String s1, int width1, String spacer, - String s2, int width2) { - int len1 = s1.length(); - int len2 = s2.length(); - - StringWriter sw = new StringWriter((len1 + len2) * 3); - TwoColumnOutput twoOut = - new TwoColumnOutput(sw, width1, width2, spacer); - - try { - twoOut.getLeft().write(s1); - twoOut.getRight().write(s2); - } catch (IOException ex) { - throw new RuntimeException("shouldn't happen", ex); - } - - twoOut.flush(); - return sw.toString(); - } - - /** - * Constructs an instance. - * - * @param out non-null; writer to send final output to - * @param leftWidth > 0; width of the left column, in characters - * @param rightWidth > 0; width of the right column, in characters - * @param spacer non-null; spacer string to sit between the two columns - */ - public TwoColumnOutput(Writer out, int leftWidth, int rightWidth, - String spacer) { - if (out == null) { - throw new NullPointerException("out == null"); - } - - if (leftWidth < 1) { - throw new IllegalArgumentException("leftWidth < 1"); - } - - if (rightWidth < 1) { - throw new IllegalArgumentException("rightWidth < 1"); - } - - if (spacer == null) { - throw new NullPointerException("spacer == null"); - } - - StringWriter leftWriter = new StringWriter(1000); - StringWriter rightWriter = new StringWriter(1000); - - this.out = out; - this.leftWidth = leftWidth; - this.leftBuf = leftWriter.getBuffer(); - this.rightBuf = rightWriter.getBuffer(); - this.leftColumn = new IndentingWriter(leftWriter, leftWidth); - this.rightColumn = - new IndentingWriter(rightWriter, rightWidth, spacer); - } - - /** - * Constructs an instance. - * - * @param out non-null; stream to send final output to - * @param leftWidth >= 1; width of the left column, in characters - * @param rightWidth >= 1; width of the right column, in characters - * @param spacer non-null; spacer string to sit between the two columns - */ - public TwoColumnOutput(OutputStream out, int leftWidth, int rightWidth, - String spacer) { - this(new OutputStreamWriter(out), leftWidth, rightWidth, spacer); - } - - /** - * Gets the writer to use to write to the left column. - * - * @return non-null; the left column writer - */ - public Writer getLeft() { - return leftColumn; - } - - /** - * Gets the writer to use to write to the right column. - * - * @return non-null; the right column writer - */ - public Writer getRight() { - return rightColumn; - } - - /** - * Flushes the output. If there are more lines of pending output in one - * column, then the other column will get filled with blank lines. - */ - public void flush() { - try { - appendNewlineIfNecessary(leftBuf, leftColumn); - appendNewlineIfNecessary(rightBuf, rightColumn); - outputFullLines(); - flushLeft(); - flushRight(); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - } - - /** - * Outputs to the final destination as many full line pairs as - * there are in the pending output, removing those lines from - * their respective buffers. This method terminates when at - * least one of the two column buffers is empty. - */ - private void outputFullLines() throws IOException { - for (;;) { - int leftLen = leftBuf.indexOf("\n"); - if (leftLen < 0) { - return; - } - - int rightLen = rightBuf.indexOf("\n"); - if (rightLen < 0) { - return; - } - - if (leftLen != 0) { - out.write(leftBuf.substring(0, leftLen)); - } - - if (rightLen != 0) { - writeSpaces(out, leftWidth - leftLen); - out.write(rightBuf.substring(0, rightLen)); - } - - out.write('\n'); - - leftBuf.delete(0, leftLen + 1); - rightBuf.delete(0, rightLen + 1); - } - } - - /** - * Flushes the left column buffer, printing it and clearing the buffer. - * If the buffer is already empty, this does nothing. - */ - private void flushLeft() throws IOException { - appendNewlineIfNecessary(leftBuf, leftColumn); - - while (leftBuf.length() != 0) { - rightColumn.write('\n'); - outputFullLines(); - } - } - - /** - * Flushes the right column buffer, printing it and clearing the buffer. - * If the buffer is already empty, this does nothing. - */ - private void flushRight() throws IOException { - appendNewlineIfNecessary(rightBuf, rightColumn); - - while (rightBuf.length() != 0) { - leftColumn.write('\n'); - outputFullLines(); - } - } - - /** - * Appends a newline to the given buffer via the given writer, but - * only if it isn't empty and doesn't already end with one. - * - * @param buf non-null; the buffer in question - * @param out non-null; the writer to use - */ - private static void appendNewlineIfNecessary(StringBuffer buf, - Writer out) - throws IOException { - int len = buf.length(); - - if ((len != 0) && (buf.charAt(len - 1) != '\n')) { - out.write('\n'); - } - } - - /** - * Writes the given number of spaces to the given writer. - * - * @param out non-null; where to write - * @param amt >= 0; the number of spaces to write - */ - private static void writeSpaces(Writer out, int amt) throws IOException { - while (amt > 0) { - out.write(' '); - amt--; - } - } -} diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/TypeUtils.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/TypeUtils.java deleted file mode 100644 index 40cedda0..00000000 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/Util/TypeUtils.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib.Util; - -import org.jf.dexlib.EncodedValue.*; -import org.jf.dexlib.TypeIdItem; - -public class TypeUtils -{ - public static EncodedValue makeDefaultValueForType(String type) { - switch (type.charAt(0)) { - case 'Z': - return BooleanEncodedValue.FalseValue; - case 'B': - return new ByteEncodedValue((byte)0); - case 'S': - return new ShortEncodedValue((short)0); - case 'C': - return new CharEncodedValue((char)0); - case 'I': - return new IntEncodedValue(0); - case 'J': - return new LongEncodedValue(0); - case 'F': - return new FloatEncodedValue(0); - case 'D': - return new DoubleEncodedValue(0); - case 'L': - case '[': - return NullEncodedValue.NullValue; - } - return null; - } - - public static EncodedValue makeDefaultValueForType(TypeIdItem type) { - return makeDefaultValueForType(type.getTypeDescriptor()); - } -} diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderDebugItem.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderDebugItem.java index bea9ca32..0969a9db 100644 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderDebugItem.java +++ b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderDebugItem.java @@ -33,14 +33,12 @@ package org.jf.dexlib2.builder; import org.jf.dexlib2.iface.debug.DebugItem; -import javax.annotation.Nonnull; import javax.annotation.Nullable; public abstract class BuilderDebugItem implements DebugItem { @Nullable MethodLocation location; - public BuilderDebugItem(@Nonnull MethodLocation location) { - this.location = location; + public BuilderDebugItem() { } @Override public int getCodeAddress() { diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/MethodLocation.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/MethodLocation.java index 5d38ff55..18daeeaa 100644 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/MethodLocation.java +++ b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/MethodLocation.java @@ -183,31 +183,31 @@ public class MethodLocation { } public void addLineNumber(int lineNumber) { - debugItems.add(new BuilderLineNumber(this, lineNumber)); + getDebugItems().add(new BuilderLineNumber(lineNumber)); } public void addStartLocal(int registerNumber, @Nullable StringReference name, @Nullable TypeReference type, @Nullable StringReference signature) { - debugItems.add(new BuilderStartLocal(this, registerNumber, name, type, signature)); + getDebugItems().add(new BuilderStartLocal(registerNumber, name, type, signature)); } public void addEndLocal(int registerNumber) { - debugItems.add(new BuilderEndLocal(this, registerNumber)); + getDebugItems().add(new BuilderEndLocal(registerNumber)); } public void addRestartLocal(int registerNumber) { - debugItems.add(new BuilderRestartLocal(this, registerNumber)); + getDebugItems().add(new BuilderRestartLocal(registerNumber)); } public void addPrologue() { - debugItems.add(new BuilderPrologueEnd(this)); + getDebugItems().add(new BuilderPrologueEnd()); } public void addEpilogue() { - debugItems.add(new BuilderEpilogueBegin(this)); + getDebugItems().add(new BuilderEpilogueBegin()); } public void addSetSourceFile(@Nullable BuilderStringReference sourceFile) { - debugItems.add(new BuilderSetSourceFile(this, sourceFile)); + getDebugItems().add(new BuilderSetSourceFile(sourceFile)); } } diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/MutableMethodImplementation.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/MutableMethodImplementation.java index 1ed48793..006b7193 100644 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/MutableMethodImplementation.java +++ b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/MutableMethodImplementation.java @@ -106,7 +106,7 @@ public class MutableMethodImplementation implements MethodImplementation { int debugCodeAddress = debugItem.getCodeAddress(); int locationIndex = mapCodeAddressToIndex(codeAddressToIndex, debugCodeAddress); MethodLocation debugLocation = instructionList.get(locationIndex); - BuilderDebugItem builderDebugItem = convertDebugItem(debugLocation, debugItem); + BuilderDebugItem builderDebugItem = convertDebugItem(debugItem); debugLocation.getDebugItems().add(builderDebugItem); builderDebugItem.location = debugLocation; } @@ -909,32 +909,32 @@ public class MutableMethodImplementation implements MethodImplementation { } @Nonnull - private BuilderDebugItem convertDebugItem(@Nonnull MethodLocation location, @Nonnull DebugItem debugItem) { + private BuilderDebugItem convertDebugItem(@Nonnull DebugItem debugItem) { switch (debugItem.getDebugItemType()) { case DebugItemType.START_LOCAL: { StartLocal startLocal = (StartLocal)debugItem; - return new BuilderStartLocal(location, startLocal.getRegister(), startLocal.getNameReference(), + return new BuilderStartLocal(startLocal.getRegister(), startLocal.getNameReference(), startLocal.getTypeReference(), startLocal.getSignatureReference()); } case DebugItemType.END_LOCAL: { EndLocal endLocal = (EndLocal)debugItem; - return new BuilderEndLocal(location, endLocal.getRegister()); + return new BuilderEndLocal(endLocal.getRegister()); } case DebugItemType.RESTART_LOCAL: { RestartLocal restartLocal = (RestartLocal)debugItem; - return new BuilderRestartLocal(location, restartLocal.getRegister()); + return new BuilderRestartLocal(restartLocal.getRegister()); } case DebugItemType.PROLOGUE_END: - return new BuilderPrologueEnd(location); + return new BuilderPrologueEnd(); case DebugItemType.EPILOGUE_BEGIN: - return new BuilderEpilogueBegin(location); + return new BuilderEpilogueBegin(); case DebugItemType.LINE_NUMBER: { LineNumber lineNumber = (LineNumber)debugItem; - return new BuilderLineNumber(location, lineNumber.getLineNumber()); + return new BuilderLineNumber(lineNumber.getLineNumber()); } case DebugItemType.SET_SOURCE_FILE: { SetSourceFile setSourceFile = (SetSourceFile)debugItem; - return new BuilderSetSourceFile(location, setSourceFile.getSourceFileReference()); + return new BuilderSetSourceFile(setSourceFile.getSourceFileReference()); } default: throw new ExceptionWithContext("Invalid debug item type: " + debugItem.getDebugItemType()); diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderEndLocal.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderEndLocal.java index 978a0a65..a3e333df 100644 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderEndLocal.java +++ b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderEndLocal.java @@ -33,18 +33,14 @@ package org.jf.dexlib2.builder.debug; import org.jf.dexlib2.DebugItemType; import org.jf.dexlib2.builder.BuilderDebugItem; -import org.jf.dexlib2.builder.MethodLocation; import org.jf.dexlib2.iface.debug.EndLocal; -import javax.annotation.Nonnull; import javax.annotation.Nullable; public class BuilderEndLocal extends BuilderDebugItem implements EndLocal { private final int register; - public BuilderEndLocal(@Nonnull MethodLocation location, - int register) { - super(location); + public BuilderEndLocal(int register) { this.register = register; } diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderEpilogueBegin.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderEpilogueBegin.java index ac27f804..65309e79 100644 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderEpilogueBegin.java +++ b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderEpilogueBegin.java @@ -33,14 +33,10 @@ package org.jf.dexlib2.builder.debug; import org.jf.dexlib2.DebugItemType; import org.jf.dexlib2.builder.BuilderDebugItem; -import org.jf.dexlib2.builder.MethodLocation; import org.jf.dexlib2.iface.debug.EpilogueBegin; -import javax.annotation.Nonnull; - public class BuilderEpilogueBegin extends BuilderDebugItem implements EpilogueBegin { - public BuilderEpilogueBegin(@Nonnull MethodLocation location) { - super(location); + public BuilderEpilogueBegin() { } @Override public int getDebugItemType() { return DebugItemType.EPILOGUE_BEGIN; } diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderLineNumber.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderLineNumber.java index 0d69f0a8..4428499f 100644 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderLineNumber.java +++ b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderLineNumber.java @@ -33,17 +33,12 @@ package org.jf.dexlib2.builder.debug; import org.jf.dexlib2.DebugItemType; import org.jf.dexlib2.builder.BuilderDebugItem; -import org.jf.dexlib2.builder.MethodLocation; import org.jf.dexlib2.iface.debug.LineNumber; -import javax.annotation.Nonnull; - public class BuilderLineNumber extends BuilderDebugItem implements LineNumber { private final int lineNumber; - public BuilderLineNumber(@Nonnull MethodLocation location, - int lineNumber) { - super(location); + public BuilderLineNumber(int lineNumber) { this.lineNumber = lineNumber; } diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderPrologueEnd.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderPrologueEnd.java index 6df4473a..d0732296 100644 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderPrologueEnd.java +++ b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderPrologueEnd.java @@ -33,14 +33,10 @@ package org.jf.dexlib2.builder.debug; import org.jf.dexlib2.DebugItemType; import org.jf.dexlib2.builder.BuilderDebugItem; -import org.jf.dexlib2.builder.MethodLocation; import org.jf.dexlib2.iface.debug.PrologueEnd; -import javax.annotation.Nonnull; - public class BuilderPrologueEnd extends BuilderDebugItem implements PrologueEnd { - public BuilderPrologueEnd(@Nonnull MethodLocation location) { - super(location); + public BuilderPrologueEnd() { } @Override public int getDebugItemType() { return DebugItemType.PROLOGUE_END; } diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderRestartLocal.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderRestartLocal.java index 5f20ae48..7ed60c8d 100644 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderRestartLocal.java +++ b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderRestartLocal.java @@ -33,18 +33,14 @@ package org.jf.dexlib2.builder.debug; import org.jf.dexlib2.DebugItemType; import org.jf.dexlib2.builder.BuilderDebugItem; -import org.jf.dexlib2.builder.MethodLocation; import org.jf.dexlib2.iface.debug.RestartLocal; -import javax.annotation.Nonnull; import javax.annotation.Nullable; public class BuilderRestartLocal extends BuilderDebugItem implements RestartLocal { private final int register; - public BuilderRestartLocal(@Nonnull MethodLocation location, - int register) { - super(location); + public BuilderRestartLocal(int register) { this.register = register; } diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderSetSourceFile.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderSetSourceFile.java index 1a04def0..562d5601 100644 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderSetSourceFile.java +++ b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderSetSourceFile.java @@ -33,20 +33,16 @@ package org.jf.dexlib2.builder.debug; import org.jf.dexlib2.DebugItemType; import org.jf.dexlib2.builder.BuilderDebugItem; -import org.jf.dexlib2.builder.MethodLocation; import org.jf.dexlib2.iface.debug.SetSourceFile; import org.jf.dexlib2.iface.reference.StringReference; -import javax.annotation.Nonnull; import javax.annotation.Nullable; public class BuilderSetSourceFile extends BuilderDebugItem implements SetSourceFile { @Nullable private final StringReference sourceFile; - public BuilderSetSourceFile(@Nonnull MethodLocation location, - @Nullable StringReference sourceFile) { - super(location); + public BuilderSetSourceFile(@Nullable StringReference sourceFile) { this.sourceFile = sourceFile; } diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderStartLocal.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderStartLocal.java index cbf515ce..3470d041 100644 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderStartLocal.java +++ b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/builder/debug/BuilderStartLocal.java @@ -33,12 +33,10 @@ package org.jf.dexlib2.builder.debug; import org.jf.dexlib2.DebugItemType; import org.jf.dexlib2.builder.BuilderDebugItem; -import org.jf.dexlib2.builder.MethodLocation; import org.jf.dexlib2.iface.debug.StartLocal; import org.jf.dexlib2.iface.reference.StringReference; import org.jf.dexlib2.iface.reference.TypeReference; -import javax.annotation.Nonnull; import javax.annotation.Nullable; public class BuilderStartLocal extends BuilderDebugItem implements StartLocal { @@ -47,12 +45,10 @@ public class BuilderStartLocal extends BuilderDebugItem implements StartLocal { @Nullable private final TypeReference type; @Nullable private final StringReference signature; - public BuilderStartLocal(@Nonnull MethodLocation location, - int register, + public BuilderStartLocal(int register, @Nullable StringReference name, @Nullable TypeReference type, @Nullable StringReference signature) { - super(location); this.register = register; this.name = name; this.type = type; diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/immutable/ImmutableClassDef.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/immutable/ImmutableClassDef.java index a23b90a3..42e14549 100644 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/immutable/ImmutableClassDef.java +++ b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/immutable/ImmutableClassDef.java @@ -31,10 +31,7 @@ package org.jf.dexlib2.immutable; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSortedSet; -import com.google.common.collect.Iterables; -import com.google.common.collect.Iterators; +import com.google.common.collect.*; import org.jf.dexlib2.base.reference.BaseTypeReference; import org.jf.dexlib2.iface.Annotation; import org.jf.dexlib2.iface.ClassDef; @@ -71,6 +68,13 @@ public class ImmutableClassDef extends BaseTypeReference implements ClassDef { @Nullable Collection annotations, @Nullable Iterable fields, @Nullable Iterable methods) { + if (fields == null) { + fields = ImmutableList.of(); + } + if (methods == null) { + methods = ImmutableList.of(); + } + this.type = type; this.accessFlags = accessFlags; this.superclass = superclass; diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java index 0a26a5f7..ed591f7a 100644 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java +++ b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java @@ -31,10 +31,7 @@ package org.jf.dexlib2.writer; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Ordering; +import com.google.common.collect.*; import org.jf.dexlib2.AccessFlags; import org.jf.dexlib2.Opcode; import org.jf.dexlib2.ReferenceType; @@ -80,7 +77,6 @@ public abstract class DexWriter< StringKey extends CharSequence, StringRef extends StringReference, TypeKey extends CharSequence, TypeRef extends TypeReference, ProtoKey extends Comparable, FieldRefKey extends FieldReference, MethodRefKey extends MethodReference, - BaseReference extends Reference, ClassKey extends Comparable, AnnotationKey extends Annotation, AnnotationSetKey, TypeListKey, @@ -117,8 +113,6 @@ public abstract class DexWriter< protected int numCodeItemItems = 0; protected int numClassDataItems = 0; - protected final InstructionFactory instructionFactory; - protected final StringSection stringSection; protected final TypeSection typeSection; protected final ProtoSection protoSection; @@ -132,7 +126,6 @@ public abstract class DexWriter< protected final AnnotationSetSection annotationSetSection; protected DexWriter(int api, - InstructionFactory instructionFactory, StringSection stringSection, TypeSection typeSection, ProtoSection protoSection, @@ -145,7 +138,6 @@ public abstract class DexWriter< EncodedValue> annotationSection, AnnotationSetSection annotationSetSection) { this.api = api; - this.instructionFactory = instructionFactory; this.stringSection = stringSection; this.typeSection = typeSection; this.protoSection = protoSection; @@ -816,7 +808,8 @@ public abstract class DexWriter< } } - if (debugItems == null && parameterCount == 0) { + + if (parameterCount == 0 && (debugItems == null || Iterables.isEmpty(debugItems))) { return NO_OFFSET; } @@ -1179,11 +1172,8 @@ public abstract class DexWriter< } private void writeHeader(@Nonnull DexDataWriter writer, int dataOffset, int fileSize) throws IOException { - if (api < 14) { - writer.write(HeaderItem.MAGIC_VALUES[0]); - } else { - writer.write(HeaderItem.MAGIC_VALUES[1]); - } + // always write the 035 version, there's no reason to use the 036 version for now + writer.write(HeaderItem.MAGIC_VALUES[0]); // checksum placeholder writer.writeInt(0); diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderClassDef.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderClassDef.java index fd5cc540..46e75ce0 100644 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderClassDef.java +++ b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderClassDef.java @@ -67,26 +67,23 @@ public class BuilderClassDef extends BaseTypeReference implements ClassDef { @Nonnull BuilderAnnotationSet annotations, @Nullable Iterable fields, @Nullable Iterable methods) { + if (fields == null) { + fields = ImmutableList.of(); + } + if (methods == null) { + methods = ImmutableList.of(); + } + this.type = type; this.accessFlags = accessFlags; this.superclass = superclass; this.interfaces = interfaces; this.sourceFile = sourceFile; this.annotations = annotations; - if (fields == null) { - this.staticFields = ImmutableSortedSet.of(); - this.instanceFields = ImmutableSortedSet.of(); - } else { - this.staticFields = ImmutableSortedSet.copyOf(Iterables.filter(fields, FieldUtil.FIELD_IS_STATIC)); - this.instanceFields = ImmutableSortedSet.copyOf(Iterables.filter(fields, FieldUtil.FIELD_IS_INSTANCE)); - } - if (methods == null) { - this.directMethods = ImmutableSortedSet.of(); - this.virtualMethods = ImmutableSortedSet.of(); - } else { - this.directMethods = ImmutableSortedSet.copyOf(Iterables.filter(methods, MethodUtil.METHOD_IS_DIRECT)); - this.virtualMethods = ImmutableSortedSet.copyOf(Iterables.filter(methods, MethodUtil.METHOD_IS_VIRTUAL)); - } + this.staticFields = ImmutableSortedSet.copyOf(Iterables.filter(fields, FieldUtil.FIELD_IS_STATIC)); + this.instanceFields = ImmutableSortedSet.copyOf(Iterables.filter(fields, FieldUtil.FIELD_IS_INSTANCE)); + this.directMethods = ImmutableSortedSet.copyOf(Iterables.filter(methods, MethodUtil.METHOD_IS_DIRECT)); + this.virtualMethods = ImmutableSortedSet.copyOf(Iterables.filter(methods, MethodUtil.METHOD_IS_VIRTUAL)); } @Nonnull @Override public String getType() { return type.getType(); } diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderInstruction.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderInstruction.java deleted file mode 100644 index c82d28ab..00000000 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderInstruction.java +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright 2013, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib2.writer.builder; - -import com.google.common.collect.ImmutableList; -import org.jf.dexlib2.Format; -import org.jf.dexlib2.Opcode; -import org.jf.dexlib2.iface.instruction.Instruction; -import org.jf.dexlib2.iface.instruction.SwitchElement; -import org.jf.dexlib2.iface.instruction.formats.*; -import org.jf.dexlib2.immutable.instruction.*; -import org.jf.dexlib2.util.Preconditions; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.List; - -public interface BuilderInstruction extends Instruction { - static abstract class BaseBuilderInstruction implements BuilderInstruction { - @Nonnull protected final Opcode opcode; - - public BaseBuilderInstruction(@Nonnull Opcode opcode) { - Preconditions.checkFormat(opcode, getFormat()); - this.opcode = opcode; - } - - @Nonnull public abstract Format getFormat(); - - @Nonnull @Override public Opcode getOpcode() { - return opcode; - } - - @Override public int getCodeUnits() { - return getFormat().size/2; - } - } - - public static class BuilderInstruction10t extends ImmutableInstruction10t implements BuilderInstruction { - public BuilderInstruction10t(@Nonnull Opcode opcode, int codeOffset) { - super(opcode, codeOffset); - } - } - - public static class BuilderInstruction10x extends ImmutableInstruction10x implements BuilderInstruction { - public BuilderInstruction10x(@Nonnull Opcode opcode) { - super(opcode); - } - } - - public static class BuilderInstruction11n extends ImmutableInstruction11n implements BuilderInstruction { - public BuilderInstruction11n(@Nonnull Opcode opcode, int registerA, int literal) { - super(opcode, registerA, literal); - } - } - - public static class BuilderInstruction11x extends ImmutableInstruction11x implements BuilderInstruction { - public BuilderInstruction11x(@Nonnull Opcode opcode, int registerA) { - super(opcode, registerA); - } - } - - public static class BuilderInstruction12x extends ImmutableInstruction12x implements BuilderInstruction { - public BuilderInstruction12x(@Nonnull Opcode opcode, int registerA, int registerB) { - super(opcode, registerA, registerB); - } - } - - public static class BuilderInstruction20bc extends BaseBuilderInstruction implements Instruction20bc { - public static final Format FORMAT = Format.Format20bc; - - protected final int verificationError; - @Nonnull protected final BuilderReference reference; - - public BuilderInstruction20bc(@Nonnull Opcode opcode, - int verificationError, - @Nonnull BuilderReference reference) { - super(opcode); - this.verificationError = Preconditions.checkVerificationError(verificationError); - this.reference = Preconditions.checkReference(opcode.referenceType, reference); - } - - @Override public int getVerificationError() { return verificationError; } - @Nonnull @Override public BuilderReference getReference() { return reference; } - - @Nonnull @Override public Format getFormat() { return FORMAT; } - } - - public static class BuilderInstruction20t extends ImmutableInstruction20t implements BuilderInstruction { - public BuilderInstruction20t(@Nonnull Opcode opcode, int codeOffset) { - super(opcode, codeOffset); - } - } - - public static class BuilderInstruction21c extends BaseBuilderInstruction implements Instruction21c { - public static final Format FORMAT = Format.Format21c; - - protected final int registerA; - @Nonnull protected final BuilderReference reference; - - public BuilderInstruction21c(@Nonnull Opcode opcode, - int registerA, - @Nonnull BuilderReference reference) { - super(opcode); - this.registerA = Preconditions.checkByteRegister(registerA); - this.reference = Preconditions.checkReference(opcode.referenceType, reference); - } - - @Override public int getRegisterA() { return registerA; } - @Nonnull @Override public BuilderReference getReference() { return reference; } - - @Nonnull @Override public Format getFormat() { return FORMAT; } - } - - public static class BuilderInstruction21ih extends ImmutableInstruction21ih implements BuilderInstruction { - public BuilderInstruction21ih(@Nonnull Opcode opcode, int registerA, int literal) { - super(opcode, registerA, literal); - } - } - - public static class BuilderInstruction21lh extends ImmutableInstruction21lh implements BuilderInstruction { - public BuilderInstruction21lh(@Nonnull Opcode opcode, int registerA, long literal) { - super(opcode, registerA, literal); - } - } - - public static class BuilderInstruction21s extends ImmutableInstruction21s implements BuilderInstruction { - public BuilderInstruction21s(@Nonnull Opcode opcode, int registerA, int literal) { - super(opcode, registerA, literal); - } - } - - public static class BuilderInstruction21t extends ImmutableInstruction21t implements BuilderInstruction { - public BuilderInstruction21t(@Nonnull Opcode opcode, int registerA, int codeOffset) { - super(opcode, registerA, codeOffset); - } - } - - public static class BuilderInstruction22b extends ImmutableInstruction22b implements BuilderInstruction { - public BuilderInstruction22b(@Nonnull Opcode opcode, int registerA, int registerB, int literal) { - super(opcode, registerA, registerB, literal); - } - } - - public static class BuilderInstruction22c extends BaseBuilderInstruction implements Instruction22c { - public static final Format FORMAT = Format.Format22c; - - protected final int registerA; - protected final int registerB; - @Nonnull protected final BuilderReference reference; - - public BuilderInstruction22c(@Nonnull Opcode opcode, - int registerA, - int registerB, - @Nonnull BuilderReference reference) { - super(opcode); - this.registerA = Preconditions.checkNibbleRegister(registerA); - this.registerB = Preconditions.checkNibbleRegister(registerB); - this.reference = Preconditions.checkReference(opcode.referenceType, reference); - } - - @Override public int getRegisterA() { return registerA; } - @Override public int getRegisterB() { return registerB; } - @Nonnull @Override public BuilderReference getReference() { return reference; } - - @Nonnull @Override public Format getFormat() { return FORMAT; } - } - - public static class BuilderInstruction22s extends ImmutableInstruction22s implements BuilderInstruction { - public BuilderInstruction22s(@Nonnull Opcode opcode, int registerA, int registerB, int literal) { - super(opcode, registerA, registerB, literal); - } - } - - public static class BuilderInstruction22t extends ImmutableInstruction22t implements BuilderInstruction { - public BuilderInstruction22t(@Nonnull Opcode opcode, int registerA, int registerB, int codeOffset) { - super(opcode, registerA, registerB, codeOffset); - } - } - - public static class BuilderInstruction22x extends ImmutableInstruction22x implements BuilderInstruction { - public BuilderInstruction22x(@Nonnull Opcode opcode, int registerA, int registerB) { - super(opcode, registerA, registerB); - } - } - - public static class BuilderInstruction23x extends ImmutableInstruction23x implements BuilderInstruction { - public BuilderInstruction23x(@Nonnull Opcode opcode, int registerA, int registerB, int registerC) { - super(opcode, registerA, registerB, registerC); - } - } - - public static class BuilderInstruction30t extends ImmutableInstruction30t implements BuilderInstruction { - public BuilderInstruction30t(@Nonnull Opcode opcode, int codeOffset) { - super(opcode, codeOffset); - } - } - - public static class BuilderInstruction31c extends BaseBuilderInstruction implements Instruction31c { - public static final Format FORMAT = Format.Format31c; - - protected final int registerA; - @Nonnull protected final BuilderReference reference; - - public BuilderInstruction31c(@Nonnull Opcode opcode, - int registerA, - @Nonnull BuilderReference reference) { - super(opcode); - this.registerA = Preconditions.checkByteRegister(registerA); - this.reference = Preconditions.checkReference(opcode.referenceType, reference); - } - - @Override public int getRegisterA() { return registerA; } - @Nonnull @Override public BuilderReference getReference() { return reference; } - - @Nonnull @Override public Format getFormat() { return FORMAT; } - } - - public static class BuilderInstruction31i extends ImmutableInstruction31i implements BuilderInstruction { - public BuilderInstruction31i(@Nonnull Opcode opcode, int registerA, int literal) { - super(opcode, registerA, literal); - } - } - - public static class BuilderInstruction31t extends ImmutableInstruction31t implements BuilderInstruction { - public BuilderInstruction31t(@Nonnull Opcode opcode, int registerA, int codeOffset) { - super(opcode, registerA, codeOffset); - } - } - - public static class BuilderInstruction32x extends ImmutableInstruction32x implements BuilderInstruction { - public BuilderInstruction32x(@Nonnull Opcode opcode, int registerA, int registerB) { - super(opcode, registerA, registerB); - } - } - - public static class BuilderInstruction35c extends BaseBuilderInstruction implements Instruction35c { - public static final Format FORMAT = Format.Format35c; - - protected final int registerCount; - protected final int registerC; - protected final int registerD; - protected final int registerE; - protected final int registerF; - protected final int registerG; - @Nonnull protected final BuilderReference reference; - - public BuilderInstruction35c(@Nonnull Opcode opcode, - int registerCount, - int registerC, - int registerD, - int registerE, - int registerF, - int registerG, - @Nonnull BuilderReference reference) { - super(opcode); - this.registerCount = Preconditions.check35cRegisterCount(registerCount); - this.registerC = (registerCount>0) ? Preconditions.checkNibbleRegister(registerC) : 0; - this.registerD = (registerCount>1) ? Preconditions.checkNibbleRegister(registerD) : 0; - this.registerE = (registerCount>2) ? Preconditions.checkNibbleRegister(registerE) : 0; - this.registerF = (registerCount>3) ? Preconditions.checkNibbleRegister(registerF) : 0; - this.registerG = (registerCount>4) ? Preconditions.checkNibbleRegister(registerG) : 0; - this.reference = Preconditions.checkReference(opcode.referenceType, reference); - } - - @Override public int getRegisterCount() { return registerCount; } - @Override public int getRegisterC() { return registerC; } - @Override public int getRegisterD() { return registerD; } - @Override public int getRegisterE() { return registerE; } - @Override public int getRegisterF() { return registerF; } - @Override public int getRegisterG() { return registerG; } - @Nonnull @Override public BuilderReference getReference() { return reference; } - - @Nonnull @Override public Format getFormat() { return FORMAT; } - } - - public static class BuilderInstruction3rc extends BaseBuilderInstruction implements Instruction3rc { - public static final Format FORMAT = Format.Format3rc; - - private final int startRegister; - private final int registerCount; - - @Nonnull protected final BuilderReference reference; - - public BuilderInstruction3rc(@Nonnull Opcode opcode, - int startRegister, - int registerCount, - @Nonnull BuilderReference reference) { - super(opcode); - this.startRegister = Preconditions.checkShortRegister(startRegister); - this.registerCount = Preconditions.checkRegisterRangeCount(registerCount); - this.reference = Preconditions.checkReference(opcode.referenceType, reference); - } - - @Nonnull @Override public BuilderReference getReference() { - return reference; - } - - @Override public int getStartRegister() { - return startRegister; - } - - @Override public int getRegisterCount() { - return registerCount; - } - - @Nonnull @Override public Format getFormat() { - return FORMAT; - } - } - - public static class BuilderInstruction51l extends ImmutableInstruction51l implements BuilderInstruction { - public BuilderInstruction51l(@Nonnull Opcode opcode, int registerA, long literal) { - super(opcode, registerA, literal); - } - } - - public static class BuilderArrayPayload extends BaseBuilderInstruction implements ArrayPayload { - public static final Format FORMAT = Format.ArrayPayload; - private final int elementWidth; - @Nonnull private final List arrayElements; - - public BuilderArrayPayload(int elementWidth, @Nullable List arrayElements) { - super(Opcode.ARRAY_PAYLOAD); - this.elementWidth = elementWidth; - if (arrayElements == null) { - arrayElements = ImmutableList.of(); - } - this.arrayElements = arrayElements; - } - - @Override public int getElementWidth() { - return elementWidth; - } - - @Nonnull @Override public List getArrayElements() { - return arrayElements; - } - - @Nonnull @Override public Format getFormat() { - return FORMAT; - } - - @Override public int getCodeUnits() { - return 4 + (elementWidth * arrayElements.size() + 1) / 2; - } - } - - public static class BuilderPackedSwitchPayload extends BaseBuilderInstruction implements PackedSwitchPayload { - public static final Format FORMAT = Format.PackedSwitchPayload; - @Nonnull private final List elements; - - public BuilderPackedSwitchPayload(@Nullable List switchElements) { - super(Opcode.PACKED_SWITCH_PAYLOAD); - if (switchElements == null) { - switchElements = ImmutableList.of(); - } - this.elements = switchElements; - } - - @Nonnull @Override public List getSwitchElements() { - return elements; - } - - @Nonnull @Override public Format getFormat() { - return FORMAT; - } - - @Override public int getCodeUnits() { - return 4 + elements.size() * 2; - } - } - - public static class BuilderSparseSwitchPayload extends BaseBuilderInstruction implements SparseSwitchPayload { - public static final Format FORMAT = Format.SparseSwitchPayload; - @Nonnull private final List elements; - - public BuilderSparseSwitchPayload(@Nullable List switchElements) { - super(Opcode.SPARSE_SWITCH_PAYLOAD); - if (switchElements == null) { - switchElements = ImmutableList.of(); - } - this.elements = switchElements; - } - - @Nonnull @Override public List getSwitchElements() { - return elements; - } - - @Nonnull @Override public Format getFormat() { - return FORMAT; - } - - @Override public int getCodeUnits() { - return 2 + elements.size() * 4; - } - } -} diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderInstructionFactory.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderInstructionFactory.java deleted file mode 100644 index 280c318d..00000000 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderInstructionFactory.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright 2013, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.jf.dexlib2.writer.builder; - -import org.jf.dexlib2.Opcode; -import org.jf.dexlib2.iface.instruction.SwitchElement; -import org.jf.dexlib2.writer.InstructionFactory; -import org.jf.dexlib2.writer.builder.BuilderInstruction.*; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.List; - -public class BuilderInstructionFactory implements InstructionFactory { - public static final BuilderInstructionFactory INSTANCE = new BuilderInstructionFactory(); - - private BuilderInstructionFactory() { - } - - public BuilderInstruction10t makeInstruction10t(@Nonnull Opcode opcode, - int codeOffset) { - return new BuilderInstruction10t(opcode, codeOffset); - } - - public BuilderInstruction10x makeInstruction10x(@Nonnull Opcode opcode) { - return new BuilderInstruction10x(opcode); - } - - public BuilderInstruction11n makeInstruction11n(@Nonnull Opcode opcode, - int registerA, - int literal) { - return new BuilderInstruction11n(opcode, registerA, literal); - } - - public BuilderInstruction11x makeInstruction11x(@Nonnull Opcode opcode, - int registerA) { - return new BuilderInstruction11x(opcode, registerA); - } - - public BuilderInstruction12x makeInstruction12x(@Nonnull Opcode opcode, - int registerA, - int registerB) { - return new BuilderInstruction12x(opcode, registerA, registerB); - } - - public BuilderInstruction20bc makeInstruction20bc(@Nonnull Opcode opcode, - int verificationError, - @Nonnull BuilderReference reference) { - return new BuilderInstruction20bc(opcode, verificationError, reference); - } - - public BuilderInstruction20t makeInstruction20t(@Nonnull Opcode opcode, - int codeOffset) { - return new BuilderInstruction20t(opcode, codeOffset); - } - - public BuilderInstruction21c makeInstruction21c(@Nonnull Opcode opcode, - int registerA, - @Nonnull BuilderReference reference) { - return new BuilderInstruction21c(opcode, registerA, reference); - } - - public BuilderInstruction21ih makeInstruction21ih(@Nonnull Opcode opcode, - int registerA, - int literal) { - return new BuilderInstruction21ih(opcode, registerA, literal); - } - - public BuilderInstruction21lh makeInstruction21lh(@Nonnull Opcode opcode, - int registerA, - long literal) { - return new BuilderInstruction21lh(opcode, registerA, literal); - } - - public BuilderInstruction21s makeInstruction21s(@Nonnull Opcode opcode, - int registerA, - int literal) { - return new BuilderInstruction21s(opcode, registerA, literal); - } - - public BuilderInstruction21t makeInstruction21t(@Nonnull Opcode opcode, - int registerA, - int codeOffset) { - return new BuilderInstruction21t(opcode, registerA, codeOffset); - } - - public BuilderInstruction22b makeInstruction22b(@Nonnull Opcode opcode, - int registerA, - int registerB, - int literal) { - return new BuilderInstruction22b(opcode, registerA, registerB, literal); - } - - public BuilderInstruction22c makeInstruction22c(@Nonnull Opcode opcode, - int registerA, - int registerB, - @Nonnull BuilderReference reference) { - return new BuilderInstruction22c(opcode, registerA, registerB, reference); - } - - public BuilderInstruction22s makeInstruction22s(@Nonnull Opcode opcode, - int registerA, - int registerB, - int literal) { - return new BuilderInstruction22s(opcode, registerA, registerB, literal); - } - - public BuilderInstruction22t makeInstruction22t(@Nonnull Opcode opcode, - int registerA, - int registerB, - int codeOffset) { - return new BuilderInstruction22t(opcode, registerA, registerB, codeOffset); - } - - public BuilderInstruction22x makeInstruction22x(@Nonnull Opcode opcode, - int registerA, - int registerB) { - return new BuilderInstruction22x(opcode, registerA, registerB); - } - - public BuilderInstruction23x makeInstruction23x(@Nonnull Opcode opcode, - int registerA, - int registerB, - int registerC) { - return new BuilderInstruction23x(opcode, registerA, registerB, registerC); - } - - public BuilderInstruction30t makeInstruction30t(@Nonnull Opcode opcode, - int codeOffset) { - return new BuilderInstruction30t(opcode, codeOffset); - } - - public BuilderInstruction31c makeInstruction31c(@Nonnull Opcode opcode, - int registerA, - @Nonnull BuilderReference reference) { - return new BuilderInstruction31c(opcode, registerA, reference); - } - - public BuilderInstruction31i makeInstruction31i(@Nonnull Opcode opcode, - int registerA, - int literal) { - return new BuilderInstruction31i(opcode, registerA, literal); - } - - public BuilderInstruction31t makeInstruction31t(@Nonnull Opcode opcode, - int registerA, - int codeOffset) { - return new BuilderInstruction31t(opcode, registerA, codeOffset); - } - - public BuilderInstruction32x makeInstruction32x(@Nonnull Opcode opcode, - int registerA, - int registerB) { - return new BuilderInstruction32x(opcode, registerA, registerB); - } - - public BuilderInstruction35c makeInstruction35c(@Nonnull Opcode opcode, - int registerCount, - int registerC, - int registerD, - int registerE, - int registerF, - int registerG, - @Nonnull BuilderReference reference) { - return new BuilderInstruction35c(opcode, registerCount, registerC, registerD, registerE, registerF, registerG, - reference); - } - - public BuilderInstruction3rc makeInstruction3rc(@Nonnull Opcode opcode, - int startRegister, - int registerCount, - @Nonnull BuilderReference reference) { - return new BuilderInstruction3rc(opcode, startRegister, registerCount, reference); - } - - public BuilderInstruction51l makeInstruction51l(@Nonnull Opcode opcode, - int registerA, - long literal) { - return new BuilderInstruction51l(opcode, registerA, literal); - } - - public BuilderSparseSwitchPayload makeSparseSwitchPayload(@Nullable List switchElements) { - return new BuilderSparseSwitchPayload(switchElements); - } - - public BuilderPackedSwitchPayload makePackedSwitchPayload(@Nullable List switchElements) { - return new BuilderPackedSwitchPayload(switchElements); - } - - public BuilderArrayPayload makeArrayPayload(int elementWidth, - @Nullable List arrayElements) { - return new BuilderArrayPayload(elementWidth, arrayElements); - } -} diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/DexBuilder.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/DexBuilder.java index aabf071e..469a3324 100644 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/DexBuilder.java +++ b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/DexBuilder.java @@ -54,7 +54,7 @@ import java.util.List; import java.util.Set; public class DexBuilder extends DexWriter { @@ -71,7 +71,7 @@ public class DexBuilder extends DexWriter, TypeListPool.Key>, Field, PoolMethod, EncodedValue, AnnotationElement> { @@ -79,7 +78,7 @@ public class DexPool extends DexWriter instructionFactory = - BuilderInstructionFactory.INSTANCE; public void setDexBuilder(DexBuilder dexBuilder) { this.dexBuilder = dexBuilder;