安卓--逆向入门(简单代码解释)

启程

最近开始学习起了逆向,感觉看了逆向的代码之后对正向开发有不同的见解,当然只是我个人的看法而已,看懂一大堆的逆向代码也是成就感爆棚,一点都不亚于看懂看懂别人的框架代码
(文章仅用于记录学习过程)

工具

我有win和mac端,也在研究win端和mac端哪个更合适于逆向开发,因为正向开发我是习惯用mac,所以逆向的话我应该会更喜欢用mac,但是mac的工具学习成本要高于win端,win端的工具也相对成熟和拥有比较好的可视化界面.

mac

ApkTool,dex2jar,D-GUI,具体可以参考下mac逆向工具教程

win

win端上面的工具就很多了,主要用的是Apktool和AndoridKiller

开始

image.png

首先在Android Studio上面编写一个简单的密码登录界面,图形界面就是两个EditText和一个TextView,界面略丑

image.png
图形界面
<?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=".MainActivity">

    <EditText
        android:id="@+id/edt_account"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:hint="请输入账号" />

    <EditText
        android:id="@+id/edt_passwd"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="30dp"
        android:hint="请输入密码" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="#333333"
        android:onClick="onLogin"
        android:textColor="#ffffff"
        android:layout_marginTop="30dp"
        android:gravity="center"
        android:text="登录" />

</LinearLayout>



java代码部分
package com.ss.apktool;

import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {


    private EditText mEdtAccount;
    private EditText mEdtPasswd;
    private final String ACCOUNT = "123";
    private final String PASSWD = "123";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mEdtAccount = findViewById(R.id.edt_account);
        mEdtPasswd = findViewById(R.id.edt_passwd);
    }


    public void onLogin(View view) {
        String account = mEdtAccount.getText().toString();
        String passwd = mEdtPasswd.getText().toString().trim();
        //输入账号密码 如何账号密码不等于123,就提示登录失败,反之提示登录成功
        if (!TextUtils.isEmpty(account) && !TextUtils.isEmpty(passwd)) {
            if (account.equals(ACCOUNT) && passwd.equals(PASSWD)) {
                Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "登录失败", Toast.LENGTH_SHORT).show();
            }
        }
    }


}

我在mac上,使用apktool进行反编译得到smail文件,使用Sublime Text进行查看和修改
.class public Lcom/ss/apktool/MainActivity;
.super Landroidx/appcompat/app/AppCompatActivity;
.source "MainActivity.java"  //当前类名称


# instance fields
.field private final ACCOUNT:Ljava/lang/String; //定义一个String类型的变量ACCOUNT

.field private final PASSWD:Ljava/lang/String;//定义一个String类型的变量PASSWD

.field private mEdtAccount:Landroid/widget/EditText;//定义一个EditText

.field private mEdtPasswd:Landroid/widget/EditText;定义一个EditText


//Ljava/lang/String 其中 L代表的是类型 ,java/lang/String就是具体的类型,所以就是String类型 以此类推

    
# direct methods
.method public constructor <init>()V
    .locals 1

    .line 11
    invoke-direct {p0}, Landroidx/appcompat/app/AppCompatActivity;-><init>()V

    const-string v0, "123"  //将123赋值给v0寄存器

    .line 16
    iput-object v0, p0, Lcom/ss/apktool/MainActivity;->ACCOUNT:Ljava/lang/String;  //将v0的值付给ACCOUNT

    .line 17
    iput-object v0, p0, Lcom/ss/apktool/MainActivity;->PASSWD:Ljava/lang/String;   //将v0的值付给PASSWD

    return-void
.end method


# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
    .locals 0

    .line 21
    invoke-super {p0, p1}, Landroidx/appcompat/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V

    const p1, 0x7f0b001c

    .line 22
    invoke-virtual {p0, p1}, Lcom/ss/apktool/MainActivity;->setContentView(I)V

    const p1, 0x7f08006d

    .line 23
    invoke-virtual {p0, p1}, Lcom/ss/apktool/MainActivity;->findViewById(I)Landroid/view/View;//调用findViewById方法得到一个view地址

    move-result-object p1  //将上面的操作结果赋值给p1

    check-cast p1, Landroid/widget/EditText; //将寄存器p1转成EditText类型

    iput-object p1, p0, Lcom/ss/apktool/MainActivity;->mEdtAccount:Landroid/widget/EditText;

    const p1, 0x7f08006e

    .line 24
    invoke-virtual {p0, p1}, Lcom/ss/apktool/MainActivity;->findViewById(I)Landroid/view/View;

    move-result-object p1

    check-cast p1, Landroid/widget/EditText;

    iput-object p1, p0, Lcom/ss/apktool/MainActivity;->mEdtPasswd:Landroid/widget/EditText;

    return-void
.end method

//onLogin方法,参数是View类型
.method public onLogin(Landroid/view/View;)V
    .locals 3

    .line 29
    iget-object p1, p0, Lcom/ss/apktool/MainActivity;->mEdtAccount:Landroid/widget/EditText; //获取mEdtAccount实例

    invoke-virtual {p1}, Landroid/widget/EditText;->getText()Landroid/text/Editable;//调用getText方法等到p1

    move-result-object p1//将操作结果赋值给p1

    invoke-virtual {p1}, Ljava/lang/Object;->toString()Ljava/lang/String;//继续调用toString方法返回一个String类型的p1

    move-result-object p1 //将结果赋值给p1

    .line 30
    iget-object v0, p0, Lcom/ss/apktool/MainActivity;->mEdtPasswd:Landroid/widget/EditText;//获取mEdtPasswd实例

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

    move-result-object v0

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

    move-result-object v0

    invoke-virtual {v0}, Ljava/lang/String;->trim()Ljava/lang/String;

    move-result-object v0
    //经过上面的代码,得到寄存器p1和寄存器v0
    .line 32
    invoke-static {p1}, Landroid/text/TextUtils;->isEmpty(Ljava/lang/CharSequence;)Z //调用TextUtils的静态方法isEmpty也就是判空处理

    move-result v1  //将上面的结果赋值给v1寄存器

    if-nez v1, :cond_1  //如果v1的结果不为0,也是是为true

    invoke-static {v0}, Landroid/text/TextUtils;->isEmpty(Ljava/lang/CharSequence;)Z//调用TextUtils的静态方法isEmpty也就是判空处理

    move-result v1//将上面的结果赋值给v1寄存器

    if-nez v1, :cond_1 //如果v1的结果不为0,就跳转

    const-string v1, "123" //将字符串123赋值给v1寄存器

    .line 33
    invoke-virtual {p1, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z   //调用equals方法,比较p1和v1寄存器值是否相同

    move-result p1  //将操作结果赋值给p1

    const/4 v2, 0x0 //定义Toast的时间
   // 将这里的if-eqz修改成if-nez(修改这里)
    if-eqz p1, :cond_0  //如果p1的值等于0就继续执行(true),不然就跳转到 cond_0

    invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z   //将v0和v1进行比较
 
    move-result p1  //将结果赋值给p1
   // 将这里的if-eqz修改成if-nez(修改这里)
    if-eqz p1, :cond_0//如果p1的值等于0就继续执行(true)  不然就跳转到 cond_0

    const-string p1, "\u767b\u5f55\u6210\u529f" //将字符串赋值给P1

    //调用Toast静态方法,这个方法要传入3个参数,p0 是 Landroid/content/Context(上下文这里是MainActivity),p1 是 Ljava/lang/CharSequence(字串符类型),v2 是 I(代表Int类型)
    //makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)  
    .line 34
    invoke-static {p0, p1, v2}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

    move-result-object p1 //将Toast之后的结果赋值给p1

    invoke-virtual {p1}, Landroid/widget/Toast;->show()V  //p1调用show方法

    goto :goto_0  

    :cond_0   
    const-string p1, "\u767b\u5f55\u5931\u8d25"  //定义字符串p1

    .line 36
     //调用Toast静态方法,这个方法要传入3个参数,p0 是 Landroid/content/Context(上下文这里是MainActivity),p1 是 Ljava/lang/CharSequence(字串符类型),v2 是 I(代表Int类型)
     //makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)  
    invoke-static {p0, p1, v2}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

    move-result-object p1

    invoke-virtual {p1}, Landroid/widget/Toast;->show()V  //显示toast

    :cond_1
    :goto_0
    return-void
.end method

修改的结果就是将if-eqz修改成if-nez,这样就是修改了逻辑,变成只要账号密码不等于123就可以登录成功

欢迎大家和我进行学习交流,不足的地方请指出,我好及时更正!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335