java逆向基础,Java逆向基础之函数
本文提到的函數(function)和方法(method)為同一個意思
例子1,方法名的定義public?class?HalfRandom
{
public?static?double?f()
{
return?Math.random()/2;
}
}
編譯javac?HalfRandom.java
反編譯javap?-c?-verbose?HalfRandom.class...
major?version:?52
...
#2?=?Methodref??????????#16.#17????????//?java/lang/Math.random:()D
#3?=?Double?????????????2.0d
...
#12?=?Utf8???????????????()D
...
#16?=?Class??????????????#20????????????//?java/lang/Math
#17?=?NameAndType????????#21:#12????????//?random:()D
#18?=?Utf8???????????????HalfRandom
#19?=?Utf8???????????????java/lang/Object
#20?=?Utf8???????????????java/lang/Math
#21?=?Utf8???????????????random
...
public?static?double?f();
descriptor:?()D
flags:?ACC_PUBLIC,?ACC_STATIC
Code:
stack=4,?locals=0,?args_size=0
0:?invokestatic??#2??????????????????//?Method?java/lang/Math.random:()D
3:?ldc2_w????????#3??????????????????//?double?2.0d
6:?ddiv
7:?dreturn
LineNumberTable:
line?5:?0
invokestatic? #2? 調用常量#2定義的函數
函數名定義在常量池的Methodref中,它定義類,方法名,方法返回類型
常量#2中,可以看到它是由#16.#17拼接,#16定義了類名 java/lang/Math,#17是方法名和返回類型名random:()D
常量#17中,它是由#21:#12拼接,#21定義了方法名random,#12定義了返回類型名()D
()D的解釋 ,括號內沒有東西表示括號內無參數,D表示返回類型為double,如果是V則為void
這種方式
1)JVM可以檢查數據類型的正確性:
2)java反編譯器可以從被編譯的類文件中修改數據類型。
再看"hello,world!"的例子public?class?HelloWorld
{
public?static?void?main(String[]?args)
{
System.out.println("Hello,?World");
}
}
反編譯...
major?version:?52
...
#2?=?Fieldref???????????#16.#17????????//?java/lang/System.out:Ljava/io/PrintStream;
#3?=?String?????????????#18????????????//?Hello,?World
#4?=?Methodref??????????#19.#20????????//?java/io/PrintStream.println:(Ljava/lang/String;)V
...
#16?=?Class??????????????#23????????????//?java/lang/System
#17?=?NameAndType????????#24:#25????????//?out:Ljava/io/PrintStream;
#18?=?Utf8???????????????Hello,?World
#19?=?Class??????????????#26????????????//?java/io/PrintStream
#20?=?NameAndType????????#27:#28????????//?println:(Ljava/lang/String;)V
...
#23?=?Utf8???????????????java/lang/System
#24?=?Utf8???????????????out
#25?=?Utf8???????????????Ljava/io/PrintStream;
#26?=?Utf8???????????????java/io/PrintStream
#27?=?Utf8???????????????println
#28?=?Utf8???????????????(Ljava/lang/String;)V
...
public?static?void?main(java.lang.String[]);
descriptor:?([Ljava/lang/String;)V
flags:?ACC_PUBLIC,?ACC_STATIC
Code:
stack=2,?locals=1,?args_size=1
0:?getstatic?????#2??????????????????//?Field?java/lang/System.out:Ljava/io/PrintStream;
3:?ldc???????????#3??????????????????//?String?Hello,?World
5:?invokevirtual?#4??????????????????//?Method?java/io/PrintStream.println:(Ljava/lang/String;)V
8:?return
LineNumberTable:
line?5:?0
line?6:?8
getstatic ?#2 獲取System.out的引用入棧
ldc ?#3 將字符串Hello, World入棧
invokevirtual #4 調用println()方法,這里需要傳兩個參數,參數從棧中獲取,1先將Hello, World出棧傳入(Ljava/lang/String;),2將System.out的引用出棧傳入java/io/PrintStream的引用
再看beep的函數調用(輸出計算機報警的蜂鳴聲)public?class?bee
{
public?static?void?main(String[]?args)
{
java.awt.Toolkit.getDefaultToolkit().beep();
}
}
反編譯...
major?version:?52
...
public?static?void?main(java.lang.String[]);
descriptor:?([Ljava/lang/String;)V
flags:?ACC_PUBLIC,?ACC_STATIC
Code:
stack=1,?locals=1,?args_size=1
0:?invokestatic??#2??????????????????//?Method?java/awt/Toolkit.getDefaultToolkit:()Ljava/awt/Toolkit;
3:?invokevirtual?#3??????????????????//?Method?java/awt/Toolkit.beep:()V
6:?return
LineNumberTable:
line?5:?0
line?6:?6
invokestatic ?#2 調用java.awt.Toolkit.getDefaultToolkit()方法并將返回結果的引用壓入棧頂
invokevirtual #3 調用beep()函數,其中需要傳引用,把objectref從棧頂彈出傳入java/awt/Toolkit
總結
以上是生活随笔為你收集整理的java逆向基础,Java逆向基础之函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php把时间变成整数,php怎么将字符串
- 下一篇: mysql 之后,装完MySQL之后的一