原文:https://www.jianshu.com/p/71fb7ccc05ff

0.写在前面

本文是笔者自学笔记,以破解某目标apk的方式进行学习,中间辅以原理性知识,方便面试需求。
参考文章的原文链接会附在相应流程位置,方便阅读学习。

 
逆向分析流程.jpg

1.获取目标apk

第一步是拿到目标安装包文件,这一步很简单,可以在主流的第三方市场内获取,但是主流的第三方市场都要求应用加固,为了之后方便,笔者常常去app的官网下载,或者去一些小市场下载,运气好的话能下载到他们的未加固版本。

2.确定逆向目标

这个就看各自需求,比如有破解内购,分析反逆向逻辑,crackme题目,查看竞品实现方式,确定好目标再下手。

3.拖动目标文件到集成工具

直接拖apk到集成工具,如改之理,比如jadx,这里是为了检查有没有加固。
附上一些必要的开发工具下载地址
https://www.jianshu.com/p/b33eb2f5efa0

4.加固

这里判断很好判断,形如有StubShell的包,都是被加固了的。
那接下来就是要脱壳了。

4.1加固原理

脱壳之前,了解壳是什么(加固原理)。
https://www.jianshu.com/p/cec7ef861ace

4.2脱壳

接下来才是脱壳

4.2.1手脱

手脱的麻烦点就在于过各种检测,过完所有的检测最终就是找到dex的内存地址,最后运行代码进行dump

链接是收集各种手工脱壳的帖子
https://www.jianshu.com/p/3f6bcf364197

4.2.2机脱

实际上就是各种脱壳机,原理就是
无论什么壳,最终都是要加载到内存中,等apk已经加载到内存后,脱壳机把dex dump出来就行了,也就省去了手工脱壳的麻烦。

这里的原理可参考
Android中apk加固完善篇之内存加载dex方案实现原理(不落地方式加载)
http://www.520monkey.com/archives/629

原理主要讨论了两个问题
如果解密后有一个未加密的apk做中间产物,那就是落地方式,这个方式已经被淘汰了,因为不安全。
如果不落地则可能出现加载两次到内存的效率问题。

这里不深研,只提供一个脱壳机,fdex2
看雪原帖(也说了原理)
https://bbs.pediy.com/thread-224105.htm
52破解帖
https://www.52pojie.cn/forum.php?mod=viewthread&tid=758726&fromguid=hot

核心代码,有空可以看
package com.ppma.xposed; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Method; import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XSharedPreferences;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage; public class MainHook implements IXposedHookLoadPackage { XSharedPreferences xsp;
Class Dex;
Method Dex_getBytes;
Method getDex;
String packagename; public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
xsp = new XSharedPreferences("com.ppma.appinfo", "User");
xsp.makeWorldReadable();
xsp.reload();
initRefect();
packagename = xsp.getString("packagename", null);
XposedBridge.log("设定包名:"+packagename);
if ((!lpparam.packageName.equals(packagename))||packagename==null) {
XposedBridge.log("当前程序包名与设定不一致或者包名为空");
return;
}
XposedBridge.log("目标包名:"+lpparam.packageName);
String str = "java.lang.ClassLoader";
String str2 = "loadClass"; XposedHelpers.findAndHookMethod(str, lpparam.classLoader, str2, String.class, Boolean.TYPE, new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Class cls = (Class) param.getResult();
if (cls == null) {
//XposedBridge.log("cls == null");
return;
}
String name = cls.getName();
XposedBridge.log("当前类名:" + name);
byte[] bArr = (byte[]) Dex_getBytes.invoke(getDex.invoke(cls, new Object[0]), new Object[0]);
if (bArr == null) {
XposedBridge.log("数据为空:返回");
return;
}
XposedBridge.log("开始写数据");
String dex_path = "/data/data/" + packagename + "/" + packagename + "_" + bArr.length + ".dex";
XposedBridge.log(dex_path);
File file = new File(dex_path);
if (file.exists()) return;
writeByte(bArr, file.getAbsolutePath());
}
} );
} public void initRefect() {
try {
Dex = Class.forName("com.android.dex.Dex");
Dex_getBytes = Dex.getDeclaredMethod("getBytes", new Class[0]);
getDex = Class.forName("java.lang.Class").getDeclaredMethod("getDex", new Class[0]);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} } public void writeByte(byte[] bArr, String str) {
try {
OutputStream outputStream = new FileOutputStream(str);
outputStream.write(bArr);
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
XposedBridge.log("文件写出失败");
}
}
}

4.3得到.dex文件

dex文件是什么
java,dex,smali,关系/区别又是什么
https://www.jianshu.com/p/fb9aec070c0a

5.集成工具分析

其实就是可以把刚才拿到的.dex拖进来分析了

6.减少混淆干扰

apk在打包时会被混淆,文件名被替换成影响无意义的字母甚至汉字。
jdax通过以下设置来减少混淆干扰
https://segmentfault.com/a/1190000012180752

发散:proguard的源码阅读
https://www.jianshu.com/p/734424a14eff

7.定位目标

借助第三方工具
比如adb工具
https://blog.csdn.net/halibobo1998/article/details/50623929

或者有一部已经root的机器(可以减少很多麻烦),使用layoutInspector去查布局找id

简单的就下一个第三方app 当前activity

还可以通过搜索界面里的特殊字串来定目标文件。
因为资源字串无论怎么混淆,反编译出来的public.xml一定有对应的int值

8.分析业务逻辑

9.确定逆向方法

比如想通过xposed框架去hook某个结果,还是直接nop掉某个返回值。

10.使用apktool进行反编译

执行代码

apktool d -f 目标apk路径

这里可能遇到壳利用apktool漏洞对其进行的干扰
http://www.520monkey.com/archives/808

11.得到.smali

smali语法
https://www.jianshu.com/p/54e893ae28ea
空类的smali结构
https://www.jianshu.com/p/758bccaaa0a6

12.源码调试

静态调试
https://www.jianshu.com/p/4359598a2c9b

动态调试
https://www.jianshu.com/p/90f495191a6a

动态调试so
https://www.jianshu.com/p/5617220cbb02

13.回编译 app

执行命令

apktool b -d 资源路径 -o 输出.apk

可能会遇到回编译失败的情况,比如低版本的apktool不认识高Android版本的属性,可以选择升级apktool或者删除该属性值。

14.签名

执行命令

apksigner sign --ks testKey.jks --ks-key-alias testkey --ks-pass pass:123456 --key-pass pass:123456 --out output_sign.apk source.apk

参考

Android逆向分析笔记
https://lichao890427.github.io/wiki/android%20reverse%20engineering/#%E6%A6%82%E8%BF%B0

adb指令
https://www.jianshu.com/p/85373d89bc81

作者:普通的程序员
链接:https://www.jianshu.com/p/71fb7ccc05ff
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

【转】Android逆向入门流程的更多相关文章

  1. android逆向学习小结--CrackMe_1

    断断续续的总算的把android开发和逆向的这两本书看完了,虽然没有java,和android开发的基础,但总体感觉起来还是比较能接收的,毕竟都是触类旁通的.当然要深入的话还需要对这门语言的细节特性和 ...

  2. [置顶] Android逆向从未如此简单

    哈,又标题党了..不过我一定竭尽所能,写一篇最亲民的入门文章. 本文仅供学习交流之用,切勿用于非法用途,读者若运用所学知识,进行非法任何商业目的或者非法牟利,一切责任由操作者自行承担,与本人无关.希望 ...

  3. 《Android逆向反编译代码注入》 - 逆向安全入门必看视频教程

      适合人群: Android开发人员.逆向反编译开发人员.以及对Android逆向安全感兴趣的朋友. 视频地址: 51CTO学院:https://edu.51cto.com/course/24485 ...

  4. [转]Android逆向之动态调试总结

    一.在SO中关键函数上下断点 刚学逆向调试时.大多都满足于在SO中某关键函数上下断点.然后通过操作应用程序,去触发这个断点,然后进行调试 详细的步骤可以参见非虫大大的<Android软件安全与逆 ...

  5. 包建强的培训课程(16):Android新技术入门和提高

    @import url(/css/cuteeditor.css); Normal 0 10 pt 0 2 false false false EN-US ZH-CN X-NONE $([{£¥·‘“〈 ...

  6. Android逆向之静态分析

    想必打过CTF的小伙伴多多少少都触过Android逆向,所以斗哥将给大家整一期关于Android逆向的静态分析与动态分析.本期先带来Android逆向的静态分析,包括逆向工具使用.文件说明.例题解析等 ...

  7. Vulkan入门流程

    原文摘自Vulkan入门流程 Vulkan是Khronos Group(OpenGL标准的维护组织)开发的一个新API,它提供了对现代显卡的一个更好的抽象,与OpenGL和Direct3D等现有api ...

  8. Android逆向-Android基础逆向(5)

    本文作者:i春秋作家——HAI_ 0×00 前言 不知所以然,请看 Android逆向-Android基础逆向(1)Android逆向-Android基础逆向(2)Android逆向-Android基 ...

  9. Android逆向-java代码基础

    作者:I春秋作家——HAI_ 0×00 前言 看这篇可以先看看之前的文章,进行一个了解.Android逆向-java代码基础(1)Android逆向-java代码基础(2) 之前看到有大佬用smali ...

随机推荐

  1. HTTP笔记01-http相关的基础知识

    这个系列文章是阅读<图解HTTP>后写下的笔记 当我们在浏览器输入url,点击回车后,浏览器显示我们需要的web页面,那么,这个界面是如何产生的? 根据浏览器地址中输入的url,浏览器从相 ...

  2. vs 快捷键操作

    各个版本可能不同,以vs 2013为例. 1.调试时,调出即时窗口:[Ctrl+Alt+i] 2.注释/取消注释:[Ctrl+K Ctrl+C]/[Ctrl+K Ctrl+U]

  3. SSH远程联机Linux服务器简易安全设定

    分别可以由底下这三方面来进行: 1.服务器软件本身的设定强化:/etc/ssh/sshd_config 2.TCP wrapper 的使用:/etc/hosts.allow, /etc/hosts.d ...

  4. Latex所有常用数学符号整理

    原文地址:https://blog.csdn.net/ying_xu/article/details/51240291 这段时间用Latex很多,常常需要查阅相关特殊的符号,这里做一个整理,也方便大家 ...

  5. 【BZOJ 2119】股市的预测(SAM)

    SAM很好用的啊... 传送门 双倍经验:L-Gap Substrings 基本做法类似,这道题的差分改掉,map 改掉就好了QWQ noteskey 反正就是先差分一下,然后把首项丢掉(没有比较的对 ...

  6. [IOI2000] 邮局

    ## 非常神仙的 wqs 二分优化dp,又学了一招. 首先我们需要先想到一个人类智慧版的前缀和优化. # part 1:violence 然鹅在前缀和优化之前我们先考虑暴力做法:我们可以枚举 i . ...

  7. vmware Harbor 复制功能试用

    vmware Harbor 复制功能试用 Harbor基于策略的Docker镜像复制功能,可在不同的数据中心.不同的运行环境之间同步镜像,并提供友好的管理界面,大大简化了实际运维中的镜像管理工作. 功 ...

  8. 使用nvidia-smi命令查看显卡信息

    安装: 1.先安装tensorflow-gpu,需要查看对应的版本,通过pycharm运行程序时会报错,提示需要安装CUDA,且会指明需要版本号 >> pip install tensor ...

  9. Tornado学习笔记(一) helloword/多进程/启动参数

    前言 当你觉得你过得很舒服的时候,你肯定没有在进步.所以我想学习新的东西,然后选择了Tornado.因为我觉得Tornado更匹配目前的我的综合素质. Tornado学习笔记系列主要参考<int ...

  10. (转载)(int)a、&a、(int)&a、(int&)a的区别,很偏僻的题

    #include <iostream>#include <stdio.h>#include <string.h>#include <conio.h>us ...