记一次有趣的APP反编译的过程

admin 2020年8月18日08:00:50评论164 views字数 3073阅读10分14秒阅读模式

ChaMd5安全团队出品,版权所有,转载请注明出处。
今天 测试物联网设备安全 发现了一个有趣的app:xxx可以通过用户名或用户id搜索该平台内的用户 进行交流学习

记一次有趣的APP反编译的过程

记一次有趣的APP反编译的过程

想测试下物联网设备安全性然而需要对方回复才可以继续深入地学习

记一次有趣的APP反编译的过程

发送过一次消息之后输入框会处于锁定状态,需要对方回复才可以继续发送

这样很影响我的学习 所以我们查看一下他的app

先用apktool反编译康康

使用命令 java -jar apktool.jar d filename 进行反编译

记一次有趣的APP反编译的过程

接着搜索一下刚刚出现的提示  搭讪机会用过喽

记一次有趣的APP反编译的过程

应用没有加固 直接命中了 一个是原来安装包 另一个是strings.xml

strings.xml是一个字符串资源文件,所有的界面字符串应该在这个文件中指定;

当app需要面向多个国家的用户时,我们可以简单的替换strings.xml文件就可以实现应用中字符串的适配,而不需要在java源码中修改,这样开发非常方便.

对于某些频繁出现的字符串,在strings.xml中指定一次,之后使用直接调用即可,可以节省空间

所以我们再次直接搜索 前边的字符串strid_im_chat_no_attention_accost_txt

记一次有趣的APP反编译的过程

搜索结果可以分为3类

它的安装包

刚刚的搜索出的strings.xml文件 显示了不同语言的字符串

R$string.smali文件

R$string.smali 表示该类是R.string的内部类

R.string存储了资源名称与资源id的对应表,在代码中引用十六进制的id就相当于直接调用了资源名称

记一次有趣的APP反编译的过程

所以我们再次搜索其对应的id0x7f11042c 找到这个id就是相当于找到搭讪机会用过喽这个字符串

记一次有趣的APP反编译的过程

在众多搜索结果中有一个与众不同的文件  其不在R$string.smali或xml文件中

在smali_classes2文件夹中(说明是在原安装包classes2.dex内)  且该处是一个赋值语句

打开ChatViewModel.smali查看

.line 19
    :cond_2
    iget-object v0, p0, Lcom/sistalk/app/im/chat/ChatViewModel;->i:Lc/n/m;

    const v2, 0x7f11042c

    invoke-virtual {p0, v2}, Lcom/sistalk/mvvm/base/BaseViewModel;->getString(I)Ljava/lang/String;

    move-result-object v2

    invoke-virtual {v0, v2}, Lc/n/m;->e(Ljava/lang/Object;)V


该处将0x7f11042c赋值给了本地寄存器v2

并将其作为参数传递给getString(int)方法 最后将结果赋值给v2...

这样看上去比较累 我们直接解压原apk 提取出classes2.dex

使用dex2jar转换成jar 并使用jd-gui查看java代码

记一次有趣的APP反编译的过程

记一次有趣的APP反编译的过程

在jd-gui中打开直接搜索不到 需要先转成十进制2131821612再搜索 看到的代码如下

记一次有趣的APP反编译的过程

可以看到代码逻辑很简单this.b.F().isGreeted()函数返回值为true就会执行本条语句

    this.i.e(getString(2131821612));
    this.j.e(this.i.d());
    this.l.e(false);

false就会执行这条语句      

    this.i.e(getString(2131821611));
    this.j.e(this.i.d());


很明显可以得知这个this.i.e方法就是显示字符串的 其传进的参数不同 显示的内容也不一样

除此之外true分支还调用 this.l.e(false)这个方法

猜测分析isGreeted()函数返回值的返回值就是控制能否打开输入框发送消息的

为了印证 我们先查看下当其为false时候 this.i.e(getString(2131821611))是显示什么

先将2131821611转成十六进制 再搜索

记一次有趣的APP反编译的过程

发现这个是 之前我们没有发送消息时候显示的字符串 搭讪机会只有一次

记一次有趣的APP反编译的过程

很明显如果没有和该用户发送过消息的时候isGreeted()函数返回false  此时会显示 搭讪机会只有一次

发送过消息之后isGreeted()返回值会变为true 此时就会显示 搭讪机会用过喽

并会执行 this.l.e(false)函数 猜测此函数就是控制是否禁用输入框的

我们将isGreeted()的返回值强行修改为false或者直接将 this.l.e(false)的参数换成true就可以继续发送消息了

我们这里用第二种方法 编辑ChatViewModel.smali这个文件找到 this.l.e函数

   .line 21
    iget-object v0, p0, Lcom/sistalk/app/im/chat/ChatViewModel;->l:Landroidx/databinding/ObservableBoolean;

    invoke-virtual {v0, v1}, Landroidx/databinding/ObservableBoolean;->e(Z)V

iget-object v0, p0, Lcom/sistalk/app/im/chat/ChatViewModel;->l:Landroidx/databinding/ObservableBoolean;表示获取从p0(就是this)的l成员变量(一个androidx.databinding.ObservableBoolean类的对象) 并将结果用v0寄存器存储

invoke-virtual {v0, v1}, Landroidx/databinding/ObservableBoolean;->e(Z)V表示调用了androidx.databinding.ObservableBoolean类中e(boolean)方法  返回值为void 传入的参数为v1

smali中基本变量类型表示方法

类型关键字 对应Java中的类型
V void
Z boolean
B byte
S short
C char
I int
J long (64 bits)
F float
O Object

我们直接在前方插入赋值语句 将其传入的参数改为true

    const/4 v1, 0x1


    .line 21
    iget-object v0, p0, Lcom/sistalk/app/im/chat/ChatViewModel;->l:Landroidx/databinding/ObservableBoolean;

     const/4 v1, 0x1

    invoke-virtual {v0, v1}, Landroidx/databinding/ObservableBoolean;->e(Z)V

之后我们回编译并使用apksigner进行签名

记一次有趣的APP反编译的过程

记一次有趣的APP反编译的过程

打开后发现运行一切正常 没有任何的签名校验

接下来就可以进行更方便的学习了

记一次有趣的APP反编译的过程

这次案例简要介绍了下apk逆向的过程,看上去工具比较繁琐 有兴趣可以使用像jeb,MT管理器等一些工具 可以更方便的进行改包学习

安全建议

开发者在应用发布后尽量对安装包进行加壳混淆等加固手段 防止他人恶意篡改,

在必要的地方不使用本地校验而使用服务器进行验证




欢迎大家的加入!

end


ChaMd5 ctf组 长期招新

尤其是crypto+reverse+pwn+合约的大佬

欢迎联系[email protected]



记一次有趣的APP反编译的过程

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2020年8月18日08:00:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   记一次有趣的APP反编译的过程https://cn-sec.com/archives/93815.html

发表评论

匿名网友 填写信息