日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

作者:xiaoyuer 合天智匯

 

前年的時候搞過一點Android逆向,好久沒搞了,最近有個哥們讓我幫他做個Android逆向的小題目,于是拾起來Android逆向的知識重新來搞搞吧,這個apk十分簡單,屬于入門級的Android逆向分析程序,所以本文面向的對象主要是想涉足Android逆向的讀者,讓讀者能夠了解一下Android逆向是怎么回事。我這里附上apk文件,感興趣的最好下載下來實操一下:

鏈接:https://pan.baidu.com/s/17d7zKMjh8rKjj9mUl3J_0Q 提取碼:htrx

引言

Android程序一般是使用JAVA語言開發,通過生成一個apk文件安裝到Android手機上來運行,apk我們很容易獲得,我們通過使用一些反匯編工具可以得知apk文件內部的邏輯,甚至得到他最初的Java源代碼(不完全等同于開發時的源代碼,但是大體上相同)。同時,也可以通過反匯編工具得到類似于smali代碼,smali代碼是一種類似于匯編語言的代碼,適合機器執行,但對于程序員來說就相對晦澀難懂了。

首先,使用apktools和jad-gui工具或者Androidkiller得到反匯編后的smali代碼和java代碼,這兩款工具可以很容易在網上搜到,使用方法也很簡單,這里就不贅述了。下面開始進入代碼分析階段,java代碼比較容易看懂,所以這里就先上java代碼吧:

通過java得到flag

通過上述兩款工具得到的MainActivity的java源碼如下所示:

package com.a.sample.androidtest;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.App.AppCompatActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private EditText editText;
    private byte[] s = new byte[]{(byte) 113, (byte) 123, (byte) 118, (byte) 112, (byte) 108, (byte) 94, (byte) 99, (byte) 72, (byte) 38, (byte) 68, (byte) 72, (byte) 87, (byte) 89, (byte) 72, (byte) 36, (byte) 118, (byte) 100, (byte) 78, (byte) 72, (byte) 87, (byte) 121, (byte) 83, (byte) 101, (byte) 39, (byte) 62, (byte) 94, (byte) 62, (byte) 38, (byte) 107, (byte) 115, (byte) 106};

    public boolean check() {
        byte[] chars = this.editText.getText().toString().getBytes();
        if (chars.length != this.s.length) {
            return false;
        }
        int i = 0;
        while (i < this.s.length && i < chars.length) {
            if (this.s[i] != (chars[i] ^ 23)) {
                return false;
            }
            i++;
        }
        return true;
    }

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView((int) R.layout.activity_main);
        final Context context = this;
        this.editText = (EditText) findViewById(R.id.edit_text);
        findViewById(R.id.button).setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                if (MainActivity.this.check()) {
                    Toast.makeText(context, "You got the flag!", 1).show();
                } else {
                    Toast.makeText(context, "Sorry your flag is wrong", 1).show();
                }
            }
        });
    }
}

猛一看這一段代碼可能有點懵,沒那個耐心去看這段代碼在干嘛,這里可以先嘗試使用安卓模擬器運行后觀察一下程序的運行邏輯,打開后發現是一個輸入框,然后一個check按鈕。如圖所示:

Android逆向破解入門

 

再結合代碼進行分析可知,當點擊check按鈕時,會觸發onClick函數,即如下代碼段:

if (MainActivity.this.check()) {
                    Toast.makeText(context, "You got the flag!", 1).show();
                } else {
                    Toast.makeText(context, "Sorry your flag is wrong", 1).show();

由此可知如果check函數返回true,會提示You got the flag! 否則,提示Sorry your flag is wrong。下面對check函數進行分析:

public boolean check() {
        byte[] chars = this.editText.getText().toString().getBytes();
        if (chars.length != this.s.length) {
            return false;
        }
        int i = 0;
        while (i < this.s.length && i < chars.length) {
            if (this.s[i] != (chars[i] ^ 23)) {
                return false;
            }
            i++;
        }
        return true;
    }

其中,this.s是一個byte型的數組:

private byte[] s = new byte[]{(byte) 113, (byte) 123, (byte) 118, (byte) 112, (byte) 108, (byte) 94, (byte) 99, (byte) 72, (byte) 38, (byte) 68, (byte) 72, (byte) 87, (byte) 89, (byte) 72, (byte) 36, (byte) 118, (byte) 100, (byte) 78, (byte) 72, (byte) 87, (byte) 121, (byte) 83, (byte) 101, (byte) 39, (byte) 62, (byte) 94, (byte) 62, (byte) 38, (byte) 107, (byte) 115, (byte) 106};

首先看到check函數先是檢查輸入的flag和s數組的長度是否相等,之后進行while循環,其中if中的判斷條件為:

this.s[i] != (chars[i] ^ 23)

這里^指的是二進制按位異或。這樣整個邏輯就分析清楚了,那么如何得到正確的flag呢?

有一個需要記住的實用技巧,就是兩次按位異或運算會得到自身,所以我們對s數組再進行一次異或即可得到真實的flag;Python腳本如下:

# -*- coding: utf-8 -*-
def ascii2str():
    asciis=[113,123,118,112,108,94,99,72,38,68,72,87,89,72,36,118,100,78,72,87,121,83,101,39,62,94,62,38,107,115,106]
    strs=[]
    for ascii in asciis:
        str=chr(ascii^23)
        strs.append(str)
    print(''.join(strs))

if __name__ == '__main__':
    print("begin!")
    ascii2str()
    print("finished!")

運行后輸出結果為:flag{It_1S_@N_3asY_@nDr0)I)1|d},

Android逆向破解入門

 

輸入后可知顯示You got the flag! 如圖所示:

Android逆向破解入門

 

 

通過smali修改跳轉進行破解

前面提到除了Java源碼,還有smali代碼,那既然對Java源碼都已經分析清楚了,為啥還要看smali代碼?smali的好處在于能回編譯,實現破解效果,即不需要對他的算法進行分析,無需知道真實的flag即可讓他顯示You got the flag!那么我們就用smali來搞一下;

MainActivity的smali源碼check函數如下所示:

.method public check()Z
    .locals 5

    .prologue
    const/4 v2, 0x0

    .line 15
    iget-object v3, p0, Lcom/a/sample/androidtest/MainActivity;->editText:Landroid/widget/EditText;

    invoke-virtual {v3}, Landroid/widget/EditText;->getText()Landroid/text/Editable;

    move-result-object v3

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

    move-result-object v3

    invoke-virtual {v3}, Ljava/lang/String;->getBytes()[B

    move-result-object v0

    .line 16
    .local v0, "chars":[B
    array-length v3, v0

    iget-object v4, p0, Lcom/a/sample/androidtest/MainActivity;->s:[B

    array-length v4, v4

    if-eq v3, v4, :cond_1

    .line 22
    :cond_0
    :goto_0
    return v2

    .line 18
    :cond_1
    const/4 v1, 0x0

    .local v1, "i":I
    :goto_1
    iget-object v3, p0, Lcom/a/sample/androidtest/MainActivity;->s:[B

    array-length v3, v3

    if-ge v1, v3, :cond_2

    array-length v3, v0

    if-ge v1, v3, :cond_2

    .line 19
    iget-object v3, p0, Lcom/a/sample/androidtest/MainActivity;->s:[B

    aget-byte v3, v3, v1

    aget-byte v4, v0, v1

    xor-int/lit8 v4, v4, 0x17

    if-ne v3, v4, :cond_0

    .line 18
    add-int/lit8 v1, v1, 0x1

    goto :goto_1

    .line 22
    :cond_2
    const/4 v2, 0x1

    goto :goto_0
.end method

看起來比Java源碼難懂了很多,其實我們目前只需要知道一些關鍵語句的含義就夠了,當然后面如果想深入學習肯,smali代碼越熟悉越好,這里對這里的部分smali進行解釋一下,.method public check()Z 中的Z表示這是bool類型的函數;.locals 5 表明了在這個函數中最少要用到的本地寄存器的個數。.line 15 表明了該代碼在原Java文件中的行數。其余的命令我也忘記了不少,為了避免誤人子弟,我就大概解釋一下主要的內容吧?

invoke-virtual {v3}, Landroid/widget/EditText;->getText()Landroid/text/Editable;

invoke-virtual是調用函數,invoke-static后面有一對大括號“{}”,其實是調用該方法的實例+參數列表。對v3進行分析就會發現它就是我們輸入框輸入的flag,v4就是上述數組里的s;看到這里:

if-eq v3, v4, :cond_1
Android逆向破解入門

 

其實我們已經找到了跳轉點,if-eq 也就是v3 v4相等時跳轉到某處,那么如果我們把它直接改成不相等時跳轉,豈不是輸入除真實的flag外的任何值都會提示You got the flag! 那我們就來試試直接將if-eq改成if-ne,然后使用Androidkiller中的回編譯功能,對他進行簽名,重新安裝運行,發現隨便輸入都提示You got the flag!

Android逆向破解入門

 

AndroidAPK逆向分析

apk反編譯java代碼是進行apk代碼分析、修改的基礎,也能更好的理解apk的包結構。通過本實驗,可掌握Android APK文件的逆向反編譯過程,能夠對APK文件進行簡單的分析,學習相關工具的使用。

http://www.hetianlab.com/expc.do?ec=ECID172.19.104.182014053009520900001

聲明:筆者初衷用于分享與普及網絡知識,若讀者因此作出任何危害網絡安全行為后果自負,與合天智匯及原作者無關!

分享到:
標簽:逆向 破解 Android
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定