ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

安卓逆向一——Smali学习

2021-06-02 18:59:18  阅读:405  来源: 互联网

标签:逆向 p1 p2v0 int 安卓 public v0 v1 Smali


Something u have to know:

       虽然Android平台使用Java来开发应用程序,但Android程序却不是运行在标准的Java虚拟机上,而是将Java字节码转换成Dalvik字节码,并打包到一个DEX可执行文档当中,Dalvik虚拟机通过解析DEX文件来执行这些字节码。

       因此我们想了解安卓逆向,就要先了解一下Dalvik的语法。

目录

Something u have to know

0x01 工具准备

0x02 语法了解

0x03 举例解读



0x01 工具准备:

        学习时我们可以用J2S2J(Java to Smali to Java转换工具):

            https://www.onlinedown.net/download/1209079?module=download

0x02 语法了解:

       本章节只录入部分,初次阅读快速浏览熟悉部分语法即可。

    1、数据类型对应表:

smali类型java类型
Vvoid (用于返回类型)
Zboolean
Bbyte
Sshort
Cchar
Iint
Jlong (64 bits)
Ffloat
Ddouble (64 bits)

    2、运算符描述表:

smali运算符描述
add-int v0, p1, p2v0 = p1 + p2
sub-int v0, p1, p2v0 = p1 - p2
mul-int v0, p1, p2v0 = p1 * p2
div-int v0, p1, p2v0 = p1 / p2
rem-int v0, p1, p2v0 = p1 % p2
and-int v0, p1, p2v0 = p1 & p2
or-int v0, p1, p2v0 = p1 │ p2
xor-int v0, p1, p2v0 = p1 ^ p2
shl-int v0, p1, p2v0 = p1 << p2
shr-int v0, p1, p2v0 = p1 >> p2
ushr-int v0, p1, p2v0 = p1 >>> p2
add-int/2addr v0, v1v0 = v0 + v1
sub-int/2addr v0, v1v0 = v0 - v1
add-int/lit16 v0, v1, lit16v0 = v1 + lit16
sub-int/lit16 v0, v1, lit16v0 = v1 - lit16
add-int/lit8 v0, v1, lit8v0 = v1 + lit8
sub-int/lit8 v0, v1, lit8v0 = v1 - lit8

    3、类名对照表:

smali类名java类名
Ljava/lang/String;java.lang.String
Ljava/lang/Object;java.lang.Object

4、数组对照表:

smali数组Java数组
[Iint[]
[[Iint[][]
[Ljava/lang/String;String[]
几维就在类型前加几个[号,最多255维

    5、其他指令描述表:

常用指令描述
const/4 v0, 0x0

给v0寄存器赋值0(此格式为int4bit)

move v0, v1将v1的值移入v0中
invoke-调用某方法
if-eq v0, v1, :cond_0

if (v0 == v1) cond_0

(eq==,ne!=,gt>,ge>=,lt<,le<=,eqz==0)

iget取值(默认int,iget-类型)
iput赋值(int,iget-类型)

0x03 举例解读:

    1、乘法运算:

        J2S:

        Java:

public class BaseData
{
    public int add(int i, int j)
    {
        return i * j;
    }
}

        Smali:

.class public LBaseData;    // 本类
.super Ljava/lang/Object;    // 父类
.source "BaseData.java"    // 文件名


# direct methods
// 构造方法, 方法名为<init>
.method public constructor <init>()V    // 该段未在java代码中显示,java中默认有一个隐藏的无参数的构造方法
    .registers 1    // 声明算上参数, 一共需要几个寄存器(寄存器用p) 不算参数使用locals(寄存器用v)

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

    return-void
.end method


# virtual methods
// 自定义的add方法
.method public add(II)I
    .registers 4

    .prologue
    .line 5
    mul-int v0, p1, p2    // v0=p1*p2

    return v0
.end method

     2、for循环:

        J2S:

 

        Java:

public class ForData
{
    public void forFuc()
    {
        for(int i = 0;i<10;i++)
        {
            System.out.println(i);
        };
    };
    public static void main(String[] args)
    {
        ForData data = new ForData();
        data.forFuc();
    }
}

        Smali:

.class public LForData;    // 本类
.super Ljava/lang/Object;    // 父类
.source "ForData.java"    // 文件名


# direct methods
// 构造方法, 方法名为<init>
.method public constructor <init>()V    // 该段未在java代码中显示,java中默认有一个隐藏的无参数的构造方法
    .registers 1    // 声明算上参数, 一共需要几个寄存器(寄存器用p) 不算参数使用locals(寄存器用v)

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

    return-void
.end method

// 主方法
.method public static main([Ljava/lang/String;)V
    .registers 2

    .prologue
    .line 12
    new-instance v0, LForData;    //根据ForData类创建对象,保存在v0中

    invoke-direct {v0}, LForData;-><init>()V    //调用<init>构造方法

    .line 13
    invoke-virtual {v0}, LForData;->forFuc()V    //调用自定义方法forFuc

    .line 14
    return-void
.end method


# virtual methods
// 自定义方法forFuc
.method public forFuc()V
    .registers 3

    .prologue
    .line 5
    const/4 v0, 0x0    // v0 = 0

    :goto_1
    const/16 v1, 0xa    // v1 = 10

    if-ge v0, v1, :cond_d    // if ( v0 > v1 ) 跳转cond_d

    .line 7
    sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;    //获取PrintStream类成员变量out对象,并放到v1寄存器中 v1=out()

    invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(I)V    //调用printLn方法中V1实例打印v0    println.out(v0)

    .line 5
    add-int/lit8 v0, v0, 0x1    // v0++

    goto :goto_1    // 循环

    .line 9
    :cond_d
    return-void    // 直接返回、跳出
.end method

       本篇基础引导,可以把自己的一些Java项目通过J2S2J工具转换并分析,熟练掌握Java代码和Smali代码的互相转换,为安卓逆向代码层打好基础。

标签:逆向,p1,p2v0,int,安卓,public,v0,v1,Smali
来源: https://blog.csdn.net/weixin_43526443/article/details/117468681

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有