一次安卓逆向记录

一次安卓逆向记录

前言

前段时间,因为公司附近有了确诊病例,我刚好与确诊人员有时空交错,所以被居家隔离,于是开启了相对漫长的居家隔离状态,在这段无所事事的时间中,我开始了之前一直想做,但是没有做的小想法——逆向魅族手环app

为什么要逆向这个APP呢?因为之前买过一个魅族手环,但是在2021的时候,官方的app登录服务器停止服务,没法打登录,也就没法实现数据同步,就连基本的时间同步都没法实现,也就没有了任何价值,为了让这个手环还能实现一些价值,于是我趁着这个相对漫长的无所事事的时间,逆向了官方app,同时也幸运地取得了成功,所以也就有了今天的内容。

这个手环颜值还是可以的:一次安卓逆向记录一次安卓逆向记录

本来这块的内容前几天就打算分享的,但是由于工作和一些主观的原因,迟迟一直没有花时间来做一个总结,所以一次又一次地拖,一直拖到今天。

逆向过程

项目描述

本项目是基于魅族手环H1安卓APP的一个逆向工程,通过逆向修改,解决了官方停服之后,无法登陆的问题(进行了免登处理),确保打开APP直接进入应用首页。当然,本项目也是我的第一个安卓逆向工程,后续看个人兴趣,会继续探索学习。

环境及工具

本次用到了AndroidKiller,版本v1.3.1,这是一个逆向集成工具,可以直接将apk文件的核心源码反编译为smali工程文件,然后我们通过修改smali文件,达到自己APP魔改的需求。该工具同时集成了编译、打包、ABD调试等功能,用起来很顺手,后续我会专门出一期使用教程。

相关内容已经梳理到个人知识库:androidkiller工具使用指南

smali基本语法

因为我们这里直接修改的是smali文件,所以学习一些基本语法也是必须的。作为一个java后端开发,我的安卓开发经验基本为零,所以在smali源码的过程中,踩了很多坑,当然也成长很多,后面我会把本次踩坑的知识点梳理下分享出来。

相关内容已经梳理到个人知识库:smali基本语法示例

修改内容

这块主要是说明APP的修改内容,算是给各位喜欢琢磨的小伙伴提供一个破解思路,当然仅供参考。这里先贴几张图,大概说下修改的内容:

StartActivity

这里主要是保存用户信息,同时跳转到RegistInfoActivity,确保用户信息落库。一次安卓逆向记录对应的smali源码如下:

const-string v2, "syske"
new-instance v1, Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer;
invoke-direct {v1, p0}, Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer;-><init>(Landroid/content/Context;)V
invoke-virtual {v1, v2, v2}, Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer;->saveLoginInfo(Ljava/lang/String;Ljava/lang/String;)V

new-instance v1, Lcom/meizu/smart/wristband/models/database/servers/UserInfoServer;
invoke-direct {v1, p0}, Lcom/meizu/smart/wristband/models/database/servers/UserInfoServer;-><init>(Landroid/content/Context;)V
new-instance v0, Lcom/meizu/smart/wristband/models/newwork/response/Logindata;
invoke-direct {v0}, Lcom/meizu/smart/wristband/models/newwork/response/Logindata;-><init>()V
invoke-virtual {v1, p0, v2, v0}, Lcom/meizu/smart/wristband/models/database/servers/UserInfoServer;->saveUserInfo(Landroid/content/Context;Ljava/lang/String;Lcom/meizu/smart/wristband/models/newwork/response/Logindata;)Z

.line 168
new-instance v0, Landroid/content/Intent;

const-class v2Lcom/meizu/smart/wristband/meizuUI/login_regist/RegistInfoActivity;

invoke-direct {v0, p0, v2}, Landroid/content/Intent;-><init>(Landroid/content/Context;Ljava/lang/Class;)V

完整源码可以直接去库里看。

这里原本是参照某乎大佬修改的,但是发下改了之后没啥用,还是会报错,所以我想着能不能直接改查询接口,于是我直接找到models/database/servers包下的LoginInfoServerUserInfoServer,并修改对应方法。

LoginInfoServer

LoginInfoServer我改的是getLoginInfo的实现,直接实例化一个新的LoginInfo对象返回。

一次安卓逆向记录

对应smali源码如下:

# virtual methods
.method public getLoginInfo()Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer$LoginInfo;
    .locals 5

    .prologue
    const/4 v4, 0x0

    .line 47
    iget-object v3, p0, Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer;->context:Landroid/content/Context;

    invoke-static {v3}, Lcom/meizu/smart/wristband/utils/SharePreferencesUtil;->getSharedPreferences(Landroid/content/Context;)Landroid/content/SharedPreferences;

    move-result-object v2

    .line 49
    .local v2, "preferences":Landroid/content/SharedPreferences;
    const/4 v1, 0x0

    .line 50
    .local v1, "entity":Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer$LoginInfo;
    const-string v3, "account"

    invoke-interface {v2, v3, v4}, Landroid/content/SharedPreferences;->getString(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

    move-result-object v0

    .line 51
    .local v0, "account":Ljava/lang/String;
    invoke-static {v0}, Ldolphin/tools/util/StringUtil;->isBlank(Ljava/lang/String;)Z

    move-result v3

    .line 52
    new-instance v1, Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer$LoginInfo;

    .end local v1    # "entity":Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer$LoginInfo;
    invoke-direct {v1}, Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer$LoginInfo;-><init>()V

    .line 53
    .restart local v1    # "entity":Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer$LoginInfo;
    invoke-virtual {v1, v0}, Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer$LoginInfo;->setAccount(Ljava/lang/String;)V

    .line 54
    const-string v3, "pwd"

    invoke-interface {v2, v3, v4}, Landroid/content/SharedPreferences;->getString(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

    move-result-object v3

    invoke-virtual {v1, v3}, Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer$LoginInfo;->setPwd(Ljava/lang/String;)V

    .line 57
    
    const-string v4, "syske"    
    
    new-instance v1, Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer$LoginInfo;
    .restart local v1    # "entity":Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer$LoginInfo;
    invoke-direct {v1}, Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer$LoginInfo;-><init>()V
    
    invoke-virtual {v1, v4}, Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer$LoginInfo;->setAccount(Ljava/lang/String;)V
    invoke-virtual {v1, v4}, Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer$LoginInfo;->setPwd(Ljava/lang/String;)V
     
    return-object v1
.end method
UserInfoServer

UserInfoServer也是类似的方法,主要是解决空指针异常:一次安卓逆向记录

对应smali源码:

# virtual methods
.method public getLoginUser()Lcom/meizu/smart/wristband/models/database/entity/User;
    .locals 6
    .annotation system Ldalvik/annotation/Throws;
        value = {
            Ljava/sql/SQLException;
        }
    .end annotation

    .prologue
    .line 53
    new-instance v3, Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer;

    iget-object v4, p0, Lcom/meizu/smart/wristband/models/database/servers/UserInfoServer;->context:Landroid/content/Context;

    invoke-direct {v3, v4}, Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer;-><init>(Landroid/content/Context;)V

    invoke-virtual {v3}, Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer;->getLoginInfo()Lcom/meizu/smart/wristband/models/database/servers/LoginInfoServer$LoginInfo;

    .line 54
    new-instance v1, Lcom/meizu/smart/wristband/models/database/entity/User;
    invoke-direct {v1},  Lcom/meizu/smart/wristband/models/database/entity/User;-><init>()V

    .line 55
    const-string v5, "syske"
    invoke-virtual {v1, v5}, Lcom/meizu/smart/wristband/models/database/entity/User;->setId(Ljava/lang/String;)V
    
    .line 56
    const/4 v5, 0x0

    invoke-static {v5}, Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;

    move-result-object v5

    invoke-virtual {v1, v5}, Lcom/meizu/smart/wristband/models/database/entity/User;->setSync(Ljava/lang/Boolean;)V
    invoke-virtual {v1, v5}, Lcom/meizu/smart/wristband/models/database/entity/User;->setIsEmpty(Ljava/lang/Boolean;)V
    
    const-string v5, "180"
    invoke-virtual {v1, v5}, Lcom/meizu/smart/wristband/models/database/entity/User;->setWeight(Ljava/lang/String;)V
    invoke-virtual {v1, v5}, Lcom/meizu/smart/wristband/models/database/entity/User;->setHeight(Ljava/lang/String;)V 
    
    return-object v1
.end method

结语

至此,免登app的改造基本上完成了,是不是很简单,但是就是这几行简简单单的代码,我愣是研究了好几天,然后一点点踩坑,一点点进步,一点点成长,才完成,但是整个过程还是成就感满满的,特别是第一次进入首页的那一刻,感觉一切都是值得的,奥里给 最后附上改造完成的app演示视频:

  • 未破解前:首次进入app是需要登陆的

  • 破解之后:首次进入直接进入(会白屏,这里是因为网络连接失败,重新打开就好了)

– END –

原文始发于微信公众号(云中志):一次安卓逆向记录

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/128647.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!