您的位置:首页 > 汽车 > 时评 > Smali语法(一)

Smali语法(一)

2025/1/8 11:49:20 来源:https://blog.csdn.net/qq_23025319/article/details/141163280  浏览:    关键词:Smali语法(一)

Smali语法(一)

本文主要介绍下Smali语法相关.

一: 简介

Smali是一种用于Android应用逆向工程和动态代码修改的小型低级字节码语言,它是Dalvik虚拟机(Virtual Machine)指令集的一种文本表示形式。它并非Java源代码的直接映射,而是更接近于VM实际运行的机器码。SMALI由四部分组成:

  1. 类(Class): 定义了类的数据结构,包括字段、方法等。
  2. 字段(Field): 表示类变量或实例变量。
  3. 调用(Call): 描述方法的调用,包括方法名、参数列表和返回值类型。
  4. 条件和循环(Conditions and Loops): 控制流指令,如if-else、while等。

二: Smali文件格式.

注: 本篇文章用到代码均是来自.v2rayNG.apk

2.1: 头信息

smali文件的头三行描述了当前类的一些信息,格式如下:

  1. .class <访问权限> <修饰关键字> <类名>

指令指定了当前类的类名.

  1. .super <父类名>

指令指定了当前类的父类

  1. .source <源文件名>

指令指定了当前类的源文件.

我们以MainActivity.smali为例:

.class public final Lcom/v2ray/ang/ui/MainActivity;
.super Lcom/v2ray/ang/ui/BaseActivity;
.source "MainActivity.kt"

MessageUtil.smali如下:

.class public final Lcom/v2ray/ang/util/MessageUtil;
.super Ljava/lang/Object;
.source "MessageUtil.kt"
2.2: 接口信息

MainActivity.smali 头信息紧跟着如下:

# interfaces
.implements Lcom/google/android/material/navigation/NavigationView$OnNavigationItemSelectedListener;

.implements这一行通常出现在类声明.class中,它的作用是声明该类实现了哪些接口(Interface).

也就是代表了MainActivity实现了NavigationView$OnNavigationItemSelectedListener接口.

2.3: 注解

如果一个类使用了注解,那smali代码中会使用".annotation"指令指出.

具体的格式如下:

#annotations

.annotation <注解属性> <注解类名>

.end annotation

2.4: 定义字段

smali中使用.field 来定义字段.

如MainActivity.smali 中定义了修饰符 private 私有 final 不可变的 类型 Lkotlin/Lazy. 用于延时加载的适配器类型字段: adapter$delegate.

# instance fields
.field private final adapter$delegate:Lkotlin/Lazy;
2.5: 定义方法

定义方法则是: 以 .method开始, .end method 结束;

.method public constructor <init>()V.registers 8.line 46invoke-direct {p0}, Lcom/v2ray/ang/ui/BaseActivity;-><init>()V.line 49new-instance v0, Lcom/v2ray/ang/ui/MainActivity$adapter$2;invoke-direct {v0, p0}, Lcom/v2ray/ang/ui/MainActivity$adapter$2;-><init>(Lcom/v2ray/ang/ui/MainActivity;)Vcheck-cast v0, Lkotlin/jvm/functions/Function0;invoke-static {v0}, Lkotlin/LazyKt;->lazy(Lkotlin/jvm/functions/Function0;)Lkotlin/Lazy;move-result-object v0iput-object v0, p0, Lcom/v2ray/ang/ui/MainActivity;->adapter$delegate:Lkotlin/Lazy;.line 50sget-object v0, Lcom/v2ray/ang/ui/MainActivity$mainStorage$2;->INSTANCE:Lcom/v2ray/ang/ui/MainActivity$mainStorage$2;check-cast v0, Lkotlin/jvm/functions/Function0;invoke-static {v0}, Lkotlin/LazyKt;->lazy(Lkotlin/jvm/functions/Function0;)Lkotlin/Lazy;move-result-object v0iput-object v0, p0, Lcom/v2ray/ang/ui/MainActivity;->mainStorage$delegate:Lkotlin/Lazy;.line 51sget-object v0, Lcom/v2ray/ang/ui/MainActivity$settingsStorage$2;->INSTANCE:Lcom/v2ray/ang/ui/MainActivity$settingsStorage$2;check-cast v0, Lkotlin/jvm/functions/Function0;invoke-static {v0}, Lkotlin/LazyKt;->lazy(Lkotlin/jvm/functions/Function0;)Lkotlin/Lazy;move-result-object v0iput-object v0, p0, Lcom/v2ray/ang/ui/MainActivity;->settingsStorage$delegate:Lkotlin/Lazy;.line 52new-instance v0, Landroidx/activity/result/contract/ActivityResultContracts$StartActivityForResult;invoke-direct {v0}, Landroidx/activity/result/contract/ActivityResultContracts$StartActivityForResult;-><init>()Vcheck-cast v0, Landroidx/activity/result/contract/ActivityResultContract;new-instance v1, Lcom/v2ray/ang/ui/MainActivity$$ExternalSyntheticLambda12;invoke-direct {v1, p0}, Lcom/v2ray/ang/ui/MainActivity$$ExternalSyntheticLambda12;-><init>(Lcom/v2ray/ang/ui/MainActivity;)Vinvoke-virtual {p0, v0, v1}, Lcom/v2ray/ang/ui/MainActivity;->registerForActivityResult(Landroidx/activity/result/contract/ActivityResultContract;Landroidx/activity/result/ActivityResultCallback;)Landroidx/activity/result/ActivityResultLauncher;move-result-object v0const-string v1, "registerForActivityResul\u2026rtV2Ray()\n        }\n    }"invoke-static {v0, v1}, Lkotlin/jvm/internal/Intrinsics;->checkNotNullExpressionValue(Ljava/lang/Object;Ljava/lang/String;)Viput-object v0, p0, Lcom/v2ray/ang/ui/MainActivity;->requestVpnPermission:Landroidx/activity/result/ActivityResultLauncher;.line 58move-object v0, p0check-cast v0, Landroidx/activity/ComponentActivity;.line 664new-instance v1, Lcom/v2ray/ang/ui/MainActivity$special$$inlined$viewModels$default$1;invoke-direct {v1, v0}, Lcom/v2ray/ang/ui/MainActivity$special$$inlined$viewModels$default$1;-><init>(Landroidx/activity/ComponentActivity;)Vcheck-cast v1, Lkotlin/jvm/functions/Function0;.line 668new-instance v2, Landroidx/lifecycle/ViewModelLazy;const-class v3, Lcom/v2ray/ang/viewmodel/MainViewModel;invoke-static {v3}, Lkotlin/jvm/internal/Reflection;->getOrCreateKotlinClass(Ljava/lang/Class;)Lkotlin/reflect/KClass;move-result-object v3.line 670new-instance v4, Lcom/v2ray/ang/ui/MainActivity$special$$inlined$viewModels$default$2;invoke-direct {v4, v0}, Lcom/v2ray/ang/ui/MainActivity$special$$inlined$viewModels$default$2;-><init>(Landroidx/activity/ComponentActivity;)Vcheck-cast v4, Lkotlin/jvm/functions/Function0;.line 672new-instance v5, Lcom/v2ray/ang/ui/MainActivity$special$$inlined$viewModels$default$3;const/4 v6, 0x0invoke-direct {v5, v6, v0}, Lcom/v2ray/ang/ui/MainActivity$special$$inlined$viewModels$default$3;-><init>(Lkotlin/jvm/functions/Function0;Landroidx/activity/ComponentActivity;)Vcheck-cast v5, Lkotlin/jvm/functions/Function0;.line 668invoke-direct {v2, v3, v4, v1, v5}, Landroidx/lifecycle/ViewModelLazy;-><init>(Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)Vcheck-cast v2, Lkotlin/Lazy;.line 58iput-object v2, p0, Lcom/v2ray/ang/ui/MainActivity;->mainViewModel$delegate:Lkotlin/Lazy;.line 356new-instance v0, Landroidx/activity/result/contract/ActivityResultContracts$StartActivityForResult;invoke-direct {v0}, Landroidx/activity/result/contract/ActivityResultContracts$StartActivityForResult;-><init>()Vcheck-cast v0, Landroidx/activity/result/contract/ActivityResultContract;new-instance v1, Lcom/v2ray/ang/ui/MainActivity$$ExternalSyntheticLambda10;invoke-direct {v1, p0}, Lcom/v2ray/ang/ui/MainActivity$$ExternalSyntheticLambda10;-><init>(Lcom/v2ray/ang/ui/MainActivity;)Vinvoke-virtual {p0, v0, v1}, Lcom/v2ray/ang/ui/MainActivity;->registerForActivityResult(Landroidx/activity/result/contract/ActivityResultContract;Landroidx/activity/result/ActivityResultCallback;)Landroidx/activity/result/ActivityResultLauncher;move-result-object v0const-string v1, "registerForActivityResul\u2026RESULT\"))\n        }\n    }"invoke-static {v0, v1}, Lkotlin/jvm/internal/Intrinsics;->checkNotNullExpressionValue(Ljava/lang/Object;Ljava/lang/String;)Viput-object v0, p0, Lcom/v2ray/ang/ui/MainActivity;->scanQRCodeForConfig:Landroidx/activity/result/ActivityResultLauncher;.line 362new-instance v0, Landroidx/activity/result/contract/ActivityResultContracts$StartActivityForResult;invoke-direct {v0}, Landroidx/activity/result/contract/ActivityResultContracts$StartActivityForResult;-><init>()Vcheck-cast v0, Landroidx/activity/result/contract/ActivityResultContract;new-instance v2, Lcom/v2ray/ang/ui/MainActivity$$ExternalSyntheticLambda9;invoke-direct {v2, p0}, Lcom/v2ray/ang/ui/MainActivity$$ExternalSyntheticLambda9;-><init>(Lcom/v2ray/ang/ui/MainActivity;)Vinvoke-virtual {p0, v0, v2}, Lcom/v2ray/ang/ui/MainActivity;->registerForActivityResult(Landroidx/activity/result/contract/ActivityResultContract;Landroidx/activity/result/ActivityResultCallback;)Landroidx/activity/result/ActivityResultLauncher;move-result-object v0invoke-static {v0, v1}, Lkotlin/jvm/internal/Intrinsics;->checkNotNullExpressionValue(Ljava/lang/Object;Ljava/lang/String;)Viput-object v0, p0, Lcom/v2ray/ang/ui/MainActivity;->scanQRCodeForUrlToCustomConfig:Landroidx/activity/result/ActivityResultLauncher;.line 533new-instance v0, Landroidx/activity/result/contract/ActivityResultContracts$StartActivityForResult;invoke-direct {v0}, Landroidx/activity/result/contract/ActivityResultContracts$StartActivityForResult;-><init>()Vcheck-cast v0, Landroidx/activity/result/contract/ActivityResultContract;new-instance v1, Lcom/v2ray/ang/ui/MainActivity$$ExternalSyntheticLambda11;invoke-direct {v1, p0}, Lcom/v2ray/ang/ui/MainActivity$$ExternalSyntheticLambda11;-><init>(Lcom/v2ray/ang/ui/MainActivity;)Vinvoke-virtual {p0, v0, v1}, Lcom/v2ray/ang/ui/MainActivity;->registerForActivityResult(Landroidx/activity/result/contract/ActivityResultContract;Landroidx/activity/result/ActivityResultCallback;)Landroidx/activity/result/ActivityResultLauncher;move-result-object v0const-string v1, "registerForActivityResul\u2026mUri(uri)\n        }\n    }"invoke-static {v0, v1}, Lkotlin/jvm/internal/Intrinsics;->checkNotNullExpressionValue(Ljava/lang/Object;Ljava/lang/String;)Viput-object v0, p0, Lcom/v2ray/ang/ui/MainActivity;->chooseFileForCustomConfig:Landroidx/activity/result/ActivityResultLauncher;return-void
.end method

如上所示: .method public constructor ()V

则代表了无参构造.

注意这里.registers则是指定方法内使用寄存器的总数.

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com