log注入破解注册/登陆

通过log注入破解部分本地验证的注册/登陆APK

现在有一个注册机,需要输入与用户名对应的注册码(由用户名经过一系列算法得到)才能成功注册。

当点击注册时提示与log日志输出如下

log注入破解注册/登陆_第1张图片log注入破解注册/登陆_第2张图片

通过一次未经修改时注册的log返回信息,我们无法得到有效信息,因此我们接下来对该APK进行静态分析。通过Android kill对该apk进行反编译,我们查看并分析其MainActivity.smali文件,通过插入log输出代码输出我们需要的寄存器中的值。

MainActivity.smali代码如下

.class public Lcom/qianyu/zhuceji/MainActivity;
.super Landroid/app/Activity;
.source "MainActivity.java"


# instance fields
.field private btn:Landroid/widget/Button;

.field private edit_sn:Landroid/widget/EditText;

.field private edit_username:Landroid/widget/EditText;


# direct methods
.method public constructor ()V
    .locals 0

    .prologue
    .line 14
    invoke-direct {p0}, Landroid/app/Activity;->()V

    return-void
.end method

.method static synthetic access$0(Lcom/qianyu/zhuceji/MainActivity;)Landroid/widget/EditText;
    .locals 1

    .prologue
    .line 16
    iget-object v0, p0, Lcom/qianyu/zhuceji/MainActivity;->edit_username:Landroid/widget/EditText;

    return-object v0
.end method

.method static synthetic access$1(Lcom/qianyu/zhuceji/MainActivity;)Landroid/widget/EditText;
    .locals 1

    .prologue
    .line 17
    iget-object v0, p0, Lcom/qianyu/zhuceji/MainActivity;->edit_sn:Landroid/widget/EditText;

    return-object v0
.end method

.method static synthetic access$2(Lcom/qianyu/zhuceji/MainActivity;Ljava/lang/String;Ljava/lang/String;)Z
    .locals 1

    .prologue
    .line 46
    invoke-direct {p0, p1, p2}, Lcom/qianyu/zhuceji/MainActivity;->checkSN(Ljava/lang/String;Ljava/lang/String;)Z

    move-result v0

    return v0
.end method

.method private checkSN(Ljava/lang/String;Ljava/lang/String;)Z
    .locals 10
    .param p1, "userName"    # Ljava/lang/String;
    .param p2, "sn"    # Ljava/lang/String;

    .prologue
    const/4 v7, 0x0

    .line 48
    if-eqz p1, :cond_0

    :try_start_0
    invoke-virtual {p1}, Ljava/lang/String;->length()I

    move-result v8

    if-nez v8, :cond_1

    .line 72
    :cond_0
    :goto_0
    return v7

    .line 51
    :cond_1
    if-eqz p2, :cond_0

    invoke-virtual {p2}, Ljava/lang/String;->length()I

    move-result v8

    const/16 v9, 0x10

    if-ne v8, v9, :cond_0

    .line 54
    const-string v8, "MD5"

    invoke-static {v8}, Ljava/security/MessageDigest;->getInstance(Ljava/lang/String;)Ljava/security/MessageDigest;

    move-result-object v1

    .line 55
    .local v1, "digest":Ljava/security/MessageDigest;
    invoke-virtual {v1}, Ljava/security/MessageDigest;->reset()V

    .line 56
    invoke-virtual {p1}, Ljava/lang/String;->getBytes()[B

    move-result-object v8

    invoke-virtual {v1, v8}, Ljava/security/MessageDigest;->update([B)V

    .line 57
    invoke-virtual {v1}, Ljava/security/MessageDigest;->digest()[B

    move-result-object v0

    .line 58
    .local v0, "bytes":[B
    const-string v8, ""

    invoke-static {v0, v8}, Lcom/qianyu/zhuceji/MainActivity;->toHexString([BLjava/lang/String;)Ljava/lang/String;

    move-result-object v3

    .line 59
    .local v3, "hexstr":Ljava/lang/String;
    new-instance v5, Ljava/lang/StringBuilder;

    invoke-direct {v5}, Ljava/lang/StringBuilder;->()V

    .line 60
    .local v5, "sb":Ljava/lang/StringBuilder;
    const/4 v4, 0x0

    .local v4, "i":I
    :goto_1
    invoke-virtual {v3}, Ljava/lang/String;->length()I

    move-result v8

    if-lt v4, v8, :cond_2

    .line 63
    invoke-virtual {v5}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v6

    .line 65
    .local v6, "userSN":Ljava/lang/String;
    invoke-virtual {v6, p2}, Ljava/lang/String;->equalsIgnoreCase(Ljava/lang/String;)Z

    move-result v8

    if-eqz v8, :cond_0

    .line 72
    const/4 v7, 0x1

    goto :goto_0

    .line 61
    .end local v6    # "userSN":Ljava/lang/String;
    :cond_2
    invoke-virtual {v3, v4}, Ljava/lang/String;->charAt(I)C

    move-result v8

    invoke-virtual {v5, v8}, Ljava/lang/StringBuilder;->append(C)Ljava/lang/StringBuilder;
    :try_end_0
    .catch Ljava/security/NoSuchAlgorithmException; {:try_start_0 .. :try_end_0} :catch_0

    .line 60
    add-int/lit8 v4, v4, 0x2

    goto :goto_1

    .line 68
    .end local v0    # "bytes":[B
    .end local v1    # "digest":Ljava/security/MessageDigest;
    .end local v3    # "hexstr":Ljava/lang/String;
    .end local v4    # "i":I
    .end local v5    # "sb":Ljava/lang/StringBuilder;
    :catch_0
    move-exception v2

    .line 69
    .local v2, "e":Ljava/security/NoSuchAlgorithmException;
    invoke-virtual {v2}, Ljava/security/NoSuchAlgorithmException;->printStackTrace()V

    goto :goto_0
.end method


.method private init()V
    .locals 1

    .prologue
    .line 41
    const/high16 v0, 0x7f080000

    invoke-virtual {p0, v0}, Lcom/qianyu/zhuceji/MainActivity;->findViewById(I)Landroid/view/View;

    move-result-object v0

    check-cast v0, Landroid/widget/EditText;

    iput-object v0, p0, Lcom/qianyu/zhuceji/MainActivity;->edit_username:Landroid/widget/EditText;

    .line 42
    const v0, 0x7f080001

    invoke-virtual {p0, v0}, Lcom/qianyu/zhuceji/MainActivity;->findViewById(I)Landroid/view/View;

    move-result-object v0

    check-cast v0, Landroid/widget/EditText;

    iput-object v0, p0, Lcom/qianyu/zhuceji/MainActivity;->edit_sn:Landroid/widget/EditText;

    .line 43
    const v0, 0x7f080002

    invoke-virtual {p0, v0}, Lcom/qianyu/zhuceji/MainActivity;->findViewById(I)Landroid/view/View;

    move-result-object v0

    check-cast v0, Landroid/widget/Button;

    iput-object v0, p0, Lcom/qianyu/zhuceji/MainActivity;->btn:Landroid/widget/Button;

    .line 44
    return-void
.end method

.method private static toHexString([BLjava/lang/String;)Ljava/lang/String;
    .locals 7
    .param p0, "bytes"    # [B
    .param p1, "separator"    # Ljava/lang/String;

    .prologue
    .line 77
    new-instance v2, Ljava/lang/StringBuilder;

    invoke-direct {v2}, Ljava/lang/StringBuilder;->()V

    .line 78
    .local v2, "hexString":Ljava/lang/StringBuilder;
    array-length v4, p0

    const/4 v3, 0x0

    :goto_0
    if-lt v3, v4, :cond_0

    .line 85
    invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v3

    return-object v3

    .line 78
    :cond_0
    aget-byte v0, p0, v3

    .line 79
    .local v0, "b":B
    and-int/lit16 v5, v0, 0xff

    invoke-static {v5}, Ljava/lang/Integer;->toHexString(I)Ljava/lang/String;

    move-result-object v1

    .line 80
    .local v1, "hex":Ljava/lang/String;
    invoke-virtual {v1}, Ljava/lang/String;->length()I

    move-result v5

    const/4 v6, 0x1

    if-ne v5, v6, :cond_1

    .line 81
    const/16 v5, 0x30

    invoke-virtual {v2, v5}, Ljava/lang/StringBuilder;->append(C)Ljava/lang/StringBuilder;

    .line 83
    :cond_1
    invoke-virtual {v2, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v5

    invoke-virtual {v5, p1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    .line 78
    add-int/lit8 v3, v3, 0x1

    goto :goto_0
.end method


# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
    .locals 2
    .param p1, "savedInstanceState"    # Landroid/os/Bundle;

    .prologue
    .line 22
    invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

    .line 23
    const v0, 0x7f050003

    invoke-virtual {p0, v0}, Lcom/qianyu/zhuceji/MainActivity;->setTitle(I)V

    .line 24
    const/high16 v0, 0x7f030000

    invoke-virtual {p0, v0}, Lcom/qianyu/zhuceji/MainActivity;->setContentView(I)V

    .line 25
    invoke-direct {p0}, Lcom/qianyu/zhuceji/MainActivity;->init()V

    .line 26
    iget-object v0, p0, Lcom/qianyu/zhuceji/MainActivity;->btn:Landroid/widget/Button;

    new-instance v1, Lcom/qianyu/zhuceji/MainActivity$1;

    invoke-direct {v1, p0}, Lcom/qianyu/zhuceji/MainActivity$1;->(Lcom/qianyu/zhuceji/MainActivity;)V

    invoke-virtual {v0, v1}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V

    .line 38
    return-void
.end method

由于我们只需要绕过对注册码的验证,所以我们直接从checkSN方法直接开始分析

1、分析 .line 51 中的内容我们得知这里对我们输入的注册码进行了是否输入与长度为16的检测,否则结束checkSN的检测。——(因此在之后的注册码中需要输入16位,或者将if-eqz与if-ne判断更改)

2、从 .line56中开始调用p1(及用户名)开始进行一系列的运算,最终在 .line63中得到了变量v6

3、继续往后分析,我们看到了 .line65中的“invoke-virtual {v6, p2}, Ljava/lang/String;->equalsIgnoreCase(Ljava/lang/String;)Z”,他调用了虚方法equalsIgnoreCase(),该方法用于两个字符串的比较,其中p2为我们输入的注册码,由此我们可以猜测出v6及为(2)中计算出的用户名所对应的注册码。我们通过在.line65之前添加log输出代码来输出v6中的值。

log输出代码:invoke-static {v6}, Lcom/android/killer/Log;->LogStr(Ljava/lang/String;)V

将修改后的代码进行编译生成新的APK,并安装输入信息后注册,查看log输出信息
log注入破解注册/登陆_第3张图片

上图中tag属性值为AndroidKiller-string的text属性值中成功输出正确的注册码,通过实验正确注册。

log注入破解注册/登陆_第4张图片

本文主要以log注入来破解注册,还存在其它许多破解方式

以上纯属小白胡诌,大佬看见误喷,有错误忘留言指导!!!

你可能感兴趣的:(log注入破解注册/登陆)