1. 程式人生 > >Android逆向-Android逆向基礎10(so文件分析大合集)

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

取出 ovs stat 計算 用途 instance tex -s 自動創建

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進行分析。

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