feat: input plugin for java bytecode
This commit is contained in:
+12
-1
@@ -27,10 +27,21 @@ public class JadxPluginManager {
|
||||
|
||||
public void register(JadxPlugin plugin) {
|
||||
Objects.requireNonNull(plugin);
|
||||
LOG.debug("Loaded plugin: {}", plugin.getPluginInfo().getName());
|
||||
LOG.debug("Register plugin: {}", plugin.getPluginInfo().getPluginId());
|
||||
allPlugins.put(plugin.getClass(), plugin);
|
||||
}
|
||||
|
||||
public boolean unload(String pluginId) {
|
||||
return allPlugins.values().removeIf(p -> {
|
||||
String id = p.getPluginInfo().getPluginId();
|
||||
boolean match = id.equals(pluginId);
|
||||
if (match) {
|
||||
LOG.debug("Unload plugin: {}", id);
|
||||
}
|
||||
return match;
|
||||
});
|
||||
}
|
||||
|
||||
public List<JadxPlugin> getAllPlugins() {
|
||||
return new ArrayList<>(allPlugins.values());
|
||||
}
|
||||
|
||||
+4
@@ -19,6 +19,7 @@ public class AccessFlags {
|
||||
public static final int SYNTHETIC = 0x1000;
|
||||
public static final int ANNOTATION = 0x2000;
|
||||
public static final int ENUM = 0x4000;
|
||||
public static final int MODULE = 0x8000;
|
||||
public static final int CONSTRUCTOR = 0x10000;
|
||||
public static final int DECLARED_SYNCHRONIZED = 0x20000;
|
||||
|
||||
@@ -72,6 +73,9 @@ public class AccessFlags {
|
||||
break;
|
||||
|
||||
case CLASS:
|
||||
if (hasFlag(flags, MODULE)) {
|
||||
code.append("module ");
|
||||
}
|
||||
if (hasFlag(flags, STRICT)) {
|
||||
code.append("strict ");
|
||||
}
|
||||
|
||||
+2
-1
@@ -3,8 +3,9 @@ package jadx.api.plugins.input.data;
|
||||
import java.util.List;
|
||||
|
||||
import jadx.api.plugins.input.data.annotations.EncodedValue;
|
||||
import jadx.api.plugins.input.insns.custom.ICustomPayload;
|
||||
|
||||
public interface ICallSite {
|
||||
public interface ICallSite extends ICustomPayload {
|
||||
|
||||
List<EncodedValue> getValues();
|
||||
|
||||
|
||||
+4
-9
@@ -5,12 +5,13 @@ import java.util.function.Consumer;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.plugins.input.data.annotations.EncodedValue;
|
||||
import jadx.api.plugins.input.data.annotations.IAnnotation;
|
||||
import jadx.api.plugins.input.data.attributes.IJadxAttribute;
|
||||
|
||||
public interface IClassData {
|
||||
IClassData copy();
|
||||
|
||||
String getInputFileName();
|
||||
|
||||
String getType();
|
||||
|
||||
int getAccessFlags();
|
||||
@@ -20,15 +21,9 @@ public interface IClassData {
|
||||
|
||||
List<String> getInterfacesTypes();
|
||||
|
||||
String getSourceFile();
|
||||
|
||||
String getInputFileName();
|
||||
|
||||
void visitFieldsAndMethods(Consumer<IFieldData> fieldsConsumer, Consumer<IMethodData> mthConsumer);
|
||||
|
||||
List<EncodedValue> getStaticFieldInitValues();
|
||||
|
||||
List<IAnnotation> getAnnotations();
|
||||
List<IJadxAttribute> getAttributes();
|
||||
|
||||
String getDisassembledCode();
|
||||
}
|
||||
|
||||
+3
-1
@@ -14,7 +14,9 @@ public interface ICodeReader {
|
||||
|
||||
int getRegistersCount();
|
||||
|
||||
int getInsnsCount();
|
||||
int getArgsStartReg();
|
||||
|
||||
int getUnitsCount();
|
||||
|
||||
@Nullable
|
||||
IDebugInfo getDebugInfo();
|
||||
|
||||
+3
-8
@@ -2,16 +2,11 @@ package jadx.api.plugins.input.data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import jadx.api.plugins.input.data.annotations.IAnnotation;
|
||||
import jadx.api.plugins.input.data.attributes.IJadxAttribute;
|
||||
|
||||
public interface IFieldData {
|
||||
String getParentClassType();
|
||||
|
||||
String getType();
|
||||
|
||||
String getName();
|
||||
public interface IFieldData extends IFieldRef {
|
||||
|
||||
int getAccessFlags();
|
||||
|
||||
List<IAnnotation> getAnnotations();
|
||||
List<IJadxAttribute> getAttributes();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package jadx.api.plugins.input.data;
|
||||
|
||||
public interface IFieldRef {
|
||||
String getParentClassType();
|
||||
|
||||
String getName();
|
||||
|
||||
String getType();
|
||||
}
|
||||
+2
-6
@@ -4,7 +4,7 @@ import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.plugins.input.data.annotations.IAnnotation;
|
||||
import jadx.api.plugins.input.data.attributes.IJadxAttribute;
|
||||
|
||||
public interface IMethodData {
|
||||
|
||||
@@ -12,14 +12,10 @@ public interface IMethodData {
|
||||
|
||||
int getAccessFlags();
|
||||
|
||||
boolean isDirect();
|
||||
|
||||
@Nullable
|
||||
ICodeReader getCodeReader();
|
||||
|
||||
String disassembleMethod();
|
||||
|
||||
List<IAnnotation> getAnnotations();
|
||||
|
||||
List<List<IAnnotation>> getParamsAnnotations();
|
||||
List<IJadxAttribute> getAttributes();
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ public interface IMethodHandle {
|
||||
|
||||
MethodHandleType getType();
|
||||
|
||||
IFieldData getFieldRef();
|
||||
IFieldRef getFieldRef();
|
||||
|
||||
IMethodRef getMethodRef();
|
||||
|
||||
|
||||
+2
-6
@@ -1,8 +1,8 @@
|
||||
package jadx.api.plugins.input.data;
|
||||
|
||||
import java.util.List;
|
||||
import jadx.api.plugins.input.insns.custom.ICustomPayload;
|
||||
|
||||
public interface IMethodRef {
|
||||
public interface IMethodRef extends IMethodProto, ICustomPayload {
|
||||
|
||||
int getUniqId();
|
||||
|
||||
@@ -14,8 +14,4 @@ public interface IMethodRef {
|
||||
String getParentClassType();
|
||||
|
||||
String getName();
|
||||
|
||||
String getReturnType();
|
||||
|
||||
List<String> getArgTypes();
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ public interface ITry {
|
||||
|
||||
int getStartAddress();
|
||||
|
||||
int getInstructionCount();
|
||||
int getEndAddress();
|
||||
}
|
||||
|
||||
+10
-1
@@ -2,7 +2,11 @@ package jadx.api.plugins.input.data.annotations;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class EncodedValue {
|
||||
import jadx.api.plugins.input.data.attributes.IJadxAttrType;
|
||||
import jadx.api.plugins.input.data.attributes.IJadxAttribute;
|
||||
import jadx.api.plugins.input.data.attributes.JadxAttrType;
|
||||
|
||||
public class EncodedValue implements IJadxAttribute {
|
||||
public static final EncodedValue NULL = new EncodedValue(EncodedType.ENCODED_NULL, null);
|
||||
|
||||
private final EncodedType type;
|
||||
@@ -33,6 +37,11 @@ public class EncodedValue {
|
||||
return type == that.getType() && Objects.equals(value, that.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJadxAttrType<? extends IJadxAttribute> getAttrType() {
|
||||
return JadxAttrType.CONSTANT_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getType(), getValue());
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package jadx.api.plugins.input.data.annotations;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class JadxAnnotation implements IAnnotation {
|
||||
private final AnnotationVisibility visibility;
|
||||
private final String type;
|
||||
private final Map<String, EncodedValue> values;
|
||||
|
||||
public JadxAnnotation(AnnotationVisibility visibility, String type, Map<String, EncodedValue> values) {
|
||||
this.visibility = visibility;
|
||||
this.type = type;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAnnotationClass() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisibility getVisibility() {
|
||||
return visibility;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, EncodedValue> getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Annotation{" + visibility + ", type=" + type + ", values=" + values + '}';
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package jadx.api.plugins.input.data.attributes;
|
||||
|
||||
/**
|
||||
* Marker interface for attribute type.
|
||||
* Used for attach attribute instance class information (T).
|
||||
* T - class of attribute instance
|
||||
*/
|
||||
public interface IJadxAttrType<T extends IJadxAttribute> {
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package jadx.api.plugins.input.data.attributes;
|
||||
|
||||
public interface IJadxAttribute {
|
||||
|
||||
IJadxAttrType<? extends IJadxAttribute> getAttrType();
|
||||
|
||||
/**
|
||||
* Mark type to skip unloading on node unload
|
||||
*/
|
||||
default boolean keepLoaded() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default String toAttrString() {
|
||||
return this.toString();
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package jadx.api.plugins.input.data.attributes;
|
||||
|
||||
import jadx.api.plugins.input.data.annotations.EncodedValue;
|
||||
import jadx.api.plugins.input.data.attributes.types.AnnotationDefaultAttr;
|
||||
import jadx.api.plugins.input.data.attributes.types.AnnotationDefaultClassAttr;
|
||||
import jadx.api.plugins.input.data.attributes.types.AnnotationsAttr;
|
||||
import jadx.api.plugins.input.data.attributes.types.ExceptionsAttr;
|
||||
import jadx.api.plugins.input.data.attributes.types.InnerClassesAttr;
|
||||
import jadx.api.plugins.input.data.attributes.types.MethodParamsAttr;
|
||||
import jadx.api.plugins.input.data.attributes.types.SignatureAttr;
|
||||
import jadx.api.plugins.input.data.attributes.types.SourceFileAttr;
|
||||
|
||||
public final class JadxAttrType<T extends IJadxAttribute> implements IJadxAttrType<T> {
|
||||
|
||||
// class, method, field
|
||||
public static final JadxAttrType<AnnotationsAttr> ANNOTATION_LIST = bind();
|
||||
public static final JadxAttrType<SignatureAttr> SIGNATURE = bind();
|
||||
|
||||
// class
|
||||
public static final JadxAttrType<SourceFileAttr> SOURCE_FILE = bind();
|
||||
public static final JadxAttrType<InnerClassesAttr> INNER_CLASSES = bind();
|
||||
public static final JadxAttrType<AnnotationDefaultClassAttr> ANNOTATION_DEFAULT_CLASS = bind(); // dex specific
|
||||
|
||||
// field
|
||||
public static final JadxAttrType<EncodedValue> CONSTANT_VALUE = bind();
|
||||
|
||||
// method
|
||||
public static final JadxAttrType<MethodParamsAttr> ANNOTATION_MTH_PARAMETERS = bind();
|
||||
public static final JadxAttrType<AnnotationDefaultAttr> ANNOTATION_DEFAULT = bind();
|
||||
public static final JadxAttrType<ExceptionsAttr> EXCEPTIONS = bind();
|
||||
|
||||
private static <T extends IJadxAttribute> JadxAttrType<T> bind() {
|
||||
return new JadxAttrType<>();
|
||||
}
|
||||
|
||||
private JadxAttrType() {
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package jadx.api.plugins.input.data.attributes;
|
||||
|
||||
public abstract class PinnedAttribute implements IJadxAttribute {
|
||||
|
||||
@Override
|
||||
public final boolean keepLoaded() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package jadx.api.plugins.input.data.attributes.types;
|
||||
|
||||
import jadx.api.plugins.input.data.annotations.EncodedValue;
|
||||
import jadx.api.plugins.input.data.attributes.IJadxAttrType;
|
||||
import jadx.api.plugins.input.data.attributes.IJadxAttribute;
|
||||
import jadx.api.plugins.input.data.attributes.JadxAttrType;
|
||||
import jadx.api.plugins.input.data.attributes.PinnedAttribute;
|
||||
|
||||
public class AnnotationDefaultAttr extends PinnedAttribute {
|
||||
|
||||
private final EncodedValue value;
|
||||
|
||||
public AnnotationDefaultAttr(EncodedValue value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public EncodedValue getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJadxAttrType<? extends IJadxAttribute> getAttrType() {
|
||||
return JadxAttrType.ANNOTATION_DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ANNOTATION_DEFAULT: " + value;
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package jadx.api.plugins.input.data.attributes.types;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import jadx.api.plugins.input.data.annotations.EncodedValue;
|
||||
import jadx.api.plugins.input.data.attributes.IJadxAttrType;
|
||||
import jadx.api.plugins.input.data.attributes.IJadxAttribute;
|
||||
import jadx.api.plugins.input.data.attributes.JadxAttrType;
|
||||
import jadx.api.plugins.input.data.attributes.PinnedAttribute;
|
||||
|
||||
public class AnnotationDefaultClassAttr extends PinnedAttribute {
|
||||
|
||||
private final Map<String, EncodedValue> values;
|
||||
|
||||
public AnnotationDefaultClassAttr(Map<String, EncodedValue> values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public Map<String, EncodedValue> getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJadxAttrType<? extends IJadxAttribute> getAttrType() {
|
||||
return JadxAttrType.ANNOTATION_DEFAULT_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ANNOTATION_DEFAULT_CLASS: " + values;
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package jadx.api.plugins.input.data.attributes.types;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.plugins.input.data.annotations.AnnotationVisibility;
|
||||
import jadx.api.plugins.input.data.annotations.IAnnotation;
|
||||
import jadx.api.plugins.input.data.attributes.JadxAttrType;
|
||||
import jadx.api.plugins.input.data.attributes.PinnedAttribute;
|
||||
|
||||
public class AnnotationsAttr extends PinnedAttribute {
|
||||
|
||||
@Nullable
|
||||
public static AnnotationsAttr pack(List<IAnnotation> annotationList) {
|
||||
if (annotationList.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Map<String, IAnnotation> annMap = new HashMap<>(annotationList.size());
|
||||
for (IAnnotation ann : annotationList) {
|
||||
if (ann.getVisibility() != AnnotationVisibility.SYSTEM) {
|
||||
annMap.put(ann.getAnnotationClass(), ann);
|
||||
}
|
||||
}
|
||||
if (annMap.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return new AnnotationsAttr(annMap);
|
||||
}
|
||||
|
||||
private final Map<String, IAnnotation> map;
|
||||
|
||||
public AnnotationsAttr(Map<String, IAnnotation> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public IAnnotation get(String className) {
|
||||
return map.get(className);
|
||||
}
|
||||
|
||||
public Collection<IAnnotation> getAll() {
|
||||
return map.values();
|
||||
}
|
||||
|
||||
public List<IAnnotation> getList() {
|
||||
return map.isEmpty() ? Collections.emptyList() : new ArrayList<>(map.values());
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JadxAttrType<AnnotationsAttr> getAttrType() {
|
||||
return JadxAttrType.ANNOTATION_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return map.toString();
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package jadx.api.plugins.input.data.attributes.types;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import jadx.api.plugins.input.data.attributes.IJadxAttrType;
|
||||
import jadx.api.plugins.input.data.attributes.JadxAttrType;
|
||||
import jadx.api.plugins.input.data.attributes.PinnedAttribute;
|
||||
|
||||
public class ExceptionsAttr extends PinnedAttribute {
|
||||
private final List<String> list;
|
||||
|
||||
public ExceptionsAttr(List<String> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public List<String> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJadxAttrType<ExceptionsAttr> getAttrType() {
|
||||
return JadxAttrType.EXCEPTIONS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EXCEPTIONS:" + list;
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package jadx.api.plugins.input.data.attributes.types;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import jadx.api.plugins.input.data.attributes.IJadxAttrType;
|
||||
import jadx.api.plugins.input.data.attributes.JadxAttrType;
|
||||
import jadx.api.plugins.input.data.attributes.PinnedAttribute;
|
||||
|
||||
public class InnerClassesAttr extends PinnedAttribute {
|
||||
|
||||
private final Map<String, InnerClsInfo> map;
|
||||
|
||||
public InnerClassesAttr(Map<String, InnerClsInfo> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public Map<String, InnerClsInfo> getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJadxAttrType<InnerClassesAttr> getAttrType() {
|
||||
return JadxAttrType.INNER_CLASSES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "INNER_CLASSES:" + map;
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package jadx.api.plugins.input.data.attributes.types;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.plugins.input.data.AccessFlags;
|
||||
import jadx.api.plugins.input.data.AccessFlagsScope;
|
||||
|
||||
public class InnerClsInfo {
|
||||
private final String innerCls;
|
||||
private final @Nullable String outerCls;
|
||||
private final @Nullable String name;
|
||||
private final int accessFlags;
|
||||
|
||||
public InnerClsInfo(String innerCls, @Nullable String outerCls, @Nullable String name, int accessFlags) {
|
||||
this.innerCls = innerCls;
|
||||
this.outerCls = outerCls;
|
||||
this.name = name;
|
||||
this.accessFlags = accessFlags;
|
||||
}
|
||||
|
||||
public String getInnerCls() {
|
||||
return innerCls;
|
||||
}
|
||||
|
||||
public @Nullable String getOuterCls() {
|
||||
return outerCls;
|
||||
}
|
||||
|
||||
public @Nullable String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getAccessFlags() {
|
||||
return accessFlags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "InnerCls{" + innerCls
|
||||
+ ", outerCls=" + outerCls
|
||||
+ ", name=" + name
|
||||
+ ", accessFlags=" + AccessFlags.format(accessFlags, AccessFlagsScope.CLASS)
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package jadx.api.plugins.input.data.attributes.types;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.plugins.input.data.annotations.IAnnotation;
|
||||
import jadx.api.plugins.input.data.attributes.JadxAttrType;
|
||||
import jadx.api.plugins.input.data.attributes.PinnedAttribute;
|
||||
|
||||
public class MethodParamsAttr extends PinnedAttribute {
|
||||
|
||||
@Nullable
|
||||
public static MethodParamsAttr pack(List<List<IAnnotation>> annotationRefList) {
|
||||
if (annotationRefList.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
List<AnnotationsAttr> list = new ArrayList<>(annotationRefList.size());
|
||||
for (List<IAnnotation> annList : annotationRefList) {
|
||||
list.add(AnnotationsAttr.pack(annList));
|
||||
}
|
||||
return new MethodParamsAttr(list);
|
||||
}
|
||||
|
||||
private final List<AnnotationsAttr> paramList;
|
||||
|
||||
private MethodParamsAttr(List<AnnotationsAttr> paramsList) {
|
||||
this.paramList = paramsList;
|
||||
}
|
||||
|
||||
public List<AnnotationsAttr> getParamList() {
|
||||
return paramList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JadxAttrType<MethodParamsAttr> getAttrType() {
|
||||
return JadxAttrType.ANNOTATION_MTH_PARAMETERS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return paramList.toString();
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package jadx.api.plugins.input.data.attributes.types;
|
||||
|
||||
import jadx.api.plugins.input.data.attributes.IJadxAttrType;
|
||||
import jadx.api.plugins.input.data.attributes.IJadxAttribute;
|
||||
import jadx.api.plugins.input.data.attributes.JadxAttrType;
|
||||
import jadx.api.plugins.input.data.attributes.PinnedAttribute;
|
||||
|
||||
public class SignatureAttr extends PinnedAttribute {
|
||||
|
||||
private final String signature;
|
||||
|
||||
public SignatureAttr(String signature) {
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJadxAttrType<? extends IJadxAttribute> getAttrType() {
|
||||
return JadxAttrType.SIGNATURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SIGNATURE: " + signature;
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package jadx.api.plugins.input.data.attributes.types;
|
||||
|
||||
import jadx.api.plugins.input.data.attributes.IJadxAttrType;
|
||||
import jadx.api.plugins.input.data.attributes.JadxAttrType;
|
||||
import jadx.api.plugins.input.data.attributes.PinnedAttribute;
|
||||
|
||||
public class SourceFileAttr extends PinnedAttribute {
|
||||
|
||||
private final String fileName;
|
||||
|
||||
public SourceFileAttr(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJadxAttrType<SourceFileAttr> getAttrType() {
|
||||
return JadxAttrType.SOURCE_FILE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SOURCE:" + fileName;
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package jadx.api.plugins.input.data.impl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import jadx.api.plugins.input.data.ICallSite;
|
||||
import jadx.api.plugins.input.data.IMethodHandle;
|
||||
import jadx.api.plugins.input.data.IMethodRef;
|
||||
import jadx.api.plugins.input.data.annotations.EncodedValue;
|
||||
|
||||
public class CallSite implements ICallSite {
|
||||
|
||||
private final List<EncodedValue> values;
|
||||
|
||||
public CallSite(List<EncodedValue> values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
for (EncodedValue value : values) {
|
||||
switch (value.getType()) {
|
||||
case ENCODED_METHOD_HANDLE:
|
||||
((IMethodHandle) value.getValue()).load();
|
||||
break;
|
||||
case ENCODED_METHOD:
|
||||
((IMethodRef) value.getValue()).load();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EncodedValue> getValues() {
|
||||
return values;
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package jadx.api.plugins.input.data.impl;
|
||||
|
||||
import jadx.api.plugins.input.data.ICatch;
|
||||
|
||||
public class CatchData implements ICatch {
|
||||
private final int[] addr;
|
||||
private final String[] types;
|
||||
private final int allAddr;
|
||||
|
||||
public CatchData(int[] addr, String[] types, int allAddr) {
|
||||
this.addr = addr;
|
||||
this.types = types;
|
||||
this.allAddr = allAddr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getAddresses() {
|
||||
return addr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCatchAllAddress() {
|
||||
return allAddr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder("Catch:");
|
||||
int size = types.length;
|
||||
for (int i = 0; i < size; i++) {
|
||||
sb.append(' ').append(types[i]).append("->").append(addr[i]);
|
||||
}
|
||||
if (allAddr != -1) {
|
||||
sb.append(" all->").append(allAddr);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package jadx.api.plugins.input.data.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import jadx.api.plugins.input.data.IDebugInfo;
|
||||
import jadx.api.plugins.input.data.ILocalVar;
|
||||
|
||||
public class DebugInfo implements IDebugInfo {
|
||||
|
||||
private final Map<Integer, Integer> sourceLineMap;
|
||||
private final List<ILocalVar> localVars;
|
||||
|
||||
public DebugInfo(Map<Integer, Integer> sourceLineMap, List<ILocalVar> localVars) {
|
||||
this.sourceLineMap = sourceLineMap;
|
||||
this.localVars = localVars;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, Integer> getSourceLineMapping() {
|
||||
return sourceLineMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ILocalVar> getLocalVars() {
|
||||
return localVars;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DebugInfo{lines=" + sourceLineMap + ", localVars=" + localVars + '}';
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -1,16 +1,16 @@
|
||||
package jadx.api.plugins.input.data.impl;
|
||||
|
||||
import jadx.api.plugins.input.data.IFieldData;
|
||||
import jadx.api.plugins.input.data.IFieldRef;
|
||||
import jadx.api.plugins.input.data.IMethodHandle;
|
||||
import jadx.api.plugins.input.data.IMethodRef;
|
||||
import jadx.api.plugins.input.data.MethodHandleType;
|
||||
|
||||
public class FieldRefHandle implements IMethodHandle {
|
||||
|
||||
private final IFieldData fieldRef;
|
||||
private final IFieldRef fieldRef;
|
||||
private final MethodHandleType type;
|
||||
|
||||
public FieldRefHandle(MethodHandleType type, IFieldData fieldRef) {
|
||||
public FieldRefHandle(MethodHandleType type, IFieldRef fieldRef) {
|
||||
this.fieldRef = fieldRef;
|
||||
this.type = type;
|
||||
}
|
||||
@@ -21,7 +21,7 @@ public class FieldRefHandle implements IMethodHandle {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFieldData getFieldRef() {
|
||||
public IFieldRef getFieldRef() {
|
||||
return fieldRef;
|
||||
}
|
||||
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package jadx.api.plugins.input.data.impl;
|
||||
|
||||
import jadx.api.plugins.input.data.IFieldRef;
|
||||
|
||||
public class JadxFieldRef implements IFieldRef {
|
||||
private String parentClassType;
|
||||
private String name;
|
||||
private String type;
|
||||
|
||||
public JadxFieldRef() {
|
||||
}
|
||||
|
||||
public JadxFieldRef(String parentClassType, String name, String type) {
|
||||
this.parentClassType = parentClassType;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParentClassType() {
|
||||
return parentClassType;
|
||||
}
|
||||
|
||||
public void setParentClassType(String parentClassType) {
|
||||
this.parentClassType = parentClassType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return parentClassType + "->" + name + ":" + type;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -7,12 +7,12 @@ import jadx.api.plugins.input.data.MethodHandleType;
|
||||
|
||||
public class MethodRefHandle implements IMethodHandle {
|
||||
|
||||
private final IMethodRef methodRef;
|
||||
private final MethodHandleType type;
|
||||
private final IMethodRef methodRef;
|
||||
|
||||
public MethodRefHandle(MethodHandleType type, IMethodRef methodRef) {
|
||||
this.methodRef = methodRef;
|
||||
this.type = type;
|
||||
this.methodRef = methodRef;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package jadx.api.plugins.input.data.impl;
|
||||
|
||||
import jadx.api.plugins.input.data.ICatch;
|
||||
import jadx.api.plugins.input.data.ITry;
|
||||
|
||||
public class TryData implements ITry {
|
||||
|
||||
private final int startAddr;
|
||||
private final int endAddr;
|
||||
private final ICatch catchHandler;
|
||||
|
||||
public TryData(int startAddr, int endAddr, ICatch catchHandler) {
|
||||
this.startAddr = startAddr;
|
||||
this.endAddr = endAddr;
|
||||
this.catchHandler = catchHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICatch getCatch() {
|
||||
return catchHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStartAddress() {
|
||||
return startAddr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEndAddress() {
|
||||
return endAddr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Try{" + startAddr + " - " + endAddr + ": " + catchHandler + '}';
|
||||
}
|
||||
}
|
||||
+13
-5
@@ -1,8 +1,10 @@
|
||||
package jadx.api.plugins.input.insns;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.plugins.input.data.*;
|
||||
import jadx.api.plugins.input.data.ICallSite;
|
||||
import jadx.api.plugins.input.data.IFieldRef;
|
||||
import jadx.api.plugins.input.data.IMethodHandle;
|
||||
import jadx.api.plugins.input.data.IMethodProto;
|
||||
import jadx.api.plugins.input.data.IMethodRef;
|
||||
import jadx.api.plugins.input.insns.custom.ICustomPayload;
|
||||
|
||||
public interface InsnData {
|
||||
@@ -25,6 +27,13 @@ public interface InsnData {
|
||||
|
||||
int getReg(int argNum);
|
||||
|
||||
/**
|
||||
* Workaround to set result reg without additional move-result insn
|
||||
*
|
||||
* @return result reg number or -1 if not needed
|
||||
*/
|
||||
int getResultReg();
|
||||
|
||||
long getLiteral();
|
||||
|
||||
int getTarget();
|
||||
@@ -35,7 +44,7 @@ public interface InsnData {
|
||||
|
||||
String getIndexAsType();
|
||||
|
||||
IFieldData getIndexAsField();
|
||||
IFieldRef getIndexAsField();
|
||||
|
||||
IMethodRef getIndexAsMethod();
|
||||
|
||||
@@ -45,6 +54,5 @@ public interface InsnData {
|
||||
|
||||
IMethodHandle getIndexAsMethodHandle();
|
||||
|
||||
@Nullable
|
||||
ICustomPayload getPayload();
|
||||
}
|
||||
|
||||
+2
-1
@@ -5,5 +5,6 @@ public enum InsnIndexType {
|
||||
TYPE_REF,
|
||||
STRING_REF,
|
||||
FIELD_REF,
|
||||
METHOD_REF
|
||||
METHOD_REF,
|
||||
CALL_SITE
|
||||
}
|
||||
|
||||
+3
-5
@@ -17,6 +17,7 @@ public enum Opcode {
|
||||
AGET,
|
||||
AGET_BOOLEAN,
|
||||
AGET_BYTE,
|
||||
AGET_BYTE_BOOLEAN,
|
||||
AGET_CHAR,
|
||||
AGET_OBJECT,
|
||||
AGET_SHORT,
|
||||
@@ -25,6 +26,7 @@ public enum Opcode {
|
||||
APUT,
|
||||
APUT_BOOLEAN,
|
||||
APUT_BYTE,
|
||||
APUT_BYTE_BOOLEAN,
|
||||
APUT_CHAR,
|
||||
APUT_OBJECT,
|
||||
APUT_SHORT,
|
||||
@@ -40,8 +42,6 @@ public enum Opcode {
|
||||
CMPG_FLOAT,
|
||||
CMPL_DOUBLE,
|
||||
CMPL_FLOAT,
|
||||
CMP_G,
|
||||
CMP_L,
|
||||
CMP_LONG,
|
||||
|
||||
CONST,
|
||||
@@ -112,6 +112,7 @@ public enum Opcode {
|
||||
MONITOR_EXIT,
|
||||
|
||||
MOVE,
|
||||
MOVE_MULTI,
|
||||
MOVE_EXCEPTION,
|
||||
MOVE_OBJECT,
|
||||
MOVE_RESULT,
|
||||
@@ -130,7 +131,6 @@ public enum Opcode {
|
||||
NEG_LONG,
|
||||
NEW_INSTANCE,
|
||||
|
||||
NOT,
|
||||
NOT_INT,
|
||||
NOT_LONG,
|
||||
|
||||
@@ -172,11 +172,9 @@ public enum Opcode {
|
||||
|
||||
FILLED_NEW_ARRAY,
|
||||
FILLED_NEW_ARRAY_RANGE,
|
||||
FILL_ARRAY,
|
||||
FILL_ARRAY_DATA,
|
||||
FILL_ARRAY_DATA_PAYLOAD,
|
||||
|
||||
SWITCH,
|
||||
PACKED_SWITCH,
|
||||
PACKED_SWITCH_PAYLOAD,
|
||||
SPARSE_SWITCH,
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package jadx.api.plugins.input.insns.custom.impl;
|
||||
|
||||
import jadx.api.plugins.input.insns.custom.ISwitchPayload;
|
||||
|
||||
public class SwitchPayload implements ISwitchPayload {
|
||||
|
||||
private final int size;
|
||||
private final int[] keys;
|
||||
private final int[] targets;
|
||||
|
||||
public SwitchPayload(int size, int[] keys, int[] targets) {
|
||||
this.size = size;
|
||||
this.keys = keys;
|
||||
this.targets = targets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getKeys() {
|
||||
return keys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getTargets() {
|
||||
return targets;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package jadx.api.plugins.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class Utils {
|
||||
|
||||
public static <T> void addToList(List<T> list, @Nullable T item) {
|
||||
if (item != null) {
|
||||
list.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T, I> void addToList(List<T> list, @Nullable I item, Function<I, T> map) {
|
||||
if (item != null) {
|
||||
T value = map.apply(item);
|
||||
if (value != null) {
|
||||
list.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> List<T> concat(List<T> a, List<T> b) {
|
||||
int aSize = a.size();
|
||||
int bSize = b.size();
|
||||
if (aSize == 0 && bSize == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (aSize == 0) {
|
||||
return b;
|
||||
}
|
||||
if (bSize == 0) {
|
||||
return a;
|
||||
}
|
||||
List<T> list = new ArrayList<>(aSize + bSize);
|
||||
list.addAll(a);
|
||||
list.addAll(b);
|
||||
return list;
|
||||
}
|
||||
|
||||
public static <T> String listToStr(List<T> list) {
|
||||
if (list == null) {
|
||||
return "null";
|
||||
}
|
||||
if (list.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
if (list.size() == 1) {
|
||||
return Objects.toString(list.get(0));
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Iterator<T> it = list.iterator();
|
||||
sb.append(it.next());
|
||||
while (it.hasNext()) {
|
||||
sb.append(", ").append(it.next());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String formatOffset(int offset) {
|
||||
return String.format("0x%04x", offset);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user