转贴来源不明。。。忘记了从哪里下载到的一个doc
有时候,我们在没有java源程序的情况下,想改变.CLASS文件的部分内容输出或者改变跳转流,怎么办呢?
介绍2个java hacker的工具javassist 以及jclasslib。
下载javassist-3.1RC2和jclasslib_windows_3_0。
解压后,将2个JAR 加入classpath内。
原文件HelloWorld.java
package com.unmi;
public class HelloWorld
{
public static void main(String[] args)
{
System.out.println("Hello,gorld!");
}
}
想修改输出的”hello world”,用jclasslib.exe 检测可以看到
属于常量池的23。 如下代码就针对23 做调整。
package com.unmi;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import java.io.*;
import org.gjt.jclasslib.io.ClassFileWriter;
import org.gjt.jclasslib.structures.CPInfo;
import org.gjt.jclasslib.structures.ClassFile;
import org.gjt.jclasslib.structures.constants.ConstantStringInfo;
import org.gjt.jclasslib.structures.constants.ConstantUtf8Info;
public class JclasslibTest {
public static void main(String[] args) throws Exception {
{
String filePath = "D:\\java_proj\\com\\unmi\\HelloWorld.class";
FileInputStream fis = new FileInputStream(
filePath);
DataInput di = new DataInputStream(fis);
ClassFile cf = new ClassFile();
cf.read(di);
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(" = ");
System.out.print(infos[i].getVerbose());
System.out.print(" = ");
System.out.println(infos[i].getTagVerbose());
if(i == 23){
ConstantUtf8Info uInfo = (ConstantUtf8Info)infos[i];
uInfo.setString("china alibaba inc.com");
}
}
}
cf.setConstantPool(infos);
fis.close();
File f = new File(filePath + "c");
ClassFileWriter.writeToFile(f, cf);
}
}
}
D:\java_proj>javac -cp %CLASSPATH%;. com/unmi/JclasslibTest.java
D:\java_proj>java com.unmi.JclasslibTest
1 = com/unmi/HelloWorld = CONSTANT_Class_info
2 = com/unmi/HelloWorld = CONSTANT_Utf8_info
3 = java/lang/Object = CONSTANT_Class_info
4 = java/lang/Object = CONSTANT_Utf8_info
5 = <init> = CONSTANT_Utf8_info
6 = ()V = CONSTANT_Utf8_info
7 = Code = CONSTANT_Utf8_info
8 = java/lang/Object.<init> = CONSTANT_Methodref_info
9 = <init>()V = CONSTANT_NameAndType_info
10 = LineNumberTable = CONSTANT_Utf8_info
11 = LocalVariableTable = CONSTANT_Utf8_info
12 = this = CONSTANT_Utf8_info
13 = Lcom/unmi/HelloWorld; = CONSTANT_Utf8_info
14 = main = CONSTANT_Utf8_info
15 = ([Ljava/lang/String;)V = CONSTANT_Utf8_info
16 = java/lang/System.out = CONSTANT_Fieldref_info
17 = java/lang/System = CONSTANT_Class_info
18 = java/lang/System = CONSTANT_Utf8_info
19 = outLjava/io/PrintStream; = CONSTANT_NameAndType_info
20 = out = CONSTANT_Utf8_info
21 = Ljava/io/PrintStream; = CONSTANT_Utf8_info
22 = Hello,gorld! = CONSTANT_String_info
23 = Hello,gorld! = CONSTANT_Utf8_info
24 = java/io/PrintStream.println = CONSTANT_Methodref_info
25 = java/io/PrintStream = CONSTANT_Class_info
26 = java/io/PrintStream = CONSTANT_Utf8_info
27 = println(Ljava/lang/String;)V = CONSTANT_NameAndType_info
28 = println = CONSTANT_Utf8_info
29 = (Ljava/lang/String;)V = CONSTANT_Utf8_info
30 = args = CONSTANT_Utf8_info
31 = [Ljava/lang/String; = CONSTANT_Utf8_info
32 = SourceFile = CONSTANT_Utf8_info
33 = HelloWorld.java = CONSTANT_Utf8_info
更改生成的HelloWorld.classc 为HelloWorld.class
执行输出为
D:\java_proj>java com.unmi.HelloWorld
china alibaba inc.com
另外,也可以修改if 语句跳转
Jclasslib 观测到jvm op code 如下
现在想更改>= 为<,怎么办?
查询Opcode Mnemonics by Opcode
http://java.sun.com/docs/books/jvms/second_edition/html/Mnemonics.doc.html
并查到 >= 的操作码为 0xA1
所以只要用Ultraedit 修改 0xA1 为 0xA2 就可以了。
再次用jclasslib加载 .class 可以看到仅仅变更了比较的操作码
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)