Smail语法(1)

【情景分析】Android apk,反编译之后,我们能阅读到的代码是 dalvik字节码 - smali 。有时候,工作需要,必须破解apk里面的一些协议或者方法。以此,借鉴经验,来开发自己的项目。

【官方语法链接】 http://www.blogjava.net/midea0978/archive/2012/01/04/367847.html

【语法】

一. 数据类型

原始类型:

V void,只能用于返回值类型
Z     boolean
B	byte
S	short
C	char
I	int
J	long(64位)
F	float
D	double(64位)

引用类型:

对象 和 数组

Smail表现形式

原始类型:用大写字母代替即可,用法无异
引用类型:

  对象: L + 包名.对象 + ;
      对象的表示则以L作为开头,格式是LpackageName/objectName;(注意必须有个分号跟在最后),例如String对象在smali中为:Ljava/lang/String;,其中java/lang对应java.lang包,String就是定义在该包中的一个对象。
    数组:[ + 数据类型
     数组的表示方式是:在基本类型前加上前中括号“[”,例如int数组和float数组分别表示为:[I、[F           [I——表示一个整型一维数组,相当于java中的int[]。	对于多维数组,只要增加[就行了。[[I相当于int[][],[[[I相当于int[][][]。注意每一维的最多255个。	对象数组的表示:[Ljava/lang/String;表示一个String对象数组。

二. 方法

方法定义:

表示形式:Lpackage/name/ObjectName;->MethodName(III)Z
	Lpackage/name/ObjectName;表示类型,MethodName是方法名。III为参数(在此是3个整型参数),Z是返回类型(bool型)。
	方法的参数是一个接一个的,中间没有隔开。

一个更复杂的例子:

method(I[[IILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;在java中则为:String method(int, int[][], int, String, Object[])

内部类:

既然类是用LpackageName/objectName;来表示,那类里面的内部类又如何在smali中引用呢?答案是:LpackageName/objectName$subObjectName;。也就是在内部类前加“$”符号

字段:

表示形式: Lpackage/name/ObjectName;->FieldName:Ljava/lang/String;  即包名,字段名和各字段类型。

标记说明:

# static fields             定义静态变量的标记
# instance fields        定义实例变量的标记
# direct methods       定义静态方法的标记
# virtual methods      定义非静态方法的标记
构造函数的返回类型为V,名字为<init>。

语法:If语句

if-eq p1, v0, :cond_8 表示如果p1和v0相等,则执行cond_8的流程:
    :cond_8
    invoke-direct {p0}, Lcom/paul/test/a;->d()V
调用com.paul.test.a的d()方法
if-ne p1, v0, :cond_b 表示不相等则执行cond_b的流程:
    :cond_b
    const/4 v0, 0x0
    invoke-virtual {p0, v0}, Lcom/paul/test/a;->setPressed(Z)V
    invoke-super {p0, p1, p2}, Landroid/view/View;->onKeyUp(ILandroid/view/KeyEvent;)Z
    move-result v0

大概意思就是调用com.paul.test.a的setPressed方法,然后再调用父类View的onKeyUp方法,最后 return v0

  

三. 寄存器(重点)

概念:

在dalvik字节码中,寄存器都是32位的,能够支持任何类型。64位类型(Long和Double型)用2个寄存器表示。
有两种方式指定一个方法中有多少寄存器是可用的。

  .registers指令指定了方法中寄存器的总数。  .locals指令表明了方法中非参寄存器的数量。

命名方式

有两种方式——V命名方式和P命名方式。P命名方式中的第一个寄存器就是方法中的第一个参数寄存器。在下表中我们用这两种命名方式来表示上一个例子中有5个寄存器和3个参数的方法。
v0	第一个local register
v1	第二个local register
v2	p0	第一个parameter register
v3	p1	第二个parameter register
v4	p2	第三个parameter register
你可以用任何一种方式来引用参数寄存器——他们没有任何差别。
注意:baksmali默认对参数寄存器使用P命名方式。如果想使用V命名方式,可以使用-pl—no-parameter-registers选项。
使用P命名方式是为了防止以后如果要在方法中增加寄存器,需要对参数寄存器重新进行编号的缺点。
Long/Double值
Long和double类型是64位的,需要2个寄存器(切记切记)。
例如,对于非静态方法LMyObject;->MyMethod(IJZ)V,参数分别是LMyObject;,int,long,bool。故该方法需要5个寄存器来存储参数。

p0	this
p1	I
p2,p3	J
p4	Z

下篇文章继续。

时间: 2024-10-12 01:44:43

Smail语法(1)的相关文章

android 逆向project smail 语法学习

众所周知,android 是开源的.如今市场上反编译别人的劳动果实的人也不少.所以我们也是有必要学习下smail语言,(就是androidproject反编译后出的语法语音),看看改怎么给我们的代码 "埋雷" .才干更好的保护好我们自己的劳动成果. 接下来就让我们来学习下吧~!(事先声明:本人也是初学smail语言,有介绍不当的地方还请海涵,并请指出.大家一起学习) package com.example.pushdemo; import java.io.ByteArrayInputS

android 逆向工程 smail 语法学习

众所周知,android 是开源的,现在市场上反编译别人的劳动果实的人也不少,所以我们也是有必要学习下smail语言,(就是android工程反编译后出的语法语音),看看改怎么给我们的代码 "埋雷" ,才能更好的保护好我们自己的劳动成果. 接下来就让我们来学习下吧~!(事先声明:本人也是初学smail语言,有介绍不当的地方还请海涵,并请指出,大家一起学习) ========================最后附上一片文章  http://www.blogjava.net/midea09

Smail语法

1.数据类型 2.函数: Func-Name (Para-Type1Para-Type2Para-Type3...)Return-Type 注意参数与参数之间没有任何分隔符 3.函数调用: 4.关于smail文件汇总line的说明:

Smail语法(2)指令解析

[重点]归总了一些简单的Smail指令. 1.If语句 if-nez v0,:cond_0 如果结果不为0,就跳转到cond_0标号处 if-eqz v0,:cond_1 如果结果为0,就跳转到cond_1标号处 2.数据操作指令 move v0,v1 将v1的值赋给v0 ,两个寄存器都为4位 move-result v0 将上一个invoke类型指令操作的单字非对象结果赋给v0 move-result-object v0 将上一个invoke类型指令操作的对象结果(返回值)赋给v0 3.返回指

smail 语法参考

Dalvik opcodes Author: Gabor Paller Vx values in the table denote a Dalvik register. Depending on the instruction, 16, 256 or 64k registers can be accessed. Operations on long and double values use two registers, e.g. a double value addressed in the

android smail 语法学习之二

下面是if 语句 for 语句在smali中写法: 条件跳转分支: "if-eq vA, vB, :cond_**"   如果vA等于vB则跳转到:cond_**"if-ne vA, vB, :cond_**"   如果vA不等于vB则跳转到:cond_**"if-lt vA, vB, :cond_**"    如果vA小于vB则跳转到:cond_**"if-ge vA, vB, :cond_**"   如果vA大于等于vB则

安卓实战开发之JNI入门及高效的配置(android studio一键生成.h,so及方法签名)

前言 以前也讲过NDK开发,但是开始是抱着好玩的感觉去开始的,然后呢会helloWord就觉得大大的满足,现在静下来想这NDK开发到底是干什么呢? NDK开发,其实是为了项目需要调用底层的一些C/C++的一些东西:另外就是为了效率更加高效些但是在java与C相互调用时平白又增大了开销(其实效率不见得有所提高),然后呢,基于安全性的考虑也是为了防止代码被反编译我们为了安全起见,使用C语言来编写这些重要的部分来增大系统的安全性,最后呢生成so库便于给人提供方便. 好了,我们来看一下qq的结构,我们就

Android逆向之旅---静态分析技术来破解Apk

一.前言 从这篇文章开始我们开始我们的破解之路,之前的几篇文章中我们是如何讲解怎么加固我们的Apk,防止被别人破解,那么现在我们要开始破解我们的Apk,针对于之前的加密方式采用相对应的破解技术,Android中的破解其实大体上可以分为静态分析和动态分析,对于这两种方式又可以细分为Java层(smail和dex)和native层(so).所以我们今天主要来讲解如何通过静态分析来破解我们的apk,这篇文章我们会通过破解Java层和native层的例子来讲解. 二.准备工作 在开始今天的文章之前,我们

作为安卓开发者必备的小软件(全是干货)

1.你应该要懂安卓逆向破解 在一种意外的情况下,爱上了腾讯的手游游戏,正好,那时候,天天酷跑,天天飞车真的很火.好吧,无意之间在以前黑客论坛逛帖子的时候,有人出了一个安卓逆向破解,无耻了学了,然后搞了半年的腾讯破解,不说多了哈 对于破解安卓APK 你只需要一个软件,功能能满足你的变态需求,当然你可以顺便学习一下smail语法,对你破解有很大的帮助. 小米人APK改之理(apkIde) 2.你应该懂 json格式化 也是有软件的 有不有现在拿着json字符串,去百度<json格式化>......