2

I have a problem with an old application which runs on a Java Tomcat server and the source code for the application is not fully available, but the .class files are obviously all running on the tomcat server.

Can I somehow manipulate the bytecode of a .class file (used by JVM) so that I can change a variables datatype (because this is what has to be done)? Or even reverse engineer it to its old .java source code?

I have used decompilers and javap command up to now. Can I somehow copy the whole Tomcat application and:

  1. decompile it
  2. do my changes
  3. recompile it?
3
  • 2
    Couldn't this have a snowball effect requiring you to modify even other classes that depend on ones you've modified? What are you going to do about native methods that might access that value that would not be decompiled from the compiled classes? Commented Jan 29, 2021 at 14:51
  • Yeah I know that this could happen, but the variable is a filesizelimit for an upload operation to an on-premise server and they want it to be larger. So basically from customer view we were told "we know what we are doing" whatever this means... Commented Jan 29, 2021 at 16:22
  • 1
    That seems to be a bit naive. Changing the variables’s type doesn’t change the program logic. The limit is imposed by the value stored in the variable. So you have to change all the code responsible for determining that value and assigning it to the variable. Then, there is the code using that variable. If the original authors created the variable with a smaller datatype, it’s rather unlikely that the code using it can handle larger datatypes. This may imply that the code doing the actual upload can not handle it. Commented Feb 1, 2021 at 10:17

3 Answers 3

3

Well, if you decompile it to make changes and recompile, then you're not going to need to change the byte code directly.

If you change the type, you'll have to change the type of any methods (like getters and setters) that use the variable. Then you'll need to change the calls of any methods in all classes that CALL those methods, and the types of their variables that hold these values, etc. The good news is that, if you manage to decompile it successfully, your IDE will tell you where all those places are, assuming the new type is incompatible with the old type.

I would evaluate this as "theoretically possible", but problematic. With the little information you've given us, there's no way to know the size of the job AFTER you successfully decompile the entire application.

Sign up to request clarification or add additional context in comments.

4 Comments

Not to mention, going out on a limb, that creating new code that addresses this issue might be 10x easier than to manipulate the byte code directly. So, why even try it?
that's exactly what I am thinking, but customers...
So it is basically about to change a variable from integer to long integer.
Well, the good news is that eclipse, and probably the Java compiler as well, flags the user of long when int is expected. I was afraid it wouldn't. So the compiler will tell you all the places you need to change. And if you're storing this in a database anywhere, the complexity shoots up.
0

I have a wild and crazy idea; I haven't done this, but as long as we're talking about things that are theoretically possible...

IF you manage to decompile all the code and get a system that you can recompile and run (and I strongly recommend you do that before you make any changes), if you are able to identify where the int is that you want to replace with a long, and then all the direct and indirect references to it, hopefully (because it's just this file size limit that you mention elsewhere) you end up with only a handful of classes.

The decompile should tell you their names. Create new classes with the exact same names, containing (of course) all their decompiled code. Change the methods that you need to change.

Now put those classes in a jar that is searched before the jar containing the application. You're limiting the number of classes for which you're providing new .class files to just those. This makes it easier to see exactly what has been changed, for future programmers, if it doesn't do anything else. It's possible because of the way Java handles its runtime; the step that's equivalent to 'linking' in a traditional compiled non-virtual-machine language happens when the class is loaded, instead of at compile time.

Comments

0

I did that. Not exactly that, but something very similar. Instead of decompiling and recompiling, which is very long, and tedious, I directly edited the byte-code of the class file.

pros

  • You do not need to compile anything at all, you just edit a file
  • no SDK, no IDE, etc is necessary, just a java-byte code editor
  • for small changes you can get away with single method modification

cons

  • very-very error-prone even if you know what you are doing
  • no way to track changes as you do with git
  • will probably require modifying all dependent classes
  • you should have some knowledge about how compiled code looks like, and behaves before even attempting such a thing.
  • you will most likely break a law or two since this will not be for "educational" purposes
  • you will be marked as "the hacker" and every odd job will be forwarded to you

PS: I had to edit licensing class of a product to allow more users. The company writing it ceased to exist, so buying was not an option. We switched to a new product anyway, it was just temporarily.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.