梆梆加固破解


  本文假设你已经使用过梆梆加固,手头至少有个一个通过梆梆加固后的apk,并且要求您对xposed框架有一定的了解,以下的所有hook方法都是通过xposed来实现的。

     BTW:本人实现了一个hook动态库的功能,无需root就能hook住动态库的对外接口,后面会写文章介绍方法

梆梆加固的原理,这里就不仔细描述了,可以将加固后的apk反编译后分析一下,看看梆梆在里面都加了什么内容,我总结一下梆梆加固做了哪些事情:

1、创建.cache目录,/data/data/packageName/.cache/"

2、自定义DexClassLoader:

      dexPath: /data/data/packagename/.cache/classes.jar

      optimizedDirectory: /data/data/packagename/.cache

      libraryPath: /data/data/packagename/lib

3、通过自定义dexclassloader的方式,可以将真正的dex进行隐藏,在运行时动态load该dex,

4、 由于dex在安装时会被转换为odex存放在/data/dalvik-cache目录下,梆梆加固后的app在该目录下的odex文件非真正运行的odex文件。

  小结:万变不离其宗,不管梆梆加固怎么伪装,原理上都是通过自定义DexClassLoader来实现的,这也是破解梆梆加固的根本。

  BTW:梆梆加固为了防破解还是做了很多工作的,比如笔者之前试着通过用gdb来挂进程,并通过dump内存的方式来破解,但是一挂上进程后,程序就异常终止了。

破解办法:由于梆梆加固将真实的dex进行了隐藏,所以咱们现在要做的就是想办法把真实的dex给挖出来,通过静态的文件分析没什么好办法,但是有一点可能是所有的加固软件都没办法解决的问题,就是在程序运行时,需要把dex文件加载到内存里来。这是我们破解的入口,以下内容也是围绕着这个目标来展开的。

1、 要获取dex文件的信息,必须获得系统的ClassLoaer ,每个apk运行起来后都有一个对应的数据结构:如下:

public final class LoadedApk {

    private static final String TAG = "LoadedApk";

    private final ActivityThread mActivityThread;
    private final ApplicationInfo mApplicationInfo;
    final String mPackageName;
    private final String mAppDir;
    private final String mResDir;
    private final String[] mSharedLibraries;
    private final String mDataDir;
    private final String mLibDir;
    private final File mDataDirFile;
    private final ClassLoader mBaseClassLoader;
    private final boolean mSecurityViolation;
    private final boolean mIncludeCode;
    private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
    Resources mResources;
    private ClassLoader mClassLoader;
    private Application mApplication;

    private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
        = new ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>();
    private final ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mUnregisteredReceivers
        = new ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>();
    private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
        = new ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>>();
    private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices
        = new ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>>();

    int mClientCount = 0;

          如果能拿到这个数据结构,就能拿到对应的ClassLoader信息,还能拿到所有的services、receivers信息。这个可以通过hook类

android.app.ActivityThread.AppBindData中的handleBindApplication方法来实现。

2、拿到ClassLoader后,就能拿到dex文件路径、library路径、odex文件路径,dexPath对应的类为dalvik.system.DexPathList,包含一个成员变量Element数组用来存放所有的odex文件,Element数据结构如下:

static class Element {
        private final File file;
        private final boolean isDirectory;
        private final File zip;
        private final DexFile dexFile;

        private ZipFile zipFile;
        private boolean initialized;

        其中DexFile就是odex文件的描述,而在该类中有个变量mCookie,如下图:

public final class DexFile {
    private int mCookie;
    private final String mFileName;
    private final CloseGuard guard = CloseGuard.get();

这个就是咱们要找的东西啦,这个整形变量存储的是native层的指针值,指向的是dex在内存里的地址,也就是咱们的最终目标,mCookie指向的结构体如下图。

typedef struct DexOrJar {
    char*          fileName;
    bool           isDex; //是dex文件还是jar包
    bool           okayToFree;
    RawDexFile*    pRawDexFile;
    JarFile*       pJarFile;  //如果是jar包,则指向JarFile结构
    u1* pDexMemory; //如果是dex,则指向dex内存区
} DexOrJar;

         思考:如何建立dexPath和DexOrJar结构体之间的映射关系呢?方法是:hook住dalvik.system.DexFile 中的openDexFileNative方法。在应用程序启动时,都会load dex文件,最终都会调用该方法,openDexFileNative方法为native方法,实现定义在dalvik_system_DexFile.cpp文件中的Dalvik_dalvik_system_DexFile_openDexFileNative方法中)然后根据dexpath取出DexOrJar对象指针,有了这个对象拿出odex只是时间的问题了。

   从上述结构体中可以看出,根据扩展名是dex还是jar来决定内存的组织。有了指针我们就可以将其强转换为DexOrJar对象,其实到此处就已经拿到了odex文件对应的内存内容,下一步需要将该内容导出为smali,然后做dexodex to smali,最终得到smali文件后通过baksmali,就可以还原为dex文件。得到dex文件后,通过dex2jar可以转为java文件,如下图为用梆梆加固后的陌陌解密后导出的dex文件反编译后内容:


  

在得到了dex和工程资源文件后,就可以将程序跑起来,还可以在外面加一层壳后跑起来,后面会写一篇文章详细描述这个过程。


      

评论 38
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值