0x00 前言
我們之前復習了java語言,所有簡單的知識點如下。已經復習完成的后面會有 √
在Android逆向-java代碼基礎(7)中已經復習了類中變量的定義。
這節主要是對類中方法進行學習,順便把分裝也學習了,demo就在之前的demo上改。
本教程不主要針對初學者,所以可以挑看懂的看~
java基礎
1.變量√
2.輸入√
3.輸出√
4.判斷邏輯√
5.順序邏輯√
6.類中定義√
7.類中方法
7.繼承
8.封裝
9.多態
.class文件
1.魔數√
2.版本號√
3.常亮池√
4.訪問標志位√
5.類索引√
6.父類索引√
7.接口索引√
8.field字段√
9.method字段
smali文件
1.輸出模塊√
2.輸入模塊√
3.定義模塊√
4.判斷模塊√
5.循環模塊√
6.類成員定義模塊√
7.類成員調用模塊
8.類方法的定義模塊
9.類繼承模塊
之前文章
0x01 java復習
1.demo
public class demo{
private int a=4;
public int getA()
{
return this.a;
}
public void setA(int a)
{
this.a=a;
}
public static void main(String[]args)
{
demo d=new demo();
d.setA(1);
System.out.println(d.getA());
}
}
簡單的分析
因為一次涉及到兩個內容,所以來進行一個簡單的分析。
首先第一個就是java的類方法。
不知道學過c語言沒有,其實就相當於是c語言中的函數,如果不理解的話,請自行google。
google被牆了,ssl或者鏡像,小坑隨便趴一趴就過了。
第二個就是封裝的問題了。
封裝就是讓外部不能直接調用我的類成員,要通過一些方法間接的訪問類中的成員變量。
想要學習封裝,就要學會方法的時候。
封裝說白了就是一個輸入方法和一個輸出方法。
這個是輸入方法:
這個是輸出的方法:
其他的東西網上應該很多,這里就不啰嗦了。
0x02 .class文件分析
從field字段之后就是method字段,也就是我們今天的主菜了。
慣例先看一下進本的class文件的分析。
直奔主題
這里我們就直接分析method字段。首先我們要找到這個字段。
下面是field字段,根據之前的內容進行分析。
之后就是我們method字段了。
列子先放着,先來看一看method字段有什么內容吧。
方法表集合是指由若干個方法表(method_info)組成的集合。對於在類中定義的若干個,經過JVM編譯成class文件后,會將相應的method方法信息組織到一個叫做方法表集合的結構中,字段表集合是一個類數組結構。
1.method_info結構
1.1訪問標志:
訪問標志位就是記錄這個方法的作用域,靜態或者非靜態。可變性、是否可同步、是否是本地方法,是否是抽象等信息。
1.2名稱索引:
這里是指向常量池的索引,也就是方法的名稱
1.3描述索引:
描述索引表示的是這個方法的特征或者說是簽名,一個方法會有若干個參數和返回值。
1.4屬性表
方法的實現被JVM編譯成JVM的機器碼指令,機器碼指令就存放在一個Code類型的屬性表中。
2.Attribute_info的結構
這個內容和之后的smali有重復的地方,在此就不再重復說明。
0x03 smali文件分析
首先來看看代碼,和之前的有沒有什么不一樣的內容。
.class public Ldemo;
.super Ljava/lang/Object;
.source "demo.java"
# instance fields
.field private a:I
# direct methods
.method public constructor ()V
.registers 2
.prologue
.line 1
invoke-direct {p0}, Ljava/lang/Object;->()V
.line 2
const/4 v0, 0x4
iput v0, p0, Ldemo;->a:I
return-void
.end method
.method public static main([Ljava/lang/String;)V
.registers 3
.prologue
.line 13
new-instance v0, Ldemo;
invoke-direct {v0}, Ldemo;->()V
.line 14
const/4 v1, 0x1
invoke-virtual {v0, v1}, Ldemo;->setA(I)V
.line 15
sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
invoke-virtual {v0}, Ldemo;->getA()I
move-result v0
invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(I)V
.line 16
return-void
.end method
# virtual methods
.method public getA()I
.registers 2
.prologue
.line 5
iget v0, p0, Ldemo;->a:I
return v0
.end method
.method public setA(I)V
.registers 2
.prologue
.line 9
iput p1, p0, Ldemo;->a:I
.line 10
return-void
.end method
1.第一個模塊
這里就是我們寫的方法,這兩個方法就是我們的封裝方法。
先來看看 getA()方法。
iget v0, p0, Ldemo;->a:I
Reads an instance field into vx. The instance is referenced by vy.
就是獲得p0,放在v0中,
然后通過return v0進行返回。
然后來看看setA()方法。
setA中我們就發現了和Android逆向-java代碼基礎(7)中一樣使用了iput,簡單的來說就是把p0給p1。
2.main模塊
截圖截不下了。。。
我們主要想要看到的smali中main函數是怎么調用的封裝函數
來看這兩句
new-instance v0, Ldemo;
invoke-direct {v0}, Ldemo;->()V
實例化了一個對象。
然后是這兩句
const/4 v1, 0x1
invoke-virtual {v0, v1}, Ldemo;->setA(I)V
我們的v0就是實例的對象,v1就是我們輸入的數字。然后調用了.setA(I)這個方法,感覺和c語言有一點像。
然后我們來接着來看:
sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
invoke-virtual {v0}, Ldemo;->getA()I
move-result v0
invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(I)V
這四句話就是打印出getA的內容。
小小的糾結一下,要不要把自己已經很明白的知識點全部寫出來,之前的都是忽略自己很熟悉的內容,跳着寫的。
嗯嗯,還是簡單寫一下吧。
getA()I,在它的后面有一個I,這個I的含義就是返回一個I的值,也就是說返回值為int,這個是為了更好的解釋一下java的返回。
0x4 結束語
以上進本就把一些內容說完了,比如說對.class文件的分析,然后腳本也簡單的寫了一個,加深一下對python語言的學習。可能之后還有smali語言的練習與整理,也就是把smali整理成一個可以用的小的工具包。
然后就剩下練習,這次復習寫完之后,感覺收獲有很多。
1.一直在做Android,java的一些基礎有一些遺忘,順便復習。
2.對.class文件沒有了解,了解+學習,對以后的JVM虛擬機學習打下基礎。
3.對python編程了解和復習,因為之后要用python寫一些輔助腳本,所以這里復習還是很有幫助的,記得自己爬坑爬了一整天。
4.最后就是對smali語法的熟悉,對之后的Dalvik有很大的幫助。
以上,待補充。