您好,登錄后才能下訂單哦!
本篇文章為大家展示了如何進行Android逆向基礎中的so文件分析,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
在so文件的分析上,我們需要對一些ARM匯編的邏輯實現。
在代碼邏輯上,只對if,switch,還有循環進行一個demo分析和創建。可能會篇幅比較大。
1.if邏輯NDK編程
2.if邏輯ARM分析
3.switch邏輯NDK編程
4.switch邏輯ARM分析
5.循環邏輯NDK編程
6.循環邏輯ARM分析
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); }
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 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()))); } });
很簡單,不過多解釋。
反匯編分析,當然是要丟在IDA里進行分析了。
這里有個問題就是,IDA只有32位才可以使用F5插件,我之前不知道,坑了好久。
我假裝自己不知道自己的函數名稱啊什么的。就按照流程進行分析。
本來第一步是要進行試玩的,demo試玩我就算了吧。
反編譯,找Android Killer
找到函數之后進行反匯編。
雙擊進入函數。
F5插件真的比較好用,但是我們還是以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}
其中有很多是自帶的東西,所以重要的東西畫出來。
首先是這個參數
調用參數,然后進行比較
根據寄存器進行跳轉
直接使用上次的demo來進行更改,然后直接修改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"); }
編寫還是非常簡單的,只要知道接口函數,在前期沒有什么困難的地方。
暫停:2018年2月15日02:29:01
原因:該睡覺了。恩,要好好的睡一覺,然后起來學習。
開始時間:2018年2月15日11:33:13
原因:剛吃完午飯
.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]
這是剩下的代碼邏輯,如果有興趣可以自己進行分析使用。
感覺自己一下次大徹大悟了。
接下來就是循環邏輯了。
步驟和之前一樣,我只是改變一下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"); }
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 ; 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 ; 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 ; 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 ; 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,恢復環境。程序結束。
這個是不等于#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 ; 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 ; 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 ; 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_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
然后就是繼續循環。
上述內容就是如何進行Android逆向基礎中的so文件分析,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。