今天笔者同事遇到一个问题,客户同事的数据库连接信息直接写在代码中,连接的密码改了,但是又没有源代码,所以只能直接修改Java class文件。
记录一下修改步骤:
1.下载JClassLib_windows(后面用到),下载jd-gui-1.4.0.jar,用来反编译class文件的,IDEA也可以反编译class文件;
找到需要修改文件的变量,我这里是Admin。
2.第二步把class文件,备份待用,把工程文件存一份,方法如下图所示:
3.安装JClassLib,安装完成之后用JClassLib打开需要修改的class文件,我这里是Client.class,找到需要修改的函数方法位置,我这里是main函数,然后点菜单的code,查看右侧的Bytecode,找到需要修改的变量Admin,然后点击#173,会跳到变量区,如下面二张图说明:
图1
图2
4.鼠标点击cp_info#174会跳转到174这行变量,如下图所示:
4.替换变量
写一个Java程序,替换指定变量的值,filePath变量存在需要替换的class文件路径,174是需要替换的位置,Admin123是希望替换的变量,如果替换成中文需要注意目标编码(不然会用JVM默认编码),如下图所示:
图1
图2 中文编码设置
4.上面的Java程序完整代码如下,特别需要注意的是:程序依赖JClasslib包下的jclasslib-library.jar包,所以可以进到JClasslib安装路径下拷贝一个jclasslib-library.jar包文件放到build path内,我的路径和jar包文件如下:
完整代码,你们替换三处,文件路径、变量位置、修改后目标变量
import java.io.DataInput; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import org.gjt.jclasslib.io.ClassFileWriter; import org.gjt.jclasslib.structures.CPInfo; import org.gjt.jclasslib.structures.ClassFile; import org.gjt.jclasslib.structures.InvalidByteCodeException; import org.gjt.jclasslib.structures.constants.ConstantUtf8Info; public class Client { @SuppressWarnings("deprecation") public static void main(String[] args){ String filePath = "C:\Users\zw\Desktop\Client.class"; FileInputStream fis = null; try { fis = new FileInputStream(filePath); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } DataInput di = new DataInputStream(fis); ClassFile cf = new ClassFile(); try { cf.read(di); } catch (InvalidByteCodeException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } CPInfo[] infos = cf.getConstantPool(); int count = infos.length; for (int i = 0; i < count; i++) { if (infos[i] != null) { System.out.print(i); System.out.print(" = "); try { System.out.print(infos[i].getVerbose()); } catch (InvalidByteCodeException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.print(" = "); System.out.println(infos[i].getTagVerbose()); if(i == 174){ ConstantUtf8Info uInfo = (ConstantUtf8Info)infos[i]; uInfo.setBytes("Admin123".getBytes()); infos[i]=uInfo; } } } cf.setConstantPool(infos); try { fis.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } File f = new File(filePath); try { ClassFileWriter.writeToFile(f, cf); } catch (InvalidByteCodeException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
另外我把工程