@Test
 public void testSetter() throws Exception {
   CtClass mock = new WicketMockClassFactory(Date.class).getMock();
   assertNotNull(
       mock.getMethod(
           "setSeconds",
           Descriptor.ofMethod(
               voidType, new CtClass[] {ClassPool.getDefault().get(Object.class.getName())})));
 }
예제 #2
0
  private void initExtraHarvest() {
    try {
      CtClass terraForming =
          HookManager.getInstance()
              .getClassPool()
              .get("com.wurmonline.server.behaviours.Terraforming");

      CtClass[] paramTypes = {
        HookManager.getInstance().getClassPool().get("com.wurmonline.server.creatures.Creature"),
        CtPrimitiveType.intType,
        CtPrimitiveType.intType,
        CtPrimitiveType.booleanType,
        CtPrimitiveType.intType,
        CtPrimitiveType.floatType,
        HookManager.getInstance().getClassPool().get("com.wurmonline.server.items.Item")
      };

      CtMethod method =
          terraForming.getMethod(
              "harvest", Descriptor.ofMethod(CtPrimitiveType.booleanType, paramTypes));
      MethodInfo methodInfo = method.getMethodInfo();
      CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
      CodeIterator codeIterator = codeAttribute.iterator();

      LocalVariableAttribute attr =
          (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
      int quantityIndex = -1;
      for (int i = 0; i < attr.tableLength(); i++) {
        if ("quantity".equals(attr.variableName(i))) {
          quantityIndex = attr.index(i);
        }
      }

      if (quantityIndex == -1) {
        throw new HookException("Quantity variable can not be resolved");
      }

      while (codeIterator.hasNext()) {
        int pos = codeIterator.next();
        int op = codeIterator.byteAt(pos);
        if (op == CodeIterator.ISTORE) {
          int fieldRefIdx = codeIterator.byteAt(pos + 1);
          if (quantityIndex == fieldRefIdx) {
            Bytecode bytecode = new Bytecode(codeIterator.get().getConstPool());
            bytecode.addIconst(extraHarvest);
            bytecode.add(Bytecode.IADD);
            codeIterator.insertAt(pos, bytecode.get());
            break;
          }
        }
      }
    } catch (NotFoundException | BadBytecode e) {
      throw new HookException(e);
    }
  }
예제 #3
0
  /**
   * Creates a CtClass object representing the specified class. It first examines whether or not the
   * corresponding class file exists. If yes, it creates a CtClass object.
   *
   * @return null if the class file could not be found.
   */
  protected CtClass createCtClass(String classname, boolean useCache) {
    // accept "[L<class name>;" as a class name.
    if (classname.charAt(0) == '[') classname = Descriptor.toClassName(classname);

    if (classname.endsWith("[]")) {
      String base = classname.substring(0, classname.indexOf('['));
      if ((!useCache || getCached(base) == null) && find(base) == null) return null;
      else return new CtArray(classname, this);
    } else if (find(classname) == null) return null;
    else return new CtClassType(classname, this);
  }
예제 #4
0
 public static String describe(Type t) {
   if (t instanceof Class<?>) {
     return Descriptor.of(((Class) t).getName());
   } else if (t instanceof ParameterizedType) {
     ParameterizedType pType = ((ParameterizedType) t);
     Type[] args = pType.getActualTypeArguments();
     StringBuilder formatted = new StringBuilder();
     for (Type type : args) {
       formatted.append(describe(type));
     }
     return parameterized((Class) pType.getRawType()).ofFormatted(formatted.toString()).build();
   }
   return "";
 }
예제 #5
0
  public BaseClassData(Class<?> cls) {
    className = cls.getName();
    internalName = Descriptor.toJvmName(cls.getName());
    this.loader = cls.getClassLoader();
    replaceable = false;
    if (cls.getSuperclass() != null) {
      superClassName = cls.getSuperclass().getName();
    } else {
      superClassName = null;
    }
    Set<MethodData> meths = new HashSet<MethodData>();
    for (Method m : cls.getDeclaredMethods()) {
      MemberType type = MemberType.NORMAL;
      final String descriptor = DescriptorUtils.getDescriptor(m);
      if ((descriptor.equals(Constants.ADDED_METHOD_DESCRIPTOR)
              && m.getName().equals(Constants.ADDED_METHOD_NAME))
          || (descriptor.equals(Constants.ADDED_STATIC_METHOD_DESCRIPTOR)
              && m.getName().equals(Constants.ADDED_STATIC_METHOD_NAME))) {
        type = MemberType.ADDED_SYSTEM;
      }
      MethodData md =
          new MethodData(m.getName(), descriptor, cls.getName(), type, m.getModifiers(), false);
      meths.add(md);
    }
    for (Constructor<?> c : cls.getDeclaredConstructors()) {
      MemberType type = MemberType.NORMAL;
      final String descriptor = DescriptorUtils.getDescriptor(c);
      if (descriptor.equals(Constants.ADDED_CONSTRUCTOR_DESCRIPTOR)) {
        type = MemberType.ADDED_SYSTEM;
      }
      MethodData md =
          new MethodData("<init>", descriptor, cls.getName(), type, c.getModifiers(), false);
      meths.add(md);
    }

    this.methods = Collections.unmodifiableSet(meths);
    Set<FieldData> fieldData = new HashSet<FieldData>();
    for (Field m : cls.getDeclaredFields()) {
      fieldData.add(new FieldData(m));
    }
    this.fields = Collections.unmodifiableSet(fieldData);
  }
예제 #6
0
  public BaseClassData(ClassFile file, ClassLoader loader, boolean replaceable) {
    className = file.getName();
    this.replaceable = replaceable;
    internalName = Descriptor.toJvmName(file.getName());
    this.loader = loader;
    superClassName = file.getSuperclass();
    boolean finalMethod = false;
    Set<MethodData> meths = new HashSet<MethodData>();
    for (Object o : file.getMethods()) {
      String methodClassName = className;
      MethodInfo m = (MethodInfo) o;
      MemberType type = MemberType.NORMAL;
      if ((m.getDescriptor().equals(Constants.ADDED_METHOD_DESCRIPTOR)
              && m.getName().equals(Constants.ADDED_METHOD_NAME))
          || (m.getDescriptor().equals(Constants.ADDED_STATIC_METHOD_DESCRIPTOR)
              && m.getName().equals(Constants.ADDED_STATIC_METHOD_NAME))
          || (m.getDescriptor().equals(Constants.ADDED_CONSTRUCTOR_DESCRIPTOR))) {
        type = MemberType.ADDED_SYSTEM;
      } else if (m.getAttribute(Constants.FINAL_METHOD_ATTRIBUTE) != null) {
        finalMethod = true;
      }

      MethodData md =
          new MethodData(
              m.getName(),
              m.getDescriptor(),
              methodClassName,
              type,
              m.getAccessFlags(),
              finalMethod);
      meths.add(md);
    }
    this.methods = Collections.unmodifiableSet(meths);
    Set<FieldData> fieldData = new HashSet<FieldData>();
    for (Object o : file.getFields()) {
      FieldInfo m = (FieldInfo) o;
      MemberType mt = MemberType.NORMAL;
      fieldData.add(new FieldData(m, mt, className, m.getAccessFlags()));
    }
    this.fields = Collections.unmodifiableSet(fieldData);
  }
예제 #7
0
  private Set<CtMethod> getPatchMethods(Set<CtClass> patchClasses) {
    Set<CtMethod> result = new HashSet<CtMethod>();

    // add all @PatchMethod found in a temporary map
    Map<String, List<CtMethod>> temp = new HashMap<String, List<CtMethod>>();
    for (CtClass patchClass : patchClasses) {
      for (CtMethod ctMethod : patchClass.getDeclaredMethods()) {
        if (ctMethod.hasAnnotation(PatchMethod.class)) {
          if (!Modifier.isStatic(ctMethod.getModifiers())) {
            throw new GwtTestPatchException(
                "@"
                    + PatchMethod.class.getName()
                    + " has to be static : '"
                    + ctMethod.getLongName()
                    + "'");
          }
          String nameAndSignature =
              ctMethod.getName() + Descriptor.toString(ctMethod.getSignature());
          List<CtMethod> correspondingMethods = temp.get(nameAndSignature);

          if (correspondingMethods == null) {
            correspondingMethods = new ArrayList<CtMethod>();
            temp.put(nameAndSignature, correspondingMethods);
          }

          correspondingMethods.add(ctMethod);
        }
      }
    }

    // for each @PatchMethod with the same signature, filter to get one with
    // override=true
    for (Map.Entry<String, List<CtMethod>> entry : temp.entrySet()) {
      CtMethod methodToUse = getMethodToUse(entry.getValue(), PatchMethod.class);
      methodToUse.setModifiers(Modifier.PUBLIC + Modifier.STATIC);
      result.add(methodToUse);
    }

    return result;
  }
예제 #8
0
  @Override
  public void init() {
    //
    // We initialize a method hook that gets called right before CropTilePoller.checkForFarmGrowth
    // is called
    //
    if (disableWeeds) {
      try {

        //
        // To make sure we hook the correct method the list of method parameter types is compiled
        //
        CtClass[] paramTypes = {
          CtPrimitiveType.intType,
          CtPrimitiveType.intType,
          CtPrimitiveType.intType,
          CtPrimitiveType.byteType,
          CtPrimitiveType.byteType,
          HookManager.getInstance().getClassPool().get("com.wurmonline.mesh.MeshIO"),
          CtPrimitiveType.booleanType
        };

        //
        // next we register the hook for
        // com.wurmonline.server.zones.CropTilePoller.checkForFarmGrowth(int, int, int, byte, byte,
        // MeshIO, boolean)
        //
        HookManager.getInstance()
            .registerHook(
                "com.wurmonline.server.zones.CropTilePoller",
                "checkForFarmGrowth",
                Descriptor.ofMethod(CtPrimitiveType.voidType, paramTypes),
                new InvocationHandlerFactory() {

                  @Override
                  public InvocationHandler createInvocationHandler() {
                    return new InvocationHandler() {

                      //
                      // The actual hook is an InvocationHandler. It's invoke method is called
                      // instead of the hooked method.
                      // The object, method and arguments are passed as parameters to invoke()
                      //
                      @Override
                      public Object invoke(Object object, Method method, Object[] args)
                          throws Throwable {
                        //
                        // When the hook is called we can do stuff depending on the input parameters
                        // Here we check if the tileAge is 6 (the second ripe stage)
                        //
                        byte aData = ((Number) args[4]).byteValue();
                        final int tileState = aData >> 4;
                        int tileAge = tileState & 0x7;
                        if (tileAge == 6) {
                          // tileAge is 6. Advancing it further would create weeds.
                          // Therefore we just exit here.
                          // return null is required if the hooked method has a void return type
                          return null;
                        }

                        //
                        // tileAge is not 6. We just continue by calling the hooked method
                        //
                        return method.invoke(object, args);
                      }
                    };
                  }
                });
      } catch (NotFoundException e) {
        throw new HookException(e);
      }
    }
  }
 @Test(expected = NotFoundException.class)
 public void testFinalField() throws Exception {
   CtClass mock = new WicketMockClassFactory(FieldContainer.class).getMock();
   mock.getMethod("setField", Descriptor.ofMethod(voidType, new CtClass[] {intType}));
 }
 @Test(expected = Test.None.class)
 public void testField() throws Exception {
   CtClass mock = new WicketMockClassFactory(FieldContainer.class).getMock();
   mock.getMethod("getNonFinalField", Descriptor.ofMethod(OBJECT_CLASS, new CtClass[] {}));
   mock.getMethod("setNonFinalField", Descriptor.ofMethod(voidType, new CtClass[] {intType}));
 }
예제 #11
0
 /**
  * Returns a <code>CtClass</code> object with the given name. This is almost equivalent to <code>
  * get(String)</code> except that classname can be an array-type "descriptor" (an encoded type
  * name) such as <code>[Ljava/lang/Object;</code>.
  *
  * <p>Using this method is not recommended; this method should be used only to obtain the <code>
  * CtClass</code> object with a name returned from <code>getClassInfo</code> in <code>
  * javassist.bytecode.ClassPool</code>. <code>getClassInfo</code> returns a fully-qualified class
  * name but, if the class is an array type, it returns a descriptor.
  *
  * @param classname a fully-qualified class name or a descriptor representing an array type.
  * @see #get(String)
  * @see javassist.bytecode.ConstPool#getClassInfo(int)
  * @see javassist.bytecode.Descriptor#toCtClass(String, ClassPool)
  * @since 3.8.1
  */
 public CtClass getCtClass(String classname) throws NotFoundException {
   if (classname.charAt(0) == '[') return Descriptor.toCtClass(classname, this);
   else return get(classname);
 }
예제 #12
0
 public static ClassNameBuilder parameterized(Class<?> clazz) {
   return new ClassNameBuilder(Descriptor.of(clazz.getName()));
 }
예제 #13
0
 ClassNameBuilder of(Class<?> clazz) {
   return new ClassNameBuilder(prune(this.name) + "<" + Descriptor.of(clazz.getName()) + ">;");
 }
예제 #14
0
 @Test
 public void nullDescriptor() {
   String nullDescriptor = Descriptor.ofParameters(null);
   logger.info("Descript null:{}", nullDescriptor);
 }
 public MethodAdapter(MethodVisitor mv, boolean add, CtClass target) {
   super(mv);
   addSynchronized = add;
   this.target = target;
   targetOwner = Descriptor.toJvmName(target.getName());
 }