Android逆向实战过掉MoMo签名验证和反调试

2023-11-27 10:59

本文主要是介绍Android逆向实战过掉MoMo签名验证和反调试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大家好,我是老袁,一名逆向分析人员,现主要研究Android平台逆向;今天给大家分享一篇,如何过掉MoMo的签名验证和C++层反调试。大神勿喷。

一、使用环境及工具

1.系统:windwos 10(x64)
2.设备:Google nexus 5真机。
3.反编译工具:

    Android Studio 3.2   开发和调试smali代码IDA pro 7.0          分析elf文件jeb                  Apk反编译集成工具(代码质量高)jadx‐gui             dex直接转换成java代码(代码质量高)ApkTools             集成了baksmali和smaliApkDB                将smali代码反编译成dex文件,并重新签名APK(自己编写)

4.抓包工具:Charles
5.分析的样本:com.immomo.momo_8.9.8.apk

二、开启日志信息

一般大型的应用都会自定义自己的日志系统,当发布时只需要去掉打印日志的标志即可,所以我一开始就是去找它的日志接口。通过 jadx打开APk随便打开一段代码,根据日志输出,即可定位到日志的类。
e1e8fdafb47c43a290e8a2a8ff87c357.png
9bb798d3c5de45c3a009eeb56d44455e.png

直接修改上面代码对应的smali代码:

image.png
image.png

三、回编译

现在很多的应用都对自己的APK做了反回编译处理,也就是修改完代码后使用回编译工具回编译时,出现各种错误。例如:对微信做回编译时,资源文件就有问题,实际上是它的资源文件解压库的问题(参见微信开源的资源压缩库[减小APK的体积])。

针对于上面的问题,我自己写了一个工具,大概的原理就是:只处理了APK里面的DEX文件和签名文件。
现在的APK基本上都有采用拆分DEX技术(由于Dex的设计缺陷,一个DEX最多只能保存的类大小为65535),所以反编译后会对应多个smali文件夹。
image.png

该回编译工具的大致实现思路:
  1. 使用smali.jar 针对于某一个smali文件,回编译成功后生成与smali文件夹名字一致的DEX文件。
  2. 使用压缩算法读写APK文件,替换对应的DEX文件。
  3. 在替换完成后,删除压缩包里面的签名文件(META-INF)
  4. 使用签名工具,对新的APK重新签名
    0eecc2e5a09e4e5f9d1f53e8d674aecf.png

四、过签名验证

在上一步中,我已经成功将APK回编译,但是在安装成功后,当我登录时,出现了如下对话框(在线的签名校验)。
5a07c8b3b0b54823ab9451b6d234785b.png

有了这个提示:怎么分析呢?

有几个思路:

  1. 在代码中搜索关键字符串。(可惜找不到,后来验证为从服务端传回来的)
  2. 搜索Java层获取签名信息的方法。(同样找不到,是在C++中获取的)
  3. 分析对话框(每个对话框最后显示都要调用show方法)
    我在跟踪show中,找到了发送消息的函数,从发送的消息中获取到,其中有一个字段中保存了APK的签名信息。
    image.png
    断在弹出对话框代码处
    image.png

根据栈回溯,跟踪找到了向服务器发送的数据
image.png

最后成功找到加密前的数据,在登录时一共获取了43个字段,其中包含了用户名,密码和签名信息等。
image.png
其中有21个字段是从MomoKit.a()中获取到的,其中就包含了签名信息。
image.png
在这个方法中,Codec.Des()解密出“apksign”字符串,Momokit.k()获取出正在的签名信息。
正常APK的签名:“apksign” -> “4f3a531caff3e37c278659cc78bfaecc”,所以我直接写死它。
image.png

最后再重新回编译和重新签名,能够成功安装,并且能成功登陆。

这里需要注意:获取签名信息的类和打印日志的类不在同一个DEX文件中,所以需要在修改过日志的APK的基础上进行修改,我写的工具一开始没有考虑过这个问题,所以我又重新进行了修改,现在可以一键回编译所有的DEX文件了。

五、过C++层的反调试

在分析协议的时候,我找到了关键的加解密函数,于是打算通过Hook框架Hook关键的函数并输出它的结果,但是它对Xposed Hook框架(基于注入的方式,只能针对于Java层)有检查,Hook不成功,然后改为用Frida Hook框架(基于调试的方式,支持C++和Java层,并且不仅适用于移动端),还是不成功,最后我只能拿出大杀器(IDA)来找它反调试的地方,一开始由于环境的问题,光是基于IDA调试的环境我都搭建了很久。

在我成功附加上其进程后3秒不到,提示警告接着调试断开,在网上找到了相关的介绍;(网上文章:Android Native Crash [收集 一个异常的处理接口]) 在MoMo C++的代码中大概有100多个地方在检查自己是否有被其他进程附加,如果有就产生异常。

代码如下:
在这里插入图片描述

这样的代码一共在7个so文件中有上面的代码:libsmses.so,libsevenz.so,libmkjni.so,libmjni.so,libcoded_jni.so,libcoded.so,libbsdiff.so。

一开始我是手动修改了几处fopen后面的跳转(if(v9)),让获取状态的代码都不执行,但是编译后发现程序加载不了图片(当然替换so文件,也可以用我写的那个工具,只是需要手动的打开APK包替换掉目标so文件,然后回编译重新签名)。

最后我还是选择只修改上图中“JUMPOUT”也就是“pop {R0-R2,pc}”将这两个字节的代码直接nop掉,但是这样的代码一共有大概100多处,光修改就要差不多两个小时,而且还不确定还有没有其他问题,所以我选择花两个小时学IDA的IDAPython脚本编写。

脚本代码如下:(IDA默认安装python 2.7)

import idautilsdef Main():pattern = '0x07 0xBD'        #pop {R0-R2,pc}addr    = MinEA()first   = Falseindex   = 0firstaddr = idc.FindBinary(addr, SEARCH_NEXT, pattern)for x in xrange(0,30):addr = idc.FindBinary(addr, SEARCH_NEXT, pattern)if addr == -1:continueif first == True:if firstaddr == addr:breakprint '------------------- %d --------------------------'%xprint 'addr:%s' % hex(addr)print 'firstaddr:%s'%hex(firstaddr)if addr != idc.BADADDR:find_start = addr-0x100find_end   = addrprint "funcstart:%s funcend:%s"%(find_start,find_end)cur_first      = Falsecur_first_addr = idc.FindText(find_start, SEARCH_DOWN, 0, 0, 'TracerPid')while find_start < find_end:cur_addr = idc.FindText(find_start, SEARCH_DOWN, 0, 0, 'TracerPid')if cur_first == True:if cur_addr == cur_first_addr:breakif cur_addr == idc.BADADDR:breakelse:print "  TracerPid %s %s"%(hex(cur_addr), idc.GetDisasm(cur_addr))print "  nop_cpde:%s %s"% (hex(addr),idc.GetDisasm(addr))idc.PatchByte(addr,0x00)     # 因为nop只需要1个字节,所以另一个用BFidc.PatchByte(addr+1,0xBF)print "  ----------"print "new_code:%s %s"%(hex(addr),idc.GetDisasm(addr))index += 1cur_first_addr = cur_addrcur_first      = Truecur_addr       = idc.NextHead(find_start)first     = Truefirstaddr = addrprint "find index:%d"%indexMain()

上面的代码能够成功的将一个so文件中所有符合要求的“pop {R0-R2,pc}”nop掉。

当修改完成后,先保存,再dump出so文件。(这是IDA的一个特点,在界面上修改的数据,只是修改了它为真实文件创建的数据库文件而已)。

这里顺便介绍一下IDA的两个插件:KeyPatch(能够直接输入对应的汇编代码),Patch Program(dump功能)。

KeyPatch修改代码

在这里插入图片描述

Program dump出so(在Dump之前一定要先保存数据)

6132e27410504a24912a547613365092.png
image.png

最终成功可以调试C++的代码了,下面是跟踪加密算法的位置
在这里插入图片描述

六、总结

上面的内容就是今天要分享的,由于我是第一次写文章,写的不好,希望大家见谅,并且对平台的排版工具不太熟悉,暂时就只能这样了,我这篇文章里面涉及的知识比较多,可能对初学者来说有点难度,不过没关系,我会在后面的文章中,一点一点的剖析这篇文章里面的知识。感兴趣的同学可以关注我的公众号,欢迎来扰。
在这里插入图片描述

这篇关于Android逆向实战过掉MoMo签名验证和反调试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/427540

相关文章

Spring Boot 整合 SSE(Server-Sent Events)实战案例(全网最全)

《SpringBoot整合SSE(Server-SentEvents)实战案例(全网最全)》本文通过实战案例讲解SpringBoot整合SSE技术,涵盖实现原理、代码配置、异常处理及前端交互,... 目录Spring Boot 整合 SSE(Server-Sent Events)1、简述SSE与其他技术的对

MyBatis-Plus 与 Spring Boot 集成原理实战示例

《MyBatis-Plus与SpringBoot集成原理实战示例》MyBatis-Plus通过自动配置与核心组件集成SpringBoot实现零配置,提供分页、逻辑删除等插件化功能,增强MyBa... 目录 一、MyBATis-Plus 简介 二、集成方式(Spring Boot)1. 引入依赖 三、核心机制

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据

MySQL 数据库表与查询操作实战案例

《MySQL数据库表与查询操作实战案例》本文将通过实际案例,详细介绍MySQL中数据库表的设计、数据插入以及常用的查询操作,帮助初学者快速上手,感兴趣的朋友跟随小编一起看看吧... 目录mysql 数据库表操作与查询实战案例项目一:产品相关数据库设计与创建一、数据库及表结构设计二、数据库与表的创建项目二:员

从基础到高阶详解Python多态实战应用指南

《从基础到高阶详解Python多态实战应用指南》这篇文章主要从基础到高阶为大家详细介绍Python中多态的相关应用与技巧,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、多态的本质:python的“鸭子类型”哲学二、多态的三大实战场景场景1:数据处理管道——统一处理不同数据格式

Android 缓存日志Logcat导出与分析最佳实践

《Android缓存日志Logcat导出与分析最佳实践》本文全面介绍AndroidLogcat缓存日志的导出与分析方法,涵盖按进程、缓冲区类型及日志级别过滤,自动化工具使用,常见问题解决方案和最佳实... 目录android 缓存日志(Logcat)导出与分析全攻略为什么要导出缓存日志?按需过滤导出1. 按

Java慢查询排查与性能调优完整实战指南

《Java慢查询排查与性能调优完整实战指南》Java调优是一个广泛的话题,它涵盖了代码优化、内存管理、并发处理等多个方面,:本文主要介绍Java慢查询排查与性能调优的相关资料,文中通过代码介绍的非... 目录1. 事故全景:从告警到定位1.1 事故时间线1.2 关键指标异常1.3 排查工具链2. 深度剖析:

Go语言网络故障诊断与调试技巧

《Go语言网络故障诊断与调试技巧》在分布式系统和微服务架构的浪潮中,网络编程成为系统性能和可靠性的核心支柱,从高并发的API服务到实时通信应用,网络的稳定性直接影响用户体验,本文面向熟悉Go基本语法和... 目录1. 引言2. Go 语言网络编程的优势与特色2.1 简洁高效的标准库2.2 强大的并发模型2.

Python实现Word转PDF全攻略(从入门到实战)

《Python实现Word转PDF全攻略(从入门到实战)》在数字化办公场景中,Word文档的跨平台兼容性始终是个难题,而PDF格式凭借所见即所得的特性,已成为文档分发和归档的标准格式,下面小编就来和大... 目录一、为什么需要python处理Word转PDF?二、主流转换方案对比三、五套实战方案详解方案1:

SpringBoot实现RSA+AES自动接口解密的实战指南

《SpringBoot实现RSA+AES自动接口解密的实战指南》在当今数据泄露频发的网络环境中,接口安全已成为开发者不可忽视的核心议题,RSA+AES混合加密方案因其安全性高、性能优越而被广泛采用,本... 目录一、项目依赖与环境准备1.1 Maven依赖配置1.2 密钥生成与配置二、加密工具类实现2.1