android逆向 registers,Android逆向-java代碼基礎(8)

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或者鏡像,小坑隨便趴一趴就過了。

第二個就是封裝的問題了。

封裝就是讓外部不能直接調用我的類成員,要通過一些方法間接的訪問類中的成員變量。

想要學習封裝,就要學會方法的時候。

封裝說白了就是一個輸入方法和一個輸出方法。

這個是輸入方法:

aHR0cDovL3QxLmFpeGlueGkubmV0L29fMWM0Y2hqNzM1Yzcyc3A2ZzU4MWk3NjFhOWNhLnBuZy1qLmpwZw==

這個是輸出的方法:

aHR0cDovL3QxLmFpeGlueGkubmV0L29fMWM0Y2hrdXZmN2dlMW9uMTVpaDFrbnF0ZWlhLnBuZy1qLmpwZw==

其他的東西網上應該很多,這里就不啰嗦了。

0x02 .class文件分析

從field字段之后就是method字段,也就是我們今天的主菜了。

慣例先看一下進本的class文件的分析。

aHR0cDovL3QxLmFpeGlueGkubmV0L29fMWM0Y2lnOWU0MTdqdTFhNjgxZjl2dWVlMWJvNGEucG5nLWouanBn

直奔主題

這里我們就直接分析method字段。首先我們要找到這個字段。

下面是field字段,根據之前的內容進行分析。

aHR0cDovL3QxLmFpeGlueGkubmV0L29fMWM0Y2tnMWl0MXRsYjFhNnAxZnNsMWd0aHVhbGEucG5nLWouanBn

之后就是我們method字段了。

列子先放着,先來看一看method字段有什么內容吧。

方法表集合是指由若干個方法表(method_info)組成的集合。對於在類中定義的若干個,經過JVM編譯成class文件后,會將相應的method方法信息組織到一個叫做方法表集合的結構中,字段表集合是一個類數組結構。

1.method_info結構

aHR0cDovL3QxLmFpeGlueGkubmV0L29fMWM0ZXAyODZzMWJhMTFrZTIxYWQxZXUwaWw4YS5wbmctai5qcGc=

1.1訪問標志:

訪問標志位就是記錄這個方法的作用域,靜態或者非靜態。可變性、是否可同步、是否是本地方法,是否是抽象等信息。

aHR0cDovL3QxLmFpeGlueGkubmV0L29fMWM0ZXJpbXRlOTducXVoaWp1bWFzYnNiYS5wbmctai5qcGc=

1.2名稱索引:

這里是指向常量池的索引,也就是方法的名稱

1.3描述索引:

描述索引表示的是這個方法的特征或者說是簽名,一個方法會有若干個參數和返回值。

1.4屬性表

方法的實現被JVM編譯成JVM的機器碼指令,機器碼指令就存放在一個Code類型的屬性表中。

2.Attribute_info的結構

aHR0cDovL3QxLmFpeGlueGkubmV0L29fMWM0ZXBhOGpycmdsZWlnMW85bjFkcW12bDhhLnBuZy1qLmpwZw==

這個內容和之后的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.第一個模塊

aHR0cDovL3QxLmFpeGlueGkubmV0L29fMWM0Z2o4cGw2bHM2cTl0MXJ1cGNrcmtuN2EucG5nLWouanBn

這里就是我們寫的方法,這兩個方法就是我們的封裝方法。

先來看看 getA()方法。

aHR0cDovL3QxLmFpeGlueGkubmV0L29fMWM0Z2psOWxtMTdqbGNoYXE1NjE1aXAxOWNlYS5wbmctai5qcGc=

iget v0, p0, Ldemo;->a:I

Reads an instance field into vx. The instance is referenced by vy.

就是獲得p0,放在v0中,

然后通過return v0進行返回。

然后來看看setA()方法。

aHR0cDovL3QxLmFpeGlueGkubmV0L29fMWM0Z2s0Mm81MWc2MWNiMmczdjFkbmkxZW9mYS5wbmctai5qcGc=

setA中我們就發現了和Android逆向-java代碼基礎(7)中一樣使用了iput,簡單的來說就是把p0給p1。

2.main模塊

aHR0cDovL3QxLmFpeGlueGkubmV0L29fMWM0Z2tlcGk3MXJwbHYxbjk5ajE3cjIxYTlkYS5wbmctai5qcGc=

截圖截不下了。。。

我們主要想要看到的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有很大的幫助。

以上,待補充。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值