安卓逆向经典案例——XX牛

安卓逆向经典案例——XX牛

按钮绑定方式
1.抓包
2.查看界面元素,找到控件id

通过抓包,发现点击登录后,才会出现Encrpt加密信息,所以我们通过控件找到对应id:btn_login

在这里插入图片描述

在这里插入图片描述

按钮绑定方法——第四种

在这里插入图片描述

 public class LoginActivity extends BasicActivity implements View.OnClickListener {
    private Type DEFAULT_TYPE;
    private EditText etMobile;
    private EditText etPwd;
    private long firstime = 0;
    private Map<String, String> para;
    private JsonRequest request;


case C0828R.C0830id.btn_login /* 2131558593 */:
                String mobile = ((Object) this.etMobile.getText()) + "".trim();
                String pwd = ((Object) this.etPwd.getText()) + "".trim();
                Utils.hideSoftInput(this, this.etPwd);
                if (checkInput(mobile, pwd)) {
                    login(mobile, pwd);
                    return;
                }
                return;

如果获取的id是btn_login,会执行获取账号和密码。

这里@override是注解,当编译时,用于检查父类中有没有对应方法

比如这里的View.onClickListener接口中有名为onClick的方法。如果没有编译器会报错

法2:手动搜索字符串定位关键代码

在这里插入图片描述

POST /api/user/login HTTP/1.1
Content-Type: application/json; charset=utf-8
User-Agent: Dalvik/2.1.0 (Linux; U; Android 13; Mi 10 Build/TKQ1.221114.001)
Host: api.dodovip.com
Connection: Keep-Alive
Accept-Encoding: gzip
Content-Length: 228

{"Encrypt":"NIszaqFPos1vd0pFqKlB42Np5itPxaNH\/\/FDsRnlBfgL4lcVxjXii\/UNcdXYMk0EHdbdwRDGADMQ\nFdnMX5Qq4ZVksebFB9u5C7wf1Tg0iB6TtO6yIRklzyaNV1Emb4ZfamTp8A17jqtT53LRz7g8cWbm\ntmuSM4kXcPN8tgfiwijQvx+XNn\/8BMVPVolqQvWQlI7hPd2OtWw=\n"}
搜索链接——/api/user/login

使用搜索的方法有很大的局限性。

因为关键函数(加密方法)可以被替换分散在多个类文件中,所以必须要在系统函数层面进行逆向,比如在这里MessageDigest.getInstance是系统函数。

  • 使用系统函数,函数名不会改变
MessageDigest md5 = MessageDigest.getInstance("MD5")
//Class<?> a = Class.forName(dd("..."))这样很难找到
//

在这里插入图片描述

搜索技巧,把链接拆分,因为链接可能是被拼接在一起的,所以拆分才能检索到关键代码

在这里插入图片描述

优先找到和包名相关的代码。

在这里插入图片描述

在这里插入图片描述

发现两个可能的方法,通过动态调试和hook的方法,分析
// 使用Frida的Java.perform函数来确保我们的代码在Java虚拟机的上下文中执行。
Java.perform(function (){
    // 使用Java.use来获取Java类的引用。这里我们获取的是com.dodonew.online.http.JsonRequest类的引用。
    var jsonRequest = Java.use("com.dodonew.online.http.JsonRequest");
    
    // 打印获取到的类引用到控制台,用于调试。
    console.log("jsonRequest:", jsonRequest);
    
    // 修改JsonRequest类的paraMap方法的实现。这里我们使用了Frida的implementation属性来实现方法的挂钩。
    jsonRequest.paraMap.implementation = function(a){
        // 当paraMap方法被调用时,打印传递给它的参数a。
        console.log("params1", a);
        
        // 调用原始的paraMap方法。这里的this指的是JsonRequest类的当前实例。
        this.paraMap(a);
    }
})

在这里插入图片描述

使用paraMap方法无法hook到账号和密码,尝试另一个方法

Java.perform(function (){
    var jsonRequest =Java.use("com.dodonew.online.http.JsonRequest");//对特定类名发起hook
    console.log("jsonRequest:",jsonRequest);//打印类的信息
    jsonRequest.paraMap.implementation = function(a){
        console.log("params1",a);//将类中到的params用a替换
        this.paraMap(a);//
    }
    jsonRequest.addRequestMap.implementation = function(a,b){
        console.log("params1",a,b);//将类中到的params用a替换
        this.addRequestMap(a,b);//
    }

})
//frida -UF -l test.js
Error: addRequestMap(): has more than one overload, use .overload(<signature>) to choose from:
        .overload('java.util.Map')
        .overload('java.util.Map', 'int')
        .overload('java.util.Map', 'boolean')

有多个重载函数选择.overload('java.util.Map', 'int')

    jsonRequest.addRequestMap.overload('java.util.Map', 'int').implementation = function(a,b){
        console.log("params1",a,b);//将类中到的params用a替换
        this.addRequestMap(a,b);//
    }

在这里插入图片描述

这样成功hook到函数。可以使用java对象Hashmap的toString方法(以键值对的形式被hashmap重载输出)

import java.util.HashMap;

public class Main {
    public static void main(String[] args){
        HashMap<Object,Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("username","arii");
        objectObjectHashMap.put("password","123456");
        System.out.println(objectObjectHashMap.toString());
    }
}

 jsonRequest.addRequestMap.overload('java.util.Map', 'int').implementation = function(a,b){
        console.log("addRequestMap params",a,b);//将类中到的params用a替换

        var bb = Java.cast(a,Java.use("java.util.HashMap"));//类型转换
        console.log("addRequestMap params",bb.toString());
        // console.log("addRequestMap params",a.get("username"));//这里hook的是java的类型,所以可以调用java中的toString方法
        this.addRequestMap(a,b);//
    }

在这里插入图片描述

配置webstorm代码提示

npm i @types/frida-gum
hook addRequestMap方法

通过hookRequestUtil.paraMap方法去分析返回的值。这里虽然能看到IV和KEY的值,但是防止热加载,热修复(在程序编译运行时,会修改参数),要用hook

在这里插入图片描述

结果
[Mi 10::XX在线 ]-> RequestUtilparams1 {"equtype":"ANDROID","loginImei":"Androidnull","sign":"45D0209BE26E599E4E6FF49A2B3E84A9","timeStamp":"1717570679351","userPw
d":"ffg","username":"225"} 65102933 32028092

hook前后对比:
在这里插入图片描述

DES 算法是分组密码算法,这意味着它将明文数据分割成固定长度的块(通常为 64 位,对应 8 个字节),并对每个块进行独立的加密操作。

关键代码快速定位

var btn_login_id = Java.use("com.dodonew.online.R$id").btn_login.value;
console.log("btn_login_id", btn_login_id);
var appCompatActivity = Java.use("android.support.v7.app.AppCompatActivity");
appCompatActivity.findViewById.implementation = function (a) {
    if(a == btn_login_id){
        showStacks();
        console.log("appCompatActivity.findViewById: ", a);
    }
    return this.findViewById(a);
}

相关推荐

  1. apk逆向

    2024-06-10 08:00:03       49 阅读
  2. 为什么逆向手机要root

    2024-06-10 08:00:03       37 阅读
  3. 逆向之-Xposed RPC

    2024-06-10 08:00:03       14 阅读
  4. 逆向笔记之AndroidManifest.xml篇

    2024-06-10 08:00:03       35 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-10 08:00:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-10 08:00:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-10 08:00:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-10 08:00:03       18 阅读

热门阅读

  1. FastJson

    FastJson

    2024-06-10 08:00:03      10 阅读
  2. Prompt实现简单英语单词教学

    2024-06-10 08:00:03       7 阅读
  3. 2024.6.9 六

    2024-06-10 08:00:03       7 阅读
  4. 单词记忆(第二周)

    2024-06-10 08:00:03       10 阅读
  5. 【设计模式】结构型设计模式之 享元模式

    2024-06-10 08:00:03       9 阅读
  6. 免费热榜API——哔哩哔哩

    2024-06-10 08:00:03       12 阅读
  7. 探索Excel的隐藏功能:如何求和以zzz开头的列

    2024-06-10 08:00:03       11 阅读
  8. 南京领动云计算-AI工程师-面试经历

    2024-06-10 08:00:03       10 阅读