Android逆向实例笔记—续力破解三个Android程序

这个首先感谢鱼C论坛的cbs大神,我是看了他的视频。自己再动手破解他给出这三个小程序。真心这样无私把技术分享给大家的人真的不多。再次感谢他。

这里我就我自己破解的三个小程序自己做做笔记吧,方便自己以后查看,也方便刚刚入门的童鞋。这些都是些没啥技术含量的东西,大神请飘过。

一、认识新工具

这里我先给出一个新的工具。jeb。给个我找的。分别有32和64的。https://yunpan.cn/cMuBpvug7qjc2  访问密码 da4a

还是照例给个样图

二、Crackme03

1.查看原apk

还是拖拽到蓝叠里面看看吧。

我们看到错误的提示是Bad boy。

那就让我们开心的打开apkIDE吧

2.反编译

反编译之后打开strings.xml。发现,没有Bad boy。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Android Crackme03 - [by deurus]</string>
    <string name="app_name2">About Crackme03</string>
    <string name="textoPrueba2">This is the third crackme of the Android collection crackmes, in this, the crackme take another phone values and with our name make something. For this reason, the crackme dont run in the emulator, only in the phone. Good luck for all!.</string>
    <string name="textodeurus">by deurus [29-10-10] [Made in Basque Country]</string>
    <string name="imei" />
    <string name="temp">Enter Name</string>
    <string name="labelserial">Enter Serial</string>
    <string name="line">--------------------------------------</string>
</resources>

那我们就只能看看smali里面的东西了。

搜索结果只有一处,还好。

双击过去,并往上找跳转。结果发现,这代码有混淆。没有办法了?

这个时候就该我们的jeb上了。

点击File-Open,然后选择我们的Crackme03。

然后点到Decompiled Java选项卡。双击左边的HelloAndroid。我们惊喜的发现这不是源码么?

其实不是哈。只是很类似了。而已。

其实,这里的话,我们也可以不用jeb哈。直接用apkIDE带一个东西。

点击打开,选择打开。也是一样的

让我们来看看代码。

package com.example.helloandroid;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.view.View;
import android.view.View$OnClickListener;
import android.widget.TextView;
import android.widget.Toast;

public class HelloAndroid extends Activity {
    private View$OnClickListener pulsarBoton;
    private View$OnClickListener pulsarBotonabout;

    public HelloAndroid() {
        super();
        this.pulsarBotonabout = new View$OnClickListener() {
            public void onClick(View v) {
                HelloAndroid.this.setContentView(2130903041);
                Intent v0 = new Intent();
                v0.setClass(HelloAndroid.this, prueba2.class);
                HelloAndroid.this.startActivity(v0);
                HelloAndroid.this.finish();
            }
        };
        this.pulsarBoton = new View$OnClickListener() {
            public void onClick(View v) {
                String v10 = HelloAndroid.this.findViewById(2131034116).getText().toString();
                int v11 = v10.length();
                String v12 = "";
                String v15 = HelloAndroid.this.findViewById(2131034118).getText().toString();
                if(v11 >= 4) {
                    goto label_29;
                }

                try {
                    Toast.makeText(HelloAndroid.this.getApplicationContext(), "Min 4 chars", 1).show
                            ();
                    return;
                label_29:
                    int v5;
                    for(v5 = 0; v5 < v10.length(); ++v5) {
                        v12 = String.valueOf(v12) + v10.charAt(v5);
                    }

                    v12 = String.valueOf(Integer.parseInt(v12.substring(0, 5)) ^ 438294);
                    Object v8 = HelloAndroid.this.getSystemService("phone");
                    String v6 = ((TelephonyManager)v8).getDeviceId();
                    String v16 = ((TelephonyManager)v8).getSimSerialNumber();
                    String v19 = v6.substring(0, 6);
                    if(!String.valueOf(v12) + "-" + String.valueOf(((long)(Integer.parseInt(v19) ^ Integer
                            .parseInt(v16.substring(0, 6))))) + "-" + v19.equals(v15)) {
                        goto label_114;
                    }

                    Toast.makeText(HelloAndroid.this.getApplicationContext(), "God boy", 1).show();
                    return;
                label_114:
                    Toast.makeText(HelloAndroid.this.getApplicationContext(), "Bad boy ", 1).show();
                    return;
                }
                catch(Exception v22) {
                    Toast.makeText(HelloAndroid.this.getApplicationContext(), "Another Error Ocurred :("
                            , 1).show();
                    return;
                }
            }
        };
    }

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(2130903040);
        Object v3 = this.getSystemService("phone");
        String v2 = ((TelephonyManager)v3).getDeviceId();
        new TextView(((Context)this));
        this.findViewById(2131034112).setText("HardwareID 01: " + v2);
        String v5 = ((TelephonyManager)v3).getSimSerialNumber();
        new TextView(((Context)this));
        this.findViewById(2131034113).setText("HardwareID 02: " + v5);
        String v8 = v2.substring(0, 6);
        String v9 = v5.substring(0, 6);
        Integer.parseInt(v8);
        Integer.parseInt(v9);
        new TextView(((Context)this));
        this.findViewById(2131034116).setText("");
        this.findViewById(2131034120).setOnClickListener(this.pulsarBotonabout);
        this.findViewById(2131034119).setOnClickListener(this.pulsarBoton);
    }
}

我们很容易的发现Bad boy,上面有God boy。猜测就知道这就是正确信息。

那就让我们看看这代码。我们发现上面有个 

goto label_114;

就从这个就跳转到Bad boy。那么我们就得让它不跳转,对吧。大致知道那里之后回到apkIDE。

我们往上找语句块,发现了 :cond_2

那我们搜索这个。到了这里就是我们之前看到的那个跳转。

OK,我们果断改为nez,保存,生成。

3.验证

拖拽到蓝叠,打开。不错,God boy和我们见面

这个我们就是KO了。

三、CrackMe-F1F2

1.查看原apk

无需多说,进蓝叠

这不是是写的EditView,居然不是hint属性,表示无语。懂的就懂,不懂也不重要。这里扯远了,我们继续。

既然有东西,我就懒得输了。直接验证

我们知道了错误代码就是Lisence Uncorrect.。

2.反汇编

apkIDE,常规操作。照样,string.xml没有信息。

只有smali里面搜索一波。

双击过去。找找跳转。

这里给出代码

.class Lcom/mstar/test/LisenceCheck$1;
.super Ljava/lang/Object;
.source "LisenceCheck.java"

# interfaces
.implements Landroid/view/View$OnClickListener;

# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
    value = Lcom/mstar/test/LisenceCheck;
.end annotation

.annotation system Ldalvik/annotation/InnerClass;
    accessFlags = 0x0
    name = null
.end annotation

# instance fields
.field final synthetic this$0:Lcom/mstar/test/LisenceCheck;

# direct methods
.method constructor <init>(Lcom/mstar/test/LisenceCheck;)V
    .locals 0

    .prologue
    .line 1
    iput-object p1, p0, Lcom/mstar/test/LisenceCheck$1;->this$0:Lcom/mstar/test/LisenceCheck;

    .line 51
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

# virtual methods
.method public onClick(Landroid/view/View;)V
    .locals 10
    .param p1, "v"    # Landroid/view/View;

    .prologue
    const/4 v9, 0x0

    const-string v8, ""

    .line 53
    check-cast p1, Landroid/widget/Button;

    .end local p1    # "v":Landroid/view/View;
    iget-object v6, p0, Lcom/mstar/test/LisenceCheck$1;->this$0:Lcom/mstar/test/LisenceCheck;

    iget-object v6, v6, Lcom/mstar/test/LisenceCheck;->mbutton:Landroid/widget/Button;

    if-ne p1, v6, :cond_5

    .line 55
    new-instance v4, Ljava/lang/String;

    const-string v6, ""

    invoke-direct {v4, v8}, Ljava/lang/String;-><init>(Ljava/lang/String;)V

    .line 56
    .local v4, "s1":Ljava/lang/String;
    iget-object v6, p0, Lcom/mstar/test/LisenceCheck$1;->this$0:Lcom/mstar/test/LisenceCheck;

    iget-object v6, v6, Lcom/mstar/test/LisenceCheck;->meditun:Landroid/widget/EditText;

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

    move-result-object v6

    invoke-interface {v6}, Landroid/text/Editable;->toString()Ljava/lang/String;

    move-result-object v4

    .line 57
    new-instance v5, Ljava/lang/String;

    const-string v6, ""

    invoke-direct {v5, v8}, Ljava/lang/String;-><init>(Ljava/lang/String;)V

    .line 58
    .local v5, "s2":Ljava/lang/String;
    iget-object v6, p0, Lcom/mstar/test/LisenceCheck$1;->this$0:Lcom/mstar/test/LisenceCheck;

    iget-object v6, v6, Lcom/mstar/test/LisenceCheck;->meditsn:Landroid/widget/EditText;

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

    move-result-object v6

    invoke-interface {v6}, Landroid/text/Editable;->toString()Ljava/lang/String;

    move-result-object v5

    .line 60
    const/4 v1, 0x0

    .local v1, "i":I
    const/4 v2, 0x0

    .line 62
    .local v2, "k1":I
    const/4 v1, 0x0

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

    move-result v6

    if-lt v1, v6, :cond_1

    .line 69
    :cond_0
    xor-int/lit16 v2, v2, 0x5678

    .line 72
    const/4 v3, 0x0

    .line 73
    .local v3, "k2":I
    const/4 v1, 0x0

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

    move-result v6

    if-lt v1, v6, :cond_3

    .line 78
    xor-int/lit16 v3, v3, 0x1234

    .line 80
    if-ne v2, v3, :cond_4

    .line 81
    iget-object v6, p0, Lcom/mstar/test/LisenceCheck$1;->this$0:Lcom/mstar/test/LisenceCheck;

    invoke-virtual {v6}, Lcom/mstar/test/LisenceCheck;->getApplicationContext()Landroid/content/Context;

    move-result-object v6

    const-string v7, "Lisence Correct\uff01"

    invoke-static {v6, v7, v9}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

    move-result-object v6

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

    .line 92
    .end local v1    # "i":I
    .end local v2    # "k1":I
    .end local v3    # "k2":I
    .end local v4    # "s1":Ljava/lang/String;
    .end local v5    # "s2":Ljava/lang/String;
    :goto_2
    return-void

    .line 64
    .restart local v1    # "i":I
    .restart local v2    # "k1":I
    .restart local v4    # "s1":Ljava/lang/String;
    .restart local v5    # "s2":Ljava/lang/String;
    :cond_1
    invoke-virtual {v4, v1}, Ljava/lang/String;->charAt(I)C

    move-result v0

    .line 65
    .local v0, "ch":C
    const/16 v6, 0x41

    if-lt v0, v6, :cond_0

    .line 66
    const/16 v6, 0x5a

    if-le v0, v6, :cond_2

    const/16 v6, 0x20

    sub-int v6, v0, v6

    int-to-char v0, v6

    .line 67
    :cond_2
    add-int/2addr v2, v0

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

    goto :goto_0

    .line 74
    .end local v0    # "ch":C
    .restart local v3    # "k2":I
    :cond_3
    invoke-virtual {v5, v1}, Ljava/lang/String;->charAt(I)C

    move-result v0

    .line 75
    .restart local v0    # "ch":C
    const/16 v6, 0x30

    sub-int v6, v0, v6

    int-to-char v0, v6

    .line 76
    mul-int/lit8 v6, v3, 0xa

    add-int v3, v6, v0

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

    goto :goto_1

    .line 83
    .end local v0    # "ch":C
    :cond_4
    iget-object v6, p0, Lcom/mstar/test/LisenceCheck$1;->this$0:Lcom/mstar/test/LisenceCheck;

    invoke-virtual {v6}, Lcom/mstar/test/LisenceCheck;->getApplicationContext()Landroid/content/Context;

    move-result-object v6

    const-string v7, "Lisence Uncorrect\uff01"

    invoke-static {v6, v7, v9}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

    move-result-object v6

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

    goto :goto_2

    .line 88
    .end local v1    # "i":I
    .end local v2    # "k1":I
    .end local v3    # "k2":I
    .end local v4    # "s1":Ljava/lang/String;
    .end local v5    # "s2":Ljava/lang/String;
    :cond_5
    iget-object v6, p0, Lcom/mstar/test/LisenceCheck$1;->this$0:Lcom/mstar/test/LisenceCheck;

    iget-object v6, v6, Lcom/mstar/test/LisenceCheck;->meditun:Landroid/widget/EditText;

    const-string v7, ""

    invoke-virtual {v6, v8}, Landroid/widget/EditText;->setText(Ljava/lang/CharSequence;)V

    .line 89
    iget-object v6, p0, Lcom/mstar/test/LisenceCheck$1;->this$0:Lcom/mstar/test/LisenceCheck;

    iget-object v6, v6, Lcom/mstar/test/LisenceCheck;->meditsn:Landroid/widget/EditText;

    const-string v7, ""

    invoke-virtual {v6, v8}, Landroid/widget/EditText;->setText(Ljava/lang/CharSequence;)V

    goto :goto_2
.end method

还是一片大乱,还是用jeb

看我框出来的地方。很显然,如果前面不等于后面这一段,那么就跳转到下面去,Toast出来错误。

OK,我们回到smali里面,去找这个跳转。

其实大胆一点,我们直接可以在错误的上面看到:cond_4。然后搜素这个,但是我们还是稳一点,看看类似的源码,找找思路。

搜索:cond_4,双击过去

ne就是等于,那我们改成等于就OK了。eq改上。

3.验证

保存,生成apk。拖蓝叠。

又是我们熟悉又激动的正确Toast。

四、EX05_01_

1.原apk

不废话,上蓝叠。看看错误提示

这里是直接不用输什么,直接来error--

2.反编译

来看看我们的apkIDE怎么说。

不用多想。依然那个问题。string没信息。那我们就搜索error--看看

只有一处结果就是极好的,双击过去找跳转。

显然没有什么可用信息。还是看看类源码吧。

package irdc.ex05_01;

import android.text.util.Linkify;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.TextView;
import android.widget.Toast;

class EX05_01$1
  implements View.OnKeyListener
{
  EX05_01$1(EX05_01 paramEX05_01) {}

  public boolean onKey(View paramView, int paramInt, KeyEvent paramKeyEvent)
  {
    if ("gogo".equals("11"))
    {
      EX05_01.access$0(this.this$0).setText("gogo");
      Toast.makeText(this.this$0, "right++", 1).show();
    }
    for (;;)
    {
      Linkify.addLinks(EX05_01.access$0(this.this$0), 7);
      return false;
      EX05_01.access$0(this.this$0).setText("gogo");
      Toast.makeText(this.this$0, "error--", 1).show();
    }
  }
}

这个很清晰明了。代码很少,而且可以看到思路的地方。

我们知道,意思就是“gogo”等于“11”才会跳转到正确的地方。但是怎么可能“gogo”等于“11”呢。这里我们就直接修改为不等于就OK了。

回到apkIDE,找到跳转到错误的地方。

那么就直接把eqz改为nez。让它不等于

3.验证

保存,生成,拖蓝叠。

打完收工!!!

这三个app都不是很难。但是主要的目的就是练练手,然后去理理思路。各位看官,看的开心就给个五星好评。

还是最后给出三个apk下载地址吧  https://yunpan.cn/cMu6crr4vXq5t  访问密码 21bc

时间: 2024-10-08 22:21:55

Android逆向实例笔记—续力破解三个Android程序的相关文章

Android逆向实例笔记—破解第一个Android程序_crackme02

本实例来源于<Android软件安全与逆向分析>这本书,作者是看雪的非虫,感谢提供这么好的书和实例. 一.工具 干什么都得一个好工具对吧. 1.apkIDE 反编译呢,我这里使用的是apkIDE(apk改之理),工具的话自己百度吧.个人不喜欢留一些不需要的东西在网盘里,难得整理,百度一大堆.我这里就给一个官网吧,免得有些童鞋找错了地方.现在这下下载网站一不小心,什么全家福都来了.好了,扯得有点远了.我用的就是最新版,我个人就喜欢最新版.(最新版可能有些问题) http://www.popotu

【Android开发学习笔记】【第三课】Activity和Intent

首先来看一个Activity当中启动另一个Activity,直接上代码说吧: (1)首先要多个Activity,那么首先在res-layout下新建一个 Other.xml,用来充当第二个Activity的布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu

MTOM文件的续传功能(三) Client 端程序介绍

使用WSE 3.0 MTOM的技术,让Web Service也可以传文件,而且传输更有效率,这篇将带到Client端的部分说明. 上一篇写了MTOM Server端的部分,这次要写的就是Client端的程序要怎么跟Server交互,也就是最后一篇,废话不多说,马上进入正题,Client端的程序跟Server端一样,要用WSE的Configuration Tool来设定,而Web Service是存在Web.Config,那Client端的WinForm就是存在app.config ?xml ve

Android逆向之旅---动态方式破解apk进阶篇(IDA调试so源码)

一.前言 今天我们继续来看破解apk的相关知识,在前一篇:Eclipse动态调试smali源码破解apk 我们今天主要来看如何使用IDA来调试Android中的native源码,因为现在一些app,为了安全或者效率问题,会把一些重要的功能放到native层,那么这样一来,我们前篇说到的Eclipse调试smali源码就显得很无力了,因为核心的都在native层,Android中一般native层使用的是so库文件,所以我们这篇就来介绍如何调试so文件的内容,从而让我们破解成功率达到更高的一层.

Android逆向之旅---动态方式破解apk前奏篇(Eclipse动态调试smail源码)

一.前言 今天我们开始apk破解的另外一种方式:动态代码调试破解,之前其实已经在一篇文章中说到如何破解apk了: Android中使用静态方式破解Apk  主要采用的是静态方式,步骤也很简单,首先使用apktool来反编译apk,得到smail源码,然后分析smail代码,采用代码注入技术来跟踪代码,然后找到关键方法进行修改,进而破解,同时还可以使用一些开源的hook框架,比如:Xposed和Cydia Substrate,来进行关键方法的hook.所以这里我们可以看到我们破解的第一步是使用ap

Android逆向之旅---静态方式破解微信获取聊天记录和通讯录信息

一.猜想数据存放路径 微信现在是老少皆宜,大街小巷都在使用,已经替代了传统的短信聊天方式了,只要涉及到聊天就肯定有隐私消息,那么本文就来讲解如何获取微信的聊天记录以及通讯录信息. 首先我们在没有网络的时候,打开微信同样可以查看聊天记录,说明微信会把聊天记录保存到本地,那么这么多信息肯定会保存在数据库中,所以我们可以去查看微信的databases目录看看内容: 可惜的是,我们在这个里面并没有发现一些有用的数据,所以这时候就了解到了微信因为把重要信息的数据库存在其他目录下面,我们可以直接把微信的整个

Android逆向之旅---动态方式破解apk终极篇(加固apk破解方式)

一.前言 今天总算迎来了破解系列的最后一篇文章了,之前的两篇文章分别为: 第一篇:如何使用Eclipse动态调试smali源码 第二篇:如何使用IDA动态调试SO文件 现在要说的就是最后一篇了,如何应对Android中一些加固apk安全防护,在之前的两篇破解文章中,我们可以看到一个是针对于Java层的破解,一个是针对于native层的破解,还没有涉及到apk的加固,那么今天就要来介绍一下如何应对现在市场中一些加固的apk的破解之道,现在市场中加固apk的方式一般就是两种:一种是对源apk整体做一

android菜鸟学习笔记19----Android数据存储(三)XML文件的解析及序列化

Android内置了PULL解析器的XPP3实现,以及SAX解析器等,可以直接使用PULL或SAX解析XML,直接把JAVA中进行PULL或SAX解析的代码直接拿来用,遗忘的话,可以参考java拾遗1,2,3关于XML的解析: 如有如下XmlUtils类实现PULL方式解析XML到List和序列化List到XML: Student实体类代码: 1 package cn.csc.bean; 2 3 public class Student { 4 5 private String id; 6 7

android菜鸟学习笔记14----Android控件(三) ListView的简单使用

MVC模式: MVC的基本原理就是通过Controller连接View和Model.当View中所显示的数据发生变化时,会通知Controller,然后由Controller调用Model中的相关方法执行相应的数据修改操作.反之,当Model中的数据发生变化时,也会通知Controller,由Controller通知View更新显示内容.如此一来,就使得数据部分与视图部分相分离,任何一方发生改变都不会影响到另一方. 而在android中,MVC的一个常见应用就是ListView显示数据.V代表的