Skip to content

CWrapCondition

Lenni0451 edited this page Mar 17, 2024 · 1 revision

The CWrapCondition annotation is used to wrap a method call or field put with a condition (if statement).
The return value of the transformer method is used to evaluate the condition.
Only wrapping void methods and field puts are supported.

Targets

The target field of the CWrapCondition annotation specifies the redirected method/field.
Check out the CTarget page for more information about the different targets.
Also, check out CSlice for more information about how slices work.

Method signature

When injecting into a static method, the transformer method also needs to be static and vice versa.
The return type of the transformer method needs to be boolean.

Wrapping a method call

When wrapping a method call, the parameters of the transformer method need to be:

  • The instance of the target class, if the method is not static
  • The parameters of the target method The return type of the target method needs to be void.
//Wrapping a static method call in a non-static method
@CWrapCondition(target = @CTarget(value = "INVOKE", target = "Ljava/lang/String;valueOf(I)Ljava/lang/String;"), ...)
public boolean transform(final int i)

//Wrapping a non-static method call in a static method
@CWrapCondition(target = @CTarget(value = "INVOKE", target = "Ljava/lang/String;substring(I)Ljava/lang/String;"), ...)
public static boolean transform(final String instance, final int i)

Wrapping a field put

When wrapping a field put, the parameters of the transformer method need to be:

  • The instance of the target class, if the field is not static
  • The new value of the field
//Wrapping a static field put in a non-static method
@CWrapCondition(target = @CTarget(value = "PUTSTATIC", target = "Ljava/lang/System;out:Ljava/io/PrintStream;"), ...)
public boolean transform(final PrintStream out)

//Wrapping a non-static field put in a static method
@CWrapCondition(target = @CTarget(value = "PUTFIELD", target = "Ljava/lang/String;value:Ljava/lang/String;"), ...)
public static boolean transform(final String instance, final String value)

Targets

The target field of the CWrapCondition annotation specifies the wrapped method/field.
Check out the CTarget page for more information about the different targets.
Also, check out CSlice for more information about how slices work.

Targeting multiple methods

The method field can be an array of strings to target multiple methods.
The transformer method needs to be compatible with all targeted methods.

@CWrapCondition(value = {"method1", "method2"}, ...)
public boolean transform(final String s)

Examples

Original method:

public void method() {
    this.oldOut = System.out;
    System.setOut(null);
}

Wrapping a method call

Transformer method:

@CWrapCondition(method = "method", target = @CTarget(value = "INVOKE", target = "Ljava/lang/System;setOut(Ljava/io/PrintStream;)V"))
public boolean transform(final PrintStream out) {
    return out == null;
}

Injected code:

public void method() {
    this.oldOut = System.out;
    PrintStream printStream = null;
    if (this.transform(printStream)) {
        System.setOut(printStream);
    }
}

Wrapping a field put

Transformer method:

@CWrapCondition(method = "method", target = @CTarget(value = "PUTSTATIC", target = "Ljava/lang/System;out:Ljava/io/PrintStream;"))
public boolean transform(final PrintStream out) {
    return out != null;
}

Injected code:

public void method() {
    PrintStream printStream = System.out;
    if (this.transform(printStream)) {
        this.oldOut = printStream;
    }
    System.setOut(null);
}