Android逆向——初识smali与java类

本文章首发于i春秋

请学好smali代码,对之后的学习有很大的帮助,当然也在这里等待你们回来复习
很多人都问学逆向需不需要有编程基础?需要是需要一点吧,只要最基础的就可以了。当然建议在学逆向的时候一起学习编程。

0x00 前言

1.建议食用者

1.想要学习Android逆向的小白,但是没有思路的。

2.入门了Android逆向觉得根基不稳的。

2.说明

由浅到深学习smali,强化分析能力。

另外,请参考HAI_手册,里面有之前总结的文章,还有一些练习题目,还有一些收集的文章。

3.内容说明

语言都是从HelloWorld的开始的,smali当然这样也可以这样学。所以我们就从HelloWorld开始学习。

4.内容安排

1.HelloWorld(开胃菜)

从一个helloworld,让你摆脱jd-gui。

2.smali与类(主菜)

从java类的呈现形式与smali类的呈现形式对比,从根本了解二者的关系。

3.smali改写一个类(饭后甜点)

通过用smali编写程序,更容易理解到smali代码的编写方法,从模仿开始,到轻车熟路。

4.小玩具(连载)

一个python写的小玩具,有兴趣可以当做一个练习。

0x01 HelloWorld

1.java编写HelloWord

package smali;

public class Hello {
    public static void main(String[] args) {
        System.out.println("HelloWorld");
    }
}

然后运行。

好了,这个就是我们的java代码,难度为0。

2.smali 的HelloWorld

生成一个dex文件,然后进行反编译,就会变成了smali代码了。

.class public LHello;
.super Ljava/lang/Object;
.source "Hello.java"


# direct methods
.method public constructor <init>()V
    .registers 1

    .prologue
    .line 2
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

.method public static main([Ljava/lang/String;)V
    .registers 3

    .prologue
    .line 6
    sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;

    const-string v1, "HelloWorld"

    invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

    .line 7
    return-void
.end method

3.smali分析

3.1 画块分析

主要我们把smali代码分成3块。

第一块就是信息说明部分。我直接在图中标明信息。

第二块就是init块。

也就是构造方法块,这里的是java虚拟机自己添加了一个默认的构造方法。

第三块是方法块,也就是说不管是main方法还是其他的方法都会在这一块里平行列出来。

3.2 单句分析

这次我们主要看main函数。

也就是这一块

.method public static main([Ljava/lang/String;)V
    .registers 3

    .prologue
    .line 6
    sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;

    const-string v1, "HelloWorld"

    invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

    .line 7
    return-void
.end method

.registers 3,可以使用的寄存器个数,v0,v1,v2。

sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;,简单来说就是 v0=System.out

const-string v1, "HelloWorld",v1=”HelloWorld”

invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V,把v0,和v1,当参数传进去。相当于是println(v0,v1);,也就是println(System.out,"HelloWorld");

普遍helloworld是最简单的,当然也是必须要走的过程。

0x02 smali与类

该上我们的主菜了。

类,很简单的东西,我们主要包含两个内容,属性和方法。

1.java类

我们来写一个简单的类,一个属性,两个方法。

如果觉得有点困难的话。

请戳这里

public class Person{
    private String name;

    public void setName(String name)
    {
        this.name=name;
    }
    public String getName()
    {
        return this.name;
    }
}

2.smali类

这个就是smali类。

是不是感觉比Helloworld多一块。

# instance fields
.field private name:Ljava/lang/String;

这里多了一个属性定义的部分。

那我们就从属性定义这里开始吧。

.field,这个就是属性的标志。 private 私有的,name,名字,Ljava/lang/String,String类型的变量。
和java恰恰相反,smali是先写出名字,在最后带上类型,java就是先类型后名字。

构造方法没有变。

我们来看看写的两个封装方法。

.registers 2,两个寄存器,v0,v1。

iget-object v0, p0, LPerson;->name:Ljava/lang/String,这里p0的意思是第一个传入的参数。这里就好奇了,明明java里没有参数,为什么这里会有呢。在虚拟机里,this就算是一个参数,所以这里才会是p0。iget-object v0,把p0的内容给v0。get,应该很好理解。LPerson;->name:Ljava/lang/String`,这里就是对p0做一个解释。

iput-object p1, p0, LPerson;->name:Ljava/lang/String;

核心的代码就是这一句。iput-object p1,p0,就是把p1的内容给p0。put,给,get拿到,刚好和之前的那个相反。这里的p1就是传入的参数。p0就是this。

分析透了其实很好理解。

0x03 smali改写一个类

这里算是一个小练习吧。

题目:

用smali代码为之前的Person类添加一个age属性,然后写出get,set方法。

建议自己写完了之后,来进行对照。

解:

首先第一步,添加属性。

第二步,添加setAge方法。

第三步,添加getAge方法。

最后一步,大功告成

最后源码:

.class public LPerson;
.super Ljava/lang/Object;
.source "Person.java"


# instance fields
.field private name:Ljava/lang/String;
.field private age:Ljava/lang/int;


# direct methods
.method public constructor <init>()V
    .registers 1

    .prologue
    .line 1
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method


# virtual methods
.method public getName()Ljava/lang/String;
    .registers 2

    .prologue
    .line 10
    iget-object v0, p0, LPerson;->name:Ljava/lang/String;

    return-object v0
.end method

.method public setName(Ljava/lang/String;)V
    .registers 2

    .prologue
    .line 6
    iput-object p1, p0, LPerson;->name:Ljava/lang/String;

    .line 7
    return-void
.end method

.method public setAge(Ljava/lang/int;)V
    .registers 2
    .prologue

    iput-object p1,p0,LPerson;->age:Ljava/lang/int;

    return-void
.end method

.method public getAge()Ljava/lang/int;
    .registers 2
    .prologue

    iget-object v0,p0,LPerson;->age:Ljava/lang/int;

    return-object v0
.end method

0x04 一个小玩具

一个python小玩具。

用途:

自动分析smali代码内容。

涉及知识点:

1.sys
2.while
3.str…split
4.if,elif

使用方法:

smali代码放在txt文件中。

简要说明:

暂时只对开始的一块进行分析。

第一个部分,读取txt内容。
然后进行判断字段。

.class字段

.super字段

.source字段

效果:

以上

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王嘟嘟_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值