吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3814|回复: 43
收起左侧

[Android 讨论] 《安卓逆向这档事》第五节课后小作业贴

  [复制链接]
正己 发表于 2022-11-18 10:54
本帖最后由 正己 于 2022-12-29 10:41 编辑

一.目录


《安卓逆向这档事》一、模拟器环境搭建
《安卓逆向这档事》二、初识APK文件结构、双开、汉化、基础修改
《安卓逆向这档事》三、初识smail,vip终结者
《安卓逆向这档事》四、恭喜你获得广告&弹窗静默卡
《安卓逆向这档事》五、1000-7=?&动态调试&Log插桩

二.前言


为了提高大家的积极性,特意开了这个作业贴。
编程这件事,一定要做好笔记,并且关掉视频自己动手实操一遍,这样效果最佳!!!
帖子我设置只有我可见,等一周后取消,切记不要回复和作业无关内容,否则会被扣分,前50个名交作业的同学有奖励。

免费评分

参与人数 4吾爱币 +4 热心值 +3 收起 理由
星空之下星星 + 1 + 1 催更催更!
wgd0ay + 1 + 1 用心讨论,共获提升!
rookie33 + 1 用心讨论,共获提升!
AngMer + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

jjjwwy 发表于 2022-11-19 01:01
交作业啦方法一:

第一步:定位提示关键字“无效用户名”,并搜索,定位到OnClick,发现调用checkSN方法做判断。
1.png
第二步:双击进入checkSN方法,在return处下断
2.png 3.png
第三步:进入调试模式,跟踪寄存器V5的值,得到SN码,注册完成
4.png 5.png
方法二:
直接在return处Log插桩打印
6.png 7.png

免费评分

参与人数 1吾爱币 +8 热心值 +1 收起 理由
正己 + 8 + 1 很nice!!!

查看全部评分

dx52mm 发表于 2023-2-4 21:06
正己 发表于 2023-2-4 20:56
这个注册的字符串其实是写在arsc里的string,他有一个对应的id,jeb在反编译的时候会工具这个id自动生成 ...

尝试了下:
1)在arsc中搜索字符串“注册”,出来一条,点击进去发现“successed”表示“恭喜您!注册成功”;
2)再返回搜索“successed”,出来两条,其中string是刚才的,点击type-info进去,发现“0x7f05000c”表示“successed”,中间转了一次。
3)最后再回到classes.dex中搜索代码“0x7f05000c”,可以定位到关键判断。
之前对于这一个知识学的不仔细,一直不明白,终于搞懂了,谢谢正己大神。
wgd0ay 发表于 2022-12-1 15:04
方法三:Log插桩
1、安装完作业apk,然后进入classes.dex文件内,搜索0x7F05000B定位到代码
1.png
2、找到checkSN方法,长按跳转进方法,简单分析一下smali代码
[Asm] 纯文本查看 复制代码
.method private checkSN(Ljava/lang/String;Ljava/lang/String;)Z
    .registers 13
    .param p1, "userName"  # Ljava/lang/String; 参数寄存器 p1 保存的是用户名 userName
    .param p2, "sn"  # Ljava/lang/String; 参数寄存器 p2 保存的是注册码 sn

.prologue
    const/4 v7, 0x0  # 将 0x0 存入寄存器 v7

        .line 45
        if-eqz p1, :cond_9  # 如果 p1,即 userName 等于 0,跳转到 cond_9

    :try_start_3
        invoke-virtual {p1}, Ljava/lang/String;->length()I  # 调用 userName.length()

        move-result v8   # 将 userName.length() 的执行结果存入寄存器 v8

        if-nez v8, :cond_a  # 如果 v8 不等于 0,跳转到 cond_a

        .line 69
        :cond_9
    :goto_9
        return v7

            .line 47
            :cond_a
            if-eqz p2, :cond_9 # 如果 p2,即注册码 sn 等于 0,跳转到 cond_9

            invoke-virtual {p2}, Ljava/lang/String;->length()I # 执行 sn.length()

            move-result v8  # 将 sn.length() 执行结果存入寄存器 v8

            const/16 v9, 0x10  # 将 0x10 存入寄存器 v9

                if-ne v8, v9, :cond_9 # 如果 sn.length != 0x10 ,跳转至 cond_9

                    .line 49
                    const-string v8, "MD5"  # 将字符串 "MD5" 存入寄存器 v8
                	
    				# 调用静态方法 MessageDigest.getInstance("MD5")
                    invoke-static {v8}, Ljava/security/MessageDigest;->getInstance(Ljava/lang/String;)Ljava/security/MessageDigest;

move-result-object v1 # 将上一步方法的返回结果赋给寄存器 v1,这里是 MessageDigest 对象

    .line 50
    .local v1, "digest":Ljava/security/MessageDigest;
invoke-virtual {v1}, Ljava/security/MessageDigest;->reset()V # 调用 digest.reset() 方法

    .line 51
    invoke-virtual {p1}, Ljava/lang/String;->getBytes()[B  # 调用 userName.getByte() 方法

        move-result-object v8   # 上一步得到的字节数组存入 v8

        invoke-virtual {v1, v8}, Ljava/security/MessageDigest;->update([B)V  # 调用 digest.update(byte[]) 方法

        .line 52
        invoke-virtual {v1}, Ljava/security/MessageDigest;->digest()[B  # 调用 digest.digest() 方法

        move-result-object v0   # 上一步的执行结果存入 v0,是一个 byte[] 对象

        .line 53
        .local v0, "bytes":[B
        const-string v8, ""  # 将字符串 "" 存入 v8
    
    	# 调用 MainActivity 中的 toHexString(byte[] b,String s) 方法
        invoke-static {v0, v8}, Lcom/droider/crackme0201/MainActivity;->toHexString([BLjava/lang/String;)Ljava/lang/String;

move-result-object v3 # 上一步方法返回的字符串存入 v3

    .line 54
    .local v3, "hexstr":Ljava/lang/String;
new-instance v5, Ljava/lang/StringBuilder; # 新建 StringBuilder 对象


3、分析在第117行可知v6为最终真实的的sn注册码,只需在后面添加如下代码并保存
[Asm] 纯文本查看 复制代码
invoke-static {v6}, Lcom/mtools/LogUtils;->v(Ljava/lang/Object;)V

2.png
4、然后将log插桩dex文件放入包内并改名为classes2.dex,并打包重新安装
3.png
5、LSPosed 选中程序,算法助手开启应用总开关、Log捕获不在赘述
6、运行后随便输入用户名和注册码,翻看日志,可以看到用户名对应正确的注册码
4.png
7、进行验证,注册成功
5.png

免费评分

参与人数 1吾爱币 +4 热心值 +1 收起 理由
正己 + 4 + 1 动态调试呢

查看全部评分

momingloG 发表于 2022-12-10 19:52
因为最近还在学习xposed,所以就尝试写了个模块,嘿嘿

功能:输入用户名后直接点击“注册”就可以注册成功啦
}]5XZWBMV13X23DRX@XINHQ.png
[/mw_shl_code]
    /**
     * 破解题目
     */
    class HookCrackMe {
        /**
         * 计算注册码
         *
         * @Param userName 用户名
         * @Return 注册码
         */
        public String calculateSn(String userName) {
            MessageDigest digest = null;
            try {
                digest = MessageDigest.getInstance("MD5");
                digest.reset();
                digest.update(userName.getBytes());
                byte[] bytes = digest.digest();

                StringBuilder hexString = new StringBuilder();
                for (byte b : bytes) {
                    String hex = Integer.toHexString(b & 255);
                    if (hex.length() == 1) {
                        hexString.append('0');
                    }
                    hexString.append(hex).append("");
                }

                String hexstr = hexString.toString();

                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < hexstr.length(); i += 2) {
                    sb.append(hexstr.charAt(i));
                }
                return sb.toString();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            return null;

        }

        public void hookCrackMe() {
            XposedHelpers.findAndHookMethod("com.droider.crackme0201.MainActivity", lpparam.classLoader, "onClick", android.view.View.class, new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    // 获取“用户名”控件
                    EditText edit_userName = (EditText) XposedHelpers.getObjectField(param.thisObject, "edit_userName");
                    // 获取用户输入的用户名
                    String userName = edit_userName.getText().toString();
                    // 判断用户名是否为空
                    if (!"".equals(userName)) {
                        // 获取“注册码”控件
                        EditText edit_sn = (EditText) XposedHelpers.getObjectField(param.thisObject, "edit_sn");
                        // 计算注册码
                        String sn = calculateSn(userName);
                        if (sn != null) {
                            // 设置注册码
                            edit_sn.setText(sn);
                        }
                    }
                }

                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    Button btn_register = (Button) XposedHelpers.getObjectField(param.thisObject, "btn_register");
                    btn_register.setEnabled(true);
                    btn_register.setText("已破解");
                }

            });
        }
    }

免费评分

参与人数 1吾爱币 +8 热心值 +1 收起 理由
正己 + 8 + 1 会举一反三了,很棒

查看全部评分

Tonyha7 发表于 2022-11-18 14:45
java_lIcVb1LcVN.png QQ图片20221118144430.png

免费评分

参与人数 1吾爱币 +8 热心值 +1 收起 理由
正己 + 8 + 1 很nice!!!

查看全部评分

苏紫方璇 发表于 2022-11-18 15:27
用户名:苏紫方璇
注册码:bf68a45158fb4f77

算法取用户名MD5的奇数位
不知道为啥,我这jeb估计有问题,用的mumu模拟器和手机真机都连不上,直接看代码猜吧

免费评分

参与人数 1吾爱币 +8 热心值 +1 收起 理由
正己 + 8 + 1 大佬有在看啊?哈哈,jeb连不上是啥问题呀?截图看看?

查看全部评分

苏紫方璇 发表于 2022-11-18 15:48
就这个样子,adb是连接上了,jdk和sdk应该也没问题,有装as可以编译安卓程序
QQ截图20221118154210.jpg
yuhan694 发表于 2022-11-19 00:10
用户名取MD5的奇数位

免费评分

参与人数 1吾爱币 +4 热心值 +1 收起 理由
正己 + 4 + 1 我很赞同!

查看全部评分

huashengyue 发表于 2022-11-19 12:25
1)如果不看视频介绍,首先无从下手,其次是不知道关键字,看不懂代码。
2)到了调试阶段,从WINDOWS的cmd窗口执行ADB命令,出现错误提示如下:

是否与java环境设置不正确有关?

是否与java环境设置不正确有关?

点评

你的这个安装包有问题,装一下第四课的,你可以替换了activity,adb找不到这个activity  详情 回复 发表于 2022-11-19 13:15
 楼主| 正己 发表于 2022-11-19 13:15
huashengyue 发表于 2022-11-19 12:25
1)如果不看视频介绍,首先无从下手,其次是不知道关键字,看不懂代码。
2)到了调试阶段,从WINDOWS的cmd ...

你的这个安装包有问题,装一下第四课的,你可以替换了activity,adb找不到这个activity
头像被屏蔽
AngMer 发表于 2022-11-19 14:27
提示: 作者被禁止或删除 内容自动屏蔽
cx2018 发表于 2022-11-19 15:17
image.png
有点疑惑为啥v6显示不出来,不知道问题在哪,无奈只能用显示出的值来搞,可以看到v3是显示出来的32位可能是md5。
smail转Java分析checksn方法
image.png
看代码的意思大概是用用户名生成md5,然后根据32位md5间隔的取数字(取index为0,2,4...的数)作为密钥与输入的sn比较输出结果。那如果图1中v3显示的为md5的话直接人工间隔取出16位数就好了(有点笨QAQ)。试试,这样不知道算不算成功
image.png

免费评分

参与人数 1吾爱币 +8 热心值 +1 收起 理由
正己 + 8 + 1 可以的,所以我在视频里一直强调模拟器动态调试容易踩坑哈哈

查看全部评分

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-13 03:59

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表