动态调试与Log插桩
本文最后更新于 6 天前,其中的信息可能已经有所发展或是发生改变。

前言

在我之前刷CTF题的时候,曾遇到过调试so文件的题,现在看来其中的一些有关JEB动态调试的知识在这节教程之中还是用得到的,相关链接指路:[SWPU 2019]easyapp——Androidの初体验 – Xm's Blog

本教程使用的jeb需要java环境的,想起曾经写过有关Java环境与JEB的配置的教程,待会直接cv到下面

教程地址:《安卓逆向这档事》五、1000-7=?&动态调试&Log插桩 - 吾爱破解 - 52pojie.cn

环境配置

去52论坛上搜了个教程,不知道行不行,先试试看吧

JEB动态调试Smali-真机/模拟器(详细,新手必看) - 『移动安全区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

在这之前先去配置JAVA环境java 环境配置(详细教程)_java环境配置-CSDN博客

JAVA环境配置
安装jdk

先去安装jdkJava 下载 |Oracle 中国

这里我挂了梯子,不知道这个中国站点需不需要挂

进入官网下载x64安装程序,下载好之后创建应该文件夹双击进行安装

安装完成之后配置环境变量

新建

变量值为jdk安装的文件夹,再去设置Path变量

%Java_Home%\bin;%Java_Home%\jre\bin;放到变量值最前面,点击确认保存

这样就配置好了,终端可以看见的

安装JEB

在此链接下载:百度网盘 请输入提取码 (baidu.com)

解压之后跟着教程将fix文件夹下的jeb.jar复制并替换到jeb\bin\app文件夹下

双击jeb_wincon.bat打开并激活

………………

JEB的使用

在教程demo的第四关,我们点击验证会返回一个密钥错误的结果


所以我们可以根据返回的结果去搜索字符串所在的代码行

我们使用jeb打开教程窗口

在最下面一栏可以快速搜索字符串等内容

直接可以定位到所在的类里面

package com.zj.wuaipojie.ui;

import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.zj.wuaipojie.Encode;
import com.zj.wuaipojie.util.Base64Utils;
import com.zj.wuaipojie.util.SPUtils;
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import kotlin.text.Charsets;
import kotlin.text.StringsKt;

@Metadata(d1 = {"\u0000$\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010\u000B\n\u0000\n\u0002\u0010\u000E\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0018\u0002\n\u0000\u0018\u00002\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0002J\u000E\u0010\u0003\u001A\u00020\u00042\u0006\u0010\u0005\u001A\u00020\u0006J\u0012\u0010\u0007\u001A\u00020\b2\b\u0010\t\u001A\u0004\u0018\u00010\nH\u0014¨\u0006\u000B"}, d2 = {"Lcom/zj/wuaipojie/ui/ChallengeFourth;", "Landroidx/appcompat/app/AppCompatActivity;", "()V", "check", "", "str", "", "onCreate", "", "savedInstanceState", "Landroid/os/Bundle;", "app_release"}, k = 1, mv = {1, 7, 1}, xi = 0x30)
public final class ChallengeFourth extends AppCompatActivity {
    public final boolean check(String s) {
        int v = 0;
        Integer integer0 = null;
        if(!StringsKt.startsWith$default(s, "flag{", false, 2, null)) {
            return false;
        }

        if(!StringsKt.endsWith$default(s, "}", false, 2, null)) {
            return false;
        }

        String s1 = s.substring(5, s.length() - 1);
        Intrinsics.checkNotNullExpressionValue(s1, "this as java.lang.String…ing(startIndex, endIndex)");
        String s2 = SPUtils.INSTANCE.getString(((Context)this), "id", "");
        if(s2 != null) {
            integer0 = (int)s2.length();
        }

        int v1 = 1000;
        Intrinsics.checkNotNull(integer0);
        int v2 = (int)integer0;
        if(v2 >= 0) {
            while(true) {
                v1 += -7;
                if(v == v2) {
                    break;
                }

                ++v;
            }
        }

        byte[] arr_b = Encode.encode(s2 + v1).getBytes(Charsets.UTF_8);
        Intrinsics.checkNotNullExpressionValue(arr_b, "this as java.lang.String).getBytes(charset)");
        return Intrinsics.areEqual(s1, Base64Utils.INSTANCE.encodeToString(arr_b));
    }

    @Override  // androidx.fragment.app.FragmentActivity
    protected void onCreate(Bundle bundle0) {
        super.onCreate(bundle0);
        this.setContentView(0x7F0B001E);  // layout:activity_challenge_fourth
        ((Button)this.findViewById(0x7F08006B)).setOnClickListener((View view0) -> {
            if(this.check(((EditText)this.findViewById(0x7F0800AC)).getText().toString())) {  // id:edit_check
                Context context0 = (Context)this;
                Toast.makeText(context0, "恭喜你,密钥正确!", 1).show();
                SPUtils.INSTANCE.saveInt(context0, "level", 3);
                return;
            }

            Toast.makeText(((Context)this), "密钥错误哦,再想想!", 1).show();
        });
    }

    // Detected as a lambda impl.
    private static final void onCreate$lambda-0(ChallengeFourth challengeFourth0, EditText editText0, View view0) {
        if(challengeFourth0.check(editText0.getText().toString())) {
            Context context0 = (Context)challengeFourth0;
            Toast.makeText(context0, "恭喜你,密钥正确!", 1).show();
            SPUtils.INSTANCE.saveInt(context0, "level", 3);
            return;
        }

        Toast.makeText(((Context)challengeFourth0), "密钥错误哦,再想想!", 1).show();
    }
}

分析代码之后我们直接在加密值返回的地方下一个断点

接下来就是debug了,我们在cmd里面输入下面这一串就可以了
adb shell am start -D -n com.zj.wuaipojie/.ui.MainActivity
db shell am start -D -n
adb shell am start -D -n 包名/类名
am start -n 表示启动一个activity
am start -D 表示将应用设置为可调试模式

开始调试

点击下面的附上之后就开始调试了

然后回到模拟器or真机中,能看见软件已经开始运行,我们进入第四关,然后随便输点什么,点击验证,就能看见程序在我们的断点处断下来了


我们断点断在
000000E0 invoke-virtual Base64Utils->encodeToString([B)String, v1, v0
这一行

F6进入方法
F7跳过方法
F8从方法中跳出来
R运行到光标处

因此可以F6步进encodeToString

这样我们就能看见encodeToString方法了

这时我们走到该方法返回值的地方

能看见左侧的变量值窗口已经显示出你所得到的密钥了

回到程序中输入之后便可得到密钥正确的返回结果

Log插桩

教程中给了大佬写的dex文件,我们可以将文件打包进apk当中进行安装

将其命名为classes2.dex添加进去

然后进入classes.dex里面定位到之前找到的encodeString

这里能看见返回值是给到v0的

所以我们将下面这一行插到move-result-object v0行的后面
invoke-static {v0}, Lcom/mtools/LogUtils;->v(Ljava/lang/Object;)V

再去算法助手里面把Log捕获打开

后面我们查看日志就能看见返回的结果啦

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇