mirror of
https://github.com/revanced/smali.git
synced 2025-05-03 08:04:28 +02:00
Refactor the way the baksmali options are handled
This commit is contained in:
parent
71a580878f
commit
93aa50139c
@ -28,8 +28,11 @@
|
|||||||
|
|
||||||
package org.jf.baksmali.Adaptors;
|
package org.jf.baksmali.Adaptors;
|
||||||
|
|
||||||
|
import org.jf.baksmali.baksmaliOptions;
|
||||||
import org.jf.util.IndentingWriter;
|
import org.jf.util.IndentingWriter;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class CatchMethodItem extends MethodItem {
|
public class CatchMethodItem extends MethodItem {
|
||||||
@ -39,21 +42,22 @@ public class CatchMethodItem extends MethodItem {
|
|||||||
private final LabelMethodItem tryEndLabel;
|
private final LabelMethodItem tryEndLabel;
|
||||||
private final LabelMethodItem handlerLabel;
|
private final LabelMethodItem handlerLabel;
|
||||||
|
|
||||||
public CatchMethodItem(MethodDefinition.LabelCache labelCache, int codeAddress, String exceptionType,
|
public CatchMethodItem(@Nonnull baksmaliOptions options, @Nonnull MethodDefinition.LabelCache labelCache,
|
||||||
int startAddress, int endAddress, int handlerAddress) {
|
int codeAddress, @Nullable String exceptionType, int startAddress, int endAddress,
|
||||||
|
int handlerAddress) {
|
||||||
super(codeAddress);
|
super(codeAddress);
|
||||||
this.exceptionType = exceptionType;
|
this.exceptionType = exceptionType;
|
||||||
|
|
||||||
tryStartLabel = labelCache.internLabel(new LabelMethodItem(startAddress, "try_start_"));
|
tryStartLabel = labelCache.internLabel(new LabelMethodItem(options, startAddress, "try_start_"));
|
||||||
|
|
||||||
//use the address from the last covered instruction, but make the label
|
//use the address from the last covered instruction, but make the label
|
||||||
//name refer to the address of the next instruction
|
//name refer to the address of the next instruction
|
||||||
tryEndLabel = labelCache.internLabel(new EndTryLabelMethodItem(codeAddress, endAddress));
|
tryEndLabel = labelCache.internLabel(new EndTryLabelMethodItem(options, codeAddress, endAddress));
|
||||||
|
|
||||||
if (exceptionType == null) {
|
if (exceptionType == null) {
|
||||||
handlerLabel = labelCache.internLabel(new LabelMethodItem(handlerAddress, "catchall_"));
|
handlerLabel = labelCache.internLabel(new LabelMethodItem(options, handlerAddress, "catchall_"));
|
||||||
} else {
|
} else {
|
||||||
handlerLabel = labelCache.internLabel(new LabelMethodItem(handlerAddress, "catch_"));
|
handlerLabel = labelCache.internLabel(new LabelMethodItem(options, handlerAddress, "catch_"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
package org.jf.baksmali.Adaptors;
|
package org.jf.baksmali.Adaptors;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import org.jf.baksmali.baksmaliOptions;
|
||||||
import org.jf.dexlib2.AccessFlags;
|
import org.jf.dexlib2.AccessFlags;
|
||||||
import org.jf.dexlib2.iface.*;
|
import org.jf.dexlib2.iface.*;
|
||||||
import org.jf.dexlib2.iface.instruction.Instruction;
|
import org.jf.dexlib2.iface.instruction.Instruction;
|
||||||
@ -46,12 +47,14 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ClassDefinition {
|
public class ClassDefinition {
|
||||||
|
@Nonnull public final baksmaliOptions options;
|
||||||
@Nonnull public final ClassDef classDef;
|
@Nonnull public final ClassDef classDef;
|
||||||
@Nonnull private final HashSet<String> fieldsSetInStaticConstructor;
|
@Nonnull private final HashSet<String> fieldsSetInStaticConstructor;
|
||||||
|
|
||||||
protected boolean validationErrors;
|
protected boolean validationErrors;
|
||||||
|
|
||||||
public ClassDefinition(ClassDef classDef) {
|
public ClassDefinition(@Nonnull baksmaliOptions options, @Nonnull ClassDef classDef) {
|
||||||
|
this.options = options;
|
||||||
this.classDef = classDef;
|
this.classDef = classDef;
|
||||||
fieldsSetInStaticConstructor = findFieldsSetInStaticConstructor();
|
fieldsSetInStaticConstructor = findFieldsSetInStaticConstructor();
|
||||||
}
|
}
|
||||||
|
@ -28,11 +28,15 @@
|
|||||||
|
|
||||||
package org.jf.baksmali.Adaptors;
|
package org.jf.baksmali.Adaptors;
|
||||||
|
|
||||||
|
import org.jf.baksmali.baksmaliOptions;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class EndTryLabelMethodItem extends LabelMethodItem {
|
public class EndTryLabelMethodItem extends LabelMethodItem {
|
||||||
private int endTryAddress;
|
private int endTryAddress;
|
||||||
|
|
||||||
public EndTryLabelMethodItem(int codeAddress, int endTryAddress) {
|
public EndTryLabelMethodItem(@Nonnull baksmaliOptions options, int codeAddress, int endTryAddress) {
|
||||||
super(codeAddress, "try_end_");
|
super(options, codeAddress, "try_end_");
|
||||||
this.endTryAddress = endTryAddress;
|
this.endTryAddress = endTryAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,8 @@ public class InstructionMethodItemFactory {
|
|||||||
MethodDefinition methodDef, int codeAddress, Instruction instruction) {
|
MethodDefinition methodDef, int codeAddress, Instruction instruction) {
|
||||||
|
|
||||||
if (instruction instanceof OffsetInstruction) {
|
if (instruction instanceof OffsetInstruction) {
|
||||||
return new OffsetInstructionFormatMethodItem(methodDef, codeAddress, (OffsetInstruction)instruction);
|
return new OffsetInstructionFormatMethodItem(methodDef.classDef.options, methodDef, codeAddress,
|
||||||
|
(OffsetInstruction)instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (instruction.getOpcode().format) {
|
switch (instruction.getOpcode().format) {
|
||||||
|
@ -30,20 +30,22 @@ package org.jf.baksmali.Adaptors.Format;
|
|||||||
|
|
||||||
import org.jf.baksmali.Adaptors.LabelMethodItem;
|
import org.jf.baksmali.Adaptors.LabelMethodItem;
|
||||||
import org.jf.baksmali.Adaptors.MethodDefinition;
|
import org.jf.baksmali.Adaptors.MethodDefinition;
|
||||||
|
import org.jf.baksmali.baksmaliOptions;
|
||||||
import org.jf.dexlib2.Opcode;
|
import org.jf.dexlib2.Opcode;
|
||||||
import org.jf.dexlib2.iface.instruction.OffsetInstruction;
|
import org.jf.dexlib2.iface.instruction.OffsetInstruction;
|
||||||
import org.jf.util.IndentingWriter;
|
import org.jf.util.IndentingWriter;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class OffsetInstructionFormatMethodItem extends InstructionMethodItem<OffsetInstruction> {
|
public class OffsetInstructionFormatMethodItem extends InstructionMethodItem<OffsetInstruction> {
|
||||||
protected LabelMethodItem label;
|
protected LabelMethodItem label;
|
||||||
|
|
||||||
public OffsetInstructionFormatMethodItem(MethodDefinition methodDef, int codeAddress,
|
public OffsetInstructionFormatMethodItem(@Nonnull baksmaliOptions options, @Nonnull MethodDefinition methodDef,
|
||||||
OffsetInstruction instruction) {
|
int codeAddress, OffsetInstruction instruction) {
|
||||||
super(methodDef, codeAddress, instruction);
|
super(methodDef, codeAddress, instruction);
|
||||||
|
|
||||||
label = new LabelMethodItem(codeAddress + instruction.getCodeOffset(), getLabelPrefix());
|
label = new LabelMethodItem(options, codeAddress + instruction.getCodeOffset(), getLabelPrefix());
|
||||||
label = methodDef.getLabelCache().internLabel(label);
|
label = methodDef.getLabelCache().internLabel(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,8 @@ public class PackedSwitchMethodItem extends InstructionMethodItem<PackedSwitchPa
|
|||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
LabelMethodItem label = methodDef.getLabelCache().internLabel(
|
LabelMethodItem label = methodDef.getLabelCache().internLabel(
|
||||||
new LabelMethodItem(baseCodeAddress + switchElement.getOffset(), "pswitch_"));
|
new LabelMethodItem(methodDef.classDef.options, baseCodeAddress + switchElement.getOffset(),
|
||||||
|
"pswitch_"));
|
||||||
targets.add(new PackedSwitchLabelTarget(label));
|
targets.add(new PackedSwitchLabelTarget(label));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -51,7 +51,8 @@ public class SparseSwitchMethodItem extends InstructionMethodItem<SparseSwitchPa
|
|||||||
if (baseCodeAddress >= 0) {
|
if (baseCodeAddress >= 0) {
|
||||||
for (SwitchElement switchElement: instruction.getSwitchElements()) {
|
for (SwitchElement switchElement: instruction.getSwitchElements()) {
|
||||||
LabelMethodItem label = methodDef.getLabelCache().internLabel(
|
LabelMethodItem label = methodDef.getLabelCache().internLabel(
|
||||||
new LabelMethodItem(baseCodeAddress + switchElement.getOffset(), "sswitch_"));
|
new LabelMethodItem( methodDef.classDef.options, baseCodeAddress + switchElement.getOffset(),
|
||||||
|
"sswitch_"));
|
||||||
targets.add(new SparseSwitchLabelTarget(switchElement.getKey(), label));
|
targets.add(new SparseSwitchLabelTarget(switchElement.getKey(), label));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -28,17 +28,20 @@
|
|||||||
|
|
||||||
package org.jf.baksmali.Adaptors;
|
package org.jf.baksmali.Adaptors;
|
||||||
|
|
||||||
|
import org.jf.baksmali.baksmaliOptions;
|
||||||
import org.jf.util.IndentingWriter;
|
import org.jf.util.IndentingWriter;
|
||||||
import org.jf.baksmali.baksmali;
|
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class LabelMethodItem extends MethodItem {
|
public class LabelMethodItem extends MethodItem {
|
||||||
|
private final baksmaliOptions options;
|
||||||
private final String labelPrefix;
|
private final String labelPrefix;
|
||||||
private int labelSequence;
|
private int labelSequence;
|
||||||
|
|
||||||
public LabelMethodItem(int codeAddress, String labelPrefix) {
|
public LabelMethodItem(@Nonnull baksmaliOptions options, int codeAddress, @Nonnull String labelPrefix) {
|
||||||
super(codeAddress);
|
super(codeAddress);
|
||||||
|
this.options = options;
|
||||||
this.labelPrefix = labelPrefix;
|
this.labelPrefix = labelPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +76,7 @@ public class LabelMethodItem extends MethodItem {
|
|||||||
public boolean writeTo(IndentingWriter writer) throws IOException {
|
public boolean writeTo(IndentingWriter writer) throws IOException {
|
||||||
writer.write(':');
|
writer.write(':');
|
||||||
writer.write(labelPrefix);
|
writer.write(labelPrefix);
|
||||||
if (baksmali.useSequentialLabels) {
|
if (options.useSequentialLabels) {
|
||||||
writer.printUnsignedLongAsHex(labelSequence);
|
writer.printUnsignedLongAsHex(labelSequence);
|
||||||
} else {
|
} else {
|
||||||
writer.printUnsignedLongAsHex(this.getLabelAddress());
|
writer.printUnsignedLongAsHex(this.getLabelAddress());
|
||||||
|
@ -31,7 +31,6 @@ package org.jf.baksmali.Adaptors;
|
|||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import org.jf.baksmali.Adaptors.Debug.DebugMethodItem;
|
import org.jf.baksmali.Adaptors.Debug.DebugMethodItem;
|
||||||
import org.jf.baksmali.Adaptors.Format.InstructionMethodItemFactory;
|
import org.jf.baksmali.Adaptors.Format.InstructionMethodItemFactory;
|
||||||
import org.jf.baksmali.baksmali;
|
|
||||||
import org.jf.dexlib2.AccessFlags;
|
import org.jf.dexlib2.AccessFlags;
|
||||||
import org.jf.dexlib2.Format;
|
import org.jf.dexlib2.Format;
|
||||||
import org.jf.dexlib2.Opcode;
|
import org.jf.dexlib2.Opcode;
|
||||||
@ -157,7 +156,7 @@ public class MethodDefinition {
|
|||||||
writer.write('\n');
|
writer.write('\n');
|
||||||
|
|
||||||
writer.indent(4);
|
writer.indent(4);
|
||||||
if (baksmali.useLocalsDirective) {
|
if (classDef.options.useLocalsDirective) {
|
||||||
writer.write(".locals ");
|
writer.write(".locals ");
|
||||||
writer.printSignedIntAsDec(methodImpl.getRegisterCount() - parameterRegisterCount);
|
writer.printSignedIntAsDec(methodImpl.getRegisterCount() - parameterRegisterCount);
|
||||||
} else {
|
} else {
|
||||||
@ -168,7 +167,8 @@ public class MethodDefinition {
|
|||||||
writeParameters(writer, method, methodParameters);
|
writeParameters(writer, method, methodParameters);
|
||||||
|
|
||||||
if (registerFormatter == null) {
|
if (registerFormatter == null) {
|
||||||
registerFormatter = new RegisterFormatter(methodImpl.getRegisterCount(), parameterRegisterCount);
|
registerFormatter = new RegisterFormatter(classDef.options, methodImpl.getRegisterCount(),
|
||||||
|
parameterRegisterCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnotationFormatter.writeTo(writer, method.getAnnotations());
|
AnnotationFormatter.writeTo(writer, method.getAnnotations());
|
||||||
@ -268,18 +268,18 @@ public class MethodDefinition {
|
|||||||
private List<MethodItem> getMethodItems() {
|
private List<MethodItem> getMethodItems() {
|
||||||
ArrayList<MethodItem> methodItems = new ArrayList<MethodItem>();
|
ArrayList<MethodItem> methodItems = new ArrayList<MethodItem>();
|
||||||
|
|
||||||
if ((baksmali.registerInfo != 0) || (baksmali.deodex && needsAnalyzed())) {
|
if ((classDef.options.registerInfo != 0) || (classDef.options.deodex && needsAnalyzed())) {
|
||||||
addAnalyzedInstructionMethodItems(methodItems);
|
addAnalyzedInstructionMethodItems(methodItems);
|
||||||
} else {
|
} else {
|
||||||
addInstructionMethodItems(methodItems);
|
addInstructionMethodItems(methodItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
addTries(methodItems);
|
addTries(methodItems);
|
||||||
if (baksmali.outputDebugInfo) {
|
if (classDef.options.outputDebugInfo) {
|
||||||
addDebugInfo(methodItems);
|
addDebugInfo(methodItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (baksmali.useSequentialLabels) {
|
if (classDef.options.useSequentialLabels) {
|
||||||
setLabelSequentialNumbers();
|
setLabelSequentialNumbers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,7 +315,7 @@ public class MethodDefinition {
|
|||||||
methodItems.add(new BlankMethodItem(currentCodeAddress));
|
methodItems.add(new BlankMethodItem(currentCodeAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (baksmali.addCodeOffsets) {
|
if (classDef.options.addCodeOffsets) {
|
||||||
methodItems.add(new MethodItem(currentCodeAddress) {
|
methodItems.add(new MethodItem(currentCodeAddress) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -332,7 +332,7 @@ public class MethodDefinition {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!baksmali.noAccessorComments && (instruction instanceof ReferenceInstruction)) {
|
if (!classDef.options.noAccessorComments && (instruction instanceof ReferenceInstruction)) {
|
||||||
Opcode opcode = instruction.getOpcode();
|
Opcode opcode = instruction.getOpcode();
|
||||||
|
|
||||||
if (opcode.referenceType == ReferenceType.METHOD) {
|
if (opcode.referenceType == ReferenceType.METHOD) {
|
||||||
@ -341,7 +341,7 @@ public class MethodDefinition {
|
|||||||
|
|
||||||
if (SyntheticAccessorResolver.looksLikeSyntheticAccessor(methodReference.getName())) {
|
if (SyntheticAccessorResolver.looksLikeSyntheticAccessor(methodReference.getName())) {
|
||||||
SyntheticAccessorResolver.AccessedMember accessedMember =
|
SyntheticAccessorResolver.AccessedMember accessedMember =
|
||||||
baksmali.syntheticAccessorResolver.getAccessedMember(methodReference);
|
classDef.options.syntheticAccessorResolver.getAccessedMember(methodReference);
|
||||||
if (accessedMember != null) {
|
if (accessedMember != null) {
|
||||||
methodItems.add(new SyntheticAccessCommentMethodItem(accessedMember, currentCodeAddress));
|
methodItems.add(new SyntheticAccessCommentMethodItem(accessedMember, currentCodeAddress));
|
||||||
}
|
}
|
||||||
@ -354,7 +354,8 @@ public class MethodDefinition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addAnalyzedInstructionMethodItems(List<MethodItem> methodItems) {
|
private void addAnalyzedInstructionMethodItems(List<MethodItem> methodItems) {
|
||||||
MethodAnalyzer methodAnalyzer = new MethodAnalyzer(baksmali.classPath, method, baksmali.inlineResolver);
|
MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classDef.options.classPath, method,
|
||||||
|
classDef.options.inlineResolver);
|
||||||
|
|
||||||
AnalysisException analysisException = methodAnalyzer.getAnalysisException();
|
AnalysisException analysisException = methodAnalyzer.getAnalysisException();
|
||||||
if (analysisException != null) {
|
if (analysisException != null) {
|
||||||
@ -384,7 +385,7 @@ public class MethodDefinition {
|
|||||||
methodItems.add(new BlankMethodItem(currentCodeAddress));
|
methodItems.add(new BlankMethodItem(currentCodeAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (baksmali.addCodeOffsets) {
|
if (classDef.options.addCodeOffsets) {
|
||||||
methodItems.add(new MethodItem(currentCodeAddress) {
|
methodItems.add(new MethodItem(currentCodeAddress) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -401,9 +402,10 @@ public class MethodDefinition {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (baksmali.registerInfo != 0 && !instruction.getInstruction().getOpcode().format.isPayloadFormat) {
|
if (classDef.options.registerInfo != 0 &&
|
||||||
|
!instruction.getInstruction().getOpcode().format.isPayloadFormat) {
|
||||||
methodItems.add(
|
methodItems.add(
|
||||||
new PreInstructionRegisterInfoMethodItem(
|
new PreInstructionRegisterInfoMethodItem(classDef.options.registerInfo,
|
||||||
methodAnalyzer, registerFormatter, instruction, currentCodeAddress));
|
methodAnalyzer, registerFormatter, instruction, currentCodeAddress));
|
||||||
|
|
||||||
methodItems.add(
|
methodItems.add(
|
||||||
@ -455,7 +457,7 @@ public class MethodDefinition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//use the address from the last covered instruction
|
//use the address from the last covered instruction
|
||||||
CatchMethodItem catchMethodItem = new CatchMethodItem(labelCache, lastCoveredAddress,
|
CatchMethodItem catchMethodItem = new CatchMethodItem(classDef.options, labelCache, lastCoveredAddress,
|
||||||
handler.getExceptionType(), startAddress, endAddress, handlerAddress);
|
handler.getExceptionType(), startAddress, endAddress, handlerAddress);
|
||||||
methodItems.add(catchMethodItem);
|
methodItems.add(catchMethodItem);
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,7 @@
|
|||||||
|
|
||||||
package org.jf.baksmali.Adaptors;
|
package org.jf.baksmali.Adaptors;
|
||||||
|
|
||||||
import org.jf.baksmali.baksmali;
|
import org.jf.baksmali.baksmaliOptions;
|
||||||
import org.jf.baksmali.main;
|
|
||||||
import org.jf.dexlib2.analysis.AnalyzedInstruction;
|
import org.jf.dexlib2.analysis.AnalyzedInstruction;
|
||||||
import org.jf.dexlib2.analysis.RegisterType;
|
import org.jf.dexlib2.analysis.RegisterType;
|
||||||
import org.jf.util.IndentingWriter;
|
import org.jf.util.IndentingWriter;
|
||||||
@ -57,16 +56,16 @@ public class PostInstructionRegisterInfoMethodItem extends MethodItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean writeTo(IndentingWriter writer) throws IOException {
|
public boolean writeTo(IndentingWriter writer) throws IOException {
|
||||||
int registerInfo = baksmali.registerInfo;
|
int registerInfo = registerFormatter.options.registerInfo;
|
||||||
int registerCount = analyzedInstruction.getRegisterCount();
|
int registerCount = analyzedInstruction.getRegisterCount();
|
||||||
BitSet registers = new BitSet(registerCount);
|
BitSet registers = new BitSet(registerCount);
|
||||||
|
|
||||||
if ((registerInfo & main.ALL) != 0) {
|
if ((registerInfo & baksmaliOptions.ALL) != 0) {
|
||||||
registers.set(0, registerCount);
|
registers.set(0, registerCount);
|
||||||
} else {
|
} else {
|
||||||
if ((registerInfo & main.ALLPOST) != 0) {
|
if ((registerInfo & baksmaliOptions.ALLPOST) != 0) {
|
||||||
registers.set(0, registerCount);
|
registers.set(0, registerCount);
|
||||||
} else if ((registerInfo & main.DEST) != 0) {
|
} else if ((registerInfo & baksmaliOptions.DEST) != 0) {
|
||||||
addDestRegs(registers, registerCount);
|
addDestRegs(registers, registerCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,7 @@
|
|||||||
|
|
||||||
package org.jf.baksmali.Adaptors;
|
package org.jf.baksmali.Adaptors;
|
||||||
|
|
||||||
import org.jf.baksmali.baksmali;
|
import org.jf.baksmali.baksmaliOptions;
|
||||||
import org.jf.baksmali.main;
|
|
||||||
import org.jf.dexlib2.analysis.AnalyzedInstruction;
|
import org.jf.dexlib2.analysis.AnalyzedInstruction;
|
||||||
import org.jf.dexlib2.analysis.MethodAnalyzer;
|
import org.jf.dexlib2.analysis.MethodAnalyzer;
|
||||||
import org.jf.dexlib2.analysis.RegisterType;
|
import org.jf.dexlib2.analysis.RegisterType;
|
||||||
@ -41,15 +40,18 @@ import java.io.IOException;
|
|||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
|
|
||||||
public class PreInstructionRegisterInfoMethodItem extends MethodItem {
|
public class PreInstructionRegisterInfoMethodItem extends MethodItem {
|
||||||
|
private final int registerInfo;
|
||||||
@Nonnull private final MethodAnalyzer methodAnalyzer;
|
@Nonnull private final MethodAnalyzer methodAnalyzer;
|
||||||
@Nonnull private final RegisterFormatter registerFormatter;
|
@Nonnull private final RegisterFormatter registerFormatter;
|
||||||
@Nonnull private final AnalyzedInstruction analyzedInstruction;
|
@Nonnull private final AnalyzedInstruction analyzedInstruction;
|
||||||
|
|
||||||
public PreInstructionRegisterInfoMethodItem(@Nonnull MethodAnalyzer methodAnalyzer,
|
public PreInstructionRegisterInfoMethodItem(int registerInfo,
|
||||||
|
@Nonnull MethodAnalyzer methodAnalyzer,
|
||||||
@Nonnull RegisterFormatter registerFormatter,
|
@Nonnull RegisterFormatter registerFormatter,
|
||||||
@Nonnull AnalyzedInstruction analyzedInstruction,
|
@Nonnull AnalyzedInstruction analyzedInstruction,
|
||||||
int codeAddress) {
|
int codeAddress) {
|
||||||
super(codeAddress);
|
super(codeAddress);
|
||||||
|
this.registerInfo = registerInfo;
|
||||||
this.methodAnalyzer = methodAnalyzer;
|
this.methodAnalyzer = methodAnalyzer;
|
||||||
this.registerFormatter = registerFormatter;
|
this.registerFormatter = registerFormatter;
|
||||||
this.analyzedInstruction = analyzedInstruction;
|
this.analyzedInstruction = analyzedInstruction;
|
||||||
@ -62,22 +64,21 @@ public class PreInstructionRegisterInfoMethodItem extends MethodItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean writeTo(IndentingWriter writer) throws IOException {
|
public boolean writeTo(IndentingWriter writer) throws IOException {
|
||||||
int registerInfo = baksmali.registerInfo;
|
|
||||||
int registerCount = analyzedInstruction.getRegisterCount();
|
int registerCount = analyzedInstruction.getRegisterCount();
|
||||||
BitSet registers = new BitSet(registerCount);
|
BitSet registers = new BitSet(registerCount);
|
||||||
|
|
||||||
if ((registerInfo & main.ALL) != 0) {
|
if ((registerInfo & baksmaliOptions.ALL) != 0) {
|
||||||
registers.set(0, registerCount);
|
registers.set(0, registerCount);
|
||||||
} else {
|
} else {
|
||||||
if ((registerInfo & main.ALLPRE) != 0) {
|
if ((registerInfo & baksmaliOptions.ALLPRE) != 0) {
|
||||||
registers.set(0, registerCount);
|
registers.set(0, registerCount);
|
||||||
} else {
|
} else {
|
||||||
if ((registerInfo & main.ARGS) != 0) {
|
if ((registerInfo & baksmaliOptions.ARGS) != 0) {
|
||||||
addArgsRegs(registers);
|
addArgsRegs(registers);
|
||||||
}
|
}
|
||||||
if ((registerInfo & main.MERGE) != 0) {
|
if ((registerInfo & baksmaliOptions.MERGE) != 0) {
|
||||||
addMergeRegs(registers, registerCount);
|
addMergeRegs(registers, registerCount);
|
||||||
} else if ((registerInfo & main.FULLMERGE) != 0 &&
|
} else if ((registerInfo & baksmaliOptions.FULLMERGE) != 0 &&
|
||||||
(analyzedInstruction.isBeginningInstruction())) {
|
(analyzedInstruction.isBeginningInstruction())) {
|
||||||
addParamRegs(registers, registerCount);
|
addParamRegs(registers, registerCount);
|
||||||
}
|
}
|
||||||
@ -85,7 +86,7 @@ public class PreInstructionRegisterInfoMethodItem extends MethodItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean printedSomething = false;
|
boolean printedSomething = false;
|
||||||
if ((registerInfo & main.FULLMERGE) != 0) {
|
if ((registerInfo & baksmaliOptions.FULLMERGE) != 0) {
|
||||||
printedSomething = writeFullMergeRegs(writer, registers, registerCount);
|
printedSomething = writeFullMergeRegs(writer, registers, registerCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,19 +28,22 @@
|
|||||||
|
|
||||||
package org.jf.baksmali.Adaptors;
|
package org.jf.baksmali.Adaptors;
|
||||||
|
|
||||||
import org.jf.baksmali.baksmali;
|
import org.jf.baksmali.baksmaliOptions;
|
||||||
import org.jf.util.IndentingWriter;
|
import org.jf.util.IndentingWriter;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class contains the logic used for formatting registers
|
* This class contains the logic used for formatting registers
|
||||||
*/
|
*/
|
||||||
public class RegisterFormatter {
|
public class RegisterFormatter {
|
||||||
|
@Nonnull public final baksmaliOptions options;
|
||||||
public final int registerCount;
|
public final int registerCount;
|
||||||
public final int parameterRegisterCount;
|
public final int parameterRegisterCount;
|
||||||
|
|
||||||
public RegisterFormatter(int registerCount, int parameterRegisterCount) {
|
public RegisterFormatter(@Nonnull baksmaliOptions options, int registerCount, int parameterRegisterCount) {
|
||||||
|
this.options = options;
|
||||||
this.registerCount = registerCount;
|
this.registerCount = registerCount;
|
||||||
this.parameterRegisterCount = parameterRegisterCount;
|
this.parameterRegisterCount = parameterRegisterCount;
|
||||||
}
|
}
|
||||||
@ -55,7 +58,7 @@ public class RegisterFormatter {
|
|||||||
* @param lastRegister the last register in the range
|
* @param lastRegister the last register in the range
|
||||||
*/
|
*/
|
||||||
public void writeRegisterRange(IndentingWriter writer, int startRegister, int lastRegister) throws IOException {
|
public void writeRegisterRange(IndentingWriter writer, int startRegister, int lastRegister) throws IOException {
|
||||||
if (!baksmali.noParameterRegisters) {
|
if (!options.noParameterRegisters) {
|
||||||
assert startRegister <= lastRegister;
|
assert startRegister <= lastRegister;
|
||||||
|
|
||||||
if (startRegister >= registerCount - parameterRegisterCount) {
|
if (startRegister >= registerCount - parameterRegisterCount) {
|
||||||
@ -83,7 +86,7 @@ public class RegisterFormatter {
|
|||||||
* @param register the register number
|
* @param register the register number
|
||||||
*/
|
*/
|
||||||
public void writeTo(IndentingWriter writer, int register) throws IOException {
|
public void writeTo(IndentingWriter writer, int register) throws IOException {
|
||||||
if (!baksmali.noParameterRegisters) {
|
if (!options.noParameterRegisters) {
|
||||||
if (register >= registerCount - parameterRegisterCount) {
|
if (register >= registerCount - parameterRegisterCount) {
|
||||||
writer.write('p');
|
writer.write('p');
|
||||||
writer.printSignedIntAsDec((register - (registerCount - parameterRegisterCount)));
|
writer.printSignedIntAsDec((register - (registerCount - parameterRegisterCount)));
|
||||||
|
@ -33,7 +33,6 @@ import com.google.common.collect.ImmutableList;
|
|||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import org.jf.baksmali.Adaptors.ClassDefinition;
|
import org.jf.baksmali.Adaptors.ClassDefinition;
|
||||||
import org.jf.dexlib2.analysis.ClassPath;
|
import org.jf.dexlib2.analysis.ClassPath;
|
||||||
import org.jf.dexlib2.analysis.InlineMethodResolver;
|
|
||||||
import org.jf.dexlib2.iface.ClassDef;
|
import org.jf.dexlib2.iface.ClassDef;
|
||||||
import org.jf.dexlib2.iface.DexFile;
|
import org.jf.dexlib2.iface.DexFile;
|
||||||
import org.jf.dexlib2.util.SyntheticAccessorResolver;
|
import org.jf.dexlib2.util.SyntheticAccessorResolver;
|
||||||
@ -46,20 +45,6 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class baksmali {
|
public class baksmali {
|
||||||
public static boolean noParameterRegisters = false;
|
|
||||||
public static boolean useLocalsDirective = false;
|
|
||||||
public static boolean useSequentialLabels = false;
|
|
||||||
public static boolean outputDebugInfo = true;
|
|
||||||
public static boolean addCodeOffsets = false;
|
|
||||||
public static boolean noAccessorComments = false;
|
|
||||||
public static boolean deodex = false;
|
|
||||||
public static InlineMethodResolver inlineResolver = null;
|
|
||||||
public static int registerInfo = 0;
|
|
||||||
public static String bootClassPath;
|
|
||||||
public static ClassPath classPath = null;
|
|
||||||
|
|
||||||
public static SyntheticAccessorResolver syntheticAccessorResolver = null;
|
|
||||||
|
|
||||||
public static void disassembleDexFile(String dexFilePath, DexFile dexFile, boolean deodex, String outputDirectory,
|
public static void disassembleDexFile(String dexFilePath, DexFile dexFile, boolean deodex, String outputDirectory,
|
||||||
String[] classPathDirs, String bootClassPath, String extraBootClassPath,
|
String[] classPathDirs, String bootClassPath, String extraBootClassPath,
|
||||||
boolean noParameterRegisters, boolean useLocalsDirective,
|
boolean noParameterRegisters, boolean useLocalsDirective,
|
||||||
@ -67,15 +52,17 @@ public class baksmali {
|
|||||||
boolean noAccessorComments, int registerInfo, boolean ignoreErrors,
|
boolean noAccessorComments, int registerInfo, boolean ignoreErrors,
|
||||||
String inlineTable, boolean checkPackagePrivateAccess)
|
String inlineTable, boolean checkPackagePrivateAccess)
|
||||||
{
|
{
|
||||||
baksmali.noParameterRegisters = noParameterRegisters;
|
baksmaliOptions options = new baksmaliOptions();
|
||||||
baksmali.useLocalsDirective = useLocalsDirective;
|
|
||||||
baksmali.useSequentialLabels = useSequentialLabels;
|
options.noParameterRegisters = noParameterRegisters;
|
||||||
baksmali.outputDebugInfo = outputDebugInfo;
|
options.useLocalsDirective = useLocalsDirective;
|
||||||
baksmali.addCodeOffsets = addCodeOffsets;
|
options.useSequentialLabels = useSequentialLabels;
|
||||||
baksmali.noAccessorComments = noAccessorComments;
|
options.outputDebugInfo = outputDebugInfo;
|
||||||
baksmali.deodex = deodex;
|
options.addCodeOffsets = addCodeOffsets;
|
||||||
baksmali.registerInfo = registerInfo;
|
options.noAccessorComments = noAccessorComments;
|
||||||
baksmali.bootClassPath = bootClassPath;
|
options.deodex = deodex;
|
||||||
|
options.registerInfo = registerInfo;
|
||||||
|
options.bootClassPath = bootClassPath;
|
||||||
|
|
||||||
if (registerInfo != 0 || deodex) {
|
if (registerInfo != 0 || deodex) {
|
||||||
try {
|
try {
|
||||||
@ -92,7 +79,7 @@ public class baksmali {
|
|||||||
bootClassPaths = Splitter.on(':').split(bootClassPath);
|
bootClassPaths = Splitter.on(':').split(bootClassPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
classPath = ClassPath.fromClassPath(Arrays.asList(classPathDirs),
|
options.classPath = ClassPath.fromClassPath(Arrays.asList(classPathDirs),
|
||||||
Iterables.concat(bootClassPaths, extraBootClassPaths), dexFile);
|
Iterables.concat(bootClassPaths, extraBootClassPaths), dexFile);
|
||||||
|
|
||||||
// TODO: uncomment
|
// TODO: uncomment
|
||||||
@ -127,7 +114,7 @@ public class baksmali {
|
|||||||
classDefs = ImmutableList.copyOf(classDefs);
|
classDefs = ImmutableList.copyOf(classDefs);
|
||||||
|
|
||||||
if (!noAccessorComments) {
|
if (!noAccessorComments) {
|
||||||
syntheticAccessorResolver = new SyntheticAccessorResolver(classDefs);
|
options.syntheticAccessorResolver = new SyntheticAccessorResolver(classDefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassFileNameHandler fileNameHandler = new ClassFileNameHandler(outputDirectoryFile, ".smali");
|
ClassFileNameHandler fileNameHandler = new ClassFileNameHandler(outputDirectoryFile, ".smali");
|
||||||
@ -153,7 +140,7 @@ public class baksmali {
|
|||||||
File smaliFile = fileNameHandler.getUniqueFilenameForClass(classDescriptor);
|
File smaliFile = fileNameHandler.getUniqueFilenameForClass(classDescriptor);
|
||||||
|
|
||||||
//create and initialize the top level string template
|
//create and initialize the top level string template
|
||||||
ClassDefinition classDefinition = new ClassDefinition(classDef);
|
ClassDefinition classDefinition = new ClassDefinition(options, classDef);
|
||||||
|
|
||||||
//write the disassembly
|
//write the disassembly
|
||||||
Writer writer = null;
|
Writer writer = null;
|
||||||
|
61
baksmali/src/main/java/org/jf/baksmali/baksmaliOptions.java
Normal file
61
baksmali/src/main/java/org/jf/baksmali/baksmaliOptions.java
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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 org.jf.dexlib2.analysis.ClassPath;
|
||||||
|
import org.jf.dexlib2.analysis.InlineMethodResolver;
|
||||||
|
import org.jf.dexlib2.util.SyntheticAccessorResolver;
|
||||||
|
|
||||||
|
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 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 deodex = false;
|
||||||
|
public InlineMethodResolver inlineResolver = null;
|
||||||
|
public int registerInfo = 0;
|
||||||
|
public String bootClassPath;
|
||||||
|
public ClassPath classPath = null;
|
||||||
|
|
||||||
|
public SyntheticAccessorResolver syntheticAccessorResolver = null;
|
||||||
|
}
|
@ -51,14 +51,6 @@ public class main {
|
|||||||
private static final Options debugOptions;
|
private static final Options debugOptions;
|
||||||
private static final Options options;
|
private static final Options options;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
options = new Options();
|
options = new Options();
|
||||||
basicOptions = new Options();
|
basicOptions = new Options();
|
||||||
@ -170,31 +162,31 @@ public class main {
|
|||||||
String[] values = commandLine.getOptionValues('r');
|
String[] values = commandLine.getOptionValues('r');
|
||||||
|
|
||||||
if (values == null || values.length == 0) {
|
if (values == null || values.length == 0) {
|
||||||
registerInfo = ARGS | DEST;
|
registerInfo = baksmaliOptions.ARGS | baksmaliOptions.DEST;
|
||||||
} else {
|
} else {
|
||||||
for (String value: values) {
|
for (String value: values) {
|
||||||
if (value.equalsIgnoreCase("ALL")) {
|
if (value.equalsIgnoreCase("ALL")) {
|
||||||
registerInfo |= ALL;
|
registerInfo |= baksmaliOptions.ALL;
|
||||||
} else if (value.equalsIgnoreCase("ALLPRE")) {
|
} else if (value.equalsIgnoreCase("ALLPRE")) {
|
||||||
registerInfo |= ALLPRE;
|
registerInfo |= baksmaliOptions.ALLPRE;
|
||||||
} else if (value.equalsIgnoreCase("ALLPOST")) {
|
} else if (value.equalsIgnoreCase("ALLPOST")) {
|
||||||
registerInfo |= ALLPOST;
|
registerInfo |= baksmaliOptions.ALLPOST;
|
||||||
} else if (value.equalsIgnoreCase("ARGS")) {
|
} else if (value.equalsIgnoreCase("ARGS")) {
|
||||||
registerInfo |= ARGS;
|
registerInfo |= baksmaliOptions.ARGS;
|
||||||
} else if (value.equalsIgnoreCase("DEST")) {
|
} else if (value.equalsIgnoreCase("DEST")) {
|
||||||
registerInfo |= DEST;
|
registerInfo |= baksmaliOptions.DEST;
|
||||||
} else if (value.equalsIgnoreCase("MERGE")) {
|
} else if (value.equalsIgnoreCase("MERGE")) {
|
||||||
registerInfo |= MERGE;
|
registerInfo |= baksmaliOptions.MERGE;
|
||||||
} else if (value.equalsIgnoreCase("FULLMERGE")) {
|
} else if (value.equalsIgnoreCase("FULLMERGE")) {
|
||||||
registerInfo |= FULLMERGE;
|
registerInfo |= baksmaliOptions.FULLMERGE;
|
||||||
} else {
|
} else {
|
||||||
usage();
|
usage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((registerInfo & FULLMERGE) != 0) {
|
if ((registerInfo & baksmaliOptions.FULLMERGE) != 0) {
|
||||||
registerInfo &= ~MERGE;
|
registerInfo &= ~baksmaliOptions.MERGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user