[置顶] Android逆向从未如此简单
哈,又标题党了。。不过我一定竭尽所能,写一篇最亲民的入门文章。
本文仅供学习交流之用,切勿用于非法用途,读者若运用所学知识,进行非法任何商业目的或者非法牟利,一切责任由操作者自行承担,与本人无关。希望读者仅仅从了解原理,保护自身APP尽量减少危害出发来阅读本文。
本文发布自wing的地方酒馆,转载请注明出处。
本文以一个最简单的例子,来教给大家Android逆向入门的一些知识。所以首先我们需要准备一个APK,做的简单一些,就是一个EditText,已经一个按钮,模拟验证注册码。

当验证码填写正确的时候,则提示验证成功,错误的时候,则验证失败。
现在,我们将列举数种办法,攻破验证,来让我们输入任何密码就验证成功。
神兵利器
- ShakaApktool https://github.com/rover12421/ShakaApktool
- Dex2Jar https://github.com/pxb1988/dex2jar
- Smali https://github.com/JesusFreke/smali
- SmaliIDEA https://bitbucket.org/JesusFreke/smali/downloads/
如果你嫌命令行不好用(这是个不好的开始),那么还可以用整合到一起的可视化工具AndroidCrackTool https://github.com/Jermic/Android-Crack-Tool
首先,把我们的apk用ApkTool给反编译了,进入目录发现有以下文件夹
其中,smali文件夹里,放的都是dex反编译出来的smali文件,如果想改变应用的逻辑,只需要修改smali再重新打包即可。接下来,介绍几种突破方法。
寻找切入点
直接寻找法
将apk里面的dex文件脱离,然后使用dex2jar转换为jar文件。
在代码里,我们可以很明显看到,onClick方法内,进行了验证码的判断。此时我们已经找到切入点。
资源引用法
一般apk的代码不会如此简单,肯定有很多复杂的代码,这时候如何去寻找切入点呢,其实我们可以根据引用的资源来寻找,比如我们注册失败的时候会提示注册失败,这时候,我们去res文件夹下找string。
<string name="failed">注册失败</string>
发现name为failed,然后再去public文件里寻找对应的id,找到了
<public type="string" name="failed" id="0x7f060022" />
将这个16进制的id转化为10进制,得到2131099682,在逆向得到的jar文件,索引这个id,发现正好有引用,所以这一区域是关键代码区域.

猜测法
逆向离不开猜测,找到目标页面,假设要获取一个点击事件,那么就猜测类型为Button的属性,在混淆代码里,只有一个button叫做a,那么只要找这个a的点击事件即可。
到现在我们已经有了切入点,接下来要开始达成我们的目的了,那就是改变代码逻辑。
向代码开刀
既然我们已经抓住了切入点,如何去破解这个注册码到底是多少呢,接下来向大家介绍几种开刀方法。
直接分析法
看到混淆代码,阅读之,发现这个注册码是根据日期生成的,所以我们只需要人算出来当前日期输入即可。

当然这种方法缺陷很大,因为一般算法不会如此简单。
偷梁换柱法
既然找到了判断点,我们去阅读smali代码。

注意第48行,这里是执行了方法a(),也就是生成key的方法,把返回值交给了V0,后面所有逻辑都是根据这个判断的,所以我们可以把v0给偷偷替换掉,假设我们替换为”123”,这样我们输入123,就可以通过验证了,代码如下:

酒后真言法
什么叫做酒后真言?就是喝多了让他自己吐出来真心话,那么我们怎么让他吐出来真心话呢?当然是打log了,嘿嘿嘿,我们只要在v0后面打一条log,把这个v0打出来,验证码不是就自己出来了吗,哈哈。 代码如下:

深入敌营
这绝对是重头戏,什么叫做深入敌营呢?就是打入敌军内部,这里说的就是动态调试拉~ 直接debug smali,看看各个寄存器里的值,你说腻害不腻害~
首先,你需要有个2.3以下的AS,因为smaliidea这个插件不支持2.3,然后安装这个插件。
接下来,把逆向出来的AndroidManifest.xml文件做一点小修改,给他加入一句
<application android:debuggable="true"/>
之后重新打包,安装到手机上。接下来把整个逆向出来的项目导入到AS中。
将smali文件夹添加为source root。
接下来Run->Edit Configurations 添加Remote,稍等要修改端口。

这时,打开ddms,看到端口为8600,这时候把窗口里的端口改为8600.
将sdk改为10.

接下来,点击debug按钮,就可以动态调试了。

接下来就是打断点,在生成验证码之后,打上断点,然后点击按钮。

就可以打印出来函数调用栈,各个寄存器等信息,这时候我们使用evaluate expression 打印出v0的值:

可以看到,与我们之前代码猜想结果一致,验证码为”0318”,到此,我们就完成了这个验证系统的逆向。
结语
到此,本篇文章的内容就结束了,希望各位读者不要去运用这些知识去做坏事,天网恢恢。 反而我们应该思考的是怎么去防止别人破坏我们的APP,比如增加混淆程度,签名校验,加固等等,虽然这些也能被破解,但是会增加难度。毕竟安全这件事,防君子不防小人。房子的门可以被撬开,可是我上班出门仍然会关门。
如果你喜欢我的文章,请多关注我,也可以加入我的Android酒馆来讨论Android技术:425983695
参考:
《Android软件安全与逆向分析》
https://www.zybuluo.com/oro-oro/note/167401
[置顶] Android逆向从未如此简单的更多相关文章
- [置顶] Android开发笔记(成长轨迹)
分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API ...
- (转)[置顶] Android APK反编译就这么简单 详解(附图) .
在学习Android开发的过程你,你往往会去借鉴别人的应用是怎么开发的,那些漂亮的动画和精致的布局可能会让你爱不释手,作为一个开发者,你可能会很想知道这些效果界面是怎么去实现的,这时,你便可以对改应用 ...
- [置顶] [Android源码分析]inquiry result引起的上层变化分析
在上一篇文章中,我们详细分析了android是如何解析蓝牙反馈上来的搜索到的设备信息,本文将会继续分析这些信息到了上层之后是如何处理. 8.inquiry result引起的上层变化 我们知道inqu ...
- [置顶]
Android 适配真要命?
原始尺寸场景 相信大家对上面也有所有耳闻另外就是如何计算屏幕的密度一般都是按照勾股定理例如中等屏幕密度 480^2+800^2开根号 然后除以当前屏幕尺寸3.5-4.2之间尺寸. 对于刚出来的那些An ...
- [置顶] Android 2016新技术
版权声明:分享技术,传播快乐.如果本博客对你有帮助,请在我的博客首页为我打赏吧! 2016你需要了解Android有以下新兴的技术与框架,有些也许还不成熟,但是你应该去了解下,也许就是未来的方向. K ...
- [置顶] Android AlarmManager实现不间断轮询服务
在消息的获取上是选择轮询还是推送得根据实际的业务需要来技术选型,例如对消息实时性比较高的需求,比如微博新通知或新闻等那就最好是用推送了.但如果只是一般的消息检测比如更新检查,可能是半个小时或一个小时一 ...
- [置顶] Android四大组件之BroadcastReceiver
Android四大组件之BroadcastReceiver Broadcast Receiver 广播接收器,是一种负责接收广播消息并对消息做出响应的组件,和Service一样并不提供与用户交互的UI ...
- [置顶] Android源码分析-点击事件派发机制
转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/17339857 概述 一直想写篇关于Android事件派发机制的文章,却一直没 ...
- [置顶] Android框架攻击之Fragment注入
为了适应越来越大的设备屏幕,Android在3.X后引入了Fragment概念,作用是可以在一个屏幕上同时显示多个Activity,以达到充分利用屏幕的目的.关于Fragment的使用说明,可以阅读& ...
随机推荐
- 在w3cschool学完html,css,javascript,jquery以后,还是不会做前端怎么办?
w3cschool是一个非盈利性的在线技术学习网站,提供按W3C标准编写的基础教程.完整的看完w3cschool上面的手册,可以基本掌握编程语法.基础性的东西通常都会比较零散,因此,在学习一段时间后, ...
- 113. Path Sum II(求等于某个数的所有路径)
Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given su ...
- linux比较两个文件的不同(6/21)
cmp 命令:比较任意两个类型的文件,且吧结果输出到标准输出,默认文件相同不输出,不同的文件输出差异 必要参数 -c 显示不同的信息-l 列出所有的不同信息-s 错误信息不提示 选择参数 -i< ...
- Loopback接口的作用
Loopback接口是虚拟接口,是一种纯软件性质的虚拟接口.任何送到该接口的网络数据报文都会被认为是送往设备自身的.大多数平台都支持使用这种接口来模拟真正的接口.这样做的好处是虚拟接口不会像物理接口那 ...
- WPF ListBox ItemContainerStyle 设置BackGround 和 BorderBrush 无效
今天更改ListBox,用到ItemContainerStyle设置样式,设置Style.Triggers时,BackGround和BorderBrush均无效,其他效果正常. 翻看WPF编程宝典,发 ...
- HDU4639
/*计算里面有多少个相邻的he,1个he就是1种意思,两个就是,两种,所以这是 一个斐波拉期数列,间隔的hehe互不影响所以是互斥事件,直接相乘就可以*/ #include<stdio.h> ...
- 【Flask】Flask Cookie操作
### 什么是cookie:在网站中,http请求是无状态的.也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户.cookie的出现就是为了解决这个问题,第 ...
- 深入理解JVM 垃圾收集器(下)G1收集器
1.回顾CMS 1.1堆内存结构 1.2新生代GC 1.3老年代GC 2.G1收集器 2.1G1实现概览及使用场景 G1的推荐使用场景 2.2GC 2.2.1新生代GC 2.2.2老年代GC 老年代G ...
- Python 类的设计原则
# 面向对象遵循的原则: SOLID # S(Single Responsibility Principle) # 单一职责原则 # 一个类只负责一项职责 # 好处 # 易于维护, 写出高内聚的代码 ...
- 超详细 Linux 下编译安装Redis 以及php配套使用
一.Linux 下安装Redis 下载地址:http://redis.io/download,下载最新文档版本. 把鼠标移到上图的绿色框上,就会显示下图提示:(直接右键复制链接就好) 本教程使用的旧版 ...