Solved

Edit java class file : decompile and recompile without reopening full application

Posted on 2011-02-23
22
2,027 Views
Last Modified: 2012-05-11
Hello Everyone,

We have a java application which needs to be amended to update an FTP password within a class file.

I have inherited this application from a developer who is no longer with us, we have no documentation and do not have access to the original source files. Is it possible to recompile an individual application class file without opening the whole project in eclipse?

This is the decompiled class file:
package com.abc.ftp;

import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

public class FtpSender
{

    private static final String HOSTNAME = "xxx.xxx.xxx.xxx";
    private static final String USERNAME = "username";
    private static final String PASSWORD = "password";
    private FTPClient client;

    public FtpSender()
        throws SocketException, IOException
    {
        client = new FTPClient();
        client.connect("xxx.xxx.xxx.xxx");
        if(!FTPReply.isPositiveCompletion(client.getReplyCode()))
        {
            throw new IOException("Unable to connect to ftp server : xxx.xxx.xxx.xxx");
        }
        client.login("username", "password");
        if(!FTPReply.isPositiveCompletion(client.getReplyCode()))
        {
            throw new IOException("Unable to login as username to ftp server : xxx.xxx.xxx.xxx");
        } else
        {
            return;
        }
    }

    public void send(InputStream in, String desiredPath)
        throws IOException
    {
        client.storeFile(desiredPath, in);
        if(!FTPReply.isPositiveCompletion(client.getReplyCode()))
        {
            throw new IOException((new StringBuilder("Unable to store file at : ")).append(desiredPath).toString());
        } else
        {
            return;
        }
    }
}

Open in new window


Many thanks in advance,
Ian.
0
Comment
Question by:IW-SNK
  • 10
  • 6
  • 5
  • +1
22 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 34961009
Looks like you've been lucky there. Try compiling it standalone. Take a backup of the jar file or directory in which that class appears, then either update the jar or overwrite the class file depending on whether the class is in a jar or a directory
0
 

Author Comment

by:IW-SNK
ID: 34961457
Hi Cehj,

Thanks for your comment. The class file is located in a subdirectory of the .jar file.

Apologies if this is a really basic question, I'm not a java developer! but how do I compile the revised text file as a class file?

I initially decomplied with Cavaj to ensure the FtpSender.class file was the one that contained the FTP password.

In eclipse I can open the text version but I am unable to compile, how would I do this? Do I need to create a project first?

If I try to open the .class compiled file in eclipse I receive the following error:
Could not open the editor:
The Class File Viewer cannot handle the given input ('org.eclipse.ui.ide.FileStoreEditorInput').

Many thanks,
Ian.
0
 
LVL 86

Accepted Solution

by:
CEHJ earned 50 total points
ID: 34961582
You don't want to try to open the class file.

>>how do I compile the revised text file as a class file?

Do you have the source code in Eclipse too?
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 34961624
Sorry - you said not

Have you got a JDK installed on your system? If so, you can use javac

If not, start a separate, new, Eclipse project and add that source to your project. Add the necessary jars (Apache Commons Net etc) and let the source compile. Copy the resulting class file into the old project (which should have been backed up first)
0
 
LVL 26

Expert Comment

by:mrcoffee365
ID: 34961652
Or you can bypass Eclipse and compile your decompiled .java file with the different password (is that what you want to do?), then replace the previous .class file in the .jar file with your new .class file.
0
 

Author Comment

by:IW-SNK
ID: 34961752
I'm going to attempt to compile without using eclipse, using javac.
Does it matter which version of the SDK I install? Does it need to be the same version used for the original application?

0
 
LVL 26

Expert Comment

by:mrcoffee365
ID: 34961909
It's better to get the same SDK, but it might not matter.  It depends on the method signatures.  Don't you have javac on the machine with the jars?  If you don't, then you do have a jre -- get the sdk which matches it.
0
 

Author Comment

by:IW-SNK
ID: 34961927
Thanks for the info MrCoffee365.
I'll update the thread once i have installed and compiled the class.
Cheers,
Ian.
0
 

Author Comment

by:IW-SNK
ID: 34962780
I have installed the JDK and registered the PATH variables.

I ran the following from the command prompt with this result:

C:\java_app_path>javac FtpSender.class
javac: invalid flag: FtpSender.class
Usage: javac <options> <source files>
use -help for a list of possible options

Open in new window


Something is wrong somewhere.

I then changed the file from .class to .java and the following errors appeared:
FtpSender.java:6: package org.apache.commons.n
import org.apache.commons.net.ftp.FTPClient;

Open in new window


I am now going to try via eclipse, that way I can load the packages.

Many thanks,
Ian.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 34963412
Is that the real package name? If not, give me the real package name and i'll supply you with the files you need
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 34963592
The design of that class is poor:

a. there are hardcoded credentials in it - hence your current problem
b. the ftp connection isn't closed properly (i wonder if it even works?)

The following (assuming it DOES work) is about the minimum required to get it to work with arbitrary credentials without recompilation:
package com.abc.ftp;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

import java.io.IOException;
import java.io.InputStream;

import java.net.SocketException;


public class FtpSender {
    private static final String HOSTNAME;
    private static final String USERNAME;
    private static final String PASSWORD;
    private FTPClient client;
    static {
	java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("credentials");
	HOSTNAME = bundle.getString("hostname");
	USERNAME = bundle.getString("username");
	PASSWORD = bundle.getString("password");
    }


    public FtpSender() throws SocketException, IOException {

        client = new FTPClient();

        client.connect(HOSTNAME);

        if (!FTPReply.isPositiveCompletion(client.getReplyCode())) {
            throw new IOException(
                "Unable to connect to ftp server : " + HOSTNAME);
        }

        client.login(USERNAME, PASSWORD);

        if (!FTPReply.isPositiveCompletion(client.getReplyCode())) {
            throw new IOException(
                "Unable to login as username to ftp server : " + HOSTNAME);
        } else {
            return;
        }
    }

    public void send(InputStream in, String desiredPath)
        throws IOException {
        client.storeFile(desiredPath, in);

        if (!FTPReply.isPositiveCompletion(client.getReplyCode())) {
            throw new IOException((new StringBuilder(
                    "Unable to store file at : ")).append(desiredPath).toString());
        } else {
            return;
        }
    }
}

Open in new window

0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 26

Expert Comment

by:mrcoffee365
ID: 34964075
Or you can just add the jars to your classpath when you compile the .java file.

So: you compile .java files, you run .class files.  

Run these commands to compile your .java file.  Then you'll need to replace the .class file in the jar.

set CLASSPATH=.;comabc.jar
javac C:/java_app_path/FtpSender.java

Then you'll need to replace the .class file in comabc.jar (I don't know the name of the .jar file these are in -- you'll have to put the right name in):

jar uf comabc.jar com\abc\ftp\FtpSender.class
0
 

Author Comment

by:IW-SNK
ID: 34969155
Thanks so much for your support with this issue. Unfortunately my lack of experience/understanding of java has made this a difficult task.

I followed Cehj's approach with the revised file - updating teh .class file with the new code and saving as a text file with the .class extension. I then ran the application with the uncompiled .class but this did not produce the desired effect. The application generated an error which was not the error text as created in the new file. This makes me think that the application does not store the FTP details in this class file but perhaps somewhere else in the application.

I am going to reach out to the original developer in the hope that he can point me in the direction of the original eclipse project.

Thanks again for your support with this issue.
Ian.
0
 

Author Comment

by:IW-SNK
ID: 34969689
Hi Cehj,

Just for clarrification, when you wrote:
The following (assuming it DOES work) is about the minimum required to get it to work with arbitrary credentials without recompilation:

Does this means that a .class file can be used / accessed by the jar application without recompilation?

ie. decomplie, edit, save as uncompiled file with same name and the app can use it.

Many thanks,
Ian.
0
 
LVL 10

Expert Comment

by:gordon_vt02
ID: 34970161
IW, when you decompile the source, save it as a .java file instead of a .class file and make sure you put it in the same directory structure you found it in in the jar.  The javac compiler (or Eclipse, if you go that route) will create the .class file for you.
0
 
LVL 26

Expert Comment

by:mrcoffee365
ID: 34970197
>>Does this means that a .class file can be used / accessed by the jar application without recompilation?

No -- we mentioned this before.  A .java file is source code -- it cannot be run or executed by anything.  A .class file is the compiled code -- that is what is run.

CEHJ was suggesting you rewrite the code to behave differently.
0
 

Author Comment

by:IW-SNK
ID: 34971237
Hi Mrcoffee365,
Thanks for the clarrification, I thought that was the case.
Cheers,
Ian.
0
 

Author Comment

by:IW-SNK
ID: 35036400
Thanks for the great feedback on this issue. In the end I had to locate the original source files and the amend to the was very easy.
Cheers,
Ian.
0
 

Author Closing Comment

by:IW-SNK
ID: 35036420
My initial question was not answered, recompile .class without eclipse. The solution was to use eclipse so this was the best match comment.
0
 
LVL 26

Expert Comment

by:mrcoffee365
ID: 35036792
Too bad you didn't follow up with all the experts.  I was answering directly how to recompile a .java file into a .class file without using eclipse.   If you use EE again, try to work with the experts on the problem you want to solve.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 35036823
And i'd strongly advise  you to use the code i gave you or something like it or you could well have a similar problem again
0
 

Author Comment

by:IW-SNK
ID: 35038156
Thanks for the feedback, I will take this onboard.
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
factorial example challenge 10 62
count7 challenge 12 70
java set up 1 48
Java Timer (static) 9 19
For customizing the look of your lightweight component and making it look lucid like it was made of glass. Or: how to make your component more Apple-ish ;) This tip assumes your component to be of rectangular shape and completely opaque. (COD…
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now