Android逆向之静态分析
想必打过CTF的小伙伴多多少少都触过Android逆向,所以斗哥将给大家整一期关于Android逆向的静态分析与动态分析。本期先带来Android逆向的静态分析,包括逆向工具使用、文件说明、例题解析等。
Android逆向就是反编译的过程,因为看不懂Android正向编译后的结果所以CTF中静态分析的前提是将出现文件反编译到我们看得懂一层源码,进行静态分析。
0X01 基础说明
Android应用的逻辑代码是由Java进行开发,所以是第一层就是java代码
Java虚拟机JVM运行的是java文件编译过后的class文件
Android虚拟机Dalvik并不是执行Java虚拟机JVM编译后生成的class文件,而是执行再重新整合打包后生成的dex文件编译之后的smali文件
APK:是编译完成后的Android应用程序安装包
dex文件:是class文件的打包文件
smali文件:是Dalvik字节码文件
class文件:是JVM字节码文件
0X02 工具使用
在CTF中Android题目不一定给你完整编译完成后的APK,可能是编译过程中任意文件类型,下面斗哥分以下文件类型利用工具来得到斗哥看得懂的java源码
类型一:class文件
这种情况比较简单,推荐工具jd-gui
直接将class文件拉进去就可以看到java源码。
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/095512snfronazsyrn3z93.jpg.thumb.jpg)
类型二:APK程序
Android工程编译完成会得到我们想要的APK安装包,APK文件其实是一个压缩包。
修改后缀名为zip后解压,解压后的文件如下图所示:
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/095556ogc77czj94qpdpl3.jpg.thumb.jpg)
META-INF文件夹:
存放apk签名信息,用来保证apk包的完整性和系统的安全。
res文件夹:
存放资源文件,包括icon,xml文件。
AndroidManifest.xml文件:
应用程序配置文件,每个应用都必须定义和包含的,它描述了应用的名字、版本、权限、引用的库文件等信息。
classes.dex文件:
可以直接在Dalvik虚拟机上加载运行的文件,由java文件经过IDE编译生成。
resources.arsc文件>
二进制资源文件,包括字符串等。
反编译APK推荐工具ApkIDE、JEB
1. JEB使用:
JEB直接导入APK,反编译完成看到smali文件。
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/102616u1dxs97qydb1lcmz.jpg.thumb.jpg)
很多Android逆向工具就反编译到smali文件这步。
JEB选中smali文件中按Q,就可以看到java文件。
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/103100k2ldlz68a035ez82.jpg.thumb.jpg)
优点:从smali文件反编译成的java文件代码结构清晰。
缺点:无法修改。
2. ApkIDE使用:
项目->打开Apk
等待反编译完成。
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/103159y35np3azhaob3aqp.jpg.thumb.jpg)
看到smali文件。
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/103238a34kdek32e464376.jpg.thumb.jpg)
选择要java源码的smali文件,点击下图按钮,打开Java源码。
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/103306s5rf5gvlcvl008cz.jpg.thumb.jpg)
ApkIDE关联了jd-gui,点击后将跳转到jd-gui。
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/103428b6959d5232549p63.jpg.thumb.jpg)
ApkIDE是将APK反编译到class再用jd-gui拿到Java源码。
在ApkIDE的ApkIDE_v3.3\ApkIDE\Worksrc的项目目录下可以看到反编译后的class文件。
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/103632xprcjuugbubdu1cp.jpg.thumb.jpg)
优点:功能强大,可以修改反编译出来的smali文件,重新编译生成APK。
缺点:编译成后的java代码不够清晰。
3.反编译区别
Smali文件是由Smali语法编写,Smali语法宽松式的语法
所以反编译过程不同,工具不同,java源码肯定不同
下面是同一个APK用上面两个工具逆向的结果:
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/103721tsyizxrrrr0ret8s.jpg.thumb.jpg)
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/103732bscesnheashshase.jpg.thumb.jpg)
斗哥作为一名Java开发的爱好者喜欢JEB的逆向结果,看着比较舒服。
类型三:dex文件
推荐工具dex2.jar
classes.dex文件,这个是Android源码编译过的字节码包
尝试使用dex2.jar工具拿到java源码命令如下
.\d2j-dex2jar.bat C:\Users\lin\Desktop\classes.dex
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/103856ui4s84siowt3w3k5.jpg.thumb.jpg)
jar文件可以理解为classes文件的压缩包,java虚拟机可以直接运行
用Jd-gui打开classes-dex2jar.jar就可以看到java源码
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/103935lpkwm19071f0r50j.jpg.thumb.jpg)
类型四:smali文件
当只有一个单独的smali文件时就无法用上述的工具直接进行反编译
斗哥想到ApkIDE可以对一个APK进行反编译到smali文件,对smali文件进行增删改查的操作
于是用ApkIDE打开任意一个完整的APK然后添加smali文件(APK可以用自己开发的)
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/104024o0zossd0zpkv2022.jpg.thumb.jpg)
将smali文件添加ApkIDE项目中。
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/104114wgolz60jbj6nlomh.jpg.thumb.jpg)
重新编译生成APK。
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/104156qmpx6xxbxr637nxf.jpg.thumb.jpg)
编译成功后将在原APK目录生成一个APK。
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/104301eyyc1icj9pyzpcgc.jpg.thumb.jpg)
再用JEB等工具打开就能看到Ezreal.smali文件。
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/104432vzlslgt2hlsglssv.jpg.thumb.jpg)
其他工具:
编辑器:notepad++、Sublime等
Android模拟器:夜神模拟器等
0X04 例题分析
将应用安装到模拟器查看界面是否有提示。
在文本框输入字符点击按钮提示错误,猜想是否用来判断正确的flag。
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/104645gsr33053yzwrsm35.jpg.thumb.jpg)
使用JEB工具编译成java文件,Android文件下是sdk文件,我们要分析是com包下的源码文件。
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/104727cpio5nzvtbutnnir.jpg.thumb.jpg)
代码量不多就三个类,先从程序入口MainActivity分析,找到关键代码块。
这句if就是判断flag是否正确。
1
2
3
|
if (! "flag{" + v5.toString() + "}" .equalsIgnoreCase(arg12)) { return v7;} |
搜索类查看哪里调用了此方法。
分析得到arg12就是界面要输入的参数,这时我们知道了v5的值就是我们要的flag。
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/104804sz4lusc68ozi4ui3.jpg.thumb.jpg)
onCreate函数调用了checkSN方法并传入两个参数为:
MainActivity.this.edit_userName.trim()
MainActivity.this.edit_sn.getText().toString().trim()
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
//OnCreate是Android中的一个特别的函数,用来“表示一个窗口正在生成”。 //其不产生窗口,只是在窗口显示前设置窗口的属性如风格、位置颜色等。 public void onCreate(Bundle arg3) { super.onCreate(arg3); this.setContentView(0x7F040019); this.setTitle(0x7F06001D); this.edit_userName = "Tenshine" ; this.edit_sn = this.findViewById(0x7F0C0051); this.btn_register = this.findViewById(0x7F0C0052); this.btn_register.setOnClickListener( new View $OnClickListener () { public void onClick(View arg5) { if (!MainActivity.this.checkSN(MainActivity.this.edit_userName.trim(), MainActivity.this.edit_sn. getText ().toString().trim())) { Toast.makeText(MainActivity.this, 0x7F06001E, 0).show(); } else { Toast.makeText(MainActivity.this, 0x7F06001B, 0).show(); MainActivity.this.btn_register.setEnabled(false); MainActivity.this.setTitle(0x7F060019); } } }); } |
分析v5的值,v5是由v3和v4生成的,v4是一个int并直接赋值为0用于循环就可以直接使用
而v3则是toHexString方法的返回值,并要传入,v1是v1.update(arg11.getBytes());生成
arg11就是传入的参数"Tenshine"
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
private boolean checkSN(String arg11, String arg12) { boolean v7 = false; if (arg11 != null) { try { if (arg11.length() == 0) { return v7; } if (arg12 == null) { return v7; } if (arg12.length() != 22) { return v7; } MessageDigest v1 = MessageDigest.getInstance( "MD5" ); v1.reset(); v1.update(arg11.getBytes()); String v3 = MainActivity.toHexString(v1.digest(), "" ); StringBuilder v5 = new StringBuilder(); int v4; for (v4 = 0; v4 < v3.length(); v4 += 2) { v5.append(v3.charAt(v4)); } if (! "flag{" + v5.toString() + "}" .equalsIgnoreCase(arg12)) { return v7; } } catch (NoSuchAlgorithmException v2) { goto label_40; } v7 = true; } return v7; label_40: v2.printStackTrace(); return v7; } |
将上面的分析结果,取出生成v5的关系代码
都是纯java代码,不需要Android的包引入,只需引入java的依赖包。
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class Code { static String toHexString(byte[] arg8, String arg9) { StringBuilder v3 = new StringBuilder(); byte[] v0 = arg8; int v5 = v0.length; int v4; for (v4 = 0; v4 < v5; ++v4) { String v2 = Integer.toHexString(v0[v4] & 255); if (v2.length() == 1) { v3.append( '0' ); } v3.append(v2).append(arg9); } return v3.toString(); } public static void main(String[] args)throws NoSuchAlgorithmException{ MessageDigest v1 = MessageDigest.getInstance( "MD5" ); v1.reset(); v1.update( "Tenshine" .getBytes()); String v3 = Code.toHexString(v1.digest(), "" ); StringBuilder v5 = new StringBuilder(); int v4; for (v4 = 0; v4 < v3.length(); v4 += 2) { v5.append(v3.charAt(v4)); } System.out.println( "flag{" + v5.toString() + "}" ); } } |
用IDEA编辑运行,拿到flag。
![](https://bbs.ichunqiu.com/data/attachment/forum/201808/28/104944ufflo8qld6ondtnd.jpg.thumb.jpg)
0X05 小小总结
下期斗哥将带来Android逆向之动态分析,讲述Android开发入门、smali语法解析、动态调式smali文件。
大家有任何问题可以提问,更多文章可到i春秋论坛阅读哟~
Android逆向之静态分析的更多相关文章
- [转]Android逆向之动态调试总结
一.在SO中关键函数上下断点 刚学逆向调试时.大多都满足于在SO中某关键函数上下断点.然后通过操作应用程序,去触发这个断点,然后进行调试 详细的步骤可以参见非虫大大的<Android软件安全与逆 ...
- Android逆向之旅---动态方式破解apk进阶篇(IDA调试so源码)
Android逆向之旅---动态方式破解apk进阶篇(IDA调试so源码) 来源 https://blog.csdn.net/jiangwei0910410003/article/details/51 ...
- android逆向学习小结--CrackMe_1
断断续续的总算的把android开发和逆向的这两本书看完了,虽然没有java,和android开发的基础,但总体感觉起来还是比较能接收的,毕竟都是触类旁通的.当然要深入的话还需要对这门语言的细节特性和 ...
- Android逆向之so的半自动化逆向
因为工作需要,转型干android逆向,有几个月了.不过对于so的逆向,任然停留在,难难难的阶段,虽然上次自己还是逆向了一个15k左右的小so文件,但是,那个基本是靠,一步一步跟代码,查看堆栈信息来自 ...
- Android逆向破解表单注册程序
Android逆向破解表单注册程序 Android开发 ADT: android studio(as) 程序界面如下,注册码为6位随机数字,注册成功时弹出通知注册成功,注册失败时弹出通知注册失败. 布 ...
- Android逆向破解表单登录程序
Android逆向破解表单登录程序 Android开发 ADT: android studio(as) 程序界面如下,登录成功时弹出通知登录成功,登录失败时弹出通知登录失败. 布局代码 <?xm ...
- Android 逆向实战篇(加密数据包破解)
1. 实战背景由于工作需要,要爬取某款App的数据,App的具体名称此处不便透露,避免他们发现并修改加密逻辑我就得重新破解了. 爬取这款App时发现,抓包抓到的数据是加密过的,如图1所示(原数据较长, ...
- 【转】Android逆向入门流程
原文:https://www.jianshu.com/p/71fb7ccc05ff 0.写在前面 本文是笔者自学笔记,以破解某目标apk的方式进行学习,中间辅以原理性知识,方便面试需求. 参考文章的原 ...
- Android逆向之smali
Android逆向之smali 头信息 smail文件前三行 .class <访问权限> [关键修饰字] <类名>; .super <父类名>; .source & ...
随机推荐
- OO_多线程电梯_单元总结
概述: 面向对象的第二单元是多线程电梯.第一次实现一部傻瓜电梯,每次只送一个人:第二次实现一部可稍带电梯:第三次实现三部可稍带电梯. 一.设计策略 1.第5.6次作业设计思路 第5.6次作业的架构相似 ...
- VBA读写ini 配置文件
Option Explicit 'read Private Declare Function GetPrivateProfileString Lib "kernel32" Alia ...
- linux awk使用详解
转载:https://www.cnblogs.com/xudong-bupt/p/3721210.html awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的 ...
- ASCII,Unicode 和 UTF-8
ASCII: 英文的编码方式,规定了128个字符的编码,使用了一个字节的后七位表示. Unicode : 每个国家的字符集都不同,世界上所有的字符远远超过128个.Unicode,就是一种所有符号的编 ...
- 利用WMITool解决Windows10 浏览器主页被hao123劫持问题
利用Windows10 激活工具KMS10_1025激活系统之后会出现首页 被劫持的问题 解决办法如下 1.下载wmi tool 连接地址 链接: https://pan.baidu.com/s/1g ...
- 获取ADO连接字符串
自己如何获取ADO连接字符串 有时候我们参考网上的ADO连接字符串写未必就能连接上数据库.今天详细介绍下这个很流行的如何获取ADO字符串的方法,就能很容易直观看到这个连接字符串是否真能连接上数据库.编 ...
- 做seo应该如何选择网站程序?
网站程序:(具体网站案例,可在官网看到)绝大多数情况下,我们将做的网站有以下几种1.个人博客,推荐的程序Wordpress(php的程序,比较强大),Zblog(asp的程序,比较简单)2.门户网站( ...
- 通过PRINT过程制作报表
通过PRINT过程制作报表 PRINT过程是SAS中用于输出数据集内容的最简单常用的过程,它可将选择的观测和字段以简单的矩形表格形式输出. 1.1 制作简单报表 使用PRINT过程最简单的语法形式如下 ...
- Educational Codeforces Round 58 (Rated for Div. 2) G 线性基
https://codeforces.com/contest/1101/problem/G 题意 一个有n个数字的数组a[],将区间分成尽可能多段,使得段之间的相互组合异或和不等于零 题解 根据线性基 ...
- Ubuntu16.04安装Ambari 2.7.3
概念了解 Ambair介绍 Apache Ambari是一个用于支持大数据软件供应 管理与监控软件.它也是一个分布式软件,分为Ambair-Server与Ambari-Client两个部分.在生产环境 ...