Android开发学习之路-脱壳反编译
Posted 东月之神
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android开发学习之路-脱壳反编译相关的知识,希望对你有一定的参考价值。
前言
- 想研究下某app里面的实现技术,使用常规的反编译发现竟然是加固的,所谓Apk加固,就是对dex文件进行加密,防止App被反编译,保证apk的安全。市面上有很多的加固平台,有360加固,腾讯乐固,爱加密等等。
- 上一篇文章我们了解了加固,也有了加固后的apk,这里我们利用工具脱壳查看源码。
1. 脱壳工具FDex2
道高一尺魔高一丈嘛,有加固平台,也有脱壳工具,常见的脱壳工具有FDex2,dumpdex,drizzleDumper等。这里我们使用FDex2来实现脱壳。
FDex2通过Hook ClassLoader的loadClass方法,反射调用getDex方法取得Dex(com.android.dex.Dex类对象),在将里面的dex写出。
下载地址:
链接:https://pan.baidu.com/s/1smxtinr 密码:dk4v
我们看下主要的源码:
public class MainHook implements IXposedHookLoadPackage
Class Dex;
Method Dex_getBytes;
Method getDex = (Method)null;
XSharedPreferences shared;
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam paramLoadPackageParam)
this.shared = new XSharedPreferences("formatfa.xposed.Fdex2", "package");
this.shared.reload();
initRefect();
String str = this.shared.getString("packagename", (String)null);
if (str == null)
return;
if (!paramLoadPackageParam.packageName.equals(str))
return;
XposedBridge.log(str + " has hook");
ClassLoader classLoader = paramLoadPackageParam.classLoader;
try
Class clazz = Class.forName("java.lang.String");
XposedHelpers.findAndHookMethod("java.lang.ClassLoader", classLoader, "loadClass", new Object[] clazz, boolean.class, new XC_MethodHook(this, str, paramLoadPackageParam)
private final MainHook this$0;
private final String val$aim;
private final XC_LoadPackage.LoadPackageParam val$p1;
@Override
protected void afterHookedMethod(MethodHookParam param1MethodHookParam)
XposedBridge.log(" after hook : ");
boolean bool = true;
clazz = (Class)param1MethodHookParam.getResult();
if (clazz == null)
return;
try
str = clazz.getName();
try
Class clazz1;
(clazz1 = Class.forName("formatfa.xposed.Fdex2.MainHook")).forName(str, false, clazz1.getClassLoader().getSystemClassLoader());
catch (ClassNotFoundException str)
throw new NoClassDefFoundError(str.getMessage());
catch (ClassNotFoundException classNotFoundException)
bool = false;
if (bool)
return;
try
Object object = this.this$0.getDex.invoke(clazz, new Object[0]);
byte[] arrayOfByte = (byte[])this.this$0.Dex_getBytes.invoke(object, new Object[0]);
if (arrayOfByte != null)
"/data/data/" + this.val$aim + "/" + this.val$aim + arrayOfByte.length + ".dex";
File file = new File(this.this$0.shared.getString("dir", "/sdcard"), this.val$p1.packageName + arrayOfByte.length + ".dex");
if (!file.exists())
FIO.writeByte(arrayOfByte, file.getAbsolutePath());
return;
catch (Exception clazz)
XposedBridge.log(clazz.toString());
return;
@Override
protected void beforeHookedMethod(MethodHookParam param1MethodHookParam)
);
return;
catch (ClassNotFoundException paramLoadPackageParam)
throw new NoClassDefFoundError(paramLoadPackageParam.getMessage());
public void initRefect()
try
this.Dex = Class.forName("com.android.dex.Dex");
this.Dex_getBytes = this.Dex.getDeclaredMethod("getBytes", new Class[0]);
if (!MainActivity.h.endsWith("0"))
return;
int i = MainActivity.s.length();
if (i != 91)
return;
try
Class clazz = Class.forName("java.lang.Class");
this.getDex = clazz.getDeclaredMethod("getDex", new Class[0]);
catch (ClassNotFoundException classNotFoundException)
throw new NoClassDefFoundError(classNotFoundException.getMessage());
catch (Exception exception)
XposedBridge.log(exception.toString());
void writeDex(String paramString, Object paramObject)
try
paramObject = this.getDex.invoke(paramObject.getClass(), new Object[0]);
byte[] arrayOfByte = (byte[])this.Dex_getBytes.invoke(paramObject, new Object[0]);
if (arrayOfByte != null)
File file = new File(this.shared.getString("dir", "/sdcard"), paramString + arrayOfByte.length + ".dex");
if (!file.exists())
FIO.writeByte(arrayOfByte, file.getAbsolutePath());
return;
catch (InvocationTargetException paramString)
return;
catch (IllegalAccessException paramString)
return;
catch (IllegalArgumentException paramString)
return;
他会根据选中的package,然后运行目标apk的时候把dex文件缓存到/data/data/package下。然后我们可以拿到这些dex文件,通过dex2jar工具转换为jar包,然后再通过jd_gui来查看源码。
关于xposed的hook功能,之后一篇文章会介绍如何使用。
2.VirtualXposed
现在的手机很多都是没有root权限的,若是测试机倒没事,要是是自己在用的手机root了权限显得没那么安全。这里我们可以使用VirtualXposed(下载点击这里),即使不root掉权限,我们也可以拿到我们需要的dex文件.
3.开始脱壳
现在我们应该准备好了VirtualXposed、FDex2和需要脱壳的应用ShellApk,可以开始脱壳了。
3.1 安装
将准备好的上述应用都安装到手机上
3.2 VirtualXposed添加应用
- 启动VirtualXposed,在"设置->添加应用"中,安装FDex2和脱壳应用ShellApk。
安装完后如下所示:
- 打开Xposed Installer,在"模块"中勾选FDex2,并重启设备,这里的重启是VirtualXposed的设置中重启,是个软重启。
3.3 启动FDex2
启动VirtualXposed中的FDex2,选择要hook的目标,也就是ShellApk
3.4 启动需要脱壳的应用
启动需要脱壳的应用ShellApk,我们所需要的dex就已经缓存好了
3.5 传输
在VirtualXposed中,“设置–>高级设置–>文件管理”,安装文件管理器.Amaze文件管理器,如果没法安装可以手动安装,当然也可以安装Total Commander自定义标签为"/data/data/io.va.exposed"。
在virtual/data/user/0/com.jared.shellapk目录下选中dex文件,然后通过分享传输到电脑上
注:这里要是不能传输的话,可以试试安装qq,可以通过qq传输到电脑上。
4 查看源码
拿到了dex文件,我们就可以通过dex2jar来生成jar文件,然后通过jd-gui来查看具体的代码了(怎么从dex到jar并查看源码,这里就不分析了,可以参考这篇文章,《逆向分析反编译》)
- 逆向后的代码如下所示:
和ApkTest的源码比较,基本上一致,这里有两个方法gotoSecondActivity和showStr,下一篇文章基于此做一个hook插件。
以上是关于Android开发学习之路-脱壳反编译的主要内容,如果未能解决你的问题,请参考以下文章