使用AndroidKiller進行APK反編譯

春告鳥 發表於 2022-06-23
Android

安裝環境

  • JDK
    最好用JDK8,問就是坑太多了
  • Android Studio
    官網安裝即可,安裝教程如下

https://www.runoob.com/android/android-studio-install.html

使用AndroidKiller進行APK反編譯

實際上還有一些雜七雜八的東西,後面遇到的時候再安裝

編寫第一個Android APP

開啟Android Studio,建立一個Empty Activity

使用AndroidKiller進行APK反編譯

編寫MainActivity.java程式碼

package com.example.test2;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    EditText Name; //定義Plain Test控制元件第一個輸入框的名字
    EditText Pass; //定義Plain Test控制元件第二個輸入框的名字
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Name = (EditText) findViewById(R.id.TEST_NAME); //通過findViewById找到輸入框控制元件對應的id並給它起一個名字
        Pass = (EditText) findViewById(R.id.TEST_PASS);//通過findViewById
        // 找到輸入框控制元件對應的id並給它起一個名字
        Button Login = (Button) findViewById(R.id.BTN_Login);//通過findViewById找到按鈕控制元件對應的id並給它起一個名字
        Login.setOnClickListener(new View.OnClickListener() { //監聽有沒有點選按鈕控制元件 如果點選了就會執行onClick函式
            @Override
            public void onClick(View view) {
                check(Name.getText().toString().trim(),Pass.getText().toString().trim()); //呼叫check函式
            }
        });
    }
    public void check(String name,String pass)
    {
        if(name.equals("admin")&&pass.equals("admin123"))
        {
            Toast.makeText(MainActivity.this,"登入成功", Toast.LENGTH_SHORT).show();//彈框
        }
        else
            Toast.makeText(MainActivity.this,"登入失敗", Toast.LENGTH_SHORT).show();//彈框
    }
}

開啟activity_main.xml,點選Design進行視覺化拖拽程式設計

使用AndroidKiller進行APK反編譯

拖拽生成使用者名稱和密碼框,以及一個登入按鈕
使用AndroidKiller進行APK反編譯

元件的屬性需要跟上面的MainActivity.java中的對應

例如這裡的使用者名稱輸入框的id是TEST_NAMEMainActivity.java中使用者名稱輸入框程式碼為:

Name = (EditText) findViewById(R.id.TEST_NAME);

使用AndroidKiller進行APK反編譯

模擬執行、手機安裝

選擇一個對應的手機型號模板,開始執行
使用AndroidKiller進行APK反編譯

輸入使用者名稱密碼正確時(admin/admin123),顯示登入成功;輸入使用者名稱密碼錯誤時(xxx/xxx),顯示登陸失敗

登陸成功
使用AndroidKiller進行APK反編譯

登陸失敗
使用AndroidKiller進行APK反編譯

選擇build apk,生成手機安裝的apk檔案
使用AndroidKiller進行APK反編譯
將生成的apk檔案傳給手機就能夠安裝執行了

Android逆向工具

安卓逆向的工具很多,這裡我們使用Android Killer

連結:http://pan.baidu.com/s/1skClh3f 密碼:6u0q

下載解壓,配置JDK路徑
使用AndroidKiller進行APK反編譯

現在就能夠正常使用該工具了

逆向初體驗

將我們剛才生成的apk檔案拖進Android Killer,等待反編譯結束

使用AndroidKiller進行APK反編譯

可以注意到這裡是smali檔案,smali是Android虛擬機器的反組合語言

我們都知道,Android程式碼一般是用java編寫的,執行java程式一般需要用到java虛擬機器,在Android平臺上也不例外,但是出於效能上的考慮,並沒有使用標準的JVM,而是使用專門的Android虛擬機器(5.0以下為Dalvik,5.0以上為ART)。Android虛擬機器的可執行檔案並不是普通的class檔案,而是再重新整合打包後生成的dex檔案。dex檔案反編譯之後就是Smali程式碼,所以說,Smali語言是Android虛擬機器的反組合語言。

我們暫時不需要刻意去學習smali語法,看不懂的地方就先百度,看得多了常見的就會了

尋找smali檔案中的check方法,也就是之前我們編寫用來判斷使用者輸入使用者名稱密碼是否正確的函式,下面對該部分程式碼逐行講解

# virtual methods

smali中函式分為兩類:direct methodvirtual method,direct method就是private私有方法,virtual method就是指其餘的方法。

.method public check(Ljava/lang/String;Ljava/lang/String;)V check方法

.locals 2 指定了方法內區域性變數的個數,這裡是使用者名稱和密碼兩個

兩個變數

.param p1, "name"    # Ljava/lang/String;
.param p2, "pass"    # Ljava/lang/String;

.line 31 表示java原始檔中指定行

const-string v0, "admin" 定義常量字串,即 v0 = admin

invoke-virtual {p1, v0}, Ljava/lang/String;->equals(Ljava/lang/Object;)Zp1v0的值進行比較

move-result v0 將上個函式的執行結果傳遞給v0,這裡的上個函式是equals

const/4 v1, 0x0 將值0x0存到v1本地暫存器

if-eqz v0, :cond_0 如果v0等於0,則跳轉到cond_0

cond_0部分的程式碼為登陸失敗程式碼

:cond_0
const-string v0, "\u767b\u5f55\u5931\u8d25"

invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

move-result-object v0

invoke-virtual {v0}, Landroid/widget/Toast;->show()V

檢測密碼的流程也類似,當檢測通過後,就會進入登入成功邏輯

const-string v0, "\u767b\u5f55\u6210\u529f"

invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

move-result-object v0

invoke-virtual {v0}, Landroid/widget/Toast;->show()V

所以整個邏輯就是使用者名稱密碼傳遞給了p1,p2,然後與硬編碼的v0依次進行比較,如果不相等則v0為0,登入失敗,如果使用者名稱密碼都正確,程式才會往下執行,顯示登入成功

想要在不知道密碼的情況下修改smali程式碼,從而登陸成功的方法有很多種,比如原文中給出了將if-eqz修改為if-nez;刪除掉判斷語句;使用goto語句直接跳轉等方式

這裡我們直接修改比較邏輯
使用AndroidKiller進行APK反編譯

然後重新編譯為新的apk

回編的時候報錯了

Exception in thread "main" brut.androlib.AndrolibException: brut.androlib.AndrolibException: brut.common.BrutException: could not exec (exit code = 1)

使用AndroidKiller進行APK反編譯

出現這個問題一般是apktool.jar的版本太老了的原因,在官網下載最新版本即可:https://ibotpeaches.github.io/Apktool/install/

將下載的jar放置在AndroidKiller\bin\apktool\apktool資料夾下,並且重新命名為ShakaApktool.jar,也就是將原來的那個過時jar覆蓋掉

該問題也可以編輯APKTOOL管理器來進行指定apktool.jar進行操作

使用AndroidKiller進行APK反編譯

重新編譯時出現新的問題:

brut.androlib.AndrolibException: brut.common.BrutException: could not exec (exit code = 1)

使用AndroidKiller進行APK反編譯

根據文章apktool重打包失敗原因之一分析

新增引數-r

使用AndroidKiller進行APK反編譯
新增後依然報錯

刪除掉C:\Users\<這裡填自己的使用者名稱>\AppData\Local\apktool\framework\1.apk檔案,重新編譯,無報錯,修改成功

參考連結

END

建了一個微信的安全交流群,歡迎新增我微信備註進群,一起來聊天吹水哇,以及一個會發布安全相關內容的公眾號,歡迎關注 😃

GIF GIF