下面列出了org.objectweb.asm.Opcodes# ACC_NATIVE 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* {@inheritDoc}
*/
public MethodManifestation getMethodManifestation() {
int modifiers = getModifiers();
switch (modifiers & (Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_FINAL | Opcodes.ACC_BRIDGE)) {
case Opcodes.ACC_NATIVE | Opcodes.ACC_FINAL:
return MethodManifestation.FINAL_NATIVE;
case Opcodes.ACC_NATIVE:
return MethodManifestation.NATIVE;
case Opcodes.ACC_FINAL:
return MethodManifestation.FINAL;
case Opcodes.ACC_BRIDGE:
return MethodManifestation.BRIDGE;
case Opcodes.ACC_BRIDGE | Opcodes.ACC_FINAL:
return MethodManifestation.FINAL_BRIDGE;
case Opcodes.ACC_ABSTRACT:
return MethodManifestation.ABSTRACT;
case EMPTY_MASK:
return MethodManifestation.PLAIN;
default:
throw new IllegalStateException("Unexpected modifiers: " + modifiers);
}
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
boolean skip = skipEnchancing || null == classInfo || mv == null
|| (access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) > 0 || "<init>".equals(name)
|| !classInfo.isContinuableMethod(access, name, desc, signature);
if (skip) {
return mv;
} else {
return new ContinuableMethodNode(
access, name, desc, signature, exceptions,
className, classHierarchy, cciResolver, mv
);
}
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
boolean skip = skipEnchancing || null == classInfo || mv == null
|| (access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) > 0 || "<init>".equals(name)
|| !classInfo.isContinuableMethod(access, name, desc, signature);
if (skip) {
return mv;
} else {
return new ContinuableMethodNode(
access, name, desc, signature, exceptions,
className, classHierarchy, cciResolver, mv
);
}
}
@Override
public MethodVisitor visitMethod(
final int access,
final String name,
final String descriptor,
final String signature,
final String[] exceptions) {
// Get constructor and method information (step 5 and 7). Also determine if there is a class
// initializer (step 6).
if (computeSvuid) {
if (CLINIT.equals(name)) {
hasStaticInitializer = true;
}
// Collect the non private constructors and methods. Only the ACC_PUBLIC, ACC_PRIVATE,
// ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT and
// ACC_STRICT flags are used.
int mods =
access
& (Opcodes.ACC_PUBLIC
| Opcodes.ACC_PRIVATE
| Opcodes.ACC_PROTECTED
| Opcodes.ACC_STATIC
| Opcodes.ACC_FINAL
| Opcodes.ACC_SYNCHRONIZED
| Opcodes.ACC_NATIVE
| Opcodes.ACC_ABSTRACT
| Opcodes.ACC_STRICT);
if ((access & Opcodes.ACC_PRIVATE) == 0) {
if ("<init>".equals(name)) {
svuidConstructors.add(new Item(name, mods, descriptor));
} else if (!CLINIT.equals(name)) {
svuidMethods.add(new Item(name, mods, descriptor));
}
}
}
return super.visitMethod(access, name, descriptor, signature, exceptions);
}
@Override
public void process(ProcessorCallback callback, ClassNode node) {
if (!enabled.getObject()) return;
if ((node.access & Opcodes.ACC_INTERFACE) == 0) {
for (MethodNode method : node.methods) {
// if ((method.access & Opcodes.ACC_BRIDGE) == 0 && (method.access & Opcodes.ACC_STATIC) == 0 && !method.name.startsWith("<")) {
// method.access |= Opcodes.ACC_BRIDGE;
// }
// if ((method.access & Opcodes.ACC_SYNTHETIC) == 0) {
if (method.name.startsWith("<"))
continue;
if ((method.access & Opcodes.ACC_NATIVE) == 0) {
continue;
}
method.access = method.access | Opcodes.ACC_BRIDGE;
method.access = method.access | Opcodes.ACC_SYNTHETIC;
// }
}
}
for (FieldNode field : node.fields) {
// if ((field.access & Opcodes.ACC_FINAL) == 0)
field.access = field.access | Opcodes.ACC_SYNTHETIC;
}
// if ((node.access & Opcodes.ACC_FINAL) == 0) {
// node.access = node.access | Opcodes.ACC_SYNTHETIC;
// }
inst.setWorkDone();
}
@Override
public MethodVisitor visitMethod(
final int access,
final String name,
final String descriptor,
final String signature,
final String[] exceptions) {
// Get constructor and method information (step 5 and 7). Also determine if there is a class
// initializer (step 6).
if (computeSvuid) {
if (CLINIT.equals(name)) {
hasStaticInitializer = true;
}
// Collect the non private constructors and methods. Only the ACC_PUBLIC, ACC_PRIVATE,
// ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT and
// ACC_STRICT flags are used.
int mods =
access
& (Opcodes.ACC_PUBLIC
| Opcodes.ACC_PRIVATE
| Opcodes.ACC_PROTECTED
| Opcodes.ACC_STATIC
| Opcodes.ACC_FINAL
| Opcodes.ACC_SYNCHRONIZED
| Opcodes.ACC_NATIVE
| Opcodes.ACC_ABSTRACT
| Opcodes.ACC_STRICT);
if ((access & Opcodes.ACC_PRIVATE) == 0) {
if ("<init>".equals(name)) {
svuidConstructors.add(new Item(name, mods, descriptor));
} else if (!CLINIT.equals(name)) {
svuidMethods.add(new Item(name, mods, descriptor));
}
}
}
return super.visitMethod(access, name, descriptor, signature, exceptions);
}
/**
* @param calledClassSet
* @param mBuilder
* @param methodName
* @param access
* @param methodDesc
* @param cBuilder
*/
private ClassParserMethodVisitor(TreeSet<ClassDescriptor> calledClassSet,
MethodInfo.Builder mBuilder, String methodName, int access,
String methodDesc, ClassNameAndSuperclassInfo.Builder cBuilder) {
this.calledClassSet = calledClassSet;
this.mBuilder = mBuilder;
this.methodName = methodName;
this.access = access;
this.methodDesc = methodDesc;
this.cBuilder = cBuilder;
sawReturn = (access & Opcodes.ACC_NATIVE) != 0;
isBridge = (access & Opcodes.ACC_SYNTHETIC) != 0 && (access & Opcodes.ACC_BRIDGE) != 0;
isAccessMethod = methodName.startsWith("access$");
}
private boolean instrument(String name, String signature, int access) {
return
(access & Opcodes.ACC_ABSTRACT) == 0 &&
(access & Opcodes.ACC_BRIDGE) == 0 &&
(access & Opcodes.ACC_NATIVE) == 0 &&
(isEntryPoint(name, signature) || isExitPoint(name, signature));
}
@Override
public void obfuscate() {
int stringLength = 5;//getStringLength();
System.out.println("Obfuscating class names...");
classLoop:
for (ClassNode c : BytecodeViewer.getLoadedClasses()) {
/** As we dont want to rename classes that contain native dll methods */
for (Object o : c.methods) {
MethodNode m = (MethodNode) o;
/** As we dont want to rename any main-classes */
if (m.name.equals("main") && m.desc.equals("([Ljava/lang/String;)V")
|| m.name.equals("init") && c.superName.equals("java/applet/Applet"))
continue classLoop;
/* As we dont want to rename native dll methods */
if ((m.access & Opcodes.ACC_NATIVE) != 0)
continue classLoop;
}
String newName = generateUniqueName(stringLength);
BytecodeViewer.refactorer.getHooks().addClass(new MappingData(c.name, newName));
/*ASMUtil_OLD.renameClassNode(c.name, newName);
c.name = newName;*/
}
System.out.println("Obfuscated class names.");
}
@Override
public MethodVisitor visitMethod(
final int access,
final String name,
final String descriptor,
final String signature,
final String[] exceptions) {
// Get constructor and method information (step 5 and 7). Also determine if there is a class
// initializer (step 6).
if (computeSVUID) {
if (CLINIT.equals(name)) {
hasStaticInitializer = true;
}
// Collect the non private constructors and methods. Only the ACC_PUBLIC, ACC_PRIVATE,
// ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT and
// ACC_STRICT flags are used.
int mods =
access
& (Opcodes.ACC_PUBLIC
| Opcodes.ACC_PRIVATE
| Opcodes.ACC_PROTECTED
| Opcodes.ACC_STATIC
| Opcodes.ACC_FINAL
| Opcodes.ACC_SYNCHRONIZED
| Opcodes.ACC_NATIVE
| Opcodes.ACC_ABSTRACT
| Opcodes.ACC_STRICT);
if ((access & Opcodes.ACC_PRIVATE) == 0) {
if ("<init>".equals(name)) {
svuidConstructors.add(new Item(name, mods, descriptor));
} else if (!CLINIT.equals(name)) {
svuidMethods.add(new Item(name, mods, descriptor));
}
}
}
return super.visitMethod(access, name, descriptor, signature, exceptions);
}
/**
* {@inheritDoc}
*/
public int getModifiers() {
return Opcodes.ACC_SYNTHETIC
| (methodDescription.isStatic() ? Opcodes.ACC_STATIC : EMPTY_MASK)
| (methodDescription.isNative() ? Opcodes.ACC_NATIVE : EMPTY_MASK)
| (instrumentedType.isInterface() ? Opcodes.ACC_PUBLIC : Opcodes.ACC_PRIVATE);
}
@Override
public Textifier visitMethod(
final int access,
final String name,
final String descriptor,
final String signature,
final String[] exceptions) {
stringBuilder.setLength(0);
stringBuilder.append('\n');
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
stringBuilder.append(tab).append(DEPRECATED);
}
stringBuilder.append(tab);
appendRawAccess(access);
if (signature != null) {
stringBuilder.append(tab);
appendDescriptor(METHOD_SIGNATURE, signature);
stringBuilder.append(tab);
appendJavaDeclaration(name, signature);
}
stringBuilder.append(tab);
appendAccess(access & ~(Opcodes.ACC_VOLATILE | Opcodes.ACC_TRANSIENT));
if ((access & Opcodes.ACC_NATIVE) != 0) {
stringBuilder.append("native ");
}
if ((access & Opcodes.ACC_VARARGS) != 0) {
stringBuilder.append("varargs ");
}
if ((access & Opcodes.ACC_BRIDGE) != 0) {
stringBuilder.append("bridge ");
}
if ((this.access & Opcodes.ACC_INTERFACE) != 0
&& (access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_STATIC)) == 0) {
stringBuilder.append("default ");
}
stringBuilder.append(name);
appendDescriptor(METHOD_DESCRIPTOR, descriptor);
if (exceptions != null && exceptions.length > 0) {
stringBuilder.append(" throws ");
for (String exception : exceptions) {
appendDescriptor(INTERNAL_NAME, exception);
stringBuilder.append(' ');
}
}
stringBuilder.append('\n');
text.add(stringBuilder.toString());
return addNewTextifier(null);
}
@Override
public String preProcess(MethodContext context) {
context.proxyMethod = context.method;
context.method.access |= Opcodes.ACC_NATIVE;
return "native_" + context.method.name + context.methodIndex;
}
static String toModifier(int access, boolean hasDefault) {
StringBuilder sb = new StringBuilder(7);
if ((Opcodes.ACC_PRIVATE & access) > 0) {
sb.append("private ");
}
if ((Opcodes.ACC_PUBLIC & access) > 0) {
sb.append("public ");
}
if ((Opcodes.ACC_PROTECTED & access) > 0) {
sb.append("protected ");
}
if ((Opcodes.ACC_STATIC & access) > 0) {
sb.append("static ");
}
if ((Opcodes.ACC_ABSTRACT & access) > 0) {
sb.append("abstract ");
}
if ((Opcodes.ACC_FINAL & access) > 0) {
sb.append("final ");
}
if ((Opcodes.ACC_INTERFACE & access) > 0) {
sb.append("interface ");
}
if ((Opcodes.ACC_NATIVE & access) > 0) {
sb.append("native ");
}
if ((Opcodes.ACC_STRICT & access) > 0) {
sb.append("strict ");
}
if ((Opcodes.ACC_SYNCHRONIZED & access) > 0) {
sb.append("synchronized ");
}
if (hasDefault) {
sb.append("default ");
}
if (sb.length() > 0) {
sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
}
private boolean instrument(int access) {
return
(access & Opcodes.ACC_ABSTRACT) == 0 &&
(access & Opcodes.ACC_BRIDGE) == 0 &&
(access & Opcodes.ACC_NATIVE) == 0;
}
private static boolean standardMethod(int access, boolean isStatic) {
return (access & Opcodes.ACC_NATIVE) == 0 && (access & Opcodes.ACC_ABSTRACT) == 0 && (access & Opcodes.ACC_STATIC)==(isStatic?Opcodes.ACC_STATIC:0);
}
private boolean instrument(int access) {
return (access & Opcodes.ACC_ABSTRACT) == 0
&& (access & Opcodes.ACC_BRIDGE) == 0
&& (access & Opcodes.ACC_NATIVE) == 0;
}
private boolean instrument(int access) {
return (access & Opcodes.ACC_ABSTRACT) == 0 && (access & Opcodes.ACC_BRIDGE) == 0 && (access & Opcodes.ACC_NATIVE) == 0;
}
/**
* Utility method to get the access modifiers of a Host
* @param modVal The bitset representation of the Host's modifiers
* @param host The Host (SootClass, SootField or SootMethod) the modifiers are to be retrieved from
* @return A bitset representation of the Host's modifiers in ASM's internal representation
*/
protected static int getModifiers(int modVal, Host host) {
int modifier = 0;
// Retrieve visibility-modifier
if (Modifier.isPublic(modVal)) {
modifier |= Opcodes.ACC_PUBLIC;
} else if (Modifier.isPrivate(modVal)) {
modifier |= Opcodes.ACC_PRIVATE;
} else if (Modifier.isProtected(modVal)) {
modifier |= Opcodes.ACC_PROTECTED;
}
// Retrieve static-modifier
if (Modifier.isStatic(modVal)
&& ((host instanceof SootField) || (host instanceof SootMethod))) {
modifier |= Opcodes.ACC_STATIC;
}
// Retrieve final-modifier
if (Modifier.isFinal(modVal)) {
modifier |= Opcodes.ACC_FINAL;
}
// Retrieve synchronized-modifier
if (Modifier.isSynchronized(modVal) && host instanceof SootMethod) {
modifier |= Opcodes.ACC_SYNCHRONIZED;
}
// Retrieve volatile/bridge-modifier
if (Modifier.isVolatile(modVal) && !(host instanceof SootClass)) {
modifier |= Opcodes.ACC_VOLATILE;
}
// Retrieve transient/varargs-modifier
if (Modifier.isTransient(modVal) && !(host instanceof SootClass)) {
modifier |= Opcodes.ACC_TRANSIENT;
}
// Retrieve native-modifier
if (Modifier.isNative(modVal) && host instanceof SootMethod) {
modifier |= Opcodes.ACC_NATIVE;
}
// Retrieve interface-modifier
if (Modifier.isInterface(modVal) && host instanceof SootClass) {
modifier |= Opcodes.ACC_INTERFACE;
} else if (host instanceof SootClass) {
/*
* For all classes except for interfaces the super-flag should be
* set. See JVM 8-Specification section 4.1, page 72.
*/
modifier |= Opcodes.ACC_SUPER;
}
// Retrieve abstract-modifier
if (Modifier.isAbstract(modVal) && !(host instanceof SootField)) {
modifier |= Opcodes.ACC_ABSTRACT;
}
// Retrieve strictFP-modifier
if (Modifier.isStrictFP(modVal) && host instanceof SootMethod) {
modifier |= Opcodes.ACC_STRICT;
}
/*
* Retrieve synthetic-modifier. Class not present in source-code but
* generated by e.g. compiler TODO Do we need both checks?
*/
if (Modifier.isSynthetic(modVal) || host.hasTag("SyntheticTag")) {
modifier |= Opcodes.ACC_SYNTHETIC;
}
// Retrieve annotation-modifier
if (Modifier.isAnnotation(modVal) && host instanceof SootClass) {
modifier |= Opcodes.ACC_ANNOTATION;
}
// Retrieve enum-modifier
if (Modifier.isEnum(modVal) && !(host instanceof SootMethod)) {
modifier |= Opcodes.ACC_ENUM;
}
return modifier;
}
/**
* Defines when a method access flags are compatible with InstantRun technology.
* <p>
* - If the method is a bridge method, we do not enable it for instantReload.
* it is most likely only calling a twin method (same name, same parameters).
* - if the method is abstract or native, we don't add a redirection.
*
* @param access the method access flags
* @return true if the method should be InstantRun enabled, false otherwise.
*/
protected static boolean isAccessCompatibleWithStark(int access) {
return (access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_BRIDGE | Opcodes.ACC_NATIVE)) == 0;
}