Android逆向-Android逆向基础10(so文件分析大合集)

0x00 前言

导航

博客导航戳这里
练习资源戳这里

说明

在so文件的分析上,我们需要对一些ARM汇编的逻辑实现。
在代码逻辑上,只对if,switch,还有循环进行一个demo分析和创建。可能会篇幅比较大。

内容

1.if逻辑NDK编程
2.if逻辑ARM分析
3.switch逻辑NDK编程
4.switch逻辑ARM分析
5.循环逻辑NDK编程
6.循环逻辑ARM分析

0x01 if逻辑NDK编程

demo使用之前的demo,如果有兴趣,可以去看看
博客导航戳这里

说明

demo主要实现一个输入,然后根据输入的内容返回不同的内容。在Native层进行实现。

第一步 函数书写

首先添加一个函数,然后使用 ALT+Enter进行自动创建

第二步 自动生成

在.cpp文件里会自动生成一个函数

JNIEXPORT jstring JNICALL
Java_com_example_hanlei_myapplication_MainActivity_panduan(JNIEnv *env, jobject instance, jint i) {

    // TODO

    return env->NewStringUTF(returnValue);
}

第三步 编写c语言代码

JNIEXPORT jstring JNICALL
Java_com_example_hanlei_myapplication_MainActivity_panduan(JNIEnv *env, jobject instance, jint i) {

    if (i==1)
    {
        return env->NewStringUTF("I LOVE YOU!");
    }
    return env->NewStringUTF("Sorrry");
}

第四步 编写xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.hanlei.myapplication.MainActivity">

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/et"
        android:hint="请输入数字"
        android:numeric="integer"
        />
    <TextView
        android:id="@+id/sample_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hai ,my Love"
         />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Go"
        android:id="@+id/btn"/>

</LinearLayout>

第五步,逻辑编写

这个是MainActivity的代码。

package com.example.hanlei.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
private TextView tv;
private EditText et;
    // Used to load the ‘native-lib‘ library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
         tv = (TextView) findViewById(R.id.sample_text);
         et=findViewById(R.id.et);
        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                tv.setText(panduan(Integer.parseInt(et.getText().toString())));
            }
        });
    }

    /**
     * A native method that is implemented by the ‘native-lib‘ native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
    public native String getHelloJni();
    public native void updateFile(String path);
    public native String panduan(int i);
}

这个是主要的代码。

findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                tv.setText(panduan(Integer.parseInt(et.getText().toString())));
            }
        });

第六步 测试



总结

很简单,不过多解释。

0x02 if逻辑反汇编分析

反汇编分析,当然是要丢在IDA里进行分析了。
这里有个问题就是,IDA只有32位才可以使用F5插件,我之前不知道,坑了好久。
我假装自己不知道自己的函数名称啊什么的。就按照流程进行分析。
本来第一步是要进行试玩的,demo试玩我就算了吧。

第一步,反编译,找到函数。

反编译,找Android Killer

找到函数之后进行反汇编。

第二步,反汇编

双击进入函数。

第三步 F5插件

F5插件真的比较好用,但是我们还是以ARM为主。

第四步 ARM分析

首先来看下流程图

从流程图上可以看到这是一个if逻辑的流程图。

我们来看主要代码

.text:00004644                 PUSH            {R7,LR}
.text:00004646                 MOV             R7, SP
.text:00004648                 SUB             SP, SP, #0x20
.text:0000464A                 MOV             R3, R2
.text:0000464C                 MOV             R12, R1
.text:0000464E                 MOV             LR, R0
.text:00004650                 STR             R0, [SP,#0x28+var_10]
.text:00004652                 STR             R1, [SP,#0x28+var_14]
.text:00004654                 STR             R2, [SP,#0x28+var_18]
.text:00004656                 LDR             R0, [SP,#0x28+var_18]
.text:00004658                 CMP             R0, #1
.text:0000465A                 STR             R3, [SP,#0x28+var_1C]
.text:0000465C                 STR.W           R12, [SP,#0x28+var_20]
.text:00004660                 STR.W           LR, [SP,#0x28+var_24]
.text:00004664                 BNE             loc_4676
.text:00004666                 B               loc_4668
PUSH            {R7,LR}

PUSH 是入栈的意思
R7是通用寄存器
LR就是:R14:链接寄存器(LR) LR是链接寄存器,是ARM处理器中一个有特殊用途的寄存器,当调用函数时,返回地址即PC的值被保存到LR中(mov lr,pc)。

那么这句话的意思就是把R7 和LR入栈

MOV             R7, SP

这句话好理解,就是把sp的值给R7。
在随机存储器区划出一块区域作为堆栈区,数据可以一个个顺序地存入(压入)到这个区域之中,这个过程称为‘压栈’(push )。通常用一个指针(堆栈指针 SP---Stack Pointer)实现做一次调整,SP 总指向最后一个压入堆栈的数据所在的数据单元(栈顶)。

SUB             SP, SP, #0x20

SUB 是减法运算。
简单的翻译一下就是:sp=sp-#0x20
这里的#0x20就是十六进制的意思。

 MOV             R3, R2

R3=R2

 MOV             R12, R1

R12=R1

MOV             LR, R0

LR=R0

STR             R0, [SP,#0x28+var_10]

STR{条件} 源寄存器,<存储器地址>
STR指令用于从源寄存器中将一个32位的字数据传送到存储器中。该指令在程序设计中比较常用。

翻译一下就是 把R0这里的数据送到[SP,#0x28+var_10]中

STR             R1, [SP,#0x28+var_14]

同理

STR             R2, [SP,#0x28+var_18]

同理

 LDR             R0, [SP,#0x28+var_18]

LDR 伪指令用于加载立即数或一个地址值到指定寄存器.

 CMP             R0, #1

CMP是比较命令,R0和#1进行比较
CF=1,因为有借位
OF=0,未溢出
SF=1,结果是负数
ZF=0,结果不全是零

 STR             R3, [SP,#0x28+var_1C]

[SP,#0x28+var_1C] 的数据送入R3中

STR.W           R12, [SP,#0x28+var_20]

.W 是wide。指定汇编器必须为这条指令选择一个32位的编码模式。如果办不到,汇编器报错。

STR.W           LR, [SP,#0x28+var_24]
BNE             loc_4676

bne: 数据跳转指令,标志寄存器中Z标志位不等于零时, 跳转到BNE后标签处
也就是说当Z不等于0的时候也就是不相等的时候就会跳转到loc_4676

B               loc_4668

无条件跳转

恩,我大概懂了。

如果不满足就跳转到这里。

loc_4668                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+22↑j
.text:00004668                 LDR             R0, [SP,#0x28+var_10] ; this
.text:0000466A                 LDR             R1, =(aILoveYou - 0x4670)
.text:0000466C                 ADD             R1, PC  ; "I LOVE YOU!"
.text:0000466E                 BLX             j__ZN7_JNIEnv12NewStringUTFEPKc ; _JNIEnv::NewStringUTF(char const*)
.text:00004672                 STR             R0, [SP,#0x28+var_C]
.text:00004674                 B               loc_4684

如果满足的话,叫跳转到这里

.text:00004676
.text:00004676 loc_4676                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+20↑j
.text:00004676                 LDR             R0, [SP,#0x28+var_10] ; this
.text:00004678                 LDR             R1, =(aSorrry - 0x467E)
.text:0000467A                 ADD             R1, PC  ; "Sorrry"
.text:0000467C                 BLX             j__ZN7_JNIEnv12NewStringUTFEPKc ; _JNIEnv::NewStringUTF(char const*)
.text:00004680                 STR             R0, [SP,#0x28+var_C]
.text:00004682                 B               loc_4684

最后就会归结在这里:

oc_4684                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+30↑j
.text:00004684                                         ; Java_com_example_hanlei_myapplication_MainActivity_panduan+3E↑j
.text:00004684                 LDR             R0, [SP,#0x28+var_C]
.text:00004686                 ADD             SP, SP, #0x20
.text:00004688                 POP             {R7,PC}

其中有很多是自带的东西,所以重要的东西画出来。

首先是这个,参数

调用参数,然后进行比较

根据寄存器进行跳转

0x03 switch逻辑NDK编程

说明

直接使用上次的demo来进行更改,然后直接修改c语言程序就可以了。

c文件编写

JNIEXPORT jstring JNICALL
Java_com_example_hanlei_myapplication_MainActivity_panduan(JNIEnv *env, jobject instance, jint i) {

    switch(i)
    {
        case 1:
            return env->NewStringUTF("Love");
            break;
        case 2:
            return env->NewStringUTF("ZHUZHU");
            break;
        case 3:
            return env->NewStringUTF("Life");
            break;
    }
    return env->NewStringUTF("Sorrry");
}

测试说明

总结

编写还是非常简单的,只要知道接口函数,在前期没有什么困难的地方。

0x04 switch逻辑ARM分析

暂停:2018年2月15日02:29:01
原因:该睡觉了。恩,要好好的睡一觉,然后起来学习。

开始时间:2018年2月15日11:33:13
原因:刚吃完午饭

直接上IDA分析了

.text:00004644 ; __unwind {
.text:00004644                 PUSH            {R7,LR}
.text:00004646                 MOV             R7, SP
.text:00004648                 SUB             SP, SP, #0x20
.text:0000464A                 MOV             R3, R2
.text:0000464C                 MOV             R12, R1
.text:0000464E                 MOV             LR, R0
.text:00004650                 STR             R0, [SP,#0x28+var_10]
.text:00004652                 STR             R1, [SP,#0x28+var_14]
.text:00004654                 STR             R2, [SP,#0x28+var_18]
.text:00004656                 LDR             R0, [SP,#0x28+var_18]
.text:00004658                 CMP             R0, #1
.text:0000465A                 STR             R3, [SP,#0x28+var_1C]
.text:0000465C                 STR.W           R12, [SP,#0x28+var_20]
.text:00004660                 STR.W           LR, [SP,#0x28+var_24]
.text:00004664                 STR             R0, [SP,#0x28+var_28]
.text:00004666                 BEQ             loc_467A
.text:00004668                 B               loc_466A

逻辑图

分析

首先来说,这些ARM代码,个人理解,就是在进行函数以及函数内参数的初始化过程,也可以理解为在构建一个我们主要ARM进行逻辑运算的环境或者是平台,之后也有一相对应的环境释放。

我们来看一下主要的逻辑判断部分。

CMP             R0, #1

用R0和#1进行比较。

BEQ             loc_467A

标志寄存器中Z标志位等于零时, 跳转到BEQ后标签处。

然后就跳转到这里了:

突然发现判断逻辑好简单,可能是我太无知了。

B               loc_466A

无条件跳转到下一个判断。
之前还在想多个if怎么实现,现在发现还是按照一个块一个来进行运行。
现在知道了那两周学习8086不是白学习的了。

loc_466A                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+24↑j
.text:0000466A                 LDR             R0, [SP,#0x28+var_28]
.text:0000466C                 CMP             R0, #2
.text:0000466E                 BEQ             loc_4688
.text:00004670                 B               loc_4672
.text:00004672 ; ---------------------------------------------------------------------------
.text:00004672
.text:00004672 loc_4672                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+2C↑j
.text:00004672                 LDR             R0, [SP,#0x28+var_28]
.text:00004674                 CMP             R0, #3
.text:00004676                 BEQ             loc_4696
.text:00004678                 B               loc_46A4
.text:0000467A ; ---------------------------------------------------------------------------
.text:0000467A
.text:0000467A loc_467A                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+22↑j
.text:0000467A                 LDR             R0, [SP,#0x28+var_10] ; this
.text:0000467C                 LDR             R1, =(aLove - 0x4682)
.text:0000467E                 ADD             R1, PC  ; "Love"
.text:00004680                 BLX             j__ZN7_JNIEnv12NewStringUTFEPKc ; _JNIEnv::NewStringUTF(char const*)
.text:00004684                 STR             R0, [SP,#0x28+var_C]
.text:00004686                 B               loc_46B2
.text:00004688 ; ---------------------------------------------------------------------------
.text:00004688
.text:00004688 loc_4688                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+2A↑j
.text:00004688                 LDR             R0, [SP,#0x28+var_10] ; this
.text:0000468A                 LDR             R1, =(aZhuzhu - 0x4690)
.text:0000468C                 ADD             R1, PC  ; "ZHUZHU"
.text:0000468E                 BLX             j__ZN7_JNIEnv12NewStringUTFEPKc ; _JNIEnv::NewStringUTF(char const*)
.text:00004692                 STR             R0, [SP,#0x28+var_C]
.text:00004694                 B               loc_46B2
.text:00004696 ; ---------------------------------------------------------------------------
.text:00004696
.text:00004696 loc_4696                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+32↑j
.text:00004696                 LDR             R0, [SP,#0x28+var_10] ; this
.text:00004698                 LDR             R1, =(aLife - 0x469E)
.text:0000469A                 ADD             R1, PC  ; "Life"
.text:0000469C                 BLX             j__ZN7_JNIEnv12NewStringUTFEPKc ; _JNIEnv::NewStringUTF(char const*)
.text:000046A0                 STR             R0, [SP,#0x28+var_C]

这是剩下的代码逻辑,如果有兴趣可以自己进行分析使用。

感觉自己一下次大彻大悟了。
接下来就是循环逻辑了。

0x05 循环逻辑NDK编程

步骤和之前一样,我只是改变一下c代码。

c代码编写

写一个简单的逻辑。
就是判断质数。

JNIEXPORT jstring JNICALL
Java_com_example_hanlei_myapplication_MainActivity_panduan(JNIEnv *env, jobject instance, jint i) {

    int j;
    int t=1;
    if(i==1)
    {
        return env->NewStringUTF("Sorrry");
    }
    if(i==2)
    {
        return env->NewStringUTF("ZHUZHU I Love YOU");
    }
    for(j=2;j<i;j++)
    {
        if(i%j==0)
        {
            t=0;
        }
    }
    if(t==1)
    {
        return env->NewStringUTF("ZHUZHU I Love YOU");
    }
    return env->NewStringUTF("Sorrry");
}

测试说明

0x06 循环逻辑ARM分析

用IDA打开so文件

 PUSH            {R7,LR}
.text:00004646                 MOV             R7, SP
.text:00004648                 SUB             SP, SP, #0x28
.text:0000464A                 MOV             R3, R2
.text:0000464C                 MOV             R12, R1
.text:0000464E                 MOV             LR, R0
.text:00004650                 STR             R0, [SP,#0x30+var_10]
.text:00004652                 STR             R1, [SP,#0x30+var_14]
.text:00004654                 STR             R2, [SP,#0x30+var_18]
.text:00004656                 MOVS            R0, #1
.text:00004658                 STR             R0, [SP,#0x30+var_20]
.text:0000465A                 LDR             R0, [SP,#0x30+var_18]
.text:0000465C                 CMP             R0, #1
.text:0000465E                 STR             R3, [SP,#0x30+var_24]
.text:00004660                 STR.W           R12, [SP,#0x30+var_28]
.text:00004664                 STR.W           LR, [SP,#0x30+var_2C]
.text:00004668                 BNE             loc_467A
.text:0000466A                 B               loc_466C

这里是主体部分,类似于main的开头

开始逻辑分析

这些ARM代码就是在搭建环境。

 PUSH            {R7,LR}
.text:00004646                 MOV             R7, SP
.text:00004648                 SUB             SP, SP, #0x28
.text:0000464A                 MOV             R3, R2
.text:0000464C                 MOV             R12, R1
.text:0000464E                 MOV             LR, R0
.text:00004650                 STR             R0, [SP,#0x30+var_10]
.text:00004652                 STR             R1, [SP,#0x30+var_14]
.text:00004654                 STR             R2, [SP,#0x30+var_18]
MOVS            R0, #1

MOV一般不影响CPSR, 除非执行类似MOV pc, lr,效果上等同于BX lr,可能会影响到T标志位
MOVS总是会影响CPSR, 包括N,Z,C标志位,执行MOVS pc, lr时,CPSR会被SPSR覆盖(内核态,USER和SYSTEM模式下没有SPSR)

再简单的说就是 R0=#1

STR             R0, [SP,#0x30+var_20]

然后把这个值存放在 [SP,#0x30+var_20]这里

 LDR             R0, [SP,#0x30+var_18]

把[SP,#0x30+var_18]的值取出来给R0

CMP             R0, #1

然后拿出来比较

STR             R3, [SP,#0x30+var_24]
.text:00004660                 STR.W           R12, [SP,#0x30+var_28]
.text:00004664                 STR.W           LR, [SP,#0x30+var_2C]

其实我真的不知道这是什么东西,如果有人知道的话可以告诉我不。反正我忽略了。不影响分析逻辑

BNE             loc_467A

bne: 数据跳转指令,标志寄存器中Z标志位不等于零时, 跳转到BNE后标签处

如果不等于#1的话就会进行跳转

B               loc_466C

如果相等,就会执行无条件跳转。

我们现在来看loc_466C这一个块

loc_466C块分析

loc_466C                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+26↑j
.text:0000466C                 LDR             R0, [SP,#0x30+var_10] ; this
.text:0000466E                 LDR             R1, =(aSorrry - 0x4674)
.text:00004670                 ADD             R1, PC  ; "Sorrry"
.text:00004672                 BLX             j__ZN7_JNIEnv12NewStringUTFEPKc ; _JNIEnv::NewStringUTF(char const*)
.text:00004676                 STR             R0, [SP,#0x30+var_C]
.text:00004678                 B               loc_46E4

调用接口函数,返回一个字符串。"Sorrry";
程序最后跳转到 loc_46E4

loc_46E4块分析

loc_46E4                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+34↑j
.text:000046E4                                         ; Java_com_example_hanlei_myapplication_MainActivity_panduan+4A↑j ...
.text:000046E4                 LDR             R0, [SP,#0x30+var_C]
.text:000046E6                 ADD             SP, SP, #0x28
.text:000046E8                 POP             {R7,PC}

这个就是拆环境的部分。

loc_467A块分析

loc_467A                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+24↑j
.text:0000467A                 LDR             R0, [SP,#0x30+var_18]
.text:0000467C                 CMP             R0, #2
.text:0000467E                 BNE             loc_4690
.text:00004680                 B               loc_4682

来看第一句

 LDR             R0, [SP,#0x30+var_18]

[SP,#0x30+var_18]这里的数据给R0
之前[SP,#0x30+var_18]的数据就是我们输入的数据。

CMP             R0, #2
BNE             loc_4690
B               loc_4682

如果等于#2 就跳转到loc_4682,如果不等于#2就跳转到loc_4690。如果等于就会跳转到loc_4682

loc_4682块分析

loc_4682                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+3C↑j
.text:00004682                 LDR             R0, [SP,#0x30+var_10] ; this
.text:00004684                 LDR             R1, =(aZhuzhuILoveYou - 0x468A)
.text:00004686                 ADD             R1, PC  ; "ZHUZHU I Love YOU"
.text:00004688                 BLX             j__ZN7_JNIEnv12NewStringUTFEPKc ; _JNIEnv::NewStringUTF(char const*)
.text:0000468C                 STR             R0, [SP,#0x30+var_C]
.text:0000468E                 B               loc_46E4

这一块就是返回"ZHUZHU I Love YOU"这个字符串,然后到loc_46E4,恢复环境。程序结束。

loc_4690块

这个是不等于#2时进行跳转的

loc_4690                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+3A↑j
.text:00004690                 MOVS            R0, #2
.text:00004692                 STR             R0, [SP,#0x30+var_1C]
.text:00004694                 B               loc_4696

来看第一句

MOVS            R0, #2

把#2的值给R0

STR             R0, [SP,#0x30+var_1C]

然后把R0的值给[SP,#0x30+var_1C]这个存储位置。

B               loc_4696

跳转到 loc_4696块。

loc_4696块分析

loc_4696                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+50↑j
.text:00004696                                         ; Java_com_example_hanlei_myapplication_MainActivity_panduan+7A↓j
.text:00004696                 LDR             R0, [SP,#0x30+var_1C]
.text:00004698                 LDR             R1, [SP,#0x30+var_18]
.text:0000469A                 CMP             R0, R1
.text:0000469C                 BGE             loc_46C0
.text:0000469E                 B               loc_46A0

第一句

LDR             R0, [SP,#0x30+var_1C]

把[SP,#0x30+var_1C]取出来给R0

LDR             R1, [SP,#0x30+var_18]

把[SP,#0x30+var_18]的数据给R1,这个[SP,#0x30+var_18]就是我们输入的数据。

CMP             R0, R1

R0和R1比较

BGE             loc_46C0

跳转的意思,BGE就是大于或等于才跳。也就是说当R0>=R1就跳转到loc_46C0

B               loc_46A0

其他情况跳转到 loc_46A0

loc_46C0 块分析

loc_46C0                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+58↑j
.text:000046C0                 LDR             R0, [SP,#0x30+var_20]
.text:000046C2                 CMP             R0, #1
.text:000046C4                 BNE             loc_46D6
.text:000046C6                 B               loc_46C8
 LDR             R0, [SP,#0x30+var_20]

把[SP,#0x30+var_20]的值拿出来给R0

CMP             R0, #1

然后进行比较。

BNE             loc_46D6

不相等就跳转到loc_46D6,loc_46D6返回sorry

B               loc_46C8

相等就跳转到loc_46C8,返回 "ZHUZHU I Love YOU"

loc_46A0块分析

loc_46A0                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+5A↑j
.text:000046A0                 LDR             R0, [SP,#0x30+var_18]
.text:000046A2                 LDR             R1, [SP,#0x30+var_1C]
.text:000046A4                 BL              sub_1422C
.text:000046A8                 CMP             R1, #0
.text:000046AA                 STR             R0, [SP,#0x30+var_30]
.text:000046AC                 BNE             loc_46B6
.text:000046AE                 B               loc_46B0

第一句

 LDR             R0, [SP,#0x30+var_18]

取出[SP,#0x30+var_18]的数据给R0,[SP,#0x30+var_18]就是输入的数值。

LDR             R1, [SP,#0x30+var_1C]

去除 [SP,#0x30+var_1C]的数据给R1, [SP,#0x30+var_1C]就是在loc_4690中存取的数据,现在是#2

 BL              sub_1422C

跳转到 sub_1422C

我们来看看 sub_1422C

sub_1422C                               ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+60↑p
.text:0001422C
.text:0001422C ; FUNCTION CHUNK AT .text:0001421A SIZE 00000012 BYTES
.text:0001422C
.text:0001422C                 CMP             R1, #0
.text:0001422E                 BEQ             loc_1421A
.text:00014230                 PUSH.W          {R0,R1,LR}
.text:00014234                 BL              sub_1416C
.text:00014238                 POP.W           {R1,R2,LR}
.text:0001423C                 MUL.W           R3, R2, R0
.text:00014240                 SUB.W           R1, R1, R3
.text:00014244                 BX              LR
.text:00014244 ; End of function sub_1422C
CMP             R1, #0

比较R1和0,之前的R1就是#2

BEQ             loc_1421A

相等则进行跳转

PUSH.W          {R0,R1,LR}

入栈

BL              sub_1416C

跳转到sub_1416c

sub_1416c

sub_1416C                               ; CODE XREF: sub_1422C+8↓p
.text:0001416C                 EOR.W           R12, R0, R1
.text:00014170                 IT MI
.text:00014172                 NEGMI           R1, R1
.text:00014174                 SUBS            R2, R1, #1
.text:00014176                 BEQ             loc_141EA
.text:00014178                 MOVS            R3, R0
.text:0001417A                 IT MI
.text:0001417C                 NEGMI           R3, R0
.text:0001417E                 CMP             R3, R1
.text:00014180                 BLS             loc_141F4
.text:00014182                 TST             R1, R2
.text:00014184                 BEQ             loc_14204
.text:00014186                 CLZ.W           R2, R1
.text:0001418A                 CLZ.W           R0, R3
.text:0001418E                 SUB.W           R0, R2, R0
.text:00014192                 MOV.W           R2, #1
.text:00014196                 LSL.W           R1, R1, R0
.text:0001419A                 LSL.W           R2, R2, R0
.text:0001419E                 MOV.W           R0, #0
EOR.W           R12, R0, R1

逻辑异或EOR(Exclusive OR)指令将寄存器<Rn>中的值和<shifter_operand>的值执行按位“异或”操作,并将执行结果存储到目的寄存器<Rd>中,同时根据指令的执行结果更新CPSR中相应的条件标志位。

IT MI

SUBS            R2, R1, #1

SUBS中S表示把进位结果写入CPSR

R2=R1-#1然后写入CPSR

之后还有很多。

我们继续来看
loc_46A0

BL              sub_1422C

这一句的逻辑就是计算R1被整除之后的内容

CMP             R1, #0

比较是不是相等

 BNE             loc_46B6

不相等跳转到loc_46B6模块

如果相等的话。

loc_46B6模块分析

loc_46B8                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan:loc_46B6↑j
.text:000046B8                 LDR             R0, [SP,#0x30+var_1C]
.text:000046BA                 ADDS            R0, #1
.text:000046BC                 STR             R0, [SP,#0x30+var_1C]
.text:000046BE                 B               loc_4696
LDR             R0, [SP,#0x30+var_1C]
ADDS            R0, #1
STR             R0, [SP,#0x30+var_1C]

取出来,把变量+1然后存进去

B               loc_4696

跳转到 loc_4696

这里就是整个循环了。

##loc_46B0模块分析

loc_46B0                                ; CODE XREF: Java_com_example_hanlei_myapplication_MainActivity_panduan+6A↑j
.text:000046B0                 MOVS            R0, #0
.text:000046B2                 STR             R0, [SP,#0x30+var_20]
.text:000046B4                 B               loc_46B6

这个模块就是更改[SP,#0x30+var_20]存储的值改变为#0

然后就是继续循环。

总结

终于分析完了。但是收获还是很明显的。你和ARM玩的越久,ARM就越喜欢你。

0x07 结束语

收获:

1.最大的收获就是对ARM汇编的理解程度变高了。
2.而且对编程还有一些流程分析有了很深的认识。
3.了解到之前学习8086有多重要了。

结束时间:

2018年2月15日16:21:05

其它说明

之后可能还要对其他的实例so进行分析。

原文地址:http://blog.51cto.com/12213986/2071710

时间: 2024-08-04 21:58:15

Android逆向-Android逆向基础10(so文件分析大合集)的相关文章

Android软件开发之盘点自定义View界面大合集(二)

Android软件开发之盘点自定义View界面大合集(二) - 雨松MOMO的程序世界 - 51CTO技术博客 雨松MOMO带大家盘点Android 中的自定义View界面的绘制 今天我用自己写的一个Demo 和大家详细介绍一个Android中自定义View中的使用与绘制技巧. 1.自定义view绘制字符串 相信在实际开发过程中必然很多地方都须要用到系统字 为什么会用到系统字? 方便 省内存 我相信做过J2ME游戏开发的朋友应该深知内存有多么多么重要 而且使用它还可以带来一个更重要的好处就是很方

Android 软件开发与游戏开发1 至 32系列博文大合集

Android 软件开发与游戏开发1 至 32系列博文大合集Android 软件开发与游戏开发1 至 32系列博文大合集 http://www.qdmm.com/BookReader/17958,65822595.aspxhttp://www.qdmm.com/BookReader/17958,65822597.aspxhttp://www.qdmm.com/BookReader/17958,65822598.aspxhttp://www.qdmm.com/BookReader/17958,65

Android软件开发之盘点所有Dialog对话框大合集

对话框大合集 今天我用自己写的一个Demo 和大家详细介绍一个Android中的对话框的使用技巧. <ignore_js_op> 1.确定取消对话框 对话框中有2个按钮   通过调用 setPositiveButton 方法 和 setNegativeButton 方法 可以设置按钮的显示内容以及按钮的监听事件.<ignore_js_op> 我们使用AlerDialog 创建对话框 AlertDialog.Builder builder = new AlertDialog.Buil

Android软件开发之盘点所有Dialog对话框大合集(一)

Android软件开发之盘点所有Dialog对话框大合集(一) - 雨松MOMO的程序世界 - 51CTO技术博客 雨松MOMO带大家盘点Android 中的对话框 今天我用自己写的一个Demo 和大家详细介绍一个Android中的对话框的使用技巧.   1.确定取消对话框 对话框中有2个按钮 通过调用 setPositiveButton 方法 和 setNegativeButton 方法 可以设置按钮的显示内容以及按钮的监听事件.   我们使用AlerDialog 创建对话框 AlertDia

2015/9/9 Python基础(10):文件和输入输出

文件对象文件对象不仅可以用来访问普通的磁盘文件,而且也可以访问其它任何类型抽象层面上的“文件”.一旦设置了合适的“钩子”,你就可以访问文件类型接口的其它对象,就好像访问的是普通文件一样.文件对象的处理要以来很多内建函数,还有很多函数会返回文件对象或者是类文件对象.进行这种轴向处理的主要原因是许多输入/输出数据结构更趋向于使用通用的接口.这样就可以在程序行为和实现上保持一致性.文件只是连续的字节序列,数据传输经常会用到字节流,无论字节流是由单个字节还是大块数据组成. 文件内建函数[open()和f

android从源码解析并实现各种Toast效果合集

前言 安卓中为了给用户的友好提示,一般的表现形式为Dialog.PopWindow.Toast,自从Snackbar的出现绝对是秒杀Toast了,Snackbar不仅能够简单实现toast的效果而且还能setAction,但是还是有很多的应用是使用了Toast的,并且安卓死丢丢也有toast的插件,可见toast还是有他存在的价值. 看效果 csdn传图片不能太大,马蛋来2张好了: 从源码解读安卓的Toast Toast窗口其实和前面分析的Activity.Dialog.PopWindow都是不

10款超实用的jQuery插件大合集

1.jQuery cxSlide实现的三款多功能大气焦点图轮播 jQuery cxSlide实现的三款多功能大气焦点图轮播特效源码,是一段拥有三种不同风格和效果的焦点图轮播代码,其中有两款最有意思,一款是在将焦点图图片分成了四块,每个图片都连接到不同的地址,并且还拥有鼠标悬浮内图时,其它图片都变暗了的效果,另外一款是,带有带缩略图和文字描述效果的焦点图轮播代码.该实例中的三款焦点图轮播代码都适合于任意网站,需要此款代码的朋友们可以前来下载使用. 在线演示 源码下载 2.jQuery多功能弹出层插

10款web前端基于jquery超实用jQuery插件大合集

1.纯CSS3实现多种箭头绘制及动画 今天要介绍的这款CSS3应用也非常实用,利用它可以用纯CSS3实现各种箭头的绘制,包括左右箭头.上下箭头以及各个方向的转弯箭头,另外还有一款更酷的CSS3箭头动画特效,可以用来做Loading加载动画.这么多箭头,你可以任选一个应用到项目中去. 在线演示 源码下载 2.基于jquery的手风琴显示详情 今天要各网友分享一款基于jquery的手风琴显示详情实例.当单击顶部箭头的时候,该项以手风琴的形式展示显示详情. 在线演示 源码下载 3.纯CSS3实现眨眼动

10款web前端超实用jQuery插件大合集

1.HTML5截图功能 可拖拽图片 截图在我们平常电脑应用中非常的广泛,包括开发者和一般的使用用户.今天介绍的这款HTML5截图应用可以帮助你在上传头像前截取自己的头像,你只需要拖拽移动图片即可选中要截取的部分,HTML5会自动将选取的图片自动生成一张新的图片来保存,从而完成截图的功能.另外,该HTML5截图应用还支持按住shift键实现图片同比例缩放. 在线演示 源码下载 2.纯CSS3动画按钮效果 5种漂亮样式 这次我们要来分享一款很不错的CSS3按钮动画,这款CSS3按钮一共有5种动画方式