跳至主要内容

java语言反编译 smali 汇编基础语法(3)之算数运算,数据定义和数据操作

http://ift.tt/2BlpZII


算数运算

首先通过一个简单的例子,来看一下

public void ShowNumberTest(int a){
        int b = a;
        boolean c =false;
        Log.d("TAG","a+b ="+(a+b));
        Log.d("TAG","a-b ="+(a-b));
        Log.d("TAG","a*b ="+(a*b));
        Log.d("TAG","a/b ="+(a/b));
        Log.d("TAG","a%b ="+(a%b));
    }

反汇编代码:

# virtual methods
.method public ShowNumberTest(I)V
    .locals 5
    .param p1, "a"    # I

    .prologue
    .line 23
    move v0, p1

    .line 24
    .local v0, "b":I
    const/4 v1, 0x0

    .line 25
    .local v1, "c":Z
    const-string/jumbo v2, "TAG"

    new-instance v3, Ljava/lang/StringBuilder;

    invoke-direct {v3}, Ljava/lang/StringBuilder;-><init>()V

    const-string/jumbo v4, "a+b ="

    invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v3

    add-int v4, p1, v0

    invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;

    move-result-object v3

    invoke-virtual {v3}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v3

    invoke-static {v2, v3}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 26
    const-string/jumbo v2, "TAG"

    new-instance v3, Ljava/lang/StringBuilder;

    invoke-direct {v3}, Ljava/lang/StringBuilder;-><init>()V

    const-string/jumbo v4, "a-b ="

    invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v3

    sub-int v4, p1, v0

    invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;

    move-result-object v3

    invoke-virtual {v3}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v3

    invoke-static {v2, v3}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 27
    const-string/jumbo v2, "TAG"

    new-instance v3, Ljava/lang/StringBuilder;

    invoke-direct {v3}, Ljava/lang/StringBuilder;-><init>()V

    const-string/jumbo v4, "a*b ="

    invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v3

    mul-int v4, p1, v0

    invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;

    move-result-object v3

    invoke-virtual {v3}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v3

    invoke-static {v2, v3}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 28
    const-string/jumbo v2, "TAG"

    new-instance v3, Ljava/lang/StringBuilder;

    invoke-direct {v3}, Ljava/lang/StringBuilder;-><init>()V

    const-string/jumbo v4, "a/b ="

    invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v3

    div-int v4, p1, v0

    invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;

    move-result-object v3

    invoke-virtual {v3}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v3

    invoke-static {v2, v3}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 29
    const-string/jumbo v2, "TAG"

    new-instance v3, Ljava/lang/StringBuilder;

    invoke-direct {v3}, Ljava/lang/StringBuilder;-><init>()V

    const-string/jumbo v4, "a%b ="

    invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v3

    rem-int v4, p1, v0

    invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;

    move-result-object v3

    invoke-virtual {v3}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v3

    invoke-static {v2, v3}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 30
    return-void
.end method

一步一步的来分析:

.locals 5说明用了5个寄存器,都是局部变量
.param p1, "a" # I是参数,用的的p1寄存器
move v0, p1 把p1中的值mov到v0中,现在v0=p1

new-instance v3, Ljava/lang/StringBuilder;

    invoke-direct {v3}, Ljava/lang/StringBuilder;-><init>()V

    const-string/jumbo v4, "a+b ="

    invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v3
    

通过对比源码可以看出,这里仅仅是在Log.d("TAG","a+b ="+(a+b));的部分操作,首先,把StringBuilder对象引用放到v3寄存器中,然后调用StringBuilder的构造函数,定义了一个常量字符穿,值为a+b =,放到寄存器v4中,调用StringBuilder中的append方法(我们也可以方法,String的字符串连接调用的其实是append),然后把生成的对象的结果返回值给v3寄存器
然后add-int v4, p1, v0才是对数据的操作
下面就又是进行字符串链接然后输出日志的函数了,自己看看吧

通过上面的一个简单的例子,可以知道基本的算数指令了

指令 功能
add-int v4,v0,p1 加法,v4 =v0+v1
sub-int v4,v0,p1 减法,v4 =v0-p1
mul-int v4,v0,p1 乘法,v4 = v0*p1
div-int v4,v0,p1 除法,v4 =v0/p1
rem-int v4,v0,p1 求余数,v4=v0%p1

数据定义

指令 功能
move
v0,p1 赋值,v0=p1
const/4,v1,0x1 定义常量,v1=1
const-string v2,”MainActivity" 定义常量字符串
.local v1,”c”:Z 定义局部变量boolean类型,寄存器生命

暂时先略过更改为详细的数据定义格式,详细可以看非冲《Android 逆向入门》

数据操作

数据操作指令的格式如下:
move destination,source

根据字节码大小和类型不同,后面添加不同的后缀

指令 说明
move vA,vB vB寄存器中值赋值给VA寄存器,都为32位
move -object vA,vB 一样的,就是换成对象了
move -resulet vAA 将上一个invoke类型的执行操作的单字费对象结果赋值vAA寄存器
move -result-object vAA 将上一个invoke类型指令操作的返回对象赋值给vAA
move -exception vAA 保存一个运行时发生异常vAA寄存器,必须是异常发生时候的异常处理的第一条指令

The post java语言反编译 smali 汇编基础语法(3)之算数运算,数据定义和数据操作 appeared first on cole.

http://ift.tt/2DyyCGb Smali, android reverse, asm, smali January 23, 2018 at 04:02PM

评论

此博客中的热门博文

反Hook 之自己实现GetProcAddress和LoadLibraryA(c++ version)

http://ift.tt/2AocAD0 // 课上练习.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <windows.h> //要实现的功能: /* 自己实现GerProcAddress LoadLibraryA */ //思路: /* GerProcAddress和LoadLibraryA都是在Kernel32.dll中的 首要的任务就是找到Kernel32.dll,然后遍历IAT就能找到这两个函数 现在首要的难点就是如何找到kernel32.dll() 通过dll的加载顺序可以找到,而且虽然需要使用未文档化的API,但是好在windgb可以直接看,而且用到的也并不是很多 懒得去晚上搜了,直接自己实现一个得了,作为演示,能用就行(最好还是搜一个正规的结构体) */ /* 0: kd> dt _TEB /a nt!_TEB +0x000 NtTib : _NT_TIB +0x01c EnvironmentPointer : Ptr32 Void +0x020 ClientId : _CLIENT_ID +0x028 ActiveRpcHandle : Ptr32 Void +0x02c ThreadLocalStoragePointer : Ptr32 Void +0x030 ProcessEnvironmentBlock : Ptr32 _PEB //首先实现部分TEB结构体,因为只需要用的PEB的部分,所以实现到这就ok了 */ //构建 TEB typedef struct _TEB { //保证0x30是peb的结构体就ok了 struct _tem { DWORD a1; DWORD a2; DWORD a3; DWORD a4; DWORD a5; DWORD a6; DWORD a7; DWORD a8; DWORD a9; DWORD a10; ...

IDA动态调试ELF中遇到的问题(1)

https://ift.tt/2Gxnf2F 遇到 got SIGCHLD singal(child status has changed)...这种提示 singal fork了子进程 直接点yes,然后继续单步执行,出来提示 pass to application就行了 内存查看 用od习惯了之后,凡事都想右键看一下内存,但是IDA中好像没有那么如意, 目前只是在栈中右键发现有查看hex的选项 动态调试的时候的nop ida保存动态调试的时候修改的数据 方法一:在程序运行的时候保存 The post IDA动态调试ELF中遇到的问题(1) appeared first on cole . https://ift.tt/2q9Qf5g WHATEVER April 05, 2018 at 09:44AM

python3语法基础之函数和类

http://ift.tt/2xXd9ze 函数 什么是函数? 函数就是一些封装在一起,能够实现某种功能的代码段 函数的定义 在python中,函数通过def关键字定义 定义的格式如下: def 函数名 ( 参数 ) : 函数体 实参和形参 形参 函数定义的时候 , 写在参数列表中的变量名 实参 调用函数的时候,往函数里传递的数据 关于return 执行return语句的时候,肯定会从当前函数退出 return 可以返回值 如果没有写return ,python中默认 return None 局部变量和全局变量 在函数内或者类内定义的变量叫做局部变量,作用域只在函数或类内 定义在文件中,任何敌方都能访问到的叫全局变量 可以使用global 关键字把局部变量声明为全局变量 默认参数 python支持默认参数,也是从右向左赋值     def TestFun ( nNumA = 10 , nNumB = 20 ) : print ( nNumA , nNumB )     if __name__ == "__main__" : TestFun(); TestFun( 5 , 1 )     关键字参数 就是可以不按照顺序参数 def TestFun ( nNumA , nNumB ) : print ( nNumA , nNumB )     if __name__ == "__main__" : TestFun( nNumB = 5 , nNumA = 6 ) 变参 python中是通过* 来实现边长参数的 def TestFun ( nNumA , *args ) : print ( nNumA ) print ( args )     if __name__ == "__main__" : TestFun( 1 , 2 , 3 , 4 , 5 , 6 ) 边长的参数默认是一个元组     类 为什么会有面向对象理念? 因为所有的...