Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

yGuard Obfuscation Causes Bean Creation Error with Spring #165

Open
Flatfish99 opened this issue Dec 20, 2024 · 6 comments
Open

yGuard Obfuscation Causes Bean Creation Error with Spring #165

Flatfish99 opened this issue Dec 20, 2024 · 6 comments

Comments

@Flatfish99
Copy link

Hi there,

I’ve been using yGuard to obfuscate my project and have configured it with the following tag to keep all classes, methods, and fields as private:
<class classes="private" methods="private" fields="private">

According to this configuration, there should be no code changes, and the functionality should remain intact after obfuscation. However, when I attempt to start the project, I encounter the following error:

Error creating bean with name "errorBean"....: BeanPostProcessor before instantiation of bean failed

The error seems to be related to Spring’s BeanPostProcessor. I expected no changes in behavior, so I’m not sure why the error is occurring.

Could anyone shed some light on why this might be happening? Is there something specific that needs to be adjusted in the yGuard configuration when dealing with Spring beans and BeanPostProcessor?

Any help would be greatly appreciated!

Thanks!

@Flatfish99
Copy link
Author

Flatfish99 commented Dec 20, 2024

Here is the configuration I’m using for the yGuard obfuscation:

 <dependency>
      <groupId>com.yworks</groupId>
      <artifactId>yguard</artifactId>
      <version>4.1.1</version>
      <scope>compile</scope>
    </dependency>
    <plugin>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.8</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>run</goal>
            </goals>
            <id>obfuscate</id>
            <configuration>
              <tasks>
                <property
                 name="project.jar"
                 value="${project.build.directory}/${project.build.finalName}.jar"/>
                <property
                 name="project.jar.unobf"
                 value="${project.build.directory}/${project.build.finalName}_unobf.jar"/>
                <move
                 file="${project.jar}"
                 tofile="${project.jar.unobf}"
                 verbose="true"/>

                <property
                 name="runtime_classpath"
                 refid="maven.runtime.classpath"/>
                <taskdef
                 name="yguard"
                 classname="com.yworks.yguard.YGuardTask"
                 classpath="${runtime_classpath}"/>
                <yguard>
                  <inoutpair in="${project.jar.unobf}" out="${project.jar}" />

                  <rename logfile="${project.build.directory}/${project.build.finalName}_renamelog.xml">
                    <keep>
                      <class classes="private" methods="private" fields="private"/>
                    </keep>
                  </rename>
                </yguard>
              </tasks>
            </configuration>
          </execution>
        </executions>
      </plugin>

Interestingly, when I remove this plugin, the project works fine and starts up without any issues. However, after adding this plugin back in, the project throws the error, even though no actual obfuscation is being done (since the classes, methods, and fields are kept private).

@thomasbehr
Copy link
Member

thomasbehr commented Dec 20, 2024

We would need more information to provide advice on this issue.
First off, we would need the complete error message. A quick google search seems to indicate that "BeanPostProcessor before instantiation of bean failed" is usually accompanied by a nested exception and a complete stacktrace.
If the stacktrace does not provide a clue as to the cause for the failure, we would also need a minimal, complete example that can be used to reproduce the issue.

@Flatfish99
Copy link
Author

We would need more information to provide advice on this issue. First off, we would need the complete error message. A quick google search seems to indicate that "BeanPostProcessor before instantiation of bean failed" is usually accompanied by a nested exception and a complete stacktrace. If the stacktrace does not provide a clue as to the cause for the failure, we would also need a minimal, complete example that can be used to reproduce the issue.

Hi,

I noticed that even though I am using <class classes="private" methods="private" fields="private"/>, the local variable names and parameter names in the code are still being obfuscated. This is causing errors in my project.

Is there a way to prevent the obfuscation of local variables and parameter names while keeping other elements obfuscated? Any suggestions would be greatly appreciated!

Thanks in advance!

Here is my source code

@Aspect
@Component
public class CreateModifyAspect {

    @Pointcut("@annotation(createModify) && args(vo,..)")
    public void pointcutList(CreateModify createModify, Collection<? extends CreateModifyVo> vo) {}

    @Pointcut("@annotation(createModify) && args(vo)")
    public void pointcut(CreateModify createModify, CreateModifyVo vo) {}

    @Before("pointcutList(createModify, vo)")
    public void beforePointcutList(CreateModify createModify, Collection<? extends CreateModifyVo> vo) {
        System.out.println("Before method execution - PointcutList");
        System.out.println("Annotation Value: " + createModify.value());
        System.out.println("Processing collection of size: " + vo.size());
    }

    @Before("pointcut(createModify, vo)")
    public void beforePointcut(CreateModify createModify, CreateModifyVo vo) {
        System.out.println("Before method execution - Pointcut");
        System.out.println("Annotation Value: " + createModify.value());
        System.out.println("Processing single item: " + vo.toString());
    }
}

and here is the decompiled code

@Aspect
@Component
public class CreateModifyAspect {
  @Pointcut("@annotation(createModify) && args(vo,..)")
  public void pointcutList(CreateModify paramCreateModify, Collection<? extends CreateModifyVo> paramCollection) {}
  
  @Pointcut("@annotation(createModify) && args(vo)")
  public void pointcut(CreateModify paramCreateModify, CreateModifyVo paramCreateModifyVo) {}
  
  @Before("pointcutList(createModify, vo)")
  public void beforePointcutList(CreateModify paramCreateModify, Collection<? extends CreateModifyVo> paramCollection) {
    System.out.println("Before method execution - PointcutList");
    System.out.println("Annotation Value: " + paramCreateModify.value());
    System.out.println("Processing collection of size: " + paramCollection.size());
  }
  
  @Before("pointcut(createModify, vo)")
  public void beforePointcut(CreateModify paramCreateModify, CreateModifyVo paramCreateModifyVo) {
    System.out.println("Before method execution - Pointcut");
    System.out.println("Annotation Value: " + paramCreateModify.value());
    System.out.println("Processing single item: " + paramCreateModifyVo.toString());
  }
}

@Flatfish99
Copy link
Author

yguardExample.zip
and here is a minimal example

@thomasbehr
Copy link
Member

thomasbehr commented Dec 27, 2024

The short answer:
Do not use yGuard (nor any other obfuscation tool, I guess). You are using coding techniques that rely on member and variable names. That does not work together with obfuscation since the very thing obfuscation does is changing names of types and members.

The slightly longer answer:
yGuard removes the LocalVariableTable byte code attribute from all .class files it processes. You can use the attribute element to retain byte code attributes, e.g.

<yguard>
  <inoutpair ...
  <attribute name="LocalVariableTable"/>
  <keep ...
</yguard>

However, I would guess even after adjusting the yGuard configuration to keep the LocalVariableTable you will just run into another problem due to Spring and AspectJ relying on type and member names. Moreover, why would you run yGuard on your byte code and essentially instruct it to not remove any attributes and not change any names? I.e. your yguard run would essentially (have to) be a no-op.

@Flatfish99
Copy link
Author

The short answer: Do not use yGuard (nor any other obfuscation tool, I guess). You are using coding techniques that rely on member and variable names. That does not work together with obfuscation since the very thing obfuscation does is changing names of types and members.

The slightly longer answer: yGuard removes the LocalVariableTable byte code attribute from all .class files it processes. You can use the attribute element to retain byte code attributes, e.g.

<yguard>
  <inoutpair ...
  <attribute name="LocalVariableTable"/>
  <keep ...
</yguard>

However, I would guess even after adjusting the yGuard configuration to keep the LocalVariableTable you will just run into another problem due to Spring and AspectJ relying on type and member names. Moreover, why would you run yGuard on your byte code and essentially instruct it to not remove any attributes and not change any names? I.e. your yguard run would essentially (have to) be a no-op.

Hi thomasbehr,

Thank you so much for your valuable help and insights!

Following your suggestions, I did adjust the settings to keep the LocalVariableTable attribute. Indeed, after making those changes, I encountered several issues, but after a lot of trial and error, I managed to resolve them one by one.

As for your question, "Why run yGuard on the bytecode and instruct it not to remove any attributes and not change any names?" — I did so because, no matter how much I tried to narrow down the scope of the obfuscation, the program still wouldn't run. So, my approach was to first ensure that the program ran correctly and then attempt to apply obfuscation gradually.

I truly appreciate your help in guiding me through this process. It’s been a learning experience, and I’m now more confident in tackling the challenges ahead.

Best regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants