android APK一键DEX加固脚本(内存加载DEX)

Overview

概况

本文目的:通过内存加载DEX文件技术,完成一键DEX加固脚本

使用说明

python sheller.py -f xxx.apk

加固原理

和我的另一个项目Native层DEX一键加固脚本基本一样,只是多了一步,引入了内存加载DEX技术

一键加固脚本实现步骤

  1. 准备原DEX加密算法以及隐藏位置(壳DEX尾部)
        """
        1. 第一步:确定加密算法
        """
        inKey = 0xFF
        print("[*] 确定加密解密算法,异或: {}".format(str(inKey)))
  1. 生成壳DEX。(壳Application动态加载原application中需要原application的name字段)
        """
        2. 第二步:准备好壳App
        """
        # 反编译原apk
        decompAPK(fp)
        # 获取Applicaiton name并保存到壳App源码中
        stSrcDexAppName = getAppName(fp)
        save_appName(stSrcDexAppName)
        # 编译出壳DEX
        compileShellDex()
        print("[*] 壳App的class字节码文件编译为:shell.dex完成")
  1. 修改原APK文件中的AndroidManifest.xml文件的applicationandroid:name字段,实现从壳application启动
        """
        3. 第三步:修改原apk AndroidManifest.xml文件中的Application name字段为壳的Application name字段
        """
        # 替换壳Applicaiton name到原apk的AndroidManifest.xml内
        replaceTag(fp, "cn.yongye.nativeshell.StubApp")
        print("[*] 原apk文件AndroidManifest.xml中application的name字段替换为壳application name字段完成")
  1. 加密原DEX到壳DEX尾部并将壳DEX替换到原APK中
        """
        4. 替换原apk中的DEX文件为壳DEX
        """
        replaceSDexToShellDex(os.path.join(stCurrentPt, "result.apk"))
        print("[*] 壳DEX替换原apk包内的DEX文件完成")
  1. 添加脱壳lib库到原apk中
        """
        5. 添加脱壳lib库到原apk中
        """
        addLib("result.apk")
  1. apk签名
        """
        6. apk签名
        """
        signApk(os.path.join(stCurrentPt, "result.apk"), os.path.join(stCurrentPt, "demo.keystore"))
        print("[*] 签名完成,生成apk文件: {}".format(os.path.join(stCurrentPt, "result.apk")))

内存加载DEX

了解内存加载DEX文件内存加载技术之前,我们需要了解DEX文件加载这一过程。

**DEX文件加载过程:**即下面左图所示的API调用链就是加载过程。DEX文件加载的核心是最后一层,通过Native层函数传入DEX文件从而获取一个cookie值

所以我们要实现内存加载DEX的话,不仅需要自己重写这套DEX文件调用链,最主要的是寻找一个Native层API实现传入DEX文件字节流来获取cookie值,就是下面右图所示调用链,API即openMemory(4.3 ART虚拟机以后, 4.3及其以前Dalvik虚拟机用openDexFile([byte...)API)即可实现这样的功能

内存加载DEX

Android 8以后BaseDexClassLoader类就有内存加载的能力,参考Android 8源码,已经加入了这样的接口,我们只需要将相关代码文件copy下来,将最底层的Native函数用openMemory替代即可

image-20200415234950548

自定义MyDexClassLoader

通过dlopen和dlsym的方法找到openMemory函数实现核心函数即可

JNICALL extern "C"
JNIEXPORT jlong JNICALL
Java_cn_yongye_inmemoryloaddex_DexFile_createCookieWithArray(JNIEnv *env, jclass clazz,
                                                             jbyteArray buf, jint start, jint end) {
    // TODO: implement createCookieWithArray()
    void *artlib =  fake_dlopen("/system/lib/libart.so", RTLD_LAZY);
    if(!artlib){
        exit(0);
    }
    org_artDexFileOpenMemory22 openMemory22 = (org_artDexFileOpenMemory22)fake_dlsym(artlib,
                                                                        "_ZN3art7DexFile10OpenMemoryEPKhjRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPNS_6MemMapEPKNS_7OatFileEPS9_");

    if(!openMemory22){
        exit(0);
    }
    jbyte *bytes;
    char *pDex  = NULL;
    std::string location = "";
    std::string err_msg;


    bytes = env->GetByteArrayElements(buf, 0);
    int inDexLen = env->GetArrayLength(buf);
    pDex = new char[inDexLen + 1];
    memset(pDex, 0, inDexLen + 1);
    memcpy(pDex, bytes, inDexLen);
    pDex[inDexLen] = 0;
    env->ReleaseByteArrayElements(buf, bytes, 0);
    const Header *dex_header = reinterpret_cast<const Header *>(pDex);
    void *value = openMemory22((const unsigned char *)pDex, inDexLen, location, dex_header->checksum_, NULL, NULL, &err_msg);

    jlong cookie = replace_cookie(env, value, 22);
    return cookie;

}

还需要实现DEX加载器另外一个重要功能,即加载类的能力,这个功能本来也是需要Native函数实现的,这里我们可以通过反射调用DexFile类的defineClass方法(加载类的调用链是:findClass->defineClass)实现

private Class defineClass(String name, ClassLoader loader, Object cookie,
                              DexFile dexFile, List<Throwable> suppressed) {
        Class result = null;
        try {
            Class clsDexFile = Class.forName("dalvik.system.DexFile");
            Method mdDefineClass = clsDexFile.getDeclaredMethod("defineClass", String.class, ClassLoader.class, long.class, List.class);
            mdDefineClass.setAccessible(true);
            result = (Class) mdDefineClass.invoke(null, name, loader, cookie, suppressed);
        } catch (NoClassDefFoundError e) {
            if (suppressed != null) {
                suppressed.add(e);
            }
        } catch (ClassNotFoundException e) {
            if (suppressed != null) {
                suppressed.add(e);
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return result;
    }

Cmake、ninja编译cpp文件

native层代码源文件在cpp目录下,可以直接调用cpp/build.bat一键编译批处理文件

cmake生成ninja编译配置文件

D:\Android\Sdk\cmake\3.10.2.4988404\bin\cmake.exe . -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=D:\Android\Sdk\ndk\20.0.5594570\build\c make\android.toolchain.cmake -DANDROID_ABI=x86 -DANDROID_NDK=D:\Android\Sdk\ndk\20.0.5594570 -DANDROID_PLATFORM=android-16 -DCMAKE_ANDROID_ARCH_ABI=x86 -DCMAKE_ANDROID_NDK=D:\Android\Sdk\ndk\20.0.5594570 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_MAKE_PROGRAM=D:\Android\Sdk\cmake\3.10.2.4988404\bin\ninja.exe -DCMAKE_SYSTEM_NAME=Android -DCMAKE_SYSTEM_VERSION=16 -GNinja

ninja生成so文件

只是修改cpp文件,直接运行ninja命令,不用重新用cmake生成ninja配置文件 如果有新cpp文件的增加删除,还是需要删除配置文件,重新运行cmake的

D:\Android\Sdk\cmake\3.10.2.4988404\bin\ninja.exe

参考

【1】Android中apk加固完善篇之内存加载dex方案实现原理(不落地方式加载)

【2】内存解密并加载DEX

鼓励

支付宝

微信

You might also like...
🌄 Photo editor using native modules for iOS and Android. Inherit from 2 available libraries, Brightroom (iOS) and PhotoEditor (Android)
🌄 Photo editor using native modules for iOS and Android. Inherit from 2 available libraries, Brightroom (iOS) and PhotoEditor (Android)

React Native Photo Editor (RNPE) 🌄 Image editor using native modules for iOS and Android. Inherit from 2 available libraries, Brightroom (iOS) and Ph

Ride-Sharing Uber Lyft Android App - Learn to build a ride-sharing Android Taxi Clone App like Uber, Lyft - Open-Source Project By MindOrks
Ride-Sharing Uber Lyft Android App - Learn to build a ride-sharing Android Taxi Clone App like Uber, Lyft - Open-Source Project By MindOrks

Ride-Sharing Uber Lyft Android App - Learn to build a ride-sharing Android Taxi Clone App like Uber, Lyft - Open-Source Project By MindOrks

A simple Android app to demonstrate the use of Hover SDK for M-PESA Send Money while offline. This SDK does not require an internet connection, it automates USSD sessions in the background of an android application.

HoverSDKDemo Hover SDK is an Android SDK that lets mobile developers to add money features to the applications. This SDK does not require an internet

Source code of JekyllEx Android App which can manage your Jekyll blog directly from your Android device!
Source code of JekyllEx Android App which can manage your Jekyll blog directly from your Android device!

JekyllEx Android App Built with ❤︎ by Gourav Khunger 🚀 Introduction JekyllEx is an Android App that allows you to manage a Jekyll Blog directly from

A Simple and Minimal Quotes Android Application to demonstrate the Modern Android Development tools
A Simple and Minimal Quotes Android Application to demonstrate the Modern Android Development tools

Quotee Android 📑 A Simple and Minimal Quotes Android Application to demonstrate the Modern Android Development tools. Developed with ❤️ by Aminullah

🎥 A Simple and Minimal Movies Android Application to demonstrate the Modern Android Development and Jetpack Compose.
🎥 A Simple and Minimal Movies Android Application to demonstrate the Modern Android Development and Jetpack Compose.

ComposeMovie Android 🎥 A Simple and Minimal Movies Android Application to demonstrate the Modern Android Development and Jetpack Compose. Built with

Android Studio project wrapper around the Elixir TodoApp Desktop app to run on Android including the Erlang runtime
Android Studio project wrapper around the Elixir TodoApp Desktop app to run on Android including the Erlang runtime

TodoApp Android: An Android Sample App This Android Studio project wraps the Desktop Sample App to run on an Android phone. How to build & run Install

GmailCompose is an Android application 📱 for showcasing Jetpack Compose for building declarative UI in Android.
GmailCompose is an Android application 📱 for showcasing Jetpack Compose for building declarative UI in Android.

GmailCompose GmailCompose Demo GmailCompose is an Android application 📱 for showcasing Jetpack Compose for building declarative UI in Android. About

Parsing and re-packing Android boot.img/vbmeta.img, supporting Android 12(preview)
Parsing and re-packing Android boot.img/vbmeta.img, supporting Android 12(preview)

Android_boot_image_editor A tool for reverse engineering Android ROM images. Getting Started install required packages Mac: brew install lz4 xz dtc Li

Comments
  • 加固后程序崩溃

    加固后程序崩溃

    测试机为华为mate20p,程序加固后崩溃,日志如下,请帮忙看一下:

      --------- beginning of crash
    2020-12-07 01:24:06.438 22114-22114/demon.demo A/libc: Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 22114 (demon.demo), pid 22114 (demon.demo)
    2020-12-07 01:24:06.489 22165-22165/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    2020-12-07 01:24:06.490 22165-22165/? A/DEBUG: Build fingerprint: 'HUAWEI/VOG-AL00/HWVOG:10/HUAWEIVOG-AL00/10.1.0.162C00:user/release-keys'
    2020-12-07 01:24:06.490 22165-22165/? A/DEBUG: Revision: '0'
    2020-12-07 01:24:06.490 22165-22165/? A/DEBUG: ABI: 'arm64'
    2020-12-07 01:24:06.490 22165-22165/? E/libc: Access denied finding property "persist.mygote.disable"
    2020-12-07 01:24:06.490 22165-22165/? E/libc: Access denied finding property "persist.mygote.escape.enable"
    2020-12-07 01:24:06.493 22165-22165/? A/DEBUG: SYSVMTYPE: Maple
    
        APPVMTYPE: Art
    2020-12-07 01:24:06.493 22165-22165/? A/DEBUG: Timestamp: 2020-12-07 01:24:06+0800
    2020-12-07 01:24:06.493 22165-22165/? A/DEBUG: pid: 22114, tid: 22114, name: demon.demo  >>> demon.demo <<<
    2020-12-07 01:24:06.493 22165-22165/? A/DEBUG: uid: 10577
    2020-12-07 01:24:06.493 22165-22165/? A/DEBUG: signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
    2020-12-07 01:24:06.493 22165-22165/? A/DEBUG: Abort message: 'terminating'
    2020-12-07 01:24:06.493 22165-22165/? A/DEBUG:     x0  0000000000000000  x1  0000000000005662  x2  0000000000000006  x3  0000007fc088e1d0
    2020-12-07 01:24:06.493 22165-22165/? A/DEBUG:     x4  fefefefeff666d68  x5  fefefefeff666d68  x6  fefefefeff666d68  x7  7f7f7f7f7f7f7f7f
    2020-12-07 01:24:06.493 22165-22165/? A/DEBUG:     x8  00000000000000f0  x9  e9308aeea94d9e08  x10 0000000000000001  x11 0000000000000000
    2020-12-07 01:24:06.493 22165-22165/? A/DEBUG:     x12 fffffff0fffffbdf  x13 000000005fcd13b6  x14 00066fe8f826db95  x15 00001a3445b54429
    2020-12-07 01:24:06.493 22165-22165/? A/DEBUG:     x16 00000075f8071908  x17 00000075f80511b0  x18 00000075fa574000  x19 0000000000005662
    2020-12-07 01:24:06.493 22165-22165/? A/DEBUG:     x20 0000000000005662  x21 00000000ffffffff  x22 0000007fc088e420  x23 00000075f806c5b0
    2020-12-07 01:24:06.493 22165-22165/? A/DEBUG:     x24 0000007fc088e300  x25 0000007fc088e340  x26 00000075fa0e7fa0  x27 00000075f8073000
    2020-12-07 01:24:06.493 22165-22165/? A/DEBUG:     x28 0000000000000018  x29 0000007fc088e270
    2020-12-07 01:24:06.493 22165-22165/? A/DEBUG:     sp  0000007fc088e1b0  lr  00000075f8006040  pc  00000075f800606c
    
    2020-12-07 01:24:06.647 22165-22165/? A/DEBUG: backtrace:
    2020-12-07 01:24:06.648 22165-22165/? A/DEBUG:       #00 pc 000000000006f06c  /apex/com.android.runtime/lib64/bionic/libc.so (abort+160) (BuildId: 212095a5bb472f1fd33898cf4066bc50)
    2020-12-07 01:24:06.648 22165-22165/? A/DEBUG:       #01 pc 00000000000500fc  /system/lib64/libc++.so (abort_message+232) (BuildId: d957c07e50073a9c45a9ca98188a85f7)
    2020-12-07 01:24:06.648 22165-22165/? A/DEBUG:       #02 pc 0000000000050218  /system/lib64/libc++.so (demangling_terminate_handler()+44) (BuildId: d957c07e50073a9c45a9ca98188a85f7)
    2020-12-07 01:24:06.648 22165-22165/? A/DEBUG:       #03 pc 00000000000646c4  /system/lib64/libc++.so (std::__terminate(void (*)())+12) (BuildId: d957c07e50073a9c45a9ca98188a85f7)
    2020-12-07 01:24:06.648 22165-22165/? A/DEBUG:       #04 pc 000000000006466c  /system/lib64/libc++.so (std::terminate()+52) (BuildId: d957c07e50073a9c45a9ca98188a85f7)
    2020-12-07 01:24:06.648 22165-22165/? A/DEBUG:       #05 pc 00000000000bb150  /system/lib64/libc++.so (std::__1::thread::~thread()+20) (BuildId: d957c07e50073a9c45a9ca98188a85f7)
    2020-12-07 01:24:06.648 22165-22165/? A/DEBUG:       #06 pc 00000000000d0f68  /apex/com.android.runtime/lib64/bionic/libc.so (__cxa_finalize+212) (BuildId: 212095a5bb472f1fd33898cf4066bc50)
    2020-12-07 01:24:06.648 22165-22165/? A/DEBUG:       #07 pc 00000000000cc950  /apex/com.android.runtime/lib64/bionic/libc.so (exit+24) (BuildId: 212095a5bb472f1fd33898cf4066bc50)
    2020-12-07 01:24:06.648 22165-22165/? A/DEBUG:       #08 pc 000000000001042c  /data/app/demon.demo-oeVxr1dMqVRE9lCbfWIWDw==/lib/arm64/libdalvik_system_DexFile.so (Java_com_example_memorytest_inmemoryloaddex_DexFile_createCookieWithArray+92) (BuildId: ad46b101231866811c1f452830a01d586d13c2a8)
    2020-12-07 01:24:06.648 22165-22165/? A/DEBUG:       #09 pc 000000000014c350  /apex/com.android.runtime/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: 696759073fd59cd48df4113ea4815c67)
    2020-12-07 01:24:06.648 22165-22165/? A/DEBUG:       #10 pc 00000000001435b8  /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: 696759073fd59cd48df4113ea4815c67)
    2020-12-07 01:24:06.648 22165-22165/? A/DEBUG:       #11 pc 00000000001521c4  /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+284) (BuildId: 696759073fd59cd48df4113ea4815c67)
    2020-12-07 01:24:06.648 22165-22165/? A/DEBUG:       #12 pc 00000000002ee2d0  /apex/com.android.runtime/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+384) (BuildId: 696759073fd59cd48df4113ea4815c67)f
    
    opened by iieshawnzhao 1
  • LoadedApk: Unable to instantiate appComponentFactory

    LoadedApk: Unable to instantiate appComponentFactory

    LoadedApk: Unable to instantiate appComponentFactory
        java.lang.ClassNotFoundException: Didn't find class "androidx.core.app.CoreComponentFactory" on path: DexPathList[[zip file "/data/app/~~7VAbzKenIo93vVoHfa9kbQ==/com.example.myapplication-hh10LEHHaCc2hidiT7KMzA==/base.apk"],nativeLibraryDirectories=[/data/app/~~7VAbzKenIo93vVoHfa9kbQ==/com.example.myapplication-hh10LEHHaCc2hidiT7KMzA==/lib/x86, /data/app/~~7VAbzKenIo93vVoHfa9kbQ==/com.example.myapplication-hh10LEHHaCc2hidiT7KMzA==/base.apk!/lib/x86, /system/lib, /system_ext/lib]]
            at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:207)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
            at android.app.LoadedApk.createAppFactory(LoadedApk.java:260)
            at android.app.LoadedApk.createOrUpdateClassLoaderLocked(LoadedApk.java:905)
            at android.app.LoadedApk.getClassLoader(LoadedApk.java:958)
            at android.app.LoadedApk.getResources(LoadedApk.java:1190)
            at android.app.ContextImpl.createAppContext(ContextImpl.java:2663)
            at android.app.ContextImpl.createAppContext(ContextImpl.java:2655)
            at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6595)
            at android.app.ActivityThread.access$1300(ActivityThread.java:237)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1913)
            at android.os.Handler.dispatchMessage(Handler.java:106)
            at android.os.Looper.loop(Looper.java:223)
            at android.app.ActivityThread.main(ActivityThread.java:7656)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
    

    source.zip apks.zip

    opened by Th3CracKed 0
Owner
yong夜
yong夜
Android cutout screen support Android P. Android O support huawei, xiaomi, oppo and vivo.

CutoutScreenSupport Android cutout screen support Android P. Android O support huawei, xiaomi, oppo and vivo. Usage whether the mobile phone is cutout

hacket 5 Nov 3, 2022
FoldingNavigationDrawer-Android This is a sample project present how to use Folding-Android to add Folding Efect to Navigation Drawer.

FoldingNavigationDrawer-Android Sample (Play Store Demo) This is a sample project present how to use Folding-Android to add Folding Efect to Navigatio

null 242 Nov 25, 2022
Twidere-Android Twidere is a powerful twitter client for Android 1.6+ 1 , which gives you a full Holo experience and nearly full Twitter's feature.

Twidere for Android Material Design ready and feature rich Twitter/Mastodon/Fanfou app for Android 4.1+. Enjoy Fediverse now! Twidere-Android is maint

Twidere Project 2.7k Jan 2, 2023
:movie_camera: Movie discovery app showcasing Android best practices with Google's recommended architecture: MVVM + Repository + Offline support + Android Architecture Components + Paging library & Retrofit2.

Popular Movies Stage 1 + Stage 2 Discover the most popular and top rated movies playing. Movies data fetched using themoviedb.org API. ✨ Screenshots M

Yassin AJDI 189 Nov 26, 2022
Extensible Android mobile voice framework: wakeword, ASR, NLU, and TTS. Easily add voice to any Android app!

Spokestack is an all-in-one solution for mobile voice interfaces on Android. It provides every piece of the speech processing puzzle, including voice

Spokestack 57 Nov 20, 2022
Aggregated Android news, articles, podcasts and conferences about Android Development

DroidFeed Curated news feed for Android Developers! Stay up to date with the latest Android Development news. Built for the Android developer communit

Dogan Gulcan 183 Dec 2, 2022
Shreyas Patil 2.1k Dec 30, 2022
A simple app to showcase Androids Material Design and some of the cool new cool stuff in Android Lollipop. RecyclerView, CardView, ActionBarDrawerToggle, DrawerLayout, Animations, Android Compat Design, Toolbar

#Android-LollipopShowcase This is a simple showcase to show off Android's all new Material Design and some other cool new stuff which is (new) in Andr

Mike Penz 1.8k Nov 10, 2022
The Android startup used to schedule tasks, jobs while launching Android App.

Android Startup, schedule your startup jobs Introduction AndroidStartup is an open source project used to refine your Andriod App startup. Compared wi

ShouHeng 46 Aug 24, 2022
Android playground project with modularization by feature (android libraries), unit tests, MVVM & MVI.

Movies Movies is a simple project to study and play with some android components, architecture and tools for Android development. Tech Stack This proj

Christopher Elias 333 Dec 30, 2022