• 周六. 10 月 5th, 2024

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

Common decompilation operations of Java class

King Wang

1 月 3, 2022

1. Jadx

jadx It’s a decompile artifact , Set apktool、jd Function in one , Can view directly apk,dex,jar file . View is not supported at this time aar file .
If you want to look at aar Word of the file , You can rename it to zip file , Decompress again to check .

Here’s how to use jadx Will be compiled class The file is converted to java The source code file :

  1. hold class The document belongs to jar Package pass jadx Mode on

     

     

  2. Click… On the menu File –>Save all( Or use shortcut keys Ctrl+S)

     

     

  3. Enter the save path , Click on Select

     

     

4. View the generated java file

 

 

attach :jadx Download address

2. Fernflower

fernflowser It is also an open source decompile tool project ,Android Studio The built-in decompiler is it .

 

fernflower There is no graphical interface , Mainly through the command line way to operate .

Here’s how to use fernflower Will be compiled class The file is converted to java The source code file :

  1. download fernflower Of jar Package file
    http://files.minecraftforge.net/maven/net/minecraftforge/fernflower/

  2. Will need to decompile jar The package file is decompressed with a compression tool

     

     

  3. Decompile output through command line output java file

java -jar fernflower.jar -dgs=1 svg2vector-applet-1.0.0 .

 

fernflower Other specific usage can refer to : https://github.com/fesh0r/fernflower

3、jad Tools

command :jad -o -r -s java -d src classes/**/*.class 

You can find it in the root directory src Folder , It’s all decompiled java Source file .

   jad The parameter meaning of the command is as follows :
       -o: Overwrite old files , And there’s no need to prompt for confirmation .
       -r: Reload build package structure .
       -s (java): Define the extension of the output file .jad For the default extension , After decompilation, of course, we need to .java Source file .
       -d: Directory of output files .src Indicates that all files after decompilation are placed in src Under the table of contents .
       classes/**/*.class:classes Is the name of the folder that needs to be decompiled , The whole expression classes All under directory class file . You can write like this **/*.class, This means all the… In the current directory and its subdirectories class file ( Contains all subdirectories ).

.jad -o -8 -r -dXXXXX -sjava XXXXX

-o: Overwrite , If the file already exists , Coverage

-r: Establish and java Package consistent folder path

-dXXXX: Save the path after decompilation , Such as D:/output/src

-sjava: Decompiled file suffix , We hope to be .java file

 -8: Avoid decompiling Chinese to unicode, essential .

Be careful : No Chinese in the path , Otherwise, an error will occur ,JavaClassFileReadException: can’t open input file on `D:\XXXXXX’

  Be careful : Comments will be lost , such as @XmlAttribute,@Autowired wait , All missing . It means very rogue

Add :

Usage method :

[1]  Decompile a class file :jad example.class, Will generate example.jad, Open it with a text editor java Source code

[2]  Specify the suffix of the generated source code :jad -sjava example.class, Generate example.java

[3]  Change the name of the generated source code , You can use it first -p Output the decompiled source code to the console window , Then use redirection , output to a file :jad -p example.class > myexample.java

[4]  Output the source code file to the specified directory :jad -dnewdir -sjava example.class, stay newdir Generate under directory example.java

[5]  hold packages In the catalog class Decompile all files :jad -sjava packages/*.class

[6] hold packages Catalog And subdirectories All the files are decompiled :jad -sjava packages/**/*.class, However, you will still find that all the source code files are put in the same file , Not according to class The package path of the file establishes the path

[7] hold packages All files in directory and subdirectory are decompiled And build and java Package consistent folder path , have access to -r command :jad -r -sjava packages/**/*.class

[8] When the command is used repeatedly to decompile ,Jad Will prompt “whether you want to overwrite it or not”, Use -o Sure Force overwrite of old files

The most authoritative is help:

bin>jad
Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov ([email protected]).
Usage: jad [option(s)] <filename(s)>
Options: -a – generate JVM instructions as comments (annotate)
-af – output fully qualified names when annotating
-b – generate redundant braces (braces)
-clear – clear all prefixes, including the default ones
-d <dir> – directory for output files
-dead – try to decompile dead parts of code (if there are any)
-dis – disassembler only (disassembler)
-f – generate fully qualified names (fullnames)
-ff – output fields before methods (fieldsfirst)
-i – print default initializers for fields (definits)
-l<num> – split strings into pieces of max <num> chars (splitstr)
-lnc – output original line numbers as comments (lnc)
-lradix<num>- display long integers using the specified radix
-nl – split strings on newline characters (splitstr)
-noconv – don’t convert Java identifiers into valid ones (noconv)
-nocast – don’t generate auxiliary casts
-noclass – don’t convert .class operators
-nocode – don’t generate the source code for methods
-noctor – suppress the empty constructors
-nodos – turn off check for class files written in DOS mode
-nofd – don’t disambiguate fields with the same names (nofldis)
-noinner – turn off the support of inner classes
-nolvt – ignore Local Variable Table entries (nolvt)
-nonlb – don’t insert a newline before opening brace (nonlb)
-o – overwrite output files without confirmation
-p – send all output to STDOUT (for piping)
-pa <pfx>- prefix for all packages in generated source files
-pc <pfx>- prefix for classes with numerical names (default: _cls)
-pe <pfx>- prefix for unused exception names (default: _ex)
-pf <pfx>- prefix for fields with numerical names (default: _fld)
-pi<num> – pack imports into one line using .* (packimports)
-pl <pfx>- prefix for locals with numerical names (default: _lcl)
-pm <pfx>- prefix for methods with numerical names (default: _mth)
-pp <pfx>- prefix for method parms with numerical names (default:_prm)
-pv<num> – pack fields with the same types into one line (packfields)
-r – restore package directory structure
-radix<num>- display integers using the specified radix (8, 10, or 16)
-s <ext> – output file extension (default: .jad)
-safe – generate additional casts to disambiguate methods/fields
-space – output space between keyword (if, while, etc) and expression
-stat – show the total number of processed classes/methods/fields
-t<num> – use <num> spaces for indentation (default: 4)
-t – use tabs instead of spaces for indentation
-v – show method names while decompiling
-8 – convert Unicode strings into ANSI strings (ansi)
-& – redirect STDERR to STDOUT

4、 Online decompiler  http://javare.cn/

5、JDK Built in decompile tool javap

javap yes JDK Built in disassembler , You can see java The bytecode that the compiler generates for us . Through it , We can compare source code and bytecode , To learn a lot about the work inside the compiler .
grammar :

-help --help -? Output this usage message
-version Version information , It's actually the present javap Where jdk Version information for , No class In which jdk The generated .
-v -verbose Output additional information ( Include line number 、 Local variable table , Disassembly and other details )
-l Output line number and local variable table
-public Show only public classes and members
-protected Show protected / Public classes and members
-package Show package / The protected / Public class And members ( Default )
-p -private Show all classes and members
-c Disassemble the code
-s Output internal type signature
-sysinfo Show system information about the class being processed ( route , size , date , MD5 hash )
-constants Show static final constant
-classpath <path> Specify where to find user class files
-bootclasspath <path> Overwrite the location of the boot class file 

Here’s a small example ,java The source code is as follows :

public class JavapTest2 {
    private String username;
    public void say(String username) {
        System.out.println("hi,"+username);
    }
}

After compiling it , Use javap To query JavapTest2 Bytecode

javac JavapTest2.java
javap -p -v JavapTest2

The generated bytecode is as follows :

Classfile ../JavapTest2.class
Last modified 2018-8-31; size 608 bytes
MD5 checksum 25f04ad8674616cb2f0e7fe9d35e6ab1
Compiled from "JavapTest2.java"
public class com.pjmike.JVM.JavapTest2
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #10.#21 // java/lang/Object."<init>":()V
#2 = Fieldref #22.#23 // java/lang/System.out:Ljava/io/PrintStream;
#3 = Class #24 // java/lang/StringBuilder
#4 = Methodref #3.#21 // java/lang/StringBuilder."<init>":()V
#5 = String #25 // hi,
#6 = Methodref #3.#26 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/String
Builder;
#7 = Methodref #3.#27 // java/lang/StringBuilder.toString:()Ljava/lang/String;
#8 = Methodref #28.#29 // java/io/PrintStream.println:(Ljava/lang/String;)V
#9 = Class #30 // com/pjmike/JVM/JavapTest2
#10 = Class #31 // java/lang/Object
#11 = Utf8 username
#12 = Utf8 Ljava/lang/String;
#13 = Utf8 <init>
#14 = Utf8 ()V
#15 = Utf8 Code
#16 = Utf8 LineNumberTable
#17 = Utf8 say
#18 = Utf8 (Ljava/lang/String;)V
#19 = Utf8 SourceFile
#20 = Utf8 JavapTest2.java
#21 = NameAndType #13:#14 // "<init>":()V
#22 = Class #32 // java/lang/System
#23 = NameAndType #33:#34 // out:Ljava/io/PrintStream;
#24 = Utf8 java/lang/StringBuilder
#25 = Utf8 hi,
#26 = NameAndType #35:#36 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#27 = NameAndType #37:#38 // toString:()Ljava/lang/String;
#28 = Class #39 // java/io/PrintStream
#29 = NameAndType #40:#18 // println:(Ljava/lang/String;)V
#30 = Utf8 com/pjmike/JVM/JavapTest2
#31 = Utf8 java/lang/Object
#32 = Utf8 java/lang/System
#33 = Utf8 out
#34 = Utf8 Ljava/io/PrintStream;
#35 = Utf8 append
#36 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder;
#37 = Utf8 toString
#38 = Utf8 ()Ljava/lang/String;
#39 = Utf8 java/io/PrintStream
#40 = Utf8 println
{
private java.lang.String username;
descriptor: Ljava/lang/String;
flags: ACC_PRIVATE
public com.pjmike.JVM.JavapTest2();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 7: 0
public void say(java.lang.String);
descriptor: (Ljava/lang/String;)V
flags: ACC_PUBLIC
Code:
stack=3, locals=2, args_size=2
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: ldc #5 // String hi,
12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/
lang/StringBuilder;
15: aload_1
16: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/
lang/StringBuilder;
19: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
25: return
LineNumberTable:
line 11: 0
line 12: 25
}
SourceFile: "JavapTest2.java"

By default javap Will print all non private fields and methods , as follows :

javap JavapTest2
Compiled from "JavapTest2.java"
public class com.pjmike.JVM.JavapTest2 {
public com.pjmike.JVM.JavapTest2();
public void say(java.lang.String);
}

javap -v -p JavapTest2 .

added -p After the options , Also print private fields and methods , add -v After the options , It will print out as much information as possible , If you only need to query the bytecode corresponding to the relevant method , have access to -c Instead of -v, The code is as follows :

Compiled from "JavapTest2.java"
public class com.pjmike.JVM.JavapTest2 {
private java.lang.String username;
public com.pjmike.JVM.JavapTest2();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public void say(java.lang.String);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: ldc #5 // String hi,
12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/la
ng/StringBuilder;
15: aload_1
16: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/la
ng/StringBuilder;
19: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
25: return
}

6、 With the help of idea、eclipse Tools

发表回复