remove smali project in preps for submodule

This commit is contained in:
Connor Tumbleson 2015-10-14 06:22:32 -05:00
parent 5e4bae0526
commit 7316a6935b
723 changed files with 0 additions and 75739 deletions

View File

@ -1,6 +0,0 @@
/baksmali/target/
/dexlib/target/
/maven-smali-plugin/target/
/smali/target/
/util/target/
*~

View File

@ -1,49 +0,0 @@
The majority of smali/baksmali is written and copyrighted by me (Ben Gruver)
and released under the following license:
*******************************************************************************
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.
*******************************************************************************
Various portions of the code are taken from the Android Open Source Project,
and are used in accordance with the following license:
*******************************************************************************
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.
*******************************************************************************

View File

@ -1,84 +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.
*/
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath depends.proguard_gradle
}
}
dependencies {
compile project(':brut.apktool.smali:util')
compile project(':brut.apktool.smali:dexlib2')
compile depends.commons_cli
compile depends.guava
testCompile depends.junit
testCompile project(':brut.apktool.smali:smali')
}
processResources.inputs.property('version', version)
processResources.expand('version': version)
// build a jar containing all dependencies
task fatJar (type: Jar) {
from sourceSets.main.output
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
manifest {
attributes('Main-Class': 'org.jf.baksmali.main')
}
}
tasks.getByPath('build').dependsOn(fatJar)
task proguard(type: proguard.gradle.ProGuardTask, dependsOn: fatJar) {
def outFile = fatJar.destinationDir.getPath() + '/' + fatJar.baseName + '-' + fatJar.version + '-small' + '.' + fatJar.extension
injars fatJar.archivePath
outjars outFile
libraryjars "${System.properties['java.home']}/lib/rt.jar"
dontobfuscate
dontoptimize
keep 'public class org.jf.baksmali.main { public static void main(java.lang.String[]); }'
keepclassmembers 'enum * { public static **[] values(); public static ** valueOf(java.lang.String); }'
dontwarn 'com.google.common.**'
dontnote 'com.google.common.**'
}
tasks.getByPath(':release').dependsOn(proguard)

View File

@ -1,69 +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.baksmali.Adaptors;
import org.jf.baksmali.Adaptors.EncodedValue.AnnotationEncodedValueAdaptor;
import org.jf.dexlib2.AnnotationVisibility;
import org.jf.dexlib2.iface.Annotation;
import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Collection;
public class AnnotationFormatter {
public static void writeTo(@Nonnull IndentingWriter writer,
@Nonnull Collection<? extends Annotation> annotations,
@Nullable String containingClass) throws IOException {
boolean first = true;
for (Annotation annotation: annotations) {
if (!first) {
writer.write('\n');
}
first = false;
writeTo(writer, annotation, containingClass);
}
}
public static void writeTo(@Nonnull IndentingWriter writer, @Nonnull Annotation annotation,
@Nullable String containingClass) throws IOException {
writer.write(".annotation ");
writer.write(AnnotationVisibility.getVisibility(annotation.getVisibility()));
writer.write(' ');
writer.write(annotation.getType());
writer.write('\n');
AnnotationEncodedValueAdaptor.writeElementsTo(writer, annotation.getElements(), containingClass);
writer.write(".end annotation\n");
}
}

View File

@ -1,48 +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.baksmali.Adaptors;
import org.jf.util.IndentingWriter;
//a "spacer" between instructions
public class BlankMethodItem extends MethodItem {
public BlankMethodItem(int codeAddress) {
super(codeAddress);
}
public double getSortOrder() {
return Integer.MAX_VALUE;
}
public boolean writeTo(IndentingWriter writer) {
//we didn't technically print something, but returning true indicates that a newline should be printed
//after this method item, which is the intended functionality
return true;
}
}

View File

@ -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.baksmali.Adaptors;
import org.jf.baksmali.baksmaliOptions;
import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
public class CatchMethodItem extends MethodItem {
private final String exceptionType;
private final LabelMethodItem tryStartLabel;
private final LabelMethodItem tryEndLabel;
private final LabelMethodItem handlerLabel;
public CatchMethodItem(@Nonnull baksmaliOptions options, @Nonnull MethodDefinition.LabelCache labelCache,
int codeAddress, @Nullable String exceptionType, int startAddress, int endAddress,
int handlerAddress) {
super(codeAddress);
this.exceptionType = exceptionType;
tryStartLabel = labelCache.internLabel(new LabelMethodItem(options, startAddress, "try_start_"));
//use the address from the last covered instruction, but make the label
//name refer to the address of the next instruction
tryEndLabel = labelCache.internLabel(new EndTryLabelMethodItem(options, codeAddress, endAddress));
if (exceptionType == null) {
handlerLabel = labelCache.internLabel(new LabelMethodItem(options, handlerAddress, "catchall_"));
} else {
handlerLabel = labelCache.internLabel(new LabelMethodItem(options, handlerAddress, "catch_"));
}
}
public LabelMethodItem getTryStartLabel() {
return tryStartLabel;
}
public LabelMethodItem getTryEndLabel() {
return tryEndLabel;
}
public LabelMethodItem getHandlerLabel() {
return handlerLabel;
}
public double getSortOrder() {
//sort after instruction and end_try label
return 102;
}
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
if (exceptionType == null) {
writer.write(".catchall");
} else {
writer.write(".catch ");
writer.write(exceptionType);
}
writer.write(" {");
tryStartLabel.writeTo(writer);
writer.write(" .. ");
tryEndLabel.writeTo(writer);
writer.write("} ");
handlerLabel.writeTo(writer);
return true;
}
}

View File

@ -1,331 +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.baksmali.Adaptors;
import com.google.common.collect.Lists;
import org.jf.baksmali.baksmaliOptions;
import org.jf.dexlib2.AccessFlags;
import org.jf.dexlib2.dexbacked.DexBackedClassDef;
import org.jf.dexlib2.dexbacked.DexBackedDexFile.InvalidItemIndex;
import org.jf.dexlib2.iface.*;
import org.jf.dexlib2.iface.instruction.Instruction;
import org.jf.dexlib2.iface.instruction.formats.Instruction21c;
import org.jf.dexlib2.iface.reference.FieldReference;
import org.jf.dexlib2.util.ReferenceUtil;
import org.jf.util.IndentingWriter;
import org.jf.util.StringUtils;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.util.*;
public class ClassDefinition {
@Nonnull public final baksmaliOptions options;
@Nonnull public final ClassDef classDef;
@Nonnull private final HashSet<String> fieldsSetInStaticConstructor;
protected boolean validationErrors;
public ClassDefinition(@Nonnull baksmaliOptions options, @Nonnull ClassDef classDef) {
this.options = options;
this.classDef = classDef;
fieldsSetInStaticConstructor = findFieldsSetInStaticConstructor();
}
public boolean hadValidationErrors() {
return validationErrors;
}
@Nonnull
private HashSet<String> findFieldsSetInStaticConstructor() {
HashSet<String> fieldsSetInStaticConstructor = new HashSet<String>();
for (Method method: classDef.getDirectMethods()) {
if (method.getName().equals("<clinit>")) {
MethodImplementation impl = method.getImplementation();
if (impl != null) {
for (Instruction instruction: impl.getInstructions()) {
switch (instruction.getOpcode()) {
case SPUT:
case SPUT_BOOLEAN:
case SPUT_BYTE:
case SPUT_CHAR:
case SPUT_OBJECT:
case SPUT_SHORT:
case SPUT_WIDE: {
Instruction21c ins = (Instruction21c)instruction;
FieldReference fieldRef = null;
try {
fieldRef = (FieldReference)ins.getReference();
} catch (InvalidItemIndex ex) {
// just ignore it for now. We'll deal with it later, when processing the instructions
// themselves
}
if (fieldRef != null &&
fieldRef.getDefiningClass().equals((classDef.getType()))) {
fieldsSetInStaticConstructor.add(ReferenceUtil.getShortFieldDescriptor(fieldRef));
}
break;
}
}
}
}
}
}
return fieldsSetInStaticConstructor;
}
public void writeTo(IndentingWriter writer) throws IOException {
writeClass(writer);
writeSuper(writer);
writeSourceFile(writer);
writeInterfaces(writer);
writeAnnotations(writer);
Set<String> staticFields = writeStaticFields(writer);
writeInstanceFields(writer, staticFields);
Set<String> directMethods = writeDirectMethods(writer);
writeVirtualMethods(writer, directMethods);
}
private void writeClass(IndentingWriter writer) throws IOException {
writer.write(".class ");
writeAccessFlags(writer);
writer.write(classDef.getType());
writer.write('\n');
}
private void writeAccessFlags(IndentingWriter writer) throws IOException {
for (AccessFlags accessFlag: AccessFlags.getAccessFlagsForClass(classDef.getAccessFlags())) {
writer.write(accessFlag.toString());
writer.write(' ');
}
}
private void writeSuper(IndentingWriter writer) throws IOException {
String superClass = classDef.getSuperclass();
if (superClass != null) {
writer.write(".super ");
writer.write(superClass);
writer.write('\n');
}
}
private void writeSourceFile(IndentingWriter writer) throws IOException {
String sourceFile = classDef.getSourceFile();
if (sourceFile != null) {
writer.write(".source \"");
StringUtils.writeEscapedString(writer, sourceFile);
writer.write("\"\n");
}
}
private void writeInterfaces(IndentingWriter writer) throws IOException {
List<String> interfaces = classDef.getInterfaces();
if (interfaces.size() != 0) {
writer.write('\n');
writer.write("# interfaces\n");
for (String interfaceName: interfaces) {
writer.write(".implements ");
writer.write(interfaceName);
writer.write('\n');
}
}
}
private void writeAnnotations(IndentingWriter writer) throws IOException {
Collection<? extends Annotation> classAnnotations = classDef.getAnnotations();
if (classAnnotations.size() != 0) {
writer.write("\n\n");
writer.write("# annotations\n");
String containingClass = null;
if (options.useImplicitReferences) {
containingClass = classDef.getType();
}
AnnotationFormatter.writeTo(writer, classAnnotations, containingClass);
}
}
private Set<String> writeStaticFields(IndentingWriter writer) throws IOException {
boolean wroteHeader = false;
Set<String> writtenFields = new HashSet<String>();
Iterable<? extends Field> staticFields;
if (classDef instanceof DexBackedClassDef) {
staticFields = ((DexBackedClassDef)classDef).getStaticFields(false);
} else {
staticFields = classDef.getStaticFields();
}
for (Field field: staticFields) {
if (!wroteHeader) {
writer.write("\n\n");
writer.write("# static fields");
wroteHeader = true;
}
writer.write('\n');
boolean setInStaticConstructor;
IndentingWriter fieldWriter = writer;
String fieldString = ReferenceUtil.getShortFieldDescriptor(field);
if (!writtenFields.add(fieldString)) {
writer.write("# duplicate field ignored\n");
fieldWriter = new CommentingIndentingWriter(writer);
System.err.println(String.format("Ignoring duplicate field: %s->%s", classDef.getType(), fieldString));
setInStaticConstructor = false;
} else {
setInStaticConstructor = fieldsSetInStaticConstructor.contains(fieldString);
}
FieldDefinition.writeTo(options, fieldWriter, field, setInStaticConstructor);
}
return writtenFields;
}
private void writeInstanceFields(IndentingWriter writer, Set<String> staticFields) throws IOException {
boolean wroteHeader = false;
Set<String> writtenFields = new HashSet<String>();
Iterable<? extends Field> instanceFields;
if (classDef instanceof DexBackedClassDef) {
instanceFields = ((DexBackedClassDef)classDef).getInstanceFields(false);
} else {
instanceFields = classDef.getInstanceFields();
}
for (Field field: instanceFields) {
if (!wroteHeader) {
writer.write("\n\n");
writer.write("# instance fields");
wroteHeader = true;
}
writer.write('\n');
IndentingWriter fieldWriter = writer;
String fieldString = ReferenceUtil.getShortFieldDescriptor(field);
if (!writtenFields.add(fieldString)) {
writer.write("# duplicate field ignored\n");
fieldWriter = new CommentingIndentingWriter(writer);
System.err.println(String.format("Ignoring duplicate field: %s->%s", classDef.getType(), fieldString));
} else if (staticFields.contains(fieldString)) {
System.err.println(String.format("Duplicate static+instance field found: %s->%s",
classDef.getType(), fieldString));
System.err.println("You will need to rename one of these fields, including all references.");
writer.write("# There is both a static and instance field with this signature.\n" +
"# You will need to rename one of these fields, including all references.\n");
}
FieldDefinition.writeTo(options, fieldWriter, field, false);
}
}
private Set<String> writeDirectMethods(IndentingWriter writer) throws IOException {
boolean wroteHeader = false;
Set<String> writtenMethods = new HashSet<String>();
Iterable<? extends Method> directMethods;
if (classDef instanceof DexBackedClassDef) {
directMethods = ((DexBackedClassDef)classDef).getDirectMethods(false);
} else {
directMethods = classDef.getDirectMethods();
}
for (Method method: directMethods) {
if (!wroteHeader) {
writer.write("\n\n");
writer.write("# direct methods");
wroteHeader = true;
}
writer.write('\n');
// TODO: check for method validation errors
String methodString = ReferenceUtil.getMethodDescriptor(method, true);
IndentingWriter methodWriter = writer;
if (!writtenMethods.add(methodString)) {
writer.write("# duplicate method ignored\n");
methodWriter = new CommentingIndentingWriter(writer);
}
MethodImplementation methodImpl = method.getImplementation();
if (methodImpl == null) {
MethodDefinition.writeEmptyMethodTo(methodWriter, method, options);
} else {
MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl);
methodDefinition.writeTo(methodWriter);
}
}
return writtenMethods;
}
private void writeVirtualMethods(IndentingWriter writer, Set<String> directMethods) throws IOException {
boolean wroteHeader = false;
Set<String> writtenMethods = new HashSet<String>();
Iterable<? extends Method> virtualMethods;
if (classDef instanceof DexBackedClassDef) {
virtualMethods = ((DexBackedClassDef)classDef).getVirtualMethods(false);
} else {
virtualMethods = classDef.getVirtualMethods();
}
for (Method method: virtualMethods) {
if (!wroteHeader) {
writer.write("\n\n");
writer.write("# virtual methods");
wroteHeader = true;
}
writer.write('\n');
// TODO: check for method validation errors
String methodString = ReferenceUtil.getMethodDescriptor(method, true);
IndentingWriter methodWriter = writer;
if (!writtenMethods.add(methodString)) {
writer.write("# duplicate method ignored\n");
methodWriter = new CommentingIndentingWriter(writer);
} else if (directMethods.contains(methodString)) {
writer.write("# There is both a direct and virtual method with this signature.\n" +
"# You will need to rename one of these methods, including all references.\n");
System.err.println(String.format("Duplicate direct+virtual method found: %s->%s",
classDef.getType(), methodString));
System.err.println("You will need to rename one of these methods, including all references.");
}
MethodImplementation methodImpl = method.getImplementation();
if (methodImpl == null) {
MethodDefinition.writeEmptyMethodTo(methodWriter, method, options);
} else {
MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl);
methodDefinition.writeTo(methodWriter);
}
}
}
}

View File

@ -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.baksmali.Adaptors;
import org.jf.util.IndentingWriter;
import java.io.IOException;
public class CommentMethodItem extends MethodItem {
//private final StringTemplate template;
private final String comment;
private final double sortOrder;
public CommentMethodItem(String comment, int codeAddress, double sortOrder) {
super(codeAddress);
this.comment = comment;
this.sortOrder = sortOrder;
}
public double getSortOrder() {
return sortOrder;
}
public boolean writeTo(IndentingWriter writer) throws IOException {
writer.write('#');
writer.write(comment);
return true;
}
}

View File

@ -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.baksmali.Adaptors;
import org.jf.util.IndentingWriter;
import java.io.IOException;
public class CommentedOutMethodItem extends MethodItem {
private final MethodItem commentedOutMethodItem;
public CommentedOutMethodItem(MethodItem commentedOutMethodItem) {
super(commentedOutMethodItem.getCodeAddress());
this.commentedOutMethodItem = commentedOutMethodItem;
}
public double getSortOrder() {
return commentedOutMethodItem.getSortOrder() + .001;
}
public boolean writeTo(IndentingWriter writer) throws IOException {
writer.write('#');
commentedOutMethodItem.writeTo(writer);
return true;
}
}

View File

@ -1,48 +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.baksmali.Adaptors;
import org.jf.util.IndentingWriter;
import java.io.IOException;
import java.io.Writer;
public class CommentingIndentingWriter extends IndentingWriter {
public CommentingIndentingWriter(Writer writer) {
super(writer);
}
@Override protected void writeIndent() throws IOException {
writer.write("# ");
super.writeIndent();
}
}

View File

@ -1,48 +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.baksmali.Adaptors.Debug;
import org.jf.util.IndentingWriter;
import java.io.IOException;
public class BeginEpilogueMethodItem extends DebugMethodItem {
public BeginEpilogueMethodItem(int codeAddress, int sortOrder) {
super(codeAddress, sortOrder);
}
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
writer.write(".prologue");
return true;
}
}

View File

@ -1,71 +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.baksmali.Adaptors.Debug;
import org.jf.baksmali.Adaptors.MethodItem;
import org.jf.baksmali.Adaptors.RegisterFormatter;
import org.jf.dexlib2.DebugItemType;
import org.jf.dexlib2.iface.debug.*;
import org.jf.util.ExceptionWithContext;
public abstract class DebugMethodItem extends MethodItem {
private final int sortOrder;
protected DebugMethodItem(int codeAddress, int sortOrder) {
super(codeAddress);
this.sortOrder = sortOrder;
}
@Override public double getSortOrder() { return sortOrder; }
public static DebugMethodItem build(RegisterFormatter registerFormatter, DebugItem debugItem) {
int codeAddress = debugItem.getCodeAddress();
switch (debugItem.getDebugItemType()) {
case DebugItemType.START_LOCAL:
return new StartLocalMethodItem(codeAddress, -1, registerFormatter, (StartLocal)debugItem);
case DebugItemType.END_LOCAL:
return new EndLocalMethodItem(codeAddress, -1, registerFormatter, (EndLocal)debugItem);
case DebugItemType.RESTART_LOCAL:
return new RestartLocalMethodItem(codeAddress, -1, registerFormatter, (RestartLocal)debugItem);
case DebugItemType.EPILOGUE_BEGIN:
return new BeginEpilogueMethodItem(codeAddress, -4);
case DebugItemType.PROLOGUE_END:
return new EndPrologueMethodItem(codeAddress, -4);
case DebugItemType.SET_SOURCE_FILE:
return new SetSourceFileMethodItem(codeAddress, -3, (SetSourceFile)debugItem);
case DebugItemType.LINE_NUMBER:
return new LineNumberMethodItem(codeAddress, -2, (LineNumber)debugItem);
default:
throw new ExceptionWithContext("Invalid debug item type: %d", debugItem.getDebugItemType());
}
}
}

View File

@ -1,66 +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.baksmali.Adaptors.Debug;
import org.jf.baksmali.Adaptors.RegisterFormatter;
import org.jf.dexlib2.iface.debug.EndLocal;
import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import java.io.IOException;
public class EndLocalMethodItem extends DebugMethodItem {
@Nonnull private final EndLocal endLocal;
@Nonnull private final RegisterFormatter registerFormatter;
public EndLocalMethodItem(int codeAddress, int sortOrder, @Nonnull RegisterFormatter registerFormatter,
@Nonnull EndLocal endLocal) {
super(codeAddress, sortOrder);
this.endLocal = endLocal;
this.registerFormatter = registerFormatter;
}
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
writer.write(".end local ");
registerFormatter.writeTo(writer, endLocal.getRegister());
String name = endLocal.getName();
String type = endLocal.getType();
String signature = endLocal.getSignature();
if (name != null || type != null || signature != null) {
writer.write(" # ");
LocalFormatter.writeLocal(writer, name, type, signature);
}
return true;
}
}

View File

@ -1,48 +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.baksmali.Adaptors.Debug;
import org.jf.util.IndentingWriter;
import java.io.IOException;
public class EndPrologueMethodItem extends DebugMethodItem {
public EndPrologueMethodItem(int codeAddress, int sortOrder) {
super(codeAddress, sortOrder);
}
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
writer.write(".prologue");
return true;
}
}

View File

@ -1,54 +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.baksmali.Adaptors.Debug;
import org.jf.dexlib2.iface.debug.LineNumber;
import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import java.io.IOException;
public class LineNumberMethodItem extends DebugMethodItem {
private final int lineNumber;
public LineNumberMethodItem(int codeAddress, int sortOrder, @Nonnull LineNumber lineNumber) {
super(codeAddress, sortOrder);
this.lineNumber = lineNumber.getLineNumber();
}
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
writer.write(".line ");
writer.printUnsignedIntAsDec(lineNumber);
return true;
}
}

View File

@ -1,73 +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.baksmali.Adaptors.Debug;
import org.jf.baksmali.Adaptors.ReferenceFormatter;
import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
public class LocalFormatter {
/**
* Writes out the given local info
*
* The written string will be something like:
*
* "localVar":Ljava/lang/String;, "SomeSignature"
* "localVar":Ljava/lang/String;
* "localVar":V, "SomeSignature"
* null:Ljava/lang/String;, "SomeSignature"
* null:V, "SomeSignature"
*
* One of name, type or signature must be non-null
*/
public static void writeLocal(@Nonnull IndentingWriter writer, @Nullable String name, @Nullable String type,
@Nullable String signature) throws IOException {
if (name != null) {
ReferenceFormatter.writeStringReference(writer, name);
} else {
writer.write("null");
}
writer.write(':');
if (type != null) {
writer.write(type);
} else {
writer.write("V");
}
if (signature != null) {
writer.write(", ");
ReferenceFormatter.writeStringReference(writer, signature);
}
}
}

View File

@ -1,66 +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.baksmali.Adaptors.Debug;
import org.jf.baksmali.Adaptors.RegisterFormatter;
import org.jf.dexlib2.iface.debug.RestartLocal;
import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import java.io.IOException;
public class RestartLocalMethodItem extends DebugMethodItem {
@Nonnull private final RestartLocal restartLocal;
@Nonnull private final RegisterFormatter registerFormatter;
public RestartLocalMethodItem(int codeAddress, int sortOrder, @Nonnull RegisterFormatter registerFormatter,
@Nonnull RestartLocal restartLocal) {
super(codeAddress, sortOrder);
this.restartLocal = restartLocal;
this.registerFormatter = registerFormatter;
}
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
writer.write(".restart local ");
registerFormatter.writeTo(writer, restartLocal.getRegister());
String name = restartLocal.getName();
String type = restartLocal.getType();
String signature = restartLocal.getSignature();
if (name != null || type != null || signature != null) {
writer.write(" # ");
LocalFormatter.writeLocal(writer, name, type, signature);
}
return true;
}
}

View File

@ -1,61 +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.baksmali.Adaptors.Debug;
import org.jf.dexlib2.iface.debug.SetSourceFile;
import org.jf.util.IndentingWriter;
import org.jf.util.StringUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
public class SetSourceFileMethodItem extends DebugMethodItem {
@Nullable private final String sourceFile;
public SetSourceFileMethodItem(int codeAddress, int sortOrder, @Nonnull SetSourceFile setSourceFile) {
super(codeAddress, sortOrder);
this.sourceFile = setSourceFile.getSourceFile();
}
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
writer.write(".source");
if (sourceFile != null) {
writer.write(" \"");
StringUtils.writeEscapedString(writer, sourceFile);
writer.write('"');
}
return true;
}
}

View File

@ -1,67 +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.baksmali.Adaptors.Debug;
import org.jf.baksmali.Adaptors.RegisterFormatter;
import org.jf.dexlib2.iface.debug.StartLocal;
import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import java.io.IOException;
public class StartLocalMethodItem extends DebugMethodItem {
@Nonnull private final StartLocal startLocal;
@Nonnull private final RegisterFormatter registerFormatter;
public StartLocalMethodItem(int codeAddress, int sortOrder, @Nonnull RegisterFormatter registerFormatter,
@Nonnull StartLocal startLocal) {
super(codeAddress, sortOrder);
this.startLocal = startLocal;
this.registerFormatter = registerFormatter;
}
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
writer.write(".local ");
registerFormatter.writeTo(writer, startLocal.getRegister());
String name = startLocal.getName();
String type = startLocal.getType();
String signature = startLocal.getSignature();
if (name != null || type != null || signature != null) {
writer.write(", ");
LocalFormatter.writeLocal(writer, name, type, signature);
}
return true;
}
}

View File

@ -1,65 +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.baksmali.Adaptors.EncodedValue;
import org.jf.dexlib2.iface.AnnotationElement;
import org.jf.dexlib2.iface.value.AnnotationEncodedValue;
import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Collection;
public abstract class AnnotationEncodedValueAdaptor {
public static void writeTo(@Nonnull IndentingWriter writer,
@Nonnull AnnotationEncodedValue annotationEncodedValue,
@Nullable String containingClass) throws IOException {
writer.write(".subannotation ");
writer.write(annotationEncodedValue.getType());
writer.write('\n');
writeElementsTo(writer, annotationEncodedValue.getElements(), containingClass);
writer.write(".end subannotation");
}
public static void writeElementsTo(@Nonnull IndentingWriter writer,
@Nonnull Collection<? extends AnnotationElement> annotationElements,
@Nullable String containingClass) throws IOException {
writer.indent(4);
for (AnnotationElement annotationElement: annotationElements) {
writer.write(annotationElement.getName());
writer.write(" = ");
EncodedValueAdaptor.writeTo(writer, annotationElement.getValue(), containingClass);
writer.write('\n');
}
writer.deindent(4);
}
}

View File

@ -1,65 +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.baksmali.Adaptors.EncodedValue;
import org.jf.dexlib2.iface.value.ArrayEncodedValue;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Collection;
public class ArrayEncodedValueAdaptor {
public static void writeTo(@Nonnull IndentingWriter writer,
@Nonnull ArrayEncodedValue arrayEncodedValue,
@Nullable String containingClass) throws IOException {
writer.write('{');
Collection<? extends EncodedValue> values = arrayEncodedValue.getValue();
if (values.size() == 0) {
writer.write('}');
return;
}
writer.write('\n');
writer.indent(4);
boolean first = true;
for (EncodedValue encodedValue: values) {
if (!first) {
writer.write(",\n");
}
first = false;
EncodedValueAdaptor.writeTo(writer, encodedValue, containingClass);
}
writer.deindent(4);
writer.write("\n}");
}
}

View File

@ -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.baksmali.Adaptors.EncodedValue;
import org.jf.baksmali.Adaptors.ReferenceFormatter;
import org.jf.baksmali.Renderers.*;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.*;
import org.jf.dexlib2.util.ReferenceUtil;
import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
public abstract class EncodedValueAdaptor {
public static void writeTo(@Nonnull IndentingWriter writer, @Nonnull EncodedValue encodedValue,
@Nullable String containingClass)
throws IOException {
switch (encodedValue.getValueType()) {
case ValueType.ANNOTATION:
AnnotationEncodedValueAdaptor.writeTo(writer, (AnnotationEncodedValue)encodedValue, containingClass);
return;
case ValueType.ARRAY:
ArrayEncodedValueAdaptor.writeTo(writer, (ArrayEncodedValue)encodedValue, containingClass);
return;
case ValueType.BOOLEAN:
BooleanRenderer.writeTo(writer, ((BooleanEncodedValue)encodedValue).getValue());
return;
case ValueType.BYTE:
ByteRenderer.writeTo(writer, ((ByteEncodedValue)encodedValue).getValue());
return;
case ValueType.CHAR:
CharRenderer.writeTo(writer, ((CharEncodedValue)encodedValue).getValue());
return;
case ValueType.DOUBLE:
DoubleRenderer.writeTo(writer, ((DoubleEncodedValue)encodedValue).getValue());
return;
case ValueType.ENUM:
EnumEncodedValue enumEncodedValue = (EnumEncodedValue)encodedValue;
boolean useImplicitReference = false;
if (enumEncodedValue.getValue().getDefiningClass().equals(containingClass)) {
useImplicitReference = true;
}
writer.write(".enum ");
ReferenceUtil.writeFieldDescriptor(writer, enumEncodedValue.getValue(), useImplicitReference);
return;
case ValueType.FIELD:
FieldEncodedValue fieldEncodedValue = (FieldEncodedValue)encodedValue;
useImplicitReference = false;
if (fieldEncodedValue.getValue().getDefiningClass().equals(containingClass)) {
useImplicitReference = true;
}
ReferenceUtil.writeFieldDescriptor(writer, fieldEncodedValue.getValue(), useImplicitReference);
return;
case ValueType.FLOAT:
FloatRenderer.writeTo(writer, ((FloatEncodedValue)encodedValue).getValue());
return;
case ValueType.INT:
IntegerRenderer.writeTo(writer, ((IntEncodedValue)encodedValue).getValue());
return;
case ValueType.LONG:
LongRenderer.writeTo(writer, ((LongEncodedValue)encodedValue).getValue());
return;
case ValueType.METHOD:
MethodEncodedValue methodEncodedValue = (MethodEncodedValue)encodedValue;
useImplicitReference = false;
if (methodEncodedValue.getValue().getDefiningClass().equals(containingClass)) {
useImplicitReference = true;
}
ReferenceUtil.writeMethodDescriptor(writer, methodEncodedValue.getValue(), useImplicitReference);
return;
case ValueType.NULL:
writer.write("null");
return;
case ValueType.SHORT:
ShortRenderer.writeTo(writer, ((ShortEncodedValue)encodedValue).getValue());
return;
case ValueType.STRING:
ReferenceFormatter.writeStringReference(writer, ((StringEncodedValue)encodedValue).getValue());
return;
case ValueType.TYPE:
writer.write(((TypeEncodedValue)encodedValue).getValue());
}
}
}

View File

@ -1,51 +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.baksmali.Adaptors;
import org.jf.baksmali.baksmaliOptions;
import javax.annotation.Nonnull;
public class EndTryLabelMethodItem extends LabelMethodItem {
private int endTryAddress;
public EndTryLabelMethodItem(@Nonnull baksmaliOptions options, int codeAddress, int endTryAddress) {
super(options, codeAddress, "try_end_");
this.endTryAddress = endTryAddress;
}
public double getSortOrder() {
//sort after instruction, but before catch directive
return 101;
}
public int getLabelAddress() {
return endTryAddress;
}
}

View File

@ -1,101 +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.baksmali.Adaptors;
import org.jf.baksmali.Adaptors.EncodedValue.EncodedValueAdaptor;
import org.jf.baksmali.baksmaliOptions;
import org.jf.dexlib2.AccessFlags;
import org.jf.dexlib2.iface.Annotation;
import org.jf.dexlib2.iface.Field;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.dexlib2.util.EncodedValueUtils;
import org.jf.util.IndentingWriter;
import java.io.IOException;
import java.util.Collection;
public class FieldDefinition {
public static void writeTo(baksmaliOptions options, IndentingWriter writer, Field field,
boolean setInStaticConstructor) throws IOException {
EncodedValue initialValue = field.getInitialValue();
int accessFlags = field.getAccessFlags();
if (setInStaticConstructor &&
AccessFlags.STATIC.isSet(accessFlags) &&
AccessFlags.FINAL.isSet(accessFlags) &&
initialValue != null) {
if (!EncodedValueUtils.isDefaultValue(initialValue)) {
writer.write("# The value of this static final field might be set in the static constructor\n");
} else {
// don't write out the default initial value for static final fields that get set in the static
// constructor
initialValue = null;
}
}
writer.write(".field ");
writeAccessFlags(writer, field.getAccessFlags());
writer.write(field.getName());
writer.write(':');
writer.write(field.getType());
if (initialValue != null) {
writer.write(" = ");
String containingClass = null;
if (options.useImplicitReferences) {
containingClass = field.getDefiningClass();
}
EncodedValueAdaptor.writeTo(writer, initialValue, containingClass);
}
writer.write('\n');
Collection<? extends Annotation> annotations = field.getAnnotations();
if (annotations.size() > 0) {
writer.indent(4);
String containingClass = null;
if (options.useImplicitReferences) {
containingClass = field.getDefiningClass();
}
AnnotationFormatter.writeTo(writer, annotations, containingClass);
writer.deindent(4);
writer.write(".end field\n");
}
}
private static void writeAccessFlags(IndentingWriter writer, int accessFlags) throws IOException {
for (AccessFlags accessFlag: AccessFlags.getAccessFlagsForField(accessFlags)) {
writer.write(accessFlag.toString());
writer.write(' ');
}
}
}

View File

@ -1,81 +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.baksmali.Adaptors.Format;
import org.jf.baksmali.Adaptors.MethodDefinition;
import org.jf.baksmali.Renderers.LongRenderer;
import org.jf.dexlib2.iface.instruction.formats.ArrayPayload;
import org.jf.util.IndentingWriter;
import java.io.IOException;
import java.util.List;
public class ArrayDataMethodItem extends InstructionMethodItem<ArrayPayload> {
public ArrayDataMethodItem(MethodDefinition methodDef, int codeAddress, ArrayPayload instruction) {
super(methodDef, codeAddress, instruction);
}
public boolean writeTo(IndentingWriter writer) throws IOException {
int elementWidth = instruction.getElementWidth();
writer.write(".array-data ");
writer.printSignedIntAsDec(instruction.getElementWidth());
writer.write('\n');
writer.indent(4);
List<Number> elements = instruction.getArrayElements();
String suffix = "";
switch (elementWidth) {
case 1:
suffix = "t";
break;
case 2:
suffix = "s";
break;
}
for (Number number: elements) {
LongRenderer.writeSignedIntOrLongTo(writer, number.longValue());
writer.write(suffix);
if (elementWidth == 8) {
writeCommentIfLikelyDouble(writer, number.longValue());
} else if (elementWidth == 4) {
int value = number.intValue();
boolean isResourceId = writeCommentIfResourceId(writer, value);
if (!isResourceId) writeCommentIfLikelyFloat(writer, value);
}
writer.write("\n");
}
writer.deindent(4);
writer.write(".end array-data");
return true;
}
}

View File

@ -1,576 +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.baksmali.Adaptors.Format;
import org.jf.baksmali.Adaptors.MethodDefinition;
import org.jf.baksmali.Adaptors.MethodDefinition.InvalidSwitchPayload;
import org.jf.baksmali.Adaptors.MethodItem;
import org.jf.baksmali.Renderers.LongRenderer;
import org.jf.baksmali.baksmaliOptions;
import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.ReferenceType;
import org.jf.dexlib2.VerificationError;
import org.jf.dexlib2.dexbacked.DexBackedDexFile.InvalidItemIndex;
import org.jf.dexlib2.iface.instruction.*;
import org.jf.dexlib2.iface.instruction.formats.Instruction20bc;
import org.jf.dexlib2.iface.instruction.formats.Instruction31t;
import org.jf.dexlib2.iface.instruction.formats.UnknownInstruction;
import org.jf.dexlib2.iface.reference.Reference;
import org.jf.dexlib2.util.ReferenceUtil;
import org.jf.util.ExceptionWithContext;
import org.jf.util.IndentingWriter;
import org.jf.util.NumberUtils;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.util.Map;
public class InstructionMethodItem<T extends Instruction> extends MethodItem {
@Nonnull protected final MethodDefinition methodDef;
@Nonnull protected final T instruction;
public InstructionMethodItem(@Nonnull MethodDefinition methodDef, int codeAddress, @Nonnull T instruction) {
super(codeAddress);
this.methodDef = methodDef;
this.instruction = instruction;
}
public double getSortOrder() {
//instructions should appear after everything except an "end try" label and .catch directive
return 100;
}
private boolean isAllowedOdex(@Nonnull Opcode opcode) {
baksmaliOptions options = methodDef.classDef.options;
if (options.allowOdex) {
return true;
}
if (methodDef.classDef.options.apiLevel >= 14) {
return false;
}
return opcode.isOdexedInstanceVolatile() || opcode.isOdexedStaticVolatile() ||
opcode == Opcode.THROW_VERIFICATION_ERROR;
}
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
Opcode opcode = instruction.getOpcode();
String verificationErrorName = null;
String referenceString = null;
boolean commentOutInstruction = false;
if (instruction instanceof Instruction20bc) {
int verificationError = ((Instruction20bc)instruction).getVerificationError();
verificationErrorName = VerificationError.getVerificationErrorName(verificationError);
if (verificationErrorName == null) {
writer.write("#was invalid verification error type: ");
writer.printSignedIntAsDec(verificationError);
writer.write("\n");
verificationErrorName = "generic-error";
}
}
if (instruction instanceof ReferenceInstruction) {
ReferenceInstruction referenceInstruction = (ReferenceInstruction)instruction;
try {
Reference reference = referenceInstruction.getReference();
String classContext = null;
if (methodDef.classDef.options.useImplicitReferences) {
classContext = methodDef.method.getDefiningClass();
}
referenceString = ReferenceUtil.getReferenceString(reference, classContext);
assert referenceString != null;
} catch (InvalidItemIndex ex) {
writer.write("#");
writer.write(ex.getMessage());
writer.write("\n");
commentOutInstruction = true;
referenceString = String.format("%s@%d",
ReferenceType.toString(referenceInstruction.getReferenceType()),
ex.getInvalidIndex());
} catch (ReferenceType.InvalidReferenceTypeException ex) {
writer.write("#invalid reference type: ");
writer.printSignedIntAsDec(ex.getReferenceType());
commentOutInstruction = true;
referenceString = "invalid_reference";
}
}
if (instruction instanceof Instruction31t) {
boolean validPayload = true;
switch (instruction.getOpcode()) {
case PACKED_SWITCH:
int baseAddress = methodDef.getPackedSwitchBaseAddress(
this.codeAddress + ((Instruction31t)instruction).getCodeOffset());
if (baseAddress == -1) {
validPayload = false;
}
break;
case SPARSE_SWITCH:
baseAddress = methodDef.getSparseSwitchBaseAddress(
this.codeAddress + ((Instruction31t)instruction).getCodeOffset());
if (baseAddress == -1) {
validPayload = false;
}
break;
case FILL_ARRAY_DATA:
try {
methodDef.findPayloadOffset(this.codeAddress + ((Instruction31t)instruction).getCodeOffset(),
Opcode.ARRAY_PAYLOAD);
} catch (InvalidSwitchPayload ex) {
validPayload = false;
}
break;
default:
throw new ExceptionWithContext("Invalid 31t opcode: %s", instruction.getOpcode());
}
if (!validPayload) {
writer.write("#invalid payload reference\n");
commentOutInstruction = true;
}
}
if (opcode.odexOnly()) {
if (!isAllowedOdex(opcode)) {
writer.write("#disallowed odex opcode\n");
commentOutInstruction = true;
}
}
if (commentOutInstruction) {
writer.write("#");
}
switch (instruction.getOpcode().format) {
case Format10t:
writeOpcode(writer);
writer.write(' ');
writeTargetLabel(writer);
break;
case Format10x:
if (instruction instanceof UnknownInstruction) {
writer.write("#unknown opcode: 0x");
writer.printUnsignedLongAsHex(((UnknownInstruction)instruction).getOriginalOpcode());
writer.write('\n');
}
writeOpcode(writer);
break;
case Format11n:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeLiteral(writer);
break;
case Format11x:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
break;
case Format12x:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeSecondRegister(writer);
break;
case Format20bc:
writeOpcode(writer);
writer.write(' ');
writer.write(verificationErrorName);
writer.write(", ");
writer.write(referenceString);
break;
case Format20t:
case Format30t:
writeOpcode(writer);
writer.write(' ');
writeTargetLabel(writer);
break;
case Format21c:
case Format31c:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writer.write(referenceString);
break;
case Format21ih:
case Format21lh:
case Format21s:
case Format31i:
case Format51l:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeLiteral(writer);
if (instruction.getOpcode().setsWideRegister()) {
writeCommentIfLikelyDouble(writer);
} else {
boolean isResourceId = writeCommentIfResourceId(writer);
if (!isResourceId) writeCommentIfLikelyFloat(writer);
}
break;
case Format21t:
case Format31t:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeTargetLabel(writer);
break;
case Format22b:
case Format22s:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeSecondRegister(writer);
writer.write(", ");
writeLiteral(writer);
break;
case Format22c:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeSecondRegister(writer);
writer.write(", ");
writer.write(referenceString);
break;
case Format22cs:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeSecondRegister(writer);
writer.write(", ");
writeFieldOffset(writer);
break;
case Format22t:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeSecondRegister(writer);
writer.write(", ");
writeTargetLabel(writer);
break;
case Format22x:
case Format32x:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeSecondRegister(writer);
break;
case Format23x:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeSecondRegister(writer);
writer.write(", ");
writeThirdRegister(writer);
break;
case Format25x:
writeOpcode(writer);
writer.write(' ');
writeInvoke25xRegisters(writer); // vC, {vD, ...}
break;
case Format35c:
writeOpcode(writer);
writer.write(' ');
writeInvokeRegisters(writer);
writer.write(", ");
writer.write(referenceString);
break;
case Format35mi:
writeOpcode(writer);
writer.write(' ');
writeInvokeRegisters(writer);
writer.write(", ");
writeInlineIndex(writer);
break;
case Format35ms:
writeOpcode(writer);
writer.write(' ');
writeInvokeRegisters(writer);
writer.write(", ");
writeVtableIndex(writer);
break;
case Format3rc:
writeOpcode(writer);
writer.write(' ');
writeInvokeRangeRegisters(writer);
writer.write(", ");
writer.write(referenceString);
break;
case Format3rmi:
writeOpcode(writer);
writer.write(' ');
writeInvokeRangeRegisters(writer);
writer.write(", ");
writeInlineIndex(writer);
break;
case Format3rms:
writeOpcode(writer);
writer.write(' ');
writeInvokeRangeRegisters(writer);
writer.write(", ");
writeVtableIndex(writer);
break;
default:
assert false;
return false;
}
if (commentOutInstruction) {
writer.write("\nnop");
}
return true;
}
protected void writeOpcode(IndentingWriter writer) throws IOException {
writer.write(instruction.getOpcode().name);
}
protected void writeTargetLabel(IndentingWriter writer) throws IOException {
//this method is overridden by OffsetInstructionMethodItem, and should only be called for the formats that
//have a target
throw new RuntimeException();
}
protected void writeRegister(IndentingWriter writer, int registerNumber) throws IOException {
methodDef.registerFormatter.writeTo(writer, registerNumber);
}
protected void writeFirstRegister(IndentingWriter writer) throws IOException {
writeRegister(writer, ((OneRegisterInstruction)instruction).getRegisterA());
}
protected void writeSecondRegister(IndentingWriter writer) throws IOException {
writeRegister(writer, ((TwoRegisterInstruction)instruction).getRegisterB());
}
protected void writeThirdRegister(IndentingWriter writer) throws IOException {
writeRegister(writer, ((ThreeRegisterInstruction) instruction).getRegisterC());
}
protected void writeInvokeRegisters(IndentingWriter writer) throws IOException {
FiveRegisterInstruction instruction = (FiveRegisterInstruction)this.instruction;
final int regCount = instruction.getRegisterCount();
writer.write('{');
switch (regCount) {
case 1:
writeRegister(writer, instruction.getRegisterC());
break;
case 2:
writeRegister(writer, instruction.getRegisterC());
writer.write(", ");
writeRegister(writer, instruction.getRegisterD());
break;
case 3:
writeRegister(writer, instruction.getRegisterC());
writer.write(", ");
writeRegister(writer, instruction.getRegisterD());
writer.write(", ");
writeRegister(writer, instruction.getRegisterE());
break;
case 4:
writeRegister(writer, instruction.getRegisterC());
writer.write(", ");
writeRegister(writer, instruction.getRegisterD());
writer.write(", ");
writeRegister(writer, instruction.getRegisterE());
writer.write(", ");
writeRegister(writer, instruction.getRegisterF());
break;
case 5:
writeRegister(writer, instruction.getRegisterC());
writer.write(", ");
writeRegister(writer, instruction.getRegisterD());
writer.write(", ");
writeRegister(writer, instruction.getRegisterE());
writer.write(", ");
writeRegister(writer, instruction.getRegisterF());
writer.write(", ");
writeRegister(writer, instruction.getRegisterG());
break;
}
writer.write('}');
}
protected void writeInvoke25xRegisters(IndentingWriter writer) throws IOException {
OneFixedFourParameterRegisterInstruction instruction =
(OneFixedFourParameterRegisterInstruction)this.instruction;
final int parameterRegCount = instruction.getParameterRegisterCount();
writeRegister(writer, instruction.getRegisterFixedC()); // fixed register always present
writer.write(", {");
switch (parameterRegCount) {
case 1:
writeRegister(writer, instruction.getRegisterParameterD());
break;
case 2:
writeRegister(writer, instruction.getRegisterParameterD());
writer.write(", ");
writeRegister(writer, instruction.getRegisterParameterE());
break;
case 3:
writeRegister(writer, instruction.getRegisterParameterD());
writer.write(", ");
writeRegister(writer, instruction.getRegisterParameterE());
writer.write(", ");
writeRegister(writer, instruction.getRegisterParameterF());
break;
case 4:
writeRegister(writer, instruction.getRegisterParameterD());
writer.write(", ");
writeRegister(writer, instruction.getRegisterParameterE());
writer.write(", ");
writeRegister(writer, instruction.getRegisterParameterF());
writer.write(", ");
writeRegister(writer, instruction.getRegisterParameterG());
break;
}
writer.write('}');
}
protected void writeInvokeRangeRegisters(IndentingWriter writer) throws IOException {
RegisterRangeInstruction instruction = (RegisterRangeInstruction)this.instruction;
int regCount = instruction.getRegisterCount();
if (regCount == 0) {
writer.write("{}");
} else {
int startRegister = instruction.getStartRegister();
methodDef.registerFormatter.writeRegisterRange(writer, startRegister, startRegister+regCount-1);
}
}
protected void writeLiteral(IndentingWriter writer) throws IOException {
LongRenderer.writeSignedIntOrLongTo(writer, ((WideLiteralInstruction)instruction).getWideLiteral());
}
protected void writeCommentIfLikelyFloat(IndentingWriter writer) throws IOException {
writeCommentIfLikelyFloat(writer, ((NarrowLiteralInstruction)instruction).getNarrowLiteral());
}
protected void writeCommentIfLikelyFloat(IndentingWriter writer, int val) throws IOException {
if (NumberUtils.isLikelyFloat(val)) {
writer.write(" # ");
float fval = Float.intBitsToFloat(val);
if (fval == Float.POSITIVE_INFINITY)
writer.write("Float.POSITIVE_INFINITY");
else if (fval == Float.NEGATIVE_INFINITY)
writer.write("Float.NEGATIVE_INFINITY");
else if (fval == Float.NaN)
writer.write("Float.NaN");
else if (fval == Float.MAX_VALUE)
writer.write("Float.MAX_VALUE");
else if (fval == (float)Math.PI)
writer.write("(float)Math.PI");
else if (fval == (float)Math.E)
writer.write("(float)Math.E");
else {
writer.write(Float.toString(fval));
writer.write('f');
}
}
}
protected void writeCommentIfLikelyDouble(IndentingWriter writer) throws IOException {
writeCommentIfLikelyDouble(writer, ((WideLiteralInstruction)instruction).getWideLiteral());
}
protected void writeCommentIfLikelyDouble(IndentingWriter writer, long val) throws IOException {
if (NumberUtils.isLikelyDouble(val)) {
writer.write(" # ");
double dval = Double.longBitsToDouble(val);
if (dval == Double.POSITIVE_INFINITY)
writer.write("Double.POSITIVE_INFINITY");
else if (dval == Double.NEGATIVE_INFINITY)
writer.write("Double.NEGATIVE_INFINITY");
else if (dval == Double.NaN)
writer.write("Double.NaN");
else if (dval == Double.MAX_VALUE)
writer.write("Double.MAX_VALUE");
else if (dval == Math.PI)
writer.write("Math.PI");
else if (dval == Math.E)
writer.write("Math.E");
else
writer.write(Double.toString(dval));
}
}
protected boolean writeCommentIfResourceId(IndentingWriter writer) throws IOException {
return writeCommentIfResourceId(writer, ((NarrowLiteralInstruction)instruction).getNarrowLiteral());
}
protected boolean writeCommentIfResourceId(IndentingWriter writer, int val) throws IOException {
Map<Integer,String> resourceIds = methodDef.classDef.options.resourceIds;
String resource = resourceIds.get(Integer.valueOf(val));
if (resource != null) {
writer.write(" # ");
writer.write(resource);
return true;
}
return false;
}
protected void writeFieldOffset(IndentingWriter writer) throws IOException {
writer.write("field@0x");
writer.printUnsignedLongAsHex(((FieldOffsetInstruction)instruction).getFieldOffset());
}
protected void writeInlineIndex(IndentingWriter writer) throws IOException {
writer.write("inline@");
writer.printSignedIntAsDec(((InlineIndexInstruction)instruction).getInlineIndex());
}
protected void writeVtableIndex(IndentingWriter writer) throws IOException {
writer.write("vtable@");
writer.printSignedIntAsDec(((VtableIndexInstruction)instruction).getVtableIndex());
}
}

View File

@ -1,67 +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.baksmali.Adaptors.Format;
import org.jf.baksmali.Adaptors.MethodDefinition;
import org.jf.dexlib2.analysis.UnresolvedOdexInstruction;
import org.jf.dexlib2.iface.instruction.Instruction;
import org.jf.dexlib2.iface.instruction.OffsetInstruction;
import org.jf.dexlib2.iface.instruction.formats.ArrayPayload;
import org.jf.dexlib2.iface.instruction.formats.PackedSwitchPayload;
import org.jf.dexlib2.iface.instruction.formats.SparseSwitchPayload;
public class InstructionMethodItemFactory {
private InstructionMethodItemFactory() {
}
public static InstructionMethodItem makeInstructionFormatMethodItem(
MethodDefinition methodDef, int codeAddress, Instruction instruction) {
if (instruction instanceof OffsetInstruction) {
return new OffsetInstructionFormatMethodItem(methodDef.classDef.options, methodDef, codeAddress,
(OffsetInstruction)instruction);
}
if (instruction instanceof UnresolvedOdexInstruction) {
return new UnresolvedOdexInstructionMethodItem(methodDef, codeAddress,
(UnresolvedOdexInstruction)instruction);
}
switch (instruction.getOpcode().format) {
case ArrayPayload:
return new ArrayDataMethodItem(methodDef, codeAddress, (ArrayPayload)instruction);
case PackedSwitchPayload:
return new PackedSwitchMethodItem(methodDef, codeAddress, (PackedSwitchPayload)instruction);
case SparseSwitchPayload:
return new SparseSwitchMethodItem(methodDef, codeAddress, (SparseSwitchPayload)instruction);
default:
return new InstructionMethodItem<Instruction>(methodDef, codeAddress, instruction);
}
}
}

View File

@ -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.baksmali.Adaptors.Format;
import org.jf.baksmali.Adaptors.LabelMethodItem;
import org.jf.baksmali.Adaptors.MethodDefinition;
import org.jf.baksmali.baksmaliOptions;
import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.iface.instruction.OffsetInstruction;
import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import java.io.IOException;
public class OffsetInstructionFormatMethodItem extends InstructionMethodItem<OffsetInstruction> {
protected LabelMethodItem label;
public OffsetInstructionFormatMethodItem(@Nonnull baksmaliOptions options, @Nonnull MethodDefinition methodDef,
int codeAddress, OffsetInstruction instruction) {
super(methodDef, codeAddress, instruction);
label = new LabelMethodItem(options, codeAddress + instruction.getCodeOffset(), getLabelPrefix());
label = methodDef.getLabelCache().internLabel(label);
}
@Override
protected void writeTargetLabel(IndentingWriter writer) throws IOException {
label.writeTo(writer);
}
public LabelMethodItem getLabel() {
return label;
}
private String getLabelPrefix() {
Opcode opcode = instruction.getOpcode();
switch (opcode.format) {
case Format10t:
case Format20t:
case Format30t:
return "goto_";
case Format21t:
case Format22t:
return "cond_";
case Format31t:
if (opcode == Opcode.FILL_ARRAY_DATA) {
return "array_";
}
if (opcode == Opcode.PACKED_SWITCH) {
return "pswitch_data_";
}
// Opcode.SPARSE_SWITCH;
return "sswitch_data_";
}
assert false;
return null;
}
}

View File

@ -1,130 +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.baksmali.Adaptors.Format;
import org.jf.baksmali.Adaptors.CommentingIndentingWriter;
import org.jf.baksmali.Adaptors.LabelMethodItem;
import org.jf.baksmali.Adaptors.MethodDefinition;
import org.jf.dexlib2.iface.instruction.SwitchElement;
import org.jf.dexlib2.iface.instruction.formats.PackedSwitchPayload;
import org.jf.util.IndentingWriter;
import org.jf.baksmali.Renderers.IntegerRenderer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class PackedSwitchMethodItem extends InstructionMethodItem<PackedSwitchPayload> {
private final List<PackedSwitchTarget> targets;
private final int firstKey;
// Whether this sparse switch instruction should be commented out because it is never referenced
private boolean commentedOut;
public PackedSwitchMethodItem(MethodDefinition methodDef, int codeAddress, PackedSwitchPayload instruction) {
super(methodDef, codeAddress, instruction);
int baseCodeAddress = methodDef.getPackedSwitchBaseAddress(codeAddress);
targets = new ArrayList<PackedSwitchTarget>();
boolean first = true;
int firstKey = 0;
if (baseCodeAddress >= 0) {
for (SwitchElement switchElement: instruction.getSwitchElements()) {
if (first) {
firstKey = switchElement.getKey();
first = false;
}
LabelMethodItem label = methodDef.getLabelCache().internLabel(
new LabelMethodItem(methodDef.classDef.options, baseCodeAddress + switchElement.getOffset(),
"pswitch_"));
targets.add(new PackedSwitchLabelTarget(label));
}
} else {
commentedOut = true;
for (SwitchElement switchElement: instruction.getSwitchElements()) {
if (first) {
firstKey = switchElement.getKey();
first = false;
}
targets.add(new PackedSwitchOffsetTarget(switchElement.getOffset()));
}
}
this.firstKey = firstKey;
}
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
if (commentedOut) {
writer = new CommentingIndentingWriter(writer);
}
writer.write(".packed-switch ");
IntegerRenderer.writeTo(writer, firstKey);
writer.indent(4);
writer.write('\n');
int key = firstKey;
for (PackedSwitchTarget target: targets) {
target.writeTargetTo(writer);
writeCommentIfResourceId(writer, key);
writer.write('\n');
key++;
}
writer.deindent(4);
writer.write(".end packed-switch");
return true;
}
private static abstract class PackedSwitchTarget {
public abstract void writeTargetTo(IndentingWriter writer) throws IOException;
}
private static class PackedSwitchLabelTarget extends PackedSwitchTarget {
private final LabelMethodItem target;
public PackedSwitchLabelTarget(LabelMethodItem target) {
this.target = target;
}
public void writeTargetTo(IndentingWriter writer) throws IOException {
target.writeTo(writer);
}
}
private static class PackedSwitchOffsetTarget extends PackedSwitchTarget {
private final int target;
public PackedSwitchOffsetTarget(int target) {
this.target = target;
}
public void writeTargetTo(IndentingWriter writer) throws IOException {
if (target >= 0) {
writer.write('+');
}
writer.printSignedIntAsDec(target);
}
}
}

View File

@ -1,126 +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.baksmali.Adaptors.Format;
import org.jf.baksmali.Adaptors.CommentingIndentingWriter;
import org.jf.baksmali.Adaptors.LabelMethodItem;
import org.jf.baksmali.Adaptors.MethodDefinition;
import org.jf.dexlib2.iface.instruction.SwitchElement;
import org.jf.dexlib2.iface.instruction.formats.SparseSwitchPayload;
import org.jf.util.IndentingWriter;
import org.jf.baksmali.Renderers.IntegerRenderer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class SparseSwitchMethodItem extends InstructionMethodItem<SparseSwitchPayload> {
private final List<SparseSwitchTarget> targets;
// Whether this sparse switch instruction should be commented out because it is never referenced
private boolean commentedOut;
public SparseSwitchMethodItem(MethodDefinition methodDef, int codeAddress, SparseSwitchPayload instruction) {
super(methodDef, codeAddress, instruction);
int baseCodeAddress = methodDef.getSparseSwitchBaseAddress(codeAddress);
targets = new ArrayList<SparseSwitchTarget>();
if (baseCodeAddress >= 0) {
for (SwitchElement switchElement: instruction.getSwitchElements()) {
LabelMethodItem label = methodDef.getLabelCache().internLabel(
new LabelMethodItem( methodDef.classDef.options, baseCodeAddress + switchElement.getOffset(),
"sswitch_"));
targets.add(new SparseSwitchLabelTarget(switchElement.getKey(), label));
}
} else {
commentedOut = true;
//if we couldn't determine a base address, just use relative offsets rather than labels
for (SwitchElement switchElement: instruction.getSwitchElements()) {
targets.add(new SparseSwitchOffsetTarget(switchElement.getKey(), switchElement.getOffset()));
}
}
}
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
if (commentedOut) {
writer = new CommentingIndentingWriter(writer);
}
writer.write(".sparse-switch\n");
writer.indent(4);
for (SparseSwitchTarget target: targets) {
IntegerRenderer.writeTo(writer, target.getKey());
writer.write(" -> ");
target.writeTargetTo(writer);
writeCommentIfResourceId(writer, target.getKey());
writer.write('\n');
}
writer.deindent(4);
writer.write(".end sparse-switch");
return true;
}
private static abstract class SparseSwitchTarget {
private final int key;
public SparseSwitchTarget(int key) {
this.key = key;
}
public int getKey() { return key; }
public abstract void writeTargetTo(IndentingWriter writer) throws IOException;
}
private static class SparseSwitchLabelTarget extends SparseSwitchTarget {
private final LabelMethodItem target;
public SparseSwitchLabelTarget(int key, LabelMethodItem target) {
super(key);
this.target = target;
}
public void writeTargetTo(IndentingWriter writer) throws IOException {
target.writeTo(writer);
}
}
private static class SparseSwitchOffsetTarget extends SparseSwitchTarget {
private final int target;
public SparseSwitchOffsetTarget(int key, int target) {
super(key);
this.target = target;
}
public void writeTargetTo(IndentingWriter writer) throws IOException {
if (target >= 0) {
writer.write('+');
}
writer.printSignedIntAsDec(target);
}
}
}

View File

@ -1,54 +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.baksmali.Adaptors.Format;
import org.jf.baksmali.Adaptors.MethodDefinition;
import org.jf.dexlib2.analysis.UnresolvedOdexInstruction;
import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import java.io.IOException;
public class UnresolvedOdexInstructionMethodItem extends InstructionMethodItem<UnresolvedOdexInstruction> {
public UnresolvedOdexInstructionMethodItem(@Nonnull MethodDefinition methodDef, int codeAddress,
@Nonnull UnresolvedOdexInstruction instruction) {
super(methodDef, codeAddress, instruction);
}
public boolean writeTo(IndentingWriter writer) throws IOException {
writeThrowTo(writer);
return true;
}
private void writeThrowTo(IndentingWriter writer) throws IOException {
writer.write("#Replaced unresolvable odex instruction with a throw\n");
writer.write("throw ");
writeRegister(writer, instruction.objectRegisterNum);
}
}

View File

@ -1,102 +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.baksmali.Adaptors;
import org.jf.baksmali.baksmaliOptions;
import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import java.io.IOException;
public class LabelMethodItem extends MethodItem {
private final baksmaliOptions options;
private final String labelPrefix;
private int labelSequence;
public LabelMethodItem(@Nonnull baksmaliOptions options, int codeAddress, @Nonnull String labelPrefix) {
super(codeAddress);
this.options = options;
this.labelPrefix = labelPrefix;
}
public double getSortOrder() {
return 0;
}
public int compareTo(MethodItem methodItem) {
int result = super.compareTo(methodItem);
if (result == 0) {
if (methodItem instanceof LabelMethodItem) {
result = labelPrefix.compareTo(((LabelMethodItem)methodItem).labelPrefix);
}
}
return result;
}
public int hashCode() {
//force it to call equals when two labels are at the same address
return getCodeAddress();
}
public boolean equals(Object o) {
if (!(o instanceof LabelMethodItem)) {
return false;
}
return this.compareTo((MethodItem)o) == 0;
}
public boolean writeTo(IndentingWriter writer) throws IOException {
writer.write(':');
writer.write(labelPrefix);
if (options.useSequentialLabels) {
writer.printUnsignedLongAsHex(labelSequence);
} else {
writer.printUnsignedLongAsHex(this.getLabelAddress());
}
return true;
}
public String getLabelPrefix() {
return labelPrefix;
}
public int getLabelAddress() {
return this.getCodeAddress();
}
public int getLabelSequence() {
return labelSequence;
}
public void setLabelSequence(int labelSequence) {
this.labelSequence = labelSequence;
}
}

View File

@ -1,638 +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.baksmali.Adaptors;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
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;
import org.jf.dexlib2.ReferenceType;
import org.jf.dexlib2.analysis.AnalysisException;
import org.jf.dexlib2.analysis.AnalyzedInstruction;
import org.jf.dexlib2.analysis.MethodAnalyzer;
import org.jf.dexlib2.dexbacked.DexBackedDexFile.InvalidItemIndex;
import org.jf.dexlib2.iface.*;
import org.jf.dexlib2.iface.debug.DebugItem;
import org.jf.dexlib2.iface.instruction.Instruction;
import org.jf.dexlib2.iface.instruction.OffsetInstruction;
import org.jf.dexlib2.iface.instruction.ReferenceInstruction;
import org.jf.dexlib2.iface.instruction.formats.Instruction31t;
import org.jf.dexlib2.iface.reference.MethodReference;
import org.jf.dexlib2.immutable.instruction.ImmutableInstruction31t;
import org.jf.dexlib2.util.InstructionOffsetMap;
import org.jf.dexlib2.util.InstructionOffsetMap.InvalidInstructionOffset;
import org.jf.dexlib2.util.ReferenceUtil;
import org.jf.dexlib2.util.SyntheticAccessorResolver;
import org.jf.dexlib2.util.SyntheticAccessorResolver.AccessedMember;
import org.jf.dexlib2.util.TypeUtils;
import org.jf.util.ExceptionWithContext;
import org.jf.util.IndentingWriter;
import org.jf.util.SparseIntArray;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.*;
public class MethodDefinition {
@Nonnull public final ClassDefinition classDef;
@Nonnull public final Method method;
@Nonnull public final MethodImplementation methodImpl;
@Nonnull public final ImmutableList<Instruction> instructions;
@Nonnull public final List<Instruction> effectiveInstructions;
@Nonnull public final ImmutableList<MethodParameter> methodParameters;
public RegisterFormatter registerFormatter;
@Nonnull private final LabelCache labelCache = new LabelCache();
@Nonnull private final SparseIntArray packedSwitchMap;
@Nonnull private final SparseIntArray sparseSwitchMap;
@Nonnull private final InstructionOffsetMap instructionOffsetMap;
public MethodDefinition(@Nonnull ClassDefinition classDef, @Nonnull Method method,
@Nonnull MethodImplementation methodImpl) {
this.classDef = classDef;
this.method = method;
this.methodImpl = methodImpl;
try {
//TODO: what about try/catch blocks inside the dead code? those will need to be commented out too. ugh.
instructions = ImmutableList.copyOf(methodImpl.getInstructions());
methodParameters = ImmutableList.copyOf(method.getParameters());
effectiveInstructions = Lists.newArrayList(instructions);
packedSwitchMap = new SparseIntArray(0);
sparseSwitchMap = new SparseIntArray(0);
instructionOffsetMap = new InstructionOffsetMap(instructions);
int endOffset = instructionOffsetMap.getInstructionCodeOffset(instructions.size()-1) +
instructions.get(instructions.size()-1).getCodeUnits();
for (int i=0; i<instructions.size(); i++) {
Instruction instruction = instructions.get(i);
Opcode opcode = instruction.getOpcode();
if (opcode == Opcode.PACKED_SWITCH) {
boolean valid = true;
int codeOffset = instructionOffsetMap.getInstructionCodeOffset(i);
int targetOffset = codeOffset + ((OffsetInstruction)instruction).getCodeOffset();
try {
targetOffset = findPayloadOffset(targetOffset, Opcode.PACKED_SWITCH_PAYLOAD);
} catch (InvalidSwitchPayload ex) {
valid = false;
}
if (valid) {
if (packedSwitchMap.get(targetOffset, -1) != -1) {
Instruction payloadInstruction =
findSwitchPayload(targetOffset, Opcode.PACKED_SWITCH_PAYLOAD);
targetOffset = endOffset;
effectiveInstructions.set(i, new ImmutableInstruction31t(opcode,
((Instruction31t)instruction).getRegisterA(), targetOffset-codeOffset));
effectiveInstructions.add(payloadInstruction);
endOffset += payloadInstruction.getCodeUnits();
}
packedSwitchMap.append(targetOffset, codeOffset);
}
} else if (opcode == Opcode.SPARSE_SWITCH) {
boolean valid = true;
int codeOffset = instructionOffsetMap.getInstructionCodeOffset(i);
int targetOffset = codeOffset + ((OffsetInstruction)instruction).getCodeOffset();
try {
targetOffset = findPayloadOffset(targetOffset, Opcode.SPARSE_SWITCH_PAYLOAD);
} catch (InvalidSwitchPayload ex) {
valid = false;
// The offset to the payload instruction was invalid. Nothing to do, except that we won't
// add this instruction to the map.
}
if (valid) {
if (sparseSwitchMap.get(targetOffset, -1) != -1) {
Instruction payloadInstruction =
findSwitchPayload(targetOffset, Opcode.SPARSE_SWITCH_PAYLOAD);
targetOffset = endOffset;
effectiveInstructions.set(i, new ImmutableInstruction31t(opcode,
((Instruction31t)instruction).getRegisterA(), targetOffset-codeOffset));
effectiveInstructions.add(payloadInstruction);
endOffset += payloadInstruction.getCodeUnits();
}
sparseSwitchMap.append(targetOffset, codeOffset);
}
}
}
} catch (Exception ex) {
String methodString;
try {
methodString = ReferenceUtil.getMethodDescriptor(method);
} catch (Exception ex2) {
throw ExceptionWithContext.withContext(ex, "Error while processing method");
}
throw ExceptionWithContext.withContext(ex, "Error while processing method %s", methodString);
}
}
public static void writeEmptyMethodTo(IndentingWriter writer, Method method,
baksmaliOptions options) throws IOException {
writer.write(".method ");
writeAccessFlags(writer, method.getAccessFlags());
writer.write(method.getName());
writer.write("(");
ImmutableList<MethodParameter> methodParameters = ImmutableList.copyOf(method.getParameters());
for (MethodParameter parameter: methodParameters) {
writer.write(parameter.getType());
}
writer.write(")");
writer.write(method.getReturnType());
writer.write('\n');
writer.indent(4);
writeParameters(writer, method, methodParameters, options);
String containingClass = null;
if (options.useImplicitReferences) {
containingClass = method.getDefiningClass();
}
AnnotationFormatter.writeTo(writer, method.getAnnotations(), containingClass);
writer.deindent(4);
writer.write(".end method\n");
}
public void writeTo(IndentingWriter writer) throws IOException {
int parameterRegisterCount = 0;
if (!AccessFlags.STATIC.isSet(method.getAccessFlags())) {
parameterRegisterCount++;
}
writer.write(".method ");
writeAccessFlags(writer, method.getAccessFlags());
writer.write(method.getName());
writer.write("(");
for (MethodParameter parameter: methodParameters) {
String type = parameter.getType();
writer.write(type);
parameterRegisterCount++;
if (TypeUtils.isWideType(type)) {
parameterRegisterCount++;
}
}
writer.write(")");
writer.write(method.getReturnType());
writer.write('\n');
writer.indent(4);
if (classDef.options.useLocalsDirective) {
writer.write(".locals ");
writer.printSignedIntAsDec(methodImpl.getRegisterCount() - parameterRegisterCount);
} else {
writer.write(".registers ");
writer.printSignedIntAsDec(methodImpl.getRegisterCount());
}
writer.write('\n');
writeParameters(writer, method, methodParameters, classDef.options);
if (registerFormatter == null) {
registerFormatter = new RegisterFormatter(classDef.options, methodImpl.getRegisterCount(),
parameterRegisterCount);
}
String containingClass = null;
if (classDef.options.useImplicitReferences) {
containingClass = method.getDefiningClass();
}
AnnotationFormatter.writeTo(writer, method.getAnnotations(), containingClass);
writer.write('\n');
List<MethodItem> methodItems = getMethodItems();
for (MethodItem methodItem: methodItems) {
if (methodItem.writeTo(writer)) {
writer.write('\n');
}
}
writer.deindent(4);
writer.write(".end method\n");
}
public Instruction findSwitchPayload(int targetOffset, Opcode type) {
int targetIndex;
try {
targetIndex = instructionOffsetMap.getInstructionIndexAtCodeOffset(targetOffset);
} catch (InvalidInstructionOffset ex) {
throw new InvalidSwitchPayload(targetOffset);
}
//TODO: does dalvik let you pad with multiple nops?
//TODO: does dalvik let a switch instruction point to a non-payload instruction?
Instruction instruction = instructions.get(targetIndex);
if (instruction.getOpcode() != type) {
// maybe it's pointing to a NOP padding instruction. Look at the next instruction
if (instruction.getOpcode() == Opcode.NOP) {
targetIndex += 1;
if (targetIndex < instructions.size()) {
instruction = instructions.get(targetIndex);
if (instruction.getOpcode() == type) {
return instruction;
}
}
}
throw new InvalidSwitchPayload(targetOffset);
} else {
return instruction;
}
}
public int findPayloadOffset(int targetOffset, Opcode type) {
int targetIndex;
try {
targetIndex = instructionOffsetMap.getInstructionIndexAtCodeOffset(targetOffset);
} catch (InvalidInstructionOffset ex) {
throw new InvalidSwitchPayload(targetOffset);
}
//TODO: does dalvik let you pad with multiple nops?
//TODO: does dalvik let a switch instruction point to a non-payload instruction?
Instruction instruction = instructions.get(targetIndex);
if (instruction.getOpcode() != type) {
// maybe it's pointing to a NOP padding instruction. Look at the next instruction
if (instruction.getOpcode() == Opcode.NOP) {
targetIndex += 1;
if (targetIndex < instructions.size()) {
instruction = instructions.get(targetIndex);
if (instruction.getOpcode() == type) {
return instructionOffsetMap.getInstructionCodeOffset(targetIndex);
}
}
}
throw new InvalidSwitchPayload(targetOffset);
} else {
return targetOffset;
}
}
private static void writeAccessFlags(IndentingWriter writer, int accessFlags)
throws IOException {
for (AccessFlags accessFlag: AccessFlags.getAccessFlagsForMethod(accessFlags)) {
writer.write(accessFlag.toString());
writer.write(' ');
}
}
private static void writeParameters(IndentingWriter writer, Method method,
List<? extends MethodParameter> parameters,
baksmaliOptions options) throws IOException {
boolean isStatic = AccessFlags.STATIC.isSet(method.getAccessFlags());
int registerNumber = isStatic?0:1;
for (MethodParameter parameter: parameters) {
String parameterType = parameter.getType();
String parameterName = parameter.getName();
Collection<? extends Annotation> annotations = parameter.getAnnotations();
if (parameterName != null || annotations.size() != 0) {
writer.write(".param p");
writer.printSignedIntAsDec(registerNumber);
if (parameterName != null && options.outputDebugInfo) {
writer.write(", ");
ReferenceFormatter.writeStringReference(writer, parameterName);
}
writer.write(" # ");
writer.write(parameterType);
writer.write("\n");
if (annotations.size() > 0) {
writer.indent(4);
String containingClass = null;
if (options.useImplicitReferences) {
containingClass = method.getDefiningClass();
}
AnnotationFormatter.writeTo(writer, annotations, containingClass);
writer.deindent(4);
writer.write(".end param\n");
}
}
registerNumber++;
if (TypeUtils.isWideType(parameterType)) {
registerNumber++;
}
}
}
@Nonnull public LabelCache getLabelCache() {
return labelCache;
}
public int getPackedSwitchBaseAddress(int packedSwitchPayloadCodeOffset) {
return packedSwitchMap.get(packedSwitchPayloadCodeOffset, -1);
}
public int getSparseSwitchBaseAddress(int sparseSwitchPayloadCodeOffset) {
return sparseSwitchMap.get(sparseSwitchPayloadCodeOffset, -1);
}
private List<MethodItem> getMethodItems() {
ArrayList<MethodItem> methodItems = new ArrayList<MethodItem>();
if ((classDef.options.registerInfo != 0) || (classDef.options.deodex && needsAnalyzed())) {
addAnalyzedInstructionMethodItems(methodItems);
} else {
addInstructionMethodItems(methodItems);
}
addTries(methodItems);
if (classDef.options.outputDebugInfo) {
addDebugInfo(methodItems);
}
if (classDef.options.useSequentialLabels) {
setLabelSequentialNumbers();
}
for (LabelMethodItem labelMethodItem: labelCache.getLabels()) {
methodItems.add(labelMethodItem);
}
Collections.sort(methodItems);
return methodItems;
}
private boolean needsAnalyzed() {
for (Instruction instruction: methodImpl.getInstructions()) {
if (instruction.getOpcode().odexOnly()) {
return true;
}
}
return false;
}
private void addInstructionMethodItems(List<MethodItem> methodItems) {
int currentCodeAddress = 0;
for (int i=0; i<effectiveInstructions.size(); i++) {
Instruction instruction = effectiveInstructions.get(i);
MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(this,
currentCodeAddress, instruction);
methodItems.add(methodItem);
if (i != effectiveInstructions.size() - 1) {
methodItems.add(new BlankMethodItem(currentCodeAddress));
}
if (classDef.options.addCodeOffsets) {
methodItems.add(new MethodItem(currentCodeAddress) {
@Override
public double getSortOrder() {
return -1000;
}
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
writer.write("#@");
writer.printUnsignedLongAsHex(codeAddress & 0xFFFFFFFFL);
return true;
}
});
}
if (!classDef.options.noAccessorComments && (instruction instanceof ReferenceInstruction)) {
Opcode opcode = instruction.getOpcode();
if (opcode.referenceType == ReferenceType.METHOD) {
MethodReference methodReference = null;
try {
methodReference = (MethodReference)((ReferenceInstruction)instruction).getReference();
} catch (InvalidItemIndex ex) {
// just ignore it for now. We'll deal with it later, when processing the instructions
// themselves
}
if (methodReference != null &&
SyntheticAccessorResolver.looksLikeSyntheticAccessor(methodReference.getName())) {
AccessedMember accessedMember =
classDef.options.syntheticAccessorResolver.getAccessedMember(methodReference);
if (accessedMember != null) {
methodItems.add(new SyntheticAccessCommentMethodItem(accessedMember, currentCodeAddress));
}
}
}
}
currentCodeAddress += instruction.getCodeUnits();
}
}
private void addAnalyzedInstructionMethodItems(List<MethodItem> methodItems) {
MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classDef.options.classPath, method,
classDef.options.inlineResolver);
AnalysisException analysisException = methodAnalyzer.getAnalysisException();
if (analysisException != null) {
// TODO: need to keep track of whether any errors occurred, so we can exit with a non-zero result
methodItems.add(new CommentMethodItem(
String.format("AnalysisException: %s", analysisException.getMessage()),
analysisException.codeAddress, Integer.MIN_VALUE));
analysisException.printStackTrace(System.err);
}
List<AnalyzedInstruction> instructions = methodAnalyzer.getAnalyzedInstructions();
int currentCodeAddress = 0;
for (int i=0; i<instructions.size(); i++) {
AnalyzedInstruction instruction = instructions.get(i);
MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(
this, currentCodeAddress, instruction.getInstruction());
methodItems.add(methodItem);
if (instruction.getInstruction().getOpcode().format == Format.UnresolvedOdexInstruction) {
methodItems.add(new CommentedOutMethodItem(
InstructionMethodItemFactory.makeInstructionFormatMethodItem(
this, currentCodeAddress, instruction.getOriginalInstruction())));
}
if (i != instructions.size() - 1) {
methodItems.add(new BlankMethodItem(currentCodeAddress));
}
if (classDef.options.addCodeOffsets) {
methodItems.add(new MethodItem(currentCodeAddress) {
@Override
public double getSortOrder() {
return -1000;
}
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
writer.write("#@");
writer.printUnsignedLongAsHex(codeAddress & 0xFFFFFFFFL);
return true;
}
});
}
if (classDef.options.registerInfo != 0 &&
!instruction.getInstruction().getOpcode().format.isPayloadFormat) {
methodItems.add(
new PreInstructionRegisterInfoMethodItem(classDef.options.registerInfo,
methodAnalyzer, registerFormatter, instruction, currentCodeAddress));
methodItems.add(
new PostInstructionRegisterInfoMethodItem(registerFormatter, instruction, currentCodeAddress));
}
currentCodeAddress += instruction.getInstruction().getCodeUnits();
}
}
private void addTries(List<MethodItem> methodItems) {
List<? extends TryBlock<? extends ExceptionHandler>> tryBlocks = methodImpl.getTryBlocks();
if (tryBlocks.size() == 0) {
return;
}
int lastInstructionAddress = instructionOffsetMap.getInstructionCodeOffset(instructions.size() - 1);
int codeSize = lastInstructionAddress + instructions.get(instructions.size() - 1).getCodeUnits();
for (TryBlock<? extends ExceptionHandler> tryBlock: tryBlocks) {
int startAddress = tryBlock.getStartCodeAddress();
int endAddress = startAddress + tryBlock.getCodeUnitCount();
if (startAddress >= codeSize) {
throw new RuntimeException(String.format("Try start offset %d is past the end of the code block.",
startAddress));
}
// Note: not >=. endAddress == codeSize is valid, when the try covers the last instruction
if (endAddress > codeSize) {
throw new RuntimeException(String.format("Try end offset %d is past the end of the code block.",
endAddress));
}
/**
* The end address points to the address immediately after the end of the last
* instruction that the try block covers. We want the .catch directive and end_try
* label to be associated with the last covered instruction, so we need to get
* the address for that instruction
*/
int lastCoveredIndex = instructionOffsetMap.getInstructionIndexAtCodeOffset(endAddress - 1, false);
int lastCoveredAddress = instructionOffsetMap.getInstructionCodeOffset(lastCoveredIndex);
for (ExceptionHandler handler: tryBlock.getExceptionHandlers()) {
int handlerAddress = handler.getHandlerCodeAddress();
if (handlerAddress >= codeSize) {
throw new ExceptionWithContext(
"Exception handler offset %d is past the end of the code block.", handlerAddress);
}
//use the address from the last covered instruction
CatchMethodItem catchMethodItem = new CatchMethodItem(classDef.options, labelCache, lastCoveredAddress,
handler.getExceptionType(), startAddress, endAddress, handlerAddress);
methodItems.add(catchMethodItem);
}
}
}
private void addDebugInfo(final List<MethodItem> methodItems) {
for (DebugItem debugItem: methodImpl.getDebugItems()) {
methodItems.add(DebugMethodItem.build(registerFormatter, debugItem));
}
}
private void setLabelSequentialNumbers() {
HashMap<String, Integer> nextLabelSequenceByType = new HashMap<String, Integer>();
ArrayList<LabelMethodItem> sortedLabels = new ArrayList<LabelMethodItem>(labelCache.getLabels());
//sort the labels by their location in the method
Collections.sort(sortedLabels);
for (LabelMethodItem labelMethodItem: sortedLabels) {
Integer labelSequence = nextLabelSequenceByType.get(labelMethodItem.getLabelPrefix());
if (labelSequence == null) {
labelSequence = 0;
}
labelMethodItem.setLabelSequence(labelSequence);
nextLabelSequenceByType.put(labelMethodItem.getLabelPrefix(), labelSequence + 1);
}
}
@Nullable
private String getContainingClassForImplicitReference() {
if (classDef.options.useImplicitReferences) {
return classDef.classDef.getType();
}
return null;
}
public static class LabelCache {
protected HashMap<LabelMethodItem, LabelMethodItem> labels = new HashMap<LabelMethodItem, LabelMethodItem>();
public LabelCache() {
}
public LabelMethodItem internLabel(LabelMethodItem labelMethodItem) {
LabelMethodItem internedLabelMethodItem = labels.get(labelMethodItem);
if (internedLabelMethodItem != null) {
return internedLabelMethodItem;
}
labels.put(labelMethodItem, labelMethodItem);
return labelMethodItem;
}
public Collection<LabelMethodItem> getLabels() {
return labels.values();
}
}
public static class InvalidSwitchPayload extends ExceptionWithContext {
private final int payloadOffset;
public InvalidSwitchPayload(int payloadOffset) {
super("No switch payload at offset: %d", payloadOffset);
this.payloadOffset = payloadOffset;
}
public int getPayloadOffset() {
return payloadOffset;
}
}
}

View File

@ -1,59 +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.baksmali.Adaptors;
import org.jf.util.IndentingWriter;
import java.io.IOException;
public abstract class MethodItem implements Comparable<MethodItem> {
protected final int codeAddress;
protected MethodItem(int codeAddress) {
this.codeAddress = codeAddress;
}
public int getCodeAddress() {
return codeAddress;
}
//return an arbitrary double that determines how this item will be sorted with others at the same address
public abstract double getSortOrder();
public int compareTo(MethodItem methodItem) {
int result = ((Integer) codeAddress).compareTo(methodItem.codeAddress);
if (result == 0){
return ((Double)getSortOrder()).compareTo(methodItem.getSortOrder());
}
return result;
}
public abstract boolean writeTo(IndentingWriter writer) throws IOException;
}

View File

@ -1,102 +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.baksmali.Adaptors;
import org.jf.baksmali.baksmaliOptions;
import org.jf.dexlib2.analysis.AnalyzedInstruction;
import org.jf.dexlib2.analysis.RegisterType;
import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.util.BitSet;
public class PostInstructionRegisterInfoMethodItem extends MethodItem {
@Nonnull private final RegisterFormatter registerFormatter;
@Nonnull private final AnalyzedInstruction analyzedInstruction;
public PostInstructionRegisterInfoMethodItem(@Nonnull RegisterFormatter registerFormatter,
@Nonnull AnalyzedInstruction analyzedInstruction,
int codeAddress) {
super(codeAddress);
this.registerFormatter = registerFormatter;
this.analyzedInstruction = analyzedInstruction;
}
@Override
public double getSortOrder() {
return 100.1;
}
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
int registerInfo = registerFormatter.options.registerInfo;
int registerCount = analyzedInstruction.getRegisterCount();
BitSet registers = new BitSet(registerCount);
if ((registerInfo & baksmaliOptions.ALL) != 0) {
registers.set(0, registerCount);
} else {
if ((registerInfo & baksmaliOptions.ALLPOST) != 0) {
registers.set(0, registerCount);
} else if ((registerInfo & baksmaliOptions.DEST) != 0) {
addDestRegs(registers, registerCount);
}
}
return writeRegisterInfo(writer, registers);
}
private void addDestRegs(BitSet printPostRegister, int registerCount) {
for (int registerNum=0; registerNum<registerCount; registerNum++) {
if (!analyzedInstruction.getPreInstructionRegisterType(registerNum).equals(
analyzedInstruction.getPostInstructionRegisterType(registerNum))) {
printPostRegister.set(registerNum);
}
}
}
private boolean writeRegisterInfo(IndentingWriter writer, BitSet registers) throws IOException {
int registerNum = registers.nextSetBit(0);
if (registerNum < 0) {
return false;
}
writer.write('#');
for (; registerNum >= 0; registerNum = registers.nextSetBit(registerNum + 1)) {
RegisterType registerType = analyzedInstruction.getPostInstructionRegisterType(registerNum);
registerFormatter.writeTo(writer, registerNum);
writer.write('=');
registerType.writeTo(writer);
writer.write(';');
}
return true;
}
}

View File

@ -1,260 +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.baksmali.Adaptors;
import org.jf.baksmali.baksmaliOptions;
import org.jf.dexlib2.analysis.AnalyzedInstruction;
import org.jf.dexlib2.analysis.MethodAnalyzer;
import org.jf.dexlib2.analysis.RegisterType;
import org.jf.dexlib2.iface.instruction.*;
import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.util.BitSet;
public class PreInstructionRegisterInfoMethodItem extends MethodItem {
private static AnalyzedInstruction lastInstruction;
private final int registerInfo;
@Nonnull private final MethodAnalyzer methodAnalyzer;
@Nonnull private final RegisterFormatter registerFormatter;
@Nonnull private final AnalyzedInstruction analyzedInstruction;
public PreInstructionRegisterInfoMethodItem(int registerInfo,
@Nonnull MethodAnalyzer methodAnalyzer,
@Nonnull RegisterFormatter registerFormatter,
@Nonnull AnalyzedInstruction analyzedInstruction,
int codeAddress) {
super(codeAddress);
this.registerInfo = registerInfo;
this.methodAnalyzer = methodAnalyzer;
this.registerFormatter = registerFormatter;
this.analyzedInstruction = analyzedInstruction;
}
@Override
public double getSortOrder() {
return 99.9;
}
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
int registerCount = analyzedInstruction.getRegisterCount();
BitSet registers = new BitSet(registerCount);
BitSet mergeRegisters = null;
if ((registerInfo & baksmaliOptions.ALL) != 0) {
registers.set(0, registerCount);
} else {
if ((registerInfo & baksmaliOptions.ALLPRE) != 0) {
registers.set(0, registerCount);
} else {
if ((registerInfo & baksmaliOptions.ARGS) != 0) {
addArgsRegs(registers);
}
if ((registerInfo & baksmaliOptions.DIFFPRE) != 0) {
addDiffRegs(registers);
}
if ((registerInfo & baksmaliOptions.MERGE) != 0) {
if (analyzedInstruction.isBeginningInstruction()) {
addParamRegs(registers, registerCount);
}
mergeRegisters = new BitSet(registerCount);
addMergeRegs(mergeRegisters, registerCount);
} else if ((registerInfo & baksmaliOptions.FULLMERGE) != 0 &&
(analyzedInstruction.isBeginningInstruction())) {
addParamRegs(registers, registerCount);
}
}
}
if ((registerInfo & baksmaliOptions.FULLMERGE) != 0) {
if (mergeRegisters == null) {
mergeRegisters = new BitSet(registerCount);
addMergeRegs(mergeRegisters, registerCount);
}
registers.or(mergeRegisters);
} else if (mergeRegisters != null) {
registers.or(mergeRegisters);
mergeRegisters = null;
}
return writeRegisterInfo(writer, registers, mergeRegisters);
}
private void addArgsRegs(BitSet registers) {
if (analyzedInstruction.getInstruction() instanceof RegisterRangeInstruction) {
RegisterRangeInstruction instruction = (RegisterRangeInstruction)analyzedInstruction.getInstruction();
registers.set(instruction.getStartRegister(),
instruction.getStartRegister() + instruction.getRegisterCount());
} else if (analyzedInstruction.getInstruction() instanceof FiveRegisterInstruction) {
FiveRegisterInstruction instruction = (FiveRegisterInstruction)analyzedInstruction.getInstruction();
int regCount = instruction.getRegisterCount();
switch (regCount) {
case 5:
registers.set(instruction.getRegisterG());
//fall through
case 4:
registers.set(instruction.getRegisterF());
//fall through
case 3:
registers.set(instruction.getRegisterE());
//fall through
case 2:
registers.set(instruction.getRegisterD());
//fall through
case 1:
registers.set(instruction.getRegisterC());
}
} else if (analyzedInstruction.getInstruction() instanceof ThreeRegisterInstruction) {
ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.getInstruction();
registers.set(instruction.getRegisterA());
registers.set(instruction.getRegisterB());
registers.set(instruction.getRegisterC());
} else if (analyzedInstruction.getInstruction() instanceof TwoRegisterInstruction) {
TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.getInstruction();
registers.set(instruction.getRegisterA());
registers.set(instruction.getRegisterB());
} else if (analyzedInstruction.getInstruction() instanceof OneRegisterInstruction) {
OneRegisterInstruction instruction = (OneRegisterInstruction)analyzedInstruction.getInstruction();
registers.set(instruction.getRegisterA());
}
}
private void addDiffRegs(BitSet registers) {
if (! analyzedInstruction.isBeginningInstruction()) {
for (int i = 0; i < analyzedInstruction.getRegisterCount(); i++) {
if (lastInstruction.getPreInstructionRegisterType(i).category !=
analyzedInstruction.getPreInstructionRegisterType(i).category) {
registers.set(i);
}
}
}
lastInstruction = analyzedInstruction;
}
private void addMergeRegs(BitSet registers, int registerCount) {
if (analyzedInstruction.getPredecessorCount() <= 1) {
//in the common case of an instruction that only has a single predecessor which is the previous
//instruction, the pre-instruction registers will always match the previous instruction's
//post-instruction registers
return;
}
for (int registerNum=0; registerNum<registerCount; registerNum++) {
RegisterType mergedRegisterType = analyzedInstruction.getPreInstructionRegisterType(registerNum);
for (AnalyzedInstruction predecessor: analyzedInstruction.getPredecessors()) {
RegisterType predecessorRegisterType = predecessor.getPostInstructionRegisterType(registerNum);
if (predecessorRegisterType.category != RegisterType.UNKNOWN &&
!predecessorRegisterType.equals(mergedRegisterType)) {
registers.set(registerNum);
}
}
}
}
private void addParamRegs(BitSet registers, int registerCount) {
int parameterRegisterCount = methodAnalyzer.getParamRegisterCount();
registers.set(registerCount-parameterRegisterCount, registerCount);
}
private void writeFullMerge(IndentingWriter writer, int registerNum) throws IOException {
registerFormatter.writeTo(writer, registerNum);
writer.write('=');
analyzedInstruction.getPreInstructionRegisterType(registerNum).writeTo(writer);
writer.write(":merge{");
boolean first = true;
for (AnalyzedInstruction predecessor: analyzedInstruction.getPredecessors()) {
RegisterType predecessorRegisterType = predecessor.getPostInstructionRegisterType(registerNum);
if (!first) {
writer.write(',');
}
if (predecessor.getInstructionIndex() == -1) {
//the fake "StartOfMethod" instruction
writer.write("Start:");
} else {
writer.write("0x");
writer.printUnsignedLongAsHex(methodAnalyzer.getInstructionAddress(predecessor));
writer.write(':');
}
predecessorRegisterType.writeTo(writer);
first = false;
}
writer.write('}');
}
private boolean writeRegisterInfo(IndentingWriter writer, BitSet registers,
BitSet fullMergeRegisters) throws IOException {
boolean firstRegister = true;
boolean previousWasFullMerge = false;
int registerNum = registers.nextSetBit(0);
if (registerNum < 0) {
return false;
}
writer.write('#');
for (; registerNum >= 0; registerNum = registers.nextSetBit(registerNum + 1)) {
boolean fullMerge = fullMergeRegisters!=null && fullMergeRegisters.get(registerNum);
if (fullMerge) {
if (!firstRegister) {
writer.write('\n');
writer.write('#');
}
writeFullMerge(writer, registerNum);
previousWasFullMerge = true;
} else {
if (previousWasFullMerge) {
writer.write('\n');
writer.write('#');
previousWasFullMerge = false;
}
RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(registerNum);
registerFormatter.writeTo(writer, registerNum);
writer.write('=');
registerType.writeTo(writer);
writer.write(';');
}
firstRegister = false;
}
return true;
}
}

View File

@ -1,65 +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.baksmali.Adaptors;
import org.jf.dexlib2.ReferenceType;
import org.jf.dexlib2.iface.reference.*;
import org.jf.dexlib2.util.ReferenceUtil;
import org.jf.util.IndentingWriter;
import org.jf.util.StringUtils;
import java.io.IOException;
public class ReferenceFormatter {
public static void writeStringReference(IndentingWriter writer, String item) throws IOException {
writer.write('"');
StringUtils.writeEscapedString(writer, item);
writer.write('"');
}
public static void writeReference(IndentingWriter writer, int referenceType,
Reference reference) throws IOException {
switch (referenceType) {
case ReferenceType.STRING:
writeStringReference(writer, ((StringReference)reference).getString());
return;
case ReferenceType.TYPE:
writer.write(((TypeReference)reference).getType());
return;
case ReferenceType.METHOD:
ReferenceUtil.writeMethodDescriptor(writer, (MethodReference)reference);
return;
case ReferenceType.FIELD:
ReferenceUtil.writeFieldDescriptor(writer, (FieldReference)reference);
return;
default:
throw new IllegalStateException("Unknown reference type");
}
}
}

View File

@ -1,99 +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.baksmali.Adaptors;
import org.jf.baksmali.baksmaliOptions;
import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import java.io.IOException;
/**
* This class contains the logic used for formatting registers
*/
public class RegisterFormatter {
@Nonnull public final baksmaliOptions options;
public final int registerCount;
public final int parameterRegisterCount;
public RegisterFormatter(@Nonnull baksmaliOptions options, int registerCount, int parameterRegisterCount) {
this.options = options;
this.registerCount = registerCount;
this.parameterRegisterCount = parameterRegisterCount;
}
/**
* Write out the register range value used by Format3rc. If baksmali.noParameterRegisters is true, it will always
* output the registers in the v<n> format. But if false, then it will check if *both* registers are parameter
* registers, and if so, use the p<n> format for both. If only the last register is a parameter register, it will
* use the v<n> format for both, otherwise it would be confusing to have something like {v20 .. p1}
* @param writer the <code>IndentingWriter</code> to write to
* @param startRegister the first register in the range
* @param lastRegister the last register in the range
*/
public void writeRegisterRange(IndentingWriter writer, int startRegister, int lastRegister) throws IOException {
if (!options.noParameterRegisters) {
assert startRegister <= lastRegister;
if (startRegister >= registerCount - parameterRegisterCount) {
writer.write("{p");
writer.printSignedIntAsDec(startRegister - (registerCount - parameterRegisterCount));
writer.write(" .. p");
writer.printSignedIntAsDec(lastRegister - (registerCount - parameterRegisterCount));
writer.write('}');
return;
}
}
writer.write("{v");
writer.printSignedIntAsDec(startRegister);
writer.write(" .. v");
writer.printSignedIntAsDec(lastRegister);
writer.write('}');
}
/**
* Writes a register with the appropriate format. If baksmali.noParameterRegisters is true, then it will always
* output a register in the v<n> format. If false, then it determines if the register is a parameter register,
* and if so, formats it in the p<n> format instead.
*
* @param writer the <code>IndentingWriter</code> to write to
* @param register the register number
*/
public void writeTo(IndentingWriter writer, int register) throws IOException {
if (!options.noParameterRegisters) {
if (register >= registerCount - parameterRegisterCount) {
writer.write('p');
writer.printSignedIntAsDec((register - (registerCount - parameterRegisterCount)));
return;
}
}
writer.write('v');
writer.printSignedIntAsDec(register);
}
}

View File

@ -1,121 +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.baksmali.Adaptors;
import org.jf.dexlib2.ReferenceType;
import org.jf.dexlib2.util.SyntheticAccessorResolver;
import org.jf.util.ExceptionWithContext;
import org.jf.util.IndentingWriter;
import java.io.IOException;
public class SyntheticAccessCommentMethodItem extends MethodItem {
private final SyntheticAccessorResolver.AccessedMember accessedMember;
public SyntheticAccessCommentMethodItem(SyntheticAccessorResolver.AccessedMember accessedMember, int codeAddress) {
super(codeAddress);
this.accessedMember = accessedMember;
}
public double getSortOrder() {
//just before the pre-instruction register information, if any
return 99.8;
}
public boolean writeTo(IndentingWriter writer) throws IOException {
writer.write("# ");
switch (accessedMember.accessedMemberType) {
case SyntheticAccessorResolver.METHOD:
writer.write("invokes: ");
break;
case SyntheticAccessorResolver.GETTER:
writer.write("getter for: ");
break;
case SyntheticAccessorResolver.SETTER:
writer.write("setter for: ");
break;
case SyntheticAccessorResolver.PREFIX_INCREMENT:
writer.write("++operator for: ");
break;
case SyntheticAccessorResolver.POSTFIX_INCREMENT:
writer.write("operator++ for: ");
break;
case SyntheticAccessorResolver.PREFIX_DECREMENT:
writer.write("--operator for: ");
break;
case SyntheticAccessorResolver.POSTFIX_DECREMENT:
writer.write("operator-- for: ");
break;
case SyntheticAccessorResolver.ADD_ASSIGNMENT:
writer.write("+= operator for: ");
break;
case SyntheticAccessorResolver.SUB_ASSIGNMENT:
writer.write("-= operator for: ");
break;
case SyntheticAccessorResolver.MUL_ASSIGNMENT:
writer.write("*= operator for: ");
break;
case SyntheticAccessorResolver.DIV_ASSIGNMENT:
writer.write("/= operator for: ");
break;
case SyntheticAccessorResolver.REM_ASSIGNMENT:
writer.write("%= operator for: ");
break;
case SyntheticAccessorResolver.AND_ASSIGNMENT:
writer.write("&= operator for: ");
break;
case SyntheticAccessorResolver.OR_ASSIGNMENT:
writer.write("|= operator for: ");
break;
case SyntheticAccessorResolver.XOR_ASSIGNMENT:
writer.write("^= operator for: ");
break;
case SyntheticAccessorResolver.SHL_ASSIGNMENT:
writer.write("<<= operator for: ");
break;
case SyntheticAccessorResolver.SHR_ASSIGNMENT:
writer.write(">>= operator for: ");
break;
case SyntheticAccessorResolver.USHR_ASSIGNMENT:
writer.write(">>>= operator for: ");
break;
default:
throw new ExceptionWithContext("Unknown access type: %d", accessedMember.accessedMemberType);
}
int referenceType;
if (accessedMember.accessedMemberType == SyntheticAccessorResolver.METHOD) {
referenceType = ReferenceType.METHOD;
} else {
referenceType = ReferenceType.FIELD;
}
ReferenceFormatter.writeReference(writer, referenceType, accessedMember.accessedMember);
return true;
}
}

View File

@ -1,43 +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.baksmali.Renderers;
import org.jf.util.IndentingWriter;
import java.io.IOException;
public class BooleanRenderer {
public static void writeTo(IndentingWriter writer, boolean val) throws IOException {
if (val) {
writer.write("true");
} else {
writer.write("false");
}
}
}

View File

@ -1,53 +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.baksmali.Renderers;
import org.jf.util.IndentingWriter;
import java.io.IOException;
public class ByteRenderer {
public static void writeTo(IndentingWriter writer, byte val) throws IOException {
if (val<0) {
writer.write("-0x");
writer.printUnsignedLongAsHex(-val);
writer.write('t');
} else {
writer.write("0x");
writer.printUnsignedLongAsHex(val);
writer.write('t');
}
}
public static void writeUnsignedTo(IndentingWriter writer, byte val) throws IOException {
writer.write("0x");
writer.printUnsignedLongAsHex(val & 0xFF);
writer.write('t');
}
}

View File

@ -1,42 +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.baksmali.Renderers;
import org.jf.util.IndentingWriter;
import org.jf.util.StringUtils;
import java.io.IOException;
public class CharRenderer {
public static void writeTo(IndentingWriter writer, char val) throws IOException {
writer.write('\'');
StringUtils.writeEscapedChar(writer, val);
writer.write('\'');
}
}

View File

@ -1,39 +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.baksmali.Renderers;
import org.jf.util.IndentingWriter;
import java.io.IOException;
public class DoubleRenderer {
public static void writeTo(IndentingWriter writer, double val) throws IOException {
writer.write(Double.toString(val));
}
}

View File

@ -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.baksmali.Renderers;
import org.jf.util.IndentingWriter;
import java.io.IOException;
public class FloatRenderer {
public static void writeTo(IndentingWriter writer, float val) throws IOException {
writer.write(Float.toString(val));
writer.write('f');
}
}

View File

@ -1,50 +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.baksmali.Renderers;
import org.jf.util.IndentingWriter;
import java.io.IOException;
public class IntegerRenderer {
public static void writeTo(IndentingWriter writer, int val) throws IOException {
if (val<0) {
writer.write("-0x");
writer.printUnsignedLongAsHex(-((long) val));
} else {
writer.write("0x");
writer.printUnsignedLongAsHex(val);
}
}
public static void writeUnsignedTo(IndentingWriter writer, int val) throws IOException {
writer.write("0x");
writer.printUnsignedLongAsHex(val & 0xFFFFFFFFL);
}
}

View File

@ -1,63 +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.baksmali.Renderers;
import org.jf.util.IndentingWriter;
import java.io.IOException;
public class LongRenderer {
public static void writeTo(IndentingWriter writer, long val) throws IOException {
if (val<0) {
writer.write("-0x");
writer.printUnsignedLongAsHex(-val);
writer.write('L');
} else {
writer.write("0x");
writer.printUnsignedLongAsHex(val);
writer.write('L');
}
}
public static void writeSignedIntOrLongTo(IndentingWriter writer, long val) throws IOException {
if (val<0) {
writer.write("-0x");
writer.printUnsignedLongAsHex(-val);
if (val < Integer.MIN_VALUE) {
writer.write('L');
}
} else {
writer.write("0x");
writer.printUnsignedLongAsHex(val);
if (val > Integer.MAX_VALUE) {
writer.write('L');
}
}
}
}

View File

@ -1,47 +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.baksmali.Renderers;
import org.jf.util.IndentingWriter;
import java.io.IOException;
public class ShortRenderer {
public static void writeTo(IndentingWriter writer, short val) throws IOException {
if (val < 0) {
writer.write("-0x");
writer.printUnsignedLongAsHex(-val);
writer.write('s');
} else {
writer.write("0x");
writer.printUnsignedLongAsHex(val);
writer.write('s');
}
}
}

View File

@ -1,247 +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.baksmali;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import org.jf.baksmali.Adaptors.ClassDefinition;
import org.jf.dexlib2.analysis.ClassPath;
import org.jf.dexlib2.analysis.CustomInlineMethodResolver;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.DexFile;
import org.jf.dexlib2.util.SyntheticAccessorResolver;
import org.jf.util.ClassFileNameHandler;
import org.jf.util.IndentingWriter;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.io.*;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.*;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.ParserConfigurationException;
public class baksmali {
public static boolean disassembleDexFile(DexFile dexFile, final baksmaliOptions options) {
if (options.registerInfo != 0 || options.deodex) {
try {
Iterable<String> extraClassPathEntries;
if (options.extraClassPathEntries != null) {
extraClassPathEntries = options.extraClassPathEntries;
} else {
extraClassPathEntries = ImmutableList.of();
}
options.classPath = ClassPath.fromClassPath(options.bootClassPathDirs,
Iterables.concat(options.bootClassPathEntries, extraClassPathEntries), dexFile,
options.apiLevel, options.checkPackagePrivateAccess, options.experimental);
if (options.customInlineDefinitions != null) {
options.inlineResolver = new CustomInlineMethodResolver(options.classPath,
options.customInlineDefinitions);
}
} catch (Exception ex) {
System.err.println("\n\nError occurred while loading boot class path files. Aborting.");
ex.printStackTrace(System.err);
return false;
}
}
if (options.resourceIdFileEntries != null) {
class PublicHandler extends DefaultHandler {
String prefix = null;
public PublicHandler(String prefix) {
super();
this.prefix = prefix;
}
public void startElement(String uri, String localName,
String qName, Attributes attr) throws SAXException {
if (qName.equals("public")) {
String type = attr.getValue("type");
String name = attr.getValue("name").replace('.', '_');
Integer public_key = Integer.decode(attr.getValue("id"));
String public_val = new StringBuffer()
.append(prefix)
.append(".")
.append(type)
.append(".")
.append(name)
.toString();
options.resourceIds.put(public_key, public_val);
}
}
};
for (Entry<String,String> entry: options.resourceIdFileEntries.entrySet()) {
try {
SAXParser saxp = SAXParserFactory.newInstance().newSAXParser();
String prefix = entry.getValue();
saxp.parse(entry.getKey(), new PublicHandler(prefix));
} catch (ParserConfigurationException e) {
continue;
} catch (SAXException e) {
continue;
} catch (IOException e) {
continue;
}
}
}
File outputDirectoryFile = new File(options.outputDirectory);
if (!outputDirectoryFile.exists()) {
if (!outputDirectoryFile.mkdirs()) {
System.err.println("Can't create the output directory " + options.outputDirectory);
return false;
}
}
//sort the classes, so that if we're on a case-insensitive file system and need to handle classes with file
//name collisions, then we'll use the same name for each class, if the dex file goes through multiple
//baksmali/smali cycles for some reason. If a class with a colliding name is added or removed, the filenames
//may still change of course
List<? extends ClassDef> classDefs = Ordering.natural().sortedCopy(dexFile.getClasses());
if (!options.noAccessorComments) {
options.syntheticAccessorResolver = new SyntheticAccessorResolver(classDefs);
}
final ClassFileNameHandler fileNameHandler = new ClassFileNameHandler(outputDirectoryFile, ".smali");
ExecutorService executor = Executors.newFixedThreadPool(options.jobs);
List<Future<Boolean>> tasks = Lists.newArrayList();
for (final ClassDef classDef: classDefs) {
tasks.add(executor.submit(new Callable<Boolean>() {
@Override public Boolean call() throws Exception {
return disassembleClass(classDef, fileNameHandler, options);
}
}));
}
boolean errorOccurred = false;
try {
for (Future<Boolean> task: tasks) {
while(true) {
try {
if (!task.get()) {
errorOccurred = true;
}
} catch (InterruptedException ex) {
continue;
} catch (ExecutionException ex) {
throw new RuntimeException(ex);
}
break;
}
}
} finally {
executor.shutdown();
}
return !errorOccurred;
}
private static boolean disassembleClass(ClassDef classDef, ClassFileNameHandler fileNameHandler,
baksmaliOptions options) {
/**
* The path for the disassembly file is based on the package name
* The class descriptor will look something like:
* Ljava/lang/Object;
* Where the there is leading 'L' and a trailing ';', and the parts of the
* package name are separated by '/'
*/
String classDescriptor = classDef.getType();
//validate that the descriptor is formatted like we expect
if (classDescriptor.charAt(0) != 'L' ||
classDescriptor.charAt(classDescriptor.length()-1) != ';') {
System.err.println("Unrecognized class descriptor - " + classDescriptor + " - skipping class");
return false;
}
File smaliFile = fileNameHandler.getUniqueFilenameForClass(classDescriptor);
//create and initialize the top level string template
ClassDefinition classDefinition = new ClassDefinition(options, classDef);
//write the disassembly
Writer writer = null;
try
{
File smaliParent = smaliFile.getParentFile();
if (!smaliParent.exists()) {
if (!smaliParent.mkdirs()) {
// check again, it's likely it was created in a different thread
if (!smaliParent.exists()) {
System.err.println("Unable to create directory " + smaliParent.toString() + " - skipping class");
return false;
}
}
}
if (!smaliFile.exists()){
if (!smaliFile.createNewFile()) {
System.err.println("Unable to create file " + smaliFile.toString() + " - skipping class");
return false;
}
}
BufferedWriter bufWriter = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(smaliFile), "UTF8"));
writer = new IndentingWriter(bufWriter);
classDefinition.writeTo((IndentingWriter)writer);
} catch (Exception ex) {
System.err.println("\n\nError occurred while disassembling class " + classDescriptor.replace('/', '.') + " - skipping class");
ex.printStackTrace();
// noinspection ResultOfMethodCallIgnored
smaliFile.delete();
return false;
}
finally
{
if (writer != null) {
try {
writer.close();
} catch (Throwable ex) {
System.err.println("\n\nError occurred while closing file " + smaliFile.toString());
ex.printStackTrace();
}
}
}
return true;
}
}

View File

@ -1,105 +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.baksmali;
import com.google.common.collect.Lists;
import org.jf.dexlib2.analysis.ClassPath;
import org.jf.dexlib2.analysis.InlineMethodResolver;
import org.jf.dexlib2.util.SyntheticAccessorResolver;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class baksmaliOptions {
// register info values
public static final int ALL = 1;
public static final int ALLPRE = 2;
public static final int ALLPOST = 4;
public static final int ARGS = 8;
public static final int DEST = 16;
public static final int MERGE = 32;
public static final int FULLMERGE = 64;
public static final int DIFFPRE = 128;
public int apiLevel = 15;
public String outputDirectory = "out";
public String dexEntry = "classes.dex";
public List<String> bootClassPathDirs = Lists.newArrayList();
public List<String> bootClassPathEntries = Lists.newArrayList();
public List<String> extraClassPathEntries = Lists.newArrayList();
public Map<String,String> resourceIdFileEntries = new HashMap<String,String>();
public Map<Integer,String> resourceIds = new HashMap<Integer,String>();
public boolean noParameterRegisters = false;
public boolean useLocalsDirective = false;
public boolean useSequentialLabels = false;
public boolean outputDebugInfo = true;
public boolean addCodeOffsets = false;
public boolean noAccessorComments = false;
public boolean allowOdex = false;
public boolean deodex = false;
public boolean experimental = false;
public boolean ignoreErrors = false;
public boolean checkPackagePrivateAccess = false;
public boolean useImplicitReferences = false;
public File customInlineDefinitions = null;
public InlineMethodResolver inlineResolver = null;
public int registerInfo = 0;
public ClassPath classPath = null;
public int jobs = -1;
public SyntheticAccessorResolver syntheticAccessorResolver = null;
public void setBootClassPath(String bootClassPath) {
bootClassPathEntries = Lists.newArrayList(bootClassPath.split(":"));
}
public void addExtraClassPath(String extraClassPath) {
if (extraClassPath.startsWith(":")) {
extraClassPath = extraClassPath.substring(1);
}
extraClassPathEntries.addAll(Arrays.asList(extraClassPath.split(":")));
}
public void setResourceIdFiles(String resourceIdFiles) {
for (String resourceIdFile: resourceIdFiles.split(":")) {
String[] entry = resourceIdFile.split("=");
resourceIdFileEntries.put(entry[1], entry[0]);
}
}
}

View File

@ -1,73 +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.baksmali;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
import org.jf.dexlib2.dexbacked.raw.RawDexFile;
import org.jf.dexlib2.dexbacked.raw.util.DexAnnotator;
import org.jf.util.ConsoleUtil;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class dump {
public static void dump(DexBackedDexFile dexFile, String dumpFileName, int apiLevel, boolean experimental) throws IOException {
if (dumpFileName != null) {
Writer writer = null;
try {
writer = new BufferedWriter(new FileWriter(dumpFileName));
int consoleWidth = ConsoleUtil.getConsoleWidth();
if (consoleWidth <= 0) {
consoleWidth = 120;
}
RawDexFile rawDexFile = new RawDexFile(new Opcodes(apiLevel, experimental), dexFile);
DexAnnotator annotator = new DexAnnotator(rawDexFile, consoleWidth);
annotator.writeAnnotations(writer);
} catch (IOException ex) {
System.err.println("There was an error while dumping the dex file to " + dumpFileName);
ex.printStackTrace(System.err);
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException ex) {
System.err.println("There was an error while closing the dump file " + dumpFileName);
ex.printStackTrace(System.err);
}
}
}
}
}
}

View File

@ -1,566 +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.baksmali;
import com.google.common.collect.Lists;
import org.apache.commons.cli.*;
import org.jf.dexlib2.DexFileFactory;
import org.jf.dexlib2.analysis.InlineMethodResolver;
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
import org.jf.dexlib2.dexbacked.DexBackedOdexFile;
import org.jf.util.ConsoleUtil;
import org.jf.util.SmaliHelpFormatter;
import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
public class main {
public static final String VERSION;
private static final Options basicOptions;
private static final Options debugOptions;
private static final Options options;
static {
options = new Options();
basicOptions = new Options();
debugOptions = new Options();
buildOptions();
InputStream templateStream = baksmali.class.getClassLoader().getResourceAsStream("baksmali.properties");
if (templateStream != null) {
Properties properties = new Properties();
String version = "(unknown)";
try {
properties.load(templateStream);
version = properties.getProperty("application.version");
} catch (IOException ex) {
// ignore
}
VERSION = version;
} else {
VERSION = "[unknown version]";
}
}
/**
* This class is uninstantiable.
*/
private main() {
}
/**
* Run!
*/
public static void main(String[] args) throws IOException {
Locale locale = new Locale("en", "US");
Locale.setDefault(locale);
CommandLineParser parser = new PosixParser();
CommandLine commandLine;
try {
commandLine = parser.parse(options, args);
} catch (ParseException ex) {
usage();
return;
}
baksmaliOptions options = new baksmaliOptions();
boolean disassemble = true;
boolean doDump = false;
String dumpFileName = null;
boolean setBootClassPath = false;
String[] remainingArgs = commandLine.getArgs();
Option[] clOptions = commandLine.getOptions();
for (int i=0; i<clOptions.length; i++) {
Option option = clOptions[i];
String opt = option.getOpt();
switch (opt.charAt(0)) {
case 'v':
version();
return;
case '?':
while (++i < clOptions.length) {
if (clOptions[i].getOpt().charAt(0) == '?') {
usage(true);
return;
}
}
usage(false);
return;
case 'o':
options.outputDirectory = commandLine.getOptionValue("o");
break;
case 'p':
options.noParameterRegisters = true;
break;
case 'l':
options.useLocalsDirective = true;
break;
case 's':
options.useSequentialLabels = true;
break;
case 'b':
options.outputDebugInfo = false;
break;
case 'd':
options.bootClassPathDirs.add(option.getValue());
break;
case 'f':
options.addCodeOffsets = true;
break;
case 'r':
String[] values = commandLine.getOptionValues('r');
int registerInfo = 0;
if (values == null || values.length == 0) {
registerInfo = baksmaliOptions.ARGS | baksmaliOptions.DEST;
} else {
for (String value: values) {
if (value.equalsIgnoreCase("ALL")) {
registerInfo |= baksmaliOptions.ALL;
} else if (value.equalsIgnoreCase("ALLPRE")) {
registerInfo |= baksmaliOptions.ALLPRE;
} else if (value.equalsIgnoreCase("ALLPOST")) {
registerInfo |= baksmaliOptions.ALLPOST;
} else if (value.equalsIgnoreCase("ARGS")) {
registerInfo |= baksmaliOptions.ARGS;
} else if (value.equalsIgnoreCase("DEST")) {
registerInfo |= baksmaliOptions.DEST;
} else if (value.equalsIgnoreCase("MERGE")) {
registerInfo |= baksmaliOptions.MERGE;
} else if (value.equalsIgnoreCase("FULLMERGE")) {
registerInfo |= baksmaliOptions.FULLMERGE;
} else {
usage();
return;
}
}
if ((registerInfo & baksmaliOptions.FULLMERGE) != 0) {
registerInfo &= ~baksmaliOptions.MERGE;
}
}
options.registerInfo = registerInfo;
break;
case 'c':
String bcp = commandLine.getOptionValue("c");
if (bcp != null && bcp.charAt(0) == ':') {
options.addExtraClassPath(bcp);
} else {
setBootClassPath = true;
options.setBootClassPath(bcp);
}
break;
case 'x':
options.deodex = true;
break;
case 'X':
options.experimental = true;
break;
case 'm':
options.noAccessorComments = true;
break;
case 'a':
options.apiLevel = Integer.parseInt(commandLine.getOptionValue("a"));
break;
case 'j':
options.jobs = Integer.parseInt(commandLine.getOptionValue("j"));
break;
case 'i':
String rif = commandLine.getOptionValue("i");
options.setResourceIdFiles(rif);
break;
case 't':
options.useImplicitReferences = true;
break;
case 'e':
options.dexEntry = commandLine.getOptionValue("e");
break;
case 'k':
options.checkPackagePrivateAccess = true;
break;
case 'N':
disassemble = false;
break;
case 'D':
doDump = true;
dumpFileName = commandLine.getOptionValue("D");
break;
case 'I':
options.ignoreErrors = true;
break;
case 'T':
options.customInlineDefinitions = new File(commandLine.getOptionValue("T"));
break;
default:
assert false;
}
}
if (remainingArgs.length != 1) {
usage();
return;
}
if (options.jobs <= 0) {
options.jobs = Runtime.getRuntime().availableProcessors();
if (options.jobs > 6) {
options.jobs = 6;
}
}
String inputDexFileName = remainingArgs[0];
File dexFileFile = new File(inputDexFileName);
if (!dexFileFile.exists()) {
System.err.println("Can't find the file " + inputDexFileName);
System.exit(1);
}
//Read in and parse the dex file
DexBackedDexFile dexFile = DexFileFactory.loadDexFile(dexFileFile, options.dexEntry,
options.apiLevel, options.experimental);
if (dexFile.isOdexFile()) {
if (!options.deodex) {
System.err.println("Warning: You are disassembling an odex file without deodexing it. You");
System.err.println("won't be able to re-assemble the results unless you deodex it with the -x");
System.err.println("option");
options.allowOdex = true;
}
} else {
options.deodex = false;
}
if (!setBootClassPath && (options.deodex || options.registerInfo != 0)) {
if (dexFile instanceof DexBackedOdexFile) {
options.bootClassPathEntries = ((DexBackedOdexFile)dexFile).getDependencies();
} else {
options.bootClassPathEntries = getDefaultBootClassPathForApi(options.apiLevel,
options.experimental);
}
}
if (options.customInlineDefinitions == null && dexFile instanceof DexBackedOdexFile) {
options.inlineResolver =
InlineMethodResolver.createInlineMethodResolver(
((DexBackedOdexFile)dexFile).getOdexVersion());
}
boolean errorOccurred = false;
if (disassemble) {
errorOccurred = !baksmali.disassembleDexFile(dexFile, options);
}
if (doDump) {
if (dumpFileName == null) {
dumpFileName = commandLine.getOptionValue(inputDexFileName + ".dump");
}
dump.dump(dexFile, dumpFileName, options.apiLevel, options.experimental);
}
if (errorOccurred) {
System.exit(1);
}
}
/**
* Prints the usage message.
*/
private static void usage(boolean printDebugOptions) {
SmaliHelpFormatter formatter = new SmaliHelpFormatter();
int consoleWidth = ConsoleUtil.getConsoleWidth();
if (consoleWidth <= 0) {
consoleWidth = 80;
}
formatter.setWidth(consoleWidth);
formatter.printHelp("java -jar baksmali.jar [options] <dex-file>",
"disassembles and/or dumps a dex file", basicOptions, printDebugOptions?debugOptions:null);
}
private static void usage() {
usage(false);
}
/**
* Prints the version message.
*/
protected static void version() {
System.out.println("baksmali " + VERSION + " (http://smali.googlecode.com)");
System.out.println("Copyright (C) 2010 Ben Gruver (JesusFreke@JesusFreke.com)");
System.out.println("BSD license (http://www.opensource.org/licenses/bsd-license.php)");
System.exit(0);
}
@SuppressWarnings("AccessStaticViaInstance")
private static void buildOptions() {
Option versionOption = OptionBuilder.withLongOpt("version")
.withDescription("prints the version then exits")
.create("v");
Option helpOption = OptionBuilder.withLongOpt("help")
.withDescription("prints the help message then exits. Specify twice for debug options")
.create("?");
Option outputDirOption = OptionBuilder.withLongOpt("output")
.withDescription("the directory where the disassembled files will be placed. The default is out")
.hasArg()
.withArgName("DIR")
.create("o");
Option noParameterRegistersOption = OptionBuilder.withLongOpt("no-parameter-registers")
.withDescription("use the v<n> syntax instead of the p<n> syntax for registers mapped to method " +
"parameters")
.create("p");
Option deodexerantOption = OptionBuilder.withLongOpt("deodex")
.withDescription("deodex the given odex file. This option is ignored if the input file is not an " +
"odex file")
.create("x");
Option experimentalOption = OptionBuilder.withLongOpt("experimental")
.withDescription("enable experimental opcodes to be disassembled, even if they aren't necessarily supported in the Android runtime yet")
.create("X");
Option useLocalsOption = OptionBuilder.withLongOpt("use-locals")
.withDescription("output the .locals directive with the number of non-parameter registers, rather" +
" than the .register directive with the total number of register")
.create("l");
Option sequentialLabelsOption = OptionBuilder.withLongOpt("sequential-labels")
.withDescription("create label names using a sequential numbering scheme per label type, rather than " +
"using the bytecode address")
.create("s");
Option noDebugInfoOption = OptionBuilder.withLongOpt("no-debug-info")
.withDescription("don't write out debug info (.local, .param, .line, etc.)")
.create("b");
Option registerInfoOption = OptionBuilder.withLongOpt("register-info")
.hasOptionalArgs()
.withArgName("REGISTER_INFO_TYPES")
.withValueSeparator(',')
.withDescription("print the specificed type(s) of register information for each instruction. " +
"\"ARGS,DEST\" is the default if no types are specified.\nValid values are:\nALL: all " +
"pre- and post-instruction registers.\nALLPRE: all pre-instruction registers\nALLPOST: all " +
"post-instruction registers\nARGS: any pre-instruction registers used as arguments to the " +
"instruction\nDEST: the post-instruction destination register, if any\nMERGE: Any " +
"pre-instruction register has been merged from more than 1 different post-instruction " +
"register from its predecessors\nFULLMERGE: For each register that would be printed by " +
"MERGE, also show the incoming register types that were merged")
.create("r");
Option classPathOption = OptionBuilder.withLongOpt("bootclasspath")
.withDescription("the bootclasspath jars to use, for analysis. Defaults to " +
"core.jar:ext.jar:framework.jar:android.policy.jar:services.jar. If the value begins with a " +
":, it will be appended to the default bootclasspath instead of replacing it")
.hasOptionalArg()
.withArgName("BOOTCLASSPATH")
.create("c");
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 codeOffsetOption = OptionBuilder.withLongOpt("code-offsets")
.withDescription("add comments to the disassembly containing the code offset for each address")
.create("f");
Option noAccessorCommentsOption = OptionBuilder.withLongOpt("no-accessor-comments")
.withDescription("don't output helper comments for synthetic accessors")
.create("m");
Option apiLevelOption = OptionBuilder.withLongOpt("api-level")
.withDescription("The numeric api-level of the file being disassembled. If not " +
"specified, it defaults to 15 (ICS).")
.hasArg()
.withArgName("API_LEVEL")
.create("a");
Option jobsOption = OptionBuilder.withLongOpt("jobs")
.withDescription("The number of threads to use. Defaults to the number of cores available, up to a " +
"maximum of 6")
.hasArg()
.withArgName("NUM_THREADS")
.create("j");
Option resourceIdFilesOption = OptionBuilder.withLongOpt("resource-id-files")
.withDescription("the resource ID files to use, for analysis. A colon-separated list of prefix=file " +
"pairs. For example R=res/values/public.xml:" +
"android.R=$ANDROID_HOME/platforms/android-19/data/res/values/public.xml")
.hasArg()
.withArgName("FILES")
.create("i");
Option noImplicitReferencesOption = OptionBuilder.withLongOpt("implicit-references")
.withDescription("Use implicit (type-less) method and field references")
.create("t");
Option checkPackagePrivateAccessOption = OptionBuilder.withLongOpt("check-package-private-access")
.withDescription("When deodexing, use the package-private access check when calculating vtable " +
"indexes. It should only be needed for 4.2.0 odexes. The functionality was reverted for " +
"4.2.1.")
.create("k");
Option dumpOption = OptionBuilder.withLongOpt("dump-to")
.withDescription("dumps the given dex file into a single annotated dump file named FILE" +
" (<dexfile>.dump by default), along with the normal disassembly")
.hasOptionalArg()
.withArgName("FILE")
.create("D");
Option ignoreErrorsOption = OptionBuilder.withLongOpt("ignore-errors")
.withDescription("ignores any non-fatal errors that occur while disassembling/deodexing," +
" ignoring the class if needed, and continuing with the next class. The default" +
" behavior is to stop disassembling and exit once an error is encountered")
.create("I");
Option noDisassemblyOption = OptionBuilder.withLongOpt("no-disassembly")
.withDescription("suppresses the output of the disassembly")
.create("N");
Option inlineTableOption = OptionBuilder.withLongOpt("inline-table")
.withDescription("specify a file containing a custom inline method table to use for deodexing")
.hasArg()
.withArgName("FILE")
.create("T");
Option dexEntryOption = OptionBuilder.withLongOpt("dex-file")
.withDescription("looks for dex file named DEX_FILE, defaults to classes.dex")
.withArgName("DEX_FILE")
.hasArg()
.create("e");
basicOptions.addOption(versionOption);
basicOptions.addOption(helpOption);
basicOptions.addOption(outputDirOption);
basicOptions.addOption(noParameterRegistersOption);
basicOptions.addOption(deodexerantOption);
basicOptions.addOption(experimentalOption);
basicOptions.addOption(useLocalsOption);
basicOptions.addOption(sequentialLabelsOption);
basicOptions.addOption(noDebugInfoOption);
basicOptions.addOption(registerInfoOption);
basicOptions.addOption(classPathOption);
basicOptions.addOption(classPathDirOption);
basicOptions.addOption(codeOffsetOption);
basicOptions.addOption(noAccessorCommentsOption);
basicOptions.addOption(apiLevelOption);
basicOptions.addOption(jobsOption);
basicOptions.addOption(resourceIdFilesOption);
basicOptions.addOption(noImplicitReferencesOption);
basicOptions.addOption(dexEntryOption);
basicOptions.addOption(checkPackagePrivateAccessOption);
debugOptions.addOption(dumpOption);
debugOptions.addOption(ignoreErrorsOption);
debugOptions.addOption(noDisassemblyOption);
debugOptions.addOption(inlineTableOption);
for (Object option: basicOptions.getOptions()) {
options.addOption((Option)option);
}
for (Object option: debugOptions.getOptions()) {
options.addOption((Option)option);
}
}
@Nonnull
private static List<String> getDefaultBootClassPathForApi(int apiLevel, boolean experimental) {
if (apiLevel < 9) {
return Lists.newArrayList(
"/system/framework/core.jar",
"/system/framework/ext.jar",
"/system/framework/framework.jar",
"/system/framework/android.policy.jar",
"/system/framework/services.jar");
} else if (apiLevel < 12) {
return Lists.newArrayList(
"/system/framework/core.jar",
"/system/framework/bouncycastle.jar",
"/system/framework/ext.jar",
"/system/framework/framework.jar",
"/system/framework/android.policy.jar",
"/system/framework/services.jar",
"/system/framework/core-junit.jar");
} else if (apiLevel < 14) {
return Lists.newArrayList(
"/system/framework/core.jar",
"/system/framework/apache-xml.jar",
"/system/framework/bouncycastle.jar",
"/system/framework/ext.jar",
"/system/framework/framework.jar",
"/system/framework/android.policy.jar",
"/system/framework/services.jar",
"/system/framework/core-junit.jar");
} else if (apiLevel < 16) {
return Lists.newArrayList(
"/system/framework/core.jar",
"/system/framework/core-junit.jar",
"/system/framework/bouncycastle.jar",
"/system/framework/ext.jar",
"/system/framework/framework.jar",
"/system/framework/android.policy.jar",
"/system/framework/services.jar",
"/system/framework/apache-xml.jar",
"/system/framework/filterfw.jar");
} else {
// this is correct as of api 17/4.2.2
return Lists.newArrayList(
"/system/framework/core.jar",
"/system/framework/core-junit.jar",
"/system/framework/bouncycastle.jar",
"/system/framework/ext.jar",
"/system/framework/framework.jar",
"/system/framework/telephony-common.jar",
"/system/framework/mms-common.jar",
"/system/framework/android.policy.jar",
"/system/framework/services.jar",
"/system/framework/apache-xml.jar");
}
}
}

View File

@ -1 +0,0 @@
application.version=${version}

View File

@ -1,125 +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.baksmali;
import com.google.common.base.Charsets;
import com.google.common.io.Resources;
import junit.framework.Assert;
import org.jf.baksmali.Adaptors.ClassDefinition;
import org.jf.dexlib2.DexFileFactory;
import org.jf.dexlib2.analysis.ClassPath;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.DexFile;
import org.jf.util.IndentingWriter;
import org.jf.util.TextUtils;
import org.junit.Test;
import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URISyntaxException;
import java.net.URL;
public class AnalysisTest {
@Test
public void ConstructorTest() throws IOException, URISyntaxException {
runTest("ConstructorTest", true);
}
@Test
public void RegisterEqualityOnMergeTest() throws IOException, URISyntaxException {
runTest("RegisterEqualityOnMergeTest", true);
}
@Test
public void UninitRefIdentityTest() throws IOException, URISyntaxException {
runTest("UninitRefIdentityTest", true);
}
@Test
public void MultipleStartInstructionsTest() throws IOException, URISyntaxException {
runTest("MultipleStartInstructionsTest", true);
}
@Test
public void DuplicateTest() throws IOException, URISyntaxException {
runTest("DuplicateTest", false);
}
@Test
public void LocalTest() throws IOException, URISyntaxException {
runTest("LocalTest", false);
}
public void runTest(String test, boolean registerInfo) throws IOException, URISyntaxException {
String dexFilePath = String.format("%s%sclasses.dex", test, File.separatorChar);
DexFile dexFile = DexFileFactory.loadDexFile(findResource(dexFilePath), 15, false);
baksmaliOptions options = new baksmaliOptions();
if (registerInfo) {
options.registerInfo = baksmaliOptions.ALL | baksmaliOptions.FULLMERGE;
options.classPath = new ClassPath();
}
options.useImplicitReferences = false;
for (ClassDef classDef: dexFile.getClasses()) {
StringWriter stringWriter = new StringWriter();
IndentingWriter writer = new IndentingWriter(stringWriter);
ClassDefinition classDefinition = new ClassDefinition(options, classDef);
classDefinition.writeTo(writer);
writer.close();
String className = classDef.getType();
String smaliPath = String.format("%s%s%s.smali", test, File.separatorChar,
className.substring(1, className.length() - 1));
String smaliContents = readResource(smaliPath);
Assert.assertEquals(TextUtils.normalizeNewlines(smaliContents),
TextUtils.normalizeNewlines(stringWriter.toString()));
}
}
@Nonnull
private File findResource(String resource) throws URISyntaxException {
URL resUrl = Resources.getResource(resource);
return new File(resUrl.toURI());
}
@Nonnull
private String readResource(String resource) throws URISyntaxException, IOException {
URL url = Resources.getResource(resource);
return Resources.toString(url, Charsets.UTF_8);
}
}

View File

@ -1,119 +0,0 @@
/*
* Copyright 2015, 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.baksmali;
import com.google.common.io.ByteStreams;
import junit.framework.Assert;
import org.antlr.runtime.RecognitionException;
import org.jf.baksmali.Adaptors.ClassDefinition;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.smali.SmaliTestUtils;
import org.jf.util.IndentingWriter;
import org.jf.util.TextUtils;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
public class BaksmaliTestUtils {
public static void assertSmaliCompiledEquals(String source, String expected,
baksmaliOptions options, boolean stripComments) throws IOException,
RecognitionException {
ClassDef classDef = SmaliTestUtils.compileSmali(source, options.apiLevel,
options.experimental);
// Remove unnecessary whitespace and optionally strip all comments from smali file
String normalizedActual = getNormalizedSmali(classDef, options, stripComments);
String normalizedExpected = normalizeSmali(expected, stripComments);
// Assert that normalized strings are now equal
Assert.assertEquals(normalizedExpected, normalizedActual);
}
public static void assertSmaliCompiledEquals(String source, String expected,
baksmaliOptions options) throws IOException, RecognitionException {
assertSmaliCompiledEquals(source, expected, options, false);
}
public static void assertSmaliCompiledEquals(String source, String expected)
throws IOException, RecognitionException {
baksmaliOptions options = new baksmaliOptions();
assertSmaliCompiledEquals(source, expected, options);
}
@Nonnull
public static String normalizeSmali(@Nonnull String smaliText, boolean stripComments) {
if (stripComments) {
smaliText = TextUtils.stripComments(smaliText);
}
return TextUtils.normalizeWhitespace(smaliText);
}
@Nonnull
public static String getNormalizedSmali(@Nonnull ClassDef classDef, @Nonnull baksmaliOptions options,
boolean stripComments)
throws IOException {
StringWriter stringWriter = new StringWriter();
IndentingWriter writer = new IndentingWriter(stringWriter);
ClassDefinition classDefinition = new ClassDefinition(options, classDef);
classDefinition.writeTo(writer);
writer.close();
return normalizeSmali(stringWriter.toString(), stripComments);
}
@Nonnull
public static byte[] readResourceBytesFully(@Nonnull String fileName) throws IOException {
InputStream smaliStream = RoundtripTest.class.getClassLoader().
getResourceAsStream(fileName);
if (smaliStream == null) {
org.junit.Assert.fail("Could not load " + fileName);
}
return ByteStreams.toByteArray(smaliStream);
}
@Nonnull
public static String readResourceFully(@Nonnull String fileName) throws IOException {
return readResourceFully(fileName, "UTF-8");
}
@Nonnull
public static String readResourceFully(@Nonnull String fileName, @Nonnull String encoding)
throws IOException {
return new String(readResourceBytesFully(fileName), encoding);
}
// Static helpers class; do not instantiate.
private BaksmaliTestUtils() { throw new AssertionError(); }
}

View File

@ -1,104 +0,0 @@
/*
* Copyright 2015, 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.baksmali;
import com.google.common.collect.Iterables;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
import org.jf.dexlib2.iface.ClassDef;
import org.junit.Assert;
import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
/**
* A base test class for performing a disassembly on a dex file and verifying the results
*
* The test accepts a single-class dex file as input, disassembles it, and verifies that
* the result equals a known-good output smali file.
*
* By default, the input and output files should be resources at [testDir]/[testName]Input.dex
* and [testDir]/[testName]Output.smali respectively
*/
public class DisassemblyTest {
protected final String testDir;
protected DisassemblyTest(@Nonnull String testDir) {
this.testDir = testDir;
}
protected DisassemblyTest() {
this.testDir = this.getClass().getSimpleName();
}
@Nonnull
protected String getInputFilename(@Nonnull String testName) {
return String.format("%s%s%sInput.dex", testDir, File.separatorChar, testName);
}
@Nonnull
protected String getOutputFilename(@Nonnull String testName) {
return String.format("%s%s%sOutput.smali", testDir, File.separatorChar, testName);
}
protected void runTest(@Nonnull String testName) {
runTest(testName, new baksmaliOptions());
}
protected void runTest(@Nonnull String testName, @Nonnull baksmaliOptions options) {
try {
// Load file from resources as a stream
String inputFilename = getInputFilename(testName);
byte[] inputBytes = BaksmaliTestUtils.readResourceBytesFully(getInputFilename(testName));
DexBackedDexFile inputDex = new DexBackedDexFile(new Opcodes(options.apiLevel, false), inputBytes);
Assert.assertEquals(1, inputDex.getClassCount());
ClassDef inputClass = Iterables.getFirst(inputDex.getClasses(), null);
Assert.assertNotNull(inputClass);
String input = BaksmaliTestUtils.getNormalizedSmali(inputClass, options, true);
String output;
if (getOutputFilename(testName).equals(inputFilename)) {
output = input;
} else {
output = BaksmaliTestUtils.readResourceFully(getOutputFilename(testName));
}
output = BaksmaliTestUtils.normalizeSmali(output, true);
// Run smali, baksmali, and then compare strings are equal (minus comments/whitespace)
Assert.assertEquals(output, input);
} catch (IOException ex) {
Assert.fail();
}
}
}

View File

@ -1,59 +0,0 @@
/*
* Copyright 2015, 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.baksmali;
import javax.annotation.Nonnull;
import java.io.File;
/**
* A base test class for performing a roundtrip assembly/disassembly where the input and output
* should be identical.
*
* By default, the input/output file should be a resource at [testDir]/[testName].smali
*/
public abstract class IdenticalRoundtripTest extends RoundtripTest {
public IdenticalRoundtripTest(@Nonnull String testDir) {
super(testDir);
}
public IdenticalRoundtripTest() {
}
@Nonnull @Override protected String getInputFilename(@Nonnull String testName) {
return String.format("%s%s%s.smali", testDir, File.separatorChar, testName);
}
@Nonnull @Override protected String getOutputFilename(@Nonnull String testName) {
return getInputFilename(testName);
}
}

View File

@ -1,260 +0,0 @@
/*
* Copyright 2014, 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.baksmali;
import org.antlr.runtime.RecognitionException;
import org.junit.Test;
import java.io.IOException;
public class ImplicitReferenceTest {
@Test
public void testImplicitMethodReferences() throws IOException, RecognitionException {
String source = "" +
".class public LHelloWorld;\n" +
".super Ljava/lang/Object;\n" +
".method public static main([Ljava/lang/String;)V\n" +
" .registers 1\n" +
" invoke-static {p0}, LHelloWorld;->toString()V\n" +
" invoke-static {p0}, LHelloWorld;->V()V\n" +
" invoke-static {p0}, LHelloWorld;->I()V\n" +
" return-void\n" +
".end method";
String expected = "" +
".class public LHelloWorld;\n" +
".super Ljava/lang/Object;\n" +
"# direct methods\n" +
".method public static main([Ljava/lang/String;)V\n" +
".registers 1\n" +
"invoke-static {p0}, toString()V\n" +
"invoke-static {p0}, V()V\n" +
"invoke-static {p0}, I()V\n" +
"return-void\n" +
".end method\n";
baksmaliOptions options = new baksmaliOptions();
options.useImplicitReferences = true;
BaksmaliTestUtils.assertSmaliCompiledEquals(source, expected, options);
}
@Test
public void testExplicitMethodReferences() throws IOException, RecognitionException {
String source = "" +
".class public LHelloWorld;\n" +
".super Ljava/lang/Object;\n" +
".method public static main([Ljava/lang/String;)V\n" +
" .registers 1\n" +
" invoke-static {p0}, LHelloWorld;->toString()V\n" +
" invoke-static {p0}, LHelloWorld;->V()V\n" +
" invoke-static {p0}, LHelloWorld;->I()V\n" +
" return-void\n" +
".end method";
String expected = "" +
".class public LHelloWorld;\n" +
".super Ljava/lang/Object;\n" +
"# direct methods\n" +
".method public static main([Ljava/lang/String;)V\n" +
" .registers 1\n" +
" invoke-static {p0}, LHelloWorld;->toString()V\n" +
" invoke-static {p0}, LHelloWorld;->V()V\n" +
" invoke-static {p0}, LHelloWorld;->I()V\n" +
" return-void\n" +
".end method\n";
baksmaliOptions options = new baksmaliOptions();
options.useImplicitReferences = false;
BaksmaliTestUtils.assertSmaliCompiledEquals(source, expected, options);
}
@Test
public void testImplicitMethodLiterals() throws IOException, RecognitionException {
String source = "" +
".class public LHelloWorld;\n" +
".super Ljava/lang/Object;\n" +
".field public static field1:Ljava/lang/reflect/Method; = LHelloWorld;->toString()V\n" +
".field public static field2:Ljava/lang/reflect/Method; = LHelloWorld;->V()V\n" +
".field public static field3:Ljava/lang/reflect/Method; = LHelloWorld;->I()V\n" +
".field public static field4:Ljava/lang/Class; = I";
String expected = "" +
".class public LHelloWorld;\n" +
".super Ljava/lang/Object;\n" +
"# static fields\n" +
".field public static field1:Ljava/lang/reflect/Method; = toString()V\n" +
".field public static field2:Ljava/lang/reflect/Method; = V()V\n" +
".field public static field3:Ljava/lang/reflect/Method; = I()V\n" +
".field public static field4:Ljava/lang/Class; = I\n";
baksmaliOptions options = new baksmaliOptions();
options.useImplicitReferences = true;
BaksmaliTestUtils.assertSmaliCompiledEquals(source, expected, options);
}
@Test
public void testExplicitMethodLiterals() throws IOException, RecognitionException {
String source = "" +
".class public LHelloWorld;\n" +
".super Ljava/lang/Object;\n" +
".field public static field1:Ljava/lang/reflect/Method; = LHelloWorld;->toString()V\n" +
".field public static field2:Ljava/lang/reflect/Method; = LHelloWorld;->V()V\n" +
".field public static field3:Ljava/lang/reflect/Method; = LHelloWorld;->I()V\n" +
".field public static field4:Ljava/lang/Class; = I";
String expected = "" +
".class public LHelloWorld;\n" +
".super Ljava/lang/Object;\n" +
"# static fields\n" +
".field public static field1:Ljava/lang/reflect/Method; = LHelloWorld;->toString()V\n" +
".field public static field2:Ljava/lang/reflect/Method; = LHelloWorld;->V()V\n" +
".field public static field3:Ljava/lang/reflect/Method; = LHelloWorld;->I()V\n" +
".field public static field4:Ljava/lang/Class; = I\n";
baksmaliOptions options = new baksmaliOptions();
options.useImplicitReferences = false;
BaksmaliTestUtils.assertSmaliCompiledEquals(source, expected, options);
}
@Test
public void testImplicitFieldReferences() throws IOException, RecognitionException {
String source = "" +
".class public LHelloWorld;\n" +
".super Ljava/lang/Object;\n" +
".method public static main([Ljava/lang/String;)V\n" +
" .registers 1\n" +
" sget v0, LHelloWorld;->someField:I\n" +
" sget v0, LHelloWorld;->I:I\n" +
" sget v0, LHelloWorld;->V:I\n" +
" return-void\n" +
".end method";
String expected = "" +
".class public LHelloWorld;\n" +
".super Ljava/lang/Object;\n" +
"# direct methods\n" +
".method public static main([Ljava/lang/String;)V\n" +
" .registers 1\n" +
" sget p0, someField:I\n" +
" sget p0, I:I\n" +
" sget p0, V:I\n" +
" return-void\n" +
".end method\n";
baksmaliOptions options = new baksmaliOptions();
options.useImplicitReferences = true;
BaksmaliTestUtils.assertSmaliCompiledEquals(source, expected, options);
}
@Test
public void testExplicitFieldReferences() throws IOException, RecognitionException {
String source = "" +
".class public LHelloWorld;\n" +
".super Ljava/lang/Object;\n" +
".method public static main([Ljava/lang/String;)V\n" +
" .registers 1\n" +
" sget v0, LHelloWorld;->someField:I\n" +
" sget v0, LHelloWorld;->I:I\n" +
" sget v0, LHelloWorld;->V:I\n" +
" return-void\n" +
".end method";
String expected = "" +
".class public LHelloWorld;\n" +
".super Ljava/lang/Object;\n" +
"# direct methods\n" +
".method public static main([Ljava/lang/String;)V\n" +
" .registers 1\n" +
" sget p0, LHelloWorld;->someField:I\n" +
" sget p0, LHelloWorld;->I:I\n" +
" sget p0, LHelloWorld;->V:I\n" +
" return-void\n" +
".end method\n";
baksmaliOptions options = new baksmaliOptions();
options.useImplicitReferences = false;
BaksmaliTestUtils.assertSmaliCompiledEquals(source, expected, options);
}
@Test
public void testImplicitFieldLiterals() throws IOException, RecognitionException {
String source = "" +
".class public LHelloWorld;\n" +
".super Ljava/lang/Object;\n" +
".field public static field1:Ljava/lang/reflect/Field; = LHelloWorld;->someField:I\n" +
".field public static field2:Ljava/lang/reflect/Field; = LHelloWorld;->V:I\n" +
".field public static field3:Ljava/lang/reflect/Field; = LHelloWorld;->I:I";
String expected = "" +
".class public LHelloWorld;\n" +
".super Ljava/lang/Object;\n" +
"# static fields\n" +
".field public static field1:Ljava/lang/reflect/Field; = someField:I\n" +
".field public static field2:Ljava/lang/reflect/Field; = V:I\n" +
".field public static field3:Ljava/lang/reflect/Field; = I:I\n";
baksmaliOptions options = new baksmaliOptions();
options.useImplicitReferences = true;
BaksmaliTestUtils.assertSmaliCompiledEquals(source, expected, options);
}
@Test
public void testExplicitFieldLiterals() throws IOException, RecognitionException {
String source = "" +
".class public LHelloWorld;\n" +
".super Ljava/lang/Object;\n" +
".field public static field1:Ljava/lang/reflect/Field; = LHelloWorld;->someField:I\n" +
".field public static field2:Ljava/lang/reflect/Field; = LHelloWorld;->V:I\n" +
".field public static field3:Ljava/lang/reflect/Field; = LHelloWorld;->I:I";
String expected = "" +
".class public LHelloWorld;\n" +
".super Ljava/lang/Object;\n" +
"# static fields\n" +
".field public static field1:Ljava/lang/reflect/Field; = LHelloWorld;->someField:I\n" +
".field public static field2:Ljava/lang/reflect/Field; = LHelloWorld;->V:I\n" +
".field public static field3:Ljava/lang/reflect/Field; = LHelloWorld;->I:I\n";
baksmaliOptions options = new baksmaliOptions();
options.useImplicitReferences = false;
BaksmaliTestUtils.assertSmaliCompiledEquals(source, expected, options);
}
}

View File

@ -1,41 +0,0 @@
/*
* Copyright 2015, 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.baksmali;
import org.junit.Test;
public class InterfaceOrderTest extends IdenticalRoundtripTest {
@Test
public void testInterfaceOrder() {
runTest("InterfaceOrder", new baksmaliOptions());
}
}

View File

@ -1,49 +0,0 @@
/*
* Copyright 2015, 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.baksmali;
import org.junit.Test;
public class LambdaTest extends IdenticalRoundtripTest {
private baksmaliOptions createOptions() {
baksmaliOptions options = new baksmaliOptions();
options.apiLevel = 23; // since we need at least level 23 for lambda opcodes
options.experimental = true; // since these opcodes aren't implemented in runtime yet);
return options;
}
@Test
public void testHelloWorldLambda() {
runTest("HelloWorldLambda", createOptions());
}
}

View File

@ -1,42 +0,0 @@
/*
* Copyright 2015, 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.baksmali;
import org.junit.Test;
public class ManyRegistersTest extends IdenticalRoundtripTest {
@Test
public void testManyRegisters() {
runTest("ManyRegisters");
}
}

View File

@ -1,42 +0,0 @@
/*
* Copyright 2015, 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.baksmali;
import org.junit.Test;
public class MultiSwitchTest extends DisassemblyTest {
@Test
public void testMultiSwitch() {
runTest("MultiSwitch");
}
}

View File

@ -1,95 +0,0 @@
/*
* Copyright 2015, 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.baksmali;
import org.antlr.runtime.RecognitionException;
import org.junit.Assert;
import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
/**
* A base test class for performing a roundtrip assembly/disassembly
*
* The test accepts a smali file as input, performs a smali -> dex -> smali roundtrip, and
* verifies that the result equals a known-good output smali file.
*
* By default, the input and output files should be resources at [testDir]/[testName]Input.smali
* and [testDir]/[testName]Output.smali respectively
*/
public abstract class RoundtripTest {
protected final String testDir;
protected RoundtripTest(@Nonnull String testDir) {
this.testDir = testDir;
}
protected RoundtripTest() {
this.testDir = this.getClass().getSimpleName();
}
@Nonnull
protected String getInputFilename(@Nonnull String testName) {
return String.format("%s%s%sInput.smali", testDir, File.separatorChar, testName);
}
@Nonnull
protected String getOutputFilename(@Nonnull String testName) {
return String.format("%s%s%sOutput.smali", testDir, File.separatorChar, testName);
}
protected void runTest(@Nonnull String testName) {
runTest(testName, new baksmaliOptions());
}
protected void runTest(@Nonnull String testName, @Nonnull baksmaliOptions options) {
try {
// Load file from resources as a stream
String inputFilename = getInputFilename(testName);
String input = BaksmaliTestUtils.readResourceFully(getInputFilename(testName));
String output;
if (getOutputFilename(testName).equals(inputFilename)) {
output = input;
} else {
output = BaksmaliTestUtils.readResourceFully(getOutputFilename(testName));
}
// Run smali, baksmali, and then compare strings are equal (minus comments/whitespace)
BaksmaliTestUtils.assertSmaliCompiledEquals(input, output, options, true);
} catch (IOException ex) {
Assert.fail();
} catch (RecognitionException ex) {
Assert.fail();
}
}
}

View File

@ -1,41 +0,0 @@
/*
* Copyright 2015, 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.baksmali;
import org.junit.Test;
public class SwitchTest extends RoundtripTest {
@Test
public void testUnorderedSparseSwitch() {
runTest("UnorderedSparseSwitch");
}
}

View File

@ -1,16 +0,0 @@
.class public LConstructorTest;
.super Ljava/lang/Object;
# direct methods
.method public constructor <init>()V
.registers 4
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(UninitThis,LConstructorTest;);
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(Reference,LConstructorTest;);
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(Reference,LConstructorTest;);
return-void
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(Reference,LConstructorTest;);
.end method

View File

@ -1,25 +0,0 @@
.class public LConstructorTest2;
.super Ljava/lang/Object;
# direct methods
.method public constructor <init>()V
.registers 4
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(UninitThis,LConstructorTest2;);
if-eqz p0, :cond_3
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(UninitThis,LConstructorTest2;);
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(UninitThis,LConstructorTest2;);
nop
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(UninitThis,LConstructorTest2;);
:cond_3
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(UninitThis,LConstructorTest2;);
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(Reference,LConstructorTest2;);
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(Reference,LConstructorTest2;);
return-void
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(Reference,LConstructorTest2;);
.end method

View File

@ -1,29 +0,0 @@
.class public LDuplicateDirectMethods;
.super Ljava/lang/Object;
# direct methods
.method private alah()V
.registers 1
return-void
.end method
.method private blah()V
.registers 1
return-void
.end method
# duplicate method ignored
# .method private blah()V
# .registers 1
# return-void
# .end method
.method private clah()V
.registers 1
return-void
.end method

View File

@ -1,46 +0,0 @@
.class public LDuplicateDirectVirtualMethods;
.super Ljava/lang/Object;
# direct methods
.method private blah()V
.registers 1
return-void
.end method
# duplicate method ignored
# .method private blah()V
# .registers 1
# return-void
# .end method
# virtual methods
.method public alah()V
.registers 1
return-void
.end method
# There is both a direct and virtual method with this signature.
# You will need to rename one of these methods, including all references.
.method public blah()V
.registers 1
return-void
.end method
# duplicate method ignored
# .method public blah()V
# .registers 1
# return-void
# .end method
.method public clah()V
.registers 1
return-void
.end method

View File

@ -1,13 +0,0 @@
.class public LDuplicateInstanceFields;
.super Ljava/lang/Object;
# instance fields
.field public alah:I
.field public blah:I
# duplicate field ignored
# .field public blah:I
.field public clah:I

View File

@ -1,13 +0,0 @@
.class public LDuplicateStaticFields;
.super Ljava/lang/Object;
# static fields
.field public static alah:I
.field public static blah:I
# duplicate field ignored
# .field public static blah:I
.field public static clah:I

View File

@ -1,22 +0,0 @@
.class public LDuplicateStaticInstanceFields;
.super Ljava/lang/Object;
# static fields
.field public static blah:I
# duplicate field ignored
# .field public static blah:I
# instance fields
.field public alah:I
# There is both a static and instance field with this signature.
# You will need to rename one of these fields, including all references.
.field public blah:I
# duplicate field ignored
# .field public blah:I
.field public clah:I

View File

@ -1,29 +0,0 @@
.class public LDuplicateVirtualMethods;
.super Ljava/lang/Object;
# virtual methods
.method public alah()V
.registers 1
return-void
.end method
.method public blah()V
.registers 1
return-void
.end method
# duplicate method ignored
# .method public blah()V
# .registers 1
# return-void
# .end method
.method public clah()V
.registers 1
return-void
.end method

View File

@ -1,22 +0,0 @@
.class public LDuplicateDirectMethods;
.super Ljava/lang/Object;
.method private alah()V
.registers 1
return-void
.end method
.method private blah()V
.registers 1
return-void
.end method
.method private blah()V
.registers 1
return-void
.end method
.method private clah()V
.registers 1
return-void
.end method

View File

@ -1,32 +0,0 @@
.class public LDuplicateDirectVirtualMethods;
.super Ljava/lang/Object;
.method public alah()V
.registers 1
return-void
.end method
.method private blah()V
.registers 1
return-void
.end method
.method private blah()V
.registers 1
return-void
.end method
.method public blah()V
.registers 1
return-void
.end method
.method public blah()V
.registers 1
return-void
.end method
.method public clah()V
.registers 1
return-void
.end method

View File

@ -1,9 +0,0 @@
.class public LDuplicateInstanceFields;
.super Ljava/lang/Object;
.field public alah:I
.field public blah:I
.field public blah:I
.field public clah:I

View File

@ -1,9 +0,0 @@
.class public LDuplicateStaticFields;
.super Ljava/lang/Object;
.field public static alah:I
.field public static blah:I
.field public static blah:I
.field public static clah:I

View File

@ -1,11 +0,0 @@
.class public LDuplicateStaticInstanceFields;
.super Ljava/lang/Object;
.field public alah:I
.field public blah:I
.field public blah:I
.field static public blah:I
.field static public blah:I
.field public clah:I

View File

@ -1,22 +0,0 @@
.class public LDuplicateVirtualMethods;
.super Ljava/lang/Object;
.method public alah()V
.registers 1
return-void
.end method
.method public blah()V
.registers 1
return-void
.end method
.method public blah()V
.registers 1
return-void
.end method
.method public clah()V
.registers 1
return-void
.end method

View File

@ -1,3 +0,0 @@
The test dex file was produced from these smali files, using
an old version of smali that doesn't check for field/method
duplicates

View File

@ -1,37 +0,0 @@
.class public LInterfaceOrder;
.super Ljava/lang/Object;
# Note how these two interfaces are not in alphabetical order
.implements Ljava/io/Serializable;
.implements Ljava/util/EventListener;
.implements Ljava/lang/Runnable;
.implements Ljava/io/Flushable;
.implements Ljava/lang/Clonable;
.implements Ljava/util/Observer;
.implements Ljava/io/Closeable;
# direct methods
.method public constructor <init>()V
.registers 1
return-void
.end method
.method public close()V
.registers 1
return-void
.end method
.method public flush()V
.registers 1
return-void
.end method
.method public run()V
.registers 1
return-void
.end method
.method public update(Ljava/util/Observable;Ljava/lang/Object;)V
.registers 3
return-void
.end method

View File

@ -1,55 +0,0 @@
.class public LHelloWorldLambda;
#Ye olde hello world application (with lambdas!)
#To assemble and run this on a phone or emulator:
#
#java -jar smali.jar -o classes.dex HelloWorldLambda.smali HelloWorldFunctionalInterface.smali
#zip HelloWorld.zip classes.dex
#adb push HelloWorld.zip /data/local
#adb shell dalvikvm -cp /data/local/HelloWorld.zip HelloWorld
#
#if you get out of memory type errors when running smali.jar, try
#java -Xmx512m -jar smali.jar HelloWorldLambda.smali
#instead
.super Ljava/lang/Object;
.method public static doHelloWorld(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
.registers 6 # 4 parameters, 2 locals
liberate-variable v0, p0, "helloworld"
sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
return-void
.end method
.method public static main([Ljava/lang/String;)V
.registers 9 # 1 parameter, 8 locals
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
const-string v1, "Hello World!"
const-string v2, "How" # vD
const-string v3, "are" # vE
const-string v4, "you" # vF
const-string v5, "doing?" # vG
capture-variable v1, "helloworld"
# TODO: do I need to pass the type of the lambda's functional interface here as a type id?
create-lambda v1, LHelloWorldLambda;->doHelloWorld(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
# Method descriptor is not required here, because only the single-abstract method is ever invoked.
invoke-lambda v1, {v2, v3, v4, v5}
box-lambda v6, v1
invoke-virtual {v6, v2, v3, v4, v5}, LHelloWorldFunctionalInterface;->applyFourStrings(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
# FIXME: should be \HelloWorldFunctionalInterface; instead of L...;
# TODO: do we really need the type descriptor here at all?
unbox-lambda v7, v6, LHelloWorldFunctionalInterface;
invoke-lambda v7, {v2, v3, v4, v5}
return-void
.end method

View File

@ -1,31 +0,0 @@
.class public LLocalTest;
.super Ljava/lang/Object;
# direct methods
.method public static method1()V
.registers 10
.local v0, "blah! This local name has some spaces, a colon, even a \nnewline!":I, "some sig info:\nblah."
.local v1, "blah! This local name has some spaces, a colon, even a \nnewline!":V, "some sig info:\nblah."
.local v2, "blah! This local name has some spaces, a colon, even a \nnewline!":I
.local v3, "blah! This local name has some spaces, a colon, even a \nnewline!":V
.local v4, null:I, "some sig info:\nblah."
.local v5, null:V, "some sig info:\nblah."
.local v6, null:I
.local v7
.local v8
.local v9
return-void
.end method
.method public static method2(IJLjava/lang/String;)V
.registers 10
.param p0, "blah! This local name has some spaces, a colon, even a \nnewline!" # I
.param p1 # J
.annotation runtime LAnnotationWithValues;
.end annotation
.end param
return-void
.end method

View File

@ -1,7 +0,0 @@
.class LManyRegisters;
.super Ljava/lang/Object;
.method public manyRegisters()V
.registers 65535
return-void
.end method

View File

@ -1,72 +0,0 @@
.class public LMultiSwitch;
.super Ljava/lang/Object;
.source "Format31t.smali"
.method public multi-packed-switch()V
.registers 1
const p0, 0xc
packed-switch p0, :pswitch_data_12
goto :goto_b
:pswitch_7
return-void
:pswitch_8
return-void
:pswitch_9
return-void
:pswitch_a
return-void
:goto_b
packed-switch p0, :pswitch_data_12
nop
return-void
:pswitch_f
return-void
:pswitch_10
return-void
:pswitch_11
return-void
:pswitch_12
:pswitch_data_12
.packed-switch 0xa
:pswitch_7
:pswitch_8
:pswitch_9
:pswitch_a
.end packed-switch
.end method
.method public multi-sparse-switch()V
.registers 1
const p0, 0xd
sparse-switch p0, :sswitch_data_12
goto :goto_b
:sswitch_7
return-void
:sswitch_8
return-void
:sswitch_9
return-void
:sswitch_a
return-void
:goto_b
sparse-switch p0, :sswitch_data_12
nop
return-void
:sswitch_f
return-void
:sswitch_10
return-void
:sswitch_11
return-void
:sswitch_12
:sswitch_data_12
.sparse-switch
0xa -> :sswitch_7
0xf -> :sswitch_9
0x14 -> :sswitch_8
0x63 -> :sswitch_a
.end sparse-switch
.end method

View File

@ -1,119 +0,0 @@
.class public LMultiSwitch;
.super Ljava/lang/Object;
.source "Format31t.smali"
# virtual methods
.method public multi-packed-switch()V
.registers 1
const p0, 0xc
packed-switch p0, :pswitch_data_14
goto :goto_b
:pswitch_7
return-void
:pswitch_8
return-void
:pswitch_9
return-void
:pswitch_a
return-void
:goto_b
packed-switch p0, :pswitch_data_20
nop
:pswitch_f
return-void
:pswitch_10
return-void
:pswitch_11
return-void
:pswitch_12
return-void
nop
:pswitch_data_14
.packed-switch 0xa
:pswitch_7
:pswitch_8
:pswitch_9
:pswitch_a
.end packed-switch
:pswitch_data_20
.packed-switch 0xa
:pswitch_f
:pswitch_10
:pswitch_11
:pswitch_12
.end packed-switch
.end method
.method public multi-sparse-switch()V
.registers 1
const p0, 0xd
sparse-switch p0, :sswitch_data_14
goto :goto_b
:sswitch_7
return-void
:sswitch_8
return-void
:sswitch_9
return-void
:sswitch_a
return-void
:goto_b
sparse-switch p0, :sswitch_data_26
nop
:sswitch_f
return-void
:sswitch_10
return-void
:sswitch_11
return-void
:sswitch_12
return-void
nop
:sswitch_data_14
.sparse-switch
0xa -> :sswitch_7
0xf -> :sswitch_9
0x14 -> :sswitch_8
0x63 -> :sswitch_a
.end sparse-switch
:sswitch_data_26
.sparse-switch
0xa -> :sswitch_f
0xf -> :sswitch_11
0x14 -> :sswitch_10
0x63 -> :sswitch_12
.end sparse-switch
.end method

View File

@ -1,46 +0,0 @@
.class public LMultipleStartInstructionsTest;
.super Ljava/lang/Object;
# direct methods
.method public constructor <init>(Ljava/lang/String;)V
.registers 4
:try_start_0
#v0=(Uninit);v1=(Uninit);p0=(UninitThis,LMultipleStartInstructionsTest;);p1=(Reference,Ljava/lang/String;);
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
#v0=(Uninit);v1=(Uninit);p0=(Reference,LMultipleStartInstructionsTest;);p1=(Reference,Ljava/lang/String;);
#v0=(Uninit);v1=(Uninit);p0=(Reference,LMultipleStartInstructionsTest;);p1=(Reference,Ljava/lang/String;);
const-string v0, "blah"
#v0=(Reference,Ljava/lang/String;);v1=(Uninit);p0=(Reference,LMultipleStartInstructionsTest;);p1=(Reference,Ljava/lang/String;);
#v0=(Reference,Ljava/lang/String;);v1=(Uninit);p0=(Reference,LMultipleStartInstructionsTest;);p1=(Reference,Ljava/lang/String;);
return-void
#v0=(Reference,Ljava/lang/String;);v1=(Uninit);p0=(Reference,LMultipleStartInstructionsTest;);p1=(Reference,Ljava/lang/String;);
:try_end_6
.catchall {:try_start_0 .. :try_end_6} :catchall_6
:catchall_6
:try_start_6
#v0=(Uninit);v1=(Uninit);
#p0=(Conflicted):merge{Start:(UninitThis,LMultipleStartInstructionsTest;),0x0:(Reference,LMultipleStartInstructionsTest;)}
#p1=(Reference,Ljava/lang/String;);
invoke-static {}, LMultipleStartInstructionsTest;->blah()V
#v0=(Uninit);v1=(Uninit);p0=(Conflicted);p1=(Reference,Ljava/lang/String;);
:try_end_9
.catchall {:try_start_6 .. :try_end_9} :catchall_9
:catchall_9
#v0=(Uninit);v1=(Uninit);
#p0=(Conflicted):merge{Start:(UninitThis,LMultipleStartInstructionsTest;),0x0:(Reference,LMultipleStartInstructionsTest;),0x6:(Conflicted)}
#p1=(Reference,Ljava/lang/String;);
return-void
#v0=(Uninit);v1=(Uninit);p0=(Conflicted);p1=(Reference,Ljava/lang/String;);
.end method
.method public static blah()V
.registers 0
return-void
.end method

View File

@ -1,37 +0,0 @@
.class public LRegisterEqualityOnMerge;
.super Ljava/lang/Object;
# direct methods
.method public constructor <init>()V
.registers 4
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(UninitThis,LRegisterEqualityOnMerge;);
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(Reference,LRegisterEqualityOnMerge;);
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(Reference,LRegisterEqualityOnMerge;);
invoke-virtual {p0}, Ljava/lang/Object;->toString()Ljava/lang/String;
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(Reference,LRegisterEqualityOnMerge;);
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(Reference,LRegisterEqualityOnMerge;);
move-result-object v0
#v0=(Reference,Ljava/lang/String;);v1=(Uninit);v2=(Uninit);p0=(Reference,LRegisterEqualityOnMerge;);
#v0=(Reference,Ljava/lang/String;);v1=(Uninit);v2=(Uninit);p0=(Reference,LRegisterEqualityOnMerge;);
if-eqz v0, :cond_d
#v0=(Reference,Ljava/lang/String;);v1=(Uninit);v2=(Uninit);p0=(Reference,LRegisterEqualityOnMerge;);
#v0=(Reference,Ljava/lang/String;);v1=(Uninit);v2=(Uninit);p0=(Reference,LRegisterEqualityOnMerge;);
invoke-virtual {p0}, Ljava/lang/Object;->toString()Ljava/lang/String;
#v0=(Reference,Ljava/lang/String;);v1=(Uninit);v2=(Uninit);p0=(Reference,LRegisterEqualityOnMerge;);
#v0=(Reference,Ljava/lang/String;);v1=(Uninit);v2=(Uninit);p0=(Reference,LRegisterEqualityOnMerge;);
move-result-object v0
#v0=(Reference,Ljava/lang/String;);v1=(Uninit);v2=(Uninit);p0=(Reference,LRegisterEqualityOnMerge;);
:cond_d
#v0=(Reference,Ljava/lang/String;);v1=(Uninit);v2=(Uninit);p0=(Reference,LRegisterEqualityOnMerge;);
return-void
#v0=(Reference,Ljava/lang/String;);v1=(Uninit);v2=(Uninit);p0=(Reference,LRegisterEqualityOnMerge;);
.end method

View File

@ -1,35 +0,0 @@
.class public LUnorderedSparseSwitch;
.super Ljava/lang/Object;
.method public static test_sparse-switch()V
.registers 1
const v0, 13
sparse-switch v0, :SparseSwitch
:Label10
return-void
:Label20
return-void
:Label15
return-void
:Label13
return-void
:Label99
return-void
# Note: unordered keys
:SparseSwitch
.sparse-switch
10 -> :Label10
20 -> :Label20
15 -> :Label15
99 -> :Label99
13 -> :Label13
.end sparse-switch
.end method

View File

@ -1,28 +0,0 @@
.class public LUnorderedSparseSwitch;
.super Ljava/lang/Object;
.method public static test_sparse-switch()V
.registers 1
const v0, 0xd
sparse-switch v0, :sswitch_data_c
:sswitch_6
return-void
:sswitch_7
return-void
:sswitch_8
return-void
:sswitch_9
return-void
:sswitch_a
return-void
nop
# Note: ordered keys
:sswitch_data_c
.sparse-switch
0xa -> :sswitch_6
0xd -> :sswitch_9
0xf -> :sswitch_8
0x14 -> :sswitch_7
0x63 -> :sswitch_a
.end sparse-switch
.end method

View File

@ -1,50 +0,0 @@
.class public LUninitRefIdentityTest;
.super Ljava/lang/Object;
# direct methods
.method public constructor <init>()V
.registers 4
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(UninitThis,LUninitRefIdentityTest;);
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(Reference,LUninitRefIdentityTest;);
#v0=(Uninit);v1=(Uninit);v2=(Uninit);p0=(Reference,LUninitRefIdentityTest;);
new-instance v0, Ljava/lang/String;
#v0=(UninitRef,Ljava/lang/String;);v1=(Uninit);v2=(Uninit);p0=(Reference,LUninitRefIdentityTest;);
#v0=(UninitRef,Ljava/lang/String;);v1=(Uninit);v2=(Uninit);p0=(Reference,LUninitRefIdentityTest;);
if-eqz v0, :cond_9
#v0=(UninitRef,Ljava/lang/String;);v1=(Uninit);v2=(Uninit);p0=(Reference,LUninitRefIdentityTest;);
#v0=(UninitRef,Ljava/lang/String;);v1=(Uninit);v2=(Uninit);p0=(Reference,LUninitRefIdentityTest;);
new-instance v0, Ljava/lang/String;
#v0=(UninitRef,Ljava/lang/String;);v1=(Uninit);v2=(Uninit);p0=(Reference,LUninitRefIdentityTest;);
:cond_9
#v0=(Conflicted):merge{0x5:(UninitRef,Ljava/lang/String;),0x7:(UninitRef,Ljava/lang/String;)}
#v1=(Uninit);v2=(Uninit);p0=(Reference,LUninitRefIdentityTest;);
invoke-direct {v0}, Ljava/lang/String;-><init>()V
#v0=(Unknown);v1=(Uninit);v2=(Uninit);p0=(Reference,LUninitRefIdentityTest;);
#v0=(Unknown);v1=(Uninit);v2=(Uninit);p0=(Reference,LUninitRefIdentityTest;);
return-void
#v0=(Unknown);v1=(Uninit);v2=(Uninit);p0=(Reference,LUninitRefIdentityTest;);
.end method
.method public constructor <init>(Ljava/lang/String;)V
.registers 2
#p0=(UninitThis,LUninitRefIdentityTest;);p1=(Reference,Ljava/lang/String;);
move-object p1, p0
#p0=(UninitThis,LUninitRefIdentityTest;);p1=(UninitThis,LUninitRefIdentityTest;);
#p0=(UninitThis,LUninitRefIdentityTest;);p1=(UninitThis,LUninitRefIdentityTest;);
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
#p0=(Reference,LUninitRefIdentityTest;);p1=(Reference,LUninitRefIdentityTest;);
#p0=(Reference,LUninitRefIdentityTest;);p1=(Reference,LUninitRefIdentityTest;);
return-void
#p0=(Reference,LUninitRefIdentityTest;);p1=(Reference,LUninitRefIdentityTest;);
.end method

View File

@ -1,218 +0,0 @@
.class public Lbaksmali/test/class;
.super Ljava/lang/Object;
.source "baksmali_test_class.smali"
.implements Lsome/interface;
.implements Lsome/other/interface;
.annotation build Lsome/annotation;
value1 = "test"
value2 = .subannotation Lsome/annotation;
value1 = "test2"
value2 = Lsome/enum;
.end subannotation
.end annotation
.annotation system Lsome/annotation;
.end annotation
.field public static aStaticFieldWithoutAnInitializer:I
.field public static longStaticField:J = 0x300000000L
.field public static longNegStaticField:J = -0x300000000L
.field public static intStaticField:I = 0x70000000
.field public static intNegStaticField:I = -500
.field public static shortStaticField:S = 500s
.field public static shortNegStaticField:S = -500s
.field public static byteStaticField:B = 123t
.field public static byteNegStaticField:B = 0xAAt
.field public static floatStaticField:F = 3.1415926f
.field public static doubleStaticField:D = 3.141592653589793
.field public static charStaticField:C = 'a'
.field public static charEscapedStaticField:C = '\n'
.field public static boolTrueStaticField:Z = true
.field public static boolFalseStaticField:Z = false
.field public static typeStaticField:Ljava/lang/Class; = Lbaksmali/test/class;
.field public static stringStaticField:Ljava/lang/String; = "test"
.field public static stringEscapedStaticField:Ljava/lang/String; = "test\ntest"
.field public static fieldStaticField:Ljava/lang/reflect/Field; = Lbaksmali/test/class;->fieldStaticField:Ljava/lang/reflect/Field;
.field public static methodStaticField:Ljava/lang/reflect/Method; = Lbaksmali/test/class;->teshMethod(ILjava/lang/String;)Ljava/lang/String;
.field public static arrayStaticField:[I = {1, 2, 3, {1, 2, 3, 4}}
.field public static enumStaticField:Lsome/enum; = .enum Lsome/enum;->someEnumValue:Lsome/enum;
.field public static annotationStaticField:Lsome/annotation; = .subannotation Lsome/annotation;
value1 = "test"
value2 = .subannotation Lsome/annotation;
value1 = "test2"
value2 = Lsome/enum;
.end subannotation
.end subannotation
.field public static staticFieldWithAnnotation:I
.annotation runtime La/field/annotation;
this = "is"
a = "test"
.end annotation
.annotation runtime Lorg/junit/Test;
.end annotation
.end field
.field public instanceField:Ljava/lang/String;
.method public constructor <init>()V
.registers 1
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
.method public testMethod(ILjava/lang/String;)Ljava/lang/String;
.registers 3
.annotation runtime Lorg/junit/Test;
.end annotation
.annotation system Lyet/another/annotation;
somevalue = 1234
anothervalue = 3.14159
.end annotation
const-string v0, "testing\n123"
goto switch:
sget v0, Lbaksmali/test/class;->staticField:I
switch:
packed-switch v0, pswitch:
try_start:
const/4 v0, 7
const v0, 10
nop
try_end:
.catch Ljava/lang/Exception; {try_start: .. try_end:} handler:
.catchall {try_start: .. try_end:} handler2:
handler:
Label10:
Label11:
Label12:
Label13:
return-object v0
.array-data 4
1 2 3 4 5 6 200
.end array-data
pswitch:
.packed-switch 10
Label10:
Label11:
Label12:
Label13:
.end packed-switch
handler2:
return-void
.end method
.method public abstract testMethod2()V
.annotation runtime Lsome/annotation;
subannotation = .subannotation Lsome/other/annotation;
value = "value"
.end subannotation
.end annotation
.annotation runtime Lorg/junit/Test;
.end annotation
.end method
.method public tryTest()V
.registers 1
handler:
nop
try_start:
const/4 v0, 7
const v0, 10
nop
try_end:
.catch Ljava/lang/Exception; {try_start: .. try_end:} handler:
.end method
.method public debugTest(IIIII)V
.registers 10
.parameter "Blah"
.parameter
.parameter "BlahWithAnnotations"
.annotation runtime Lsome/annotation;
something = "some value"
somethingelse = 1234
.end annotation
.annotation runtime La/second/annotation;
.end annotation
.end parameter
.parameter
.annotation runtime Lsome/annotation;
something = "some value"
somethingelse = 1234
.end annotation
.end parameter
.parameter "LastParam"
.prologue
nop
nop
.source "somefile.java"
.line 101
nop
.line 50
.local v0, aNumber:I
const v0, 1234
.end local v0
.source "someotherfile.java"
.line 900
const-string v0, "1234"
.restart local v0
const v0, 6789
.end local v0
.epilogue
.end method

View File

@ -1,70 +0,0 @@
.class public Lmain;
.super Ljava/lang/Object;
.method public static main([Ljava/lang/String;)V
.registers 3
:here4
const v0, 0
:here3
new-instance v2, Lsuperclass;
invoke-direct {v2}, Lsuperclass;-><init>()V
if-eqz v0, :here
#this is the unresolvable instruction. v0 is always null,
#and this will always throw an exception. It should be
#replaced with throw v0.
invoke-virtual {v0}, Lrandomclass;->getSuperclass()Lsuperclass;
move-result-object v1
if-eqz v0, :here
#this would normally be deodexable, except that it follows
#the above un-deodexeable instruction, which prevents the
#propagation of any register information. It can never be
#reached, and should be replaced with throw v2
invoke-virtual {v2}, Lsuperclass;->somemethod()V
#another odexed instruction that uses the result of the
#first unresolveable odex instruction. This should
#be replaced with throw v1
invoke-virtual {v1}, Lsuperclass;->somemethod()V
:here
#and we're back to the non-dead code
invoke-virtual {v2}, Lsuperclass;->somemethod()V
if-nez v0, :here3
return-void
.end method
.method public static FirstInstructionTest(Lrandomclass;)V
.registers 1
:try_start
invoke-virtual/range {p0}, Lrandomclass;->getSuperclass()Lsuperclass;
return-void
:try_end
.catch Ljava/lang/Exception; {:try_start .. :try_end} :handler
:handler
:inner_try_start
#this tests that the parameter register types are correctly propagated to the exception handlers, in the
#case that the first instruction of the method can throw an exception and is in a try black
invoke-virtual/range {p0}, Lrandomclass;->getSuperclass()Lsuperclass;
return-void
:inner_try_end
.catch Ljava/lang/Exception; {:inner_try_start .. :inner_try_end} :inner_handler
:inner_handler
#this additionally tests that the register types are propagated recursively, in the case that the first
#instruction in the exception handler can also throw an exception, and is covered by a try block
invoke-virtual/range {p0}, Lrandomclass;->getSuperclass()Lsuperclass;
return-void
.end method

View File

@ -1,18 +0,0 @@
.class public Lrandomclass;
.super Ljava/lang/Object;
.method public constructor <init>()V
.registers 1
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
.method public getSuperclass()Lsuperclass;
.registers 2
new-instance v0, Lsuperclass;
invoke-direct {v0}, Lsuperclass;-><init>()V
return-object v0
.end method

View File

@ -1,21 +0,0 @@
.class public Lsubclass;
.super Lsuperclass;
.method public constructor <init>()V
.registers 1
invoke-direct {p0}, Lsuperclass;-><init>()V
return-void
.end method
.method public somemethod()V
.registers 2
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
const-string v1, "subclass.somemethod"
invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
return-void
.end method

Some files were not shown because too many files have changed in this diff Show More