├── README.md └── RawDexClassLoader ├── AndroidManifest.xml ├── README.md ├── assets └── test.dex ├── gen └── com │ └── payegis │ └── rawdexclassloader │ ├── BuildConfig.java │ └── R.java ├── libs ├── armeabi-v7a │ └── libegis.so ├── armeabi │ └── libegis.so └── x86 │ └── libegis.so ├── proguard-project.txt ├── project.properties ├── res ├── drawable-hdpi │ └── ic_launcher.png ├── drawable-mdpi │ └── ic_launcher.png ├── drawable-xhdpi │ └── ic_launcher.png ├── layout │ └── activity_main.xml ├── values-v11 │ └── styles.xml ├── values-v14 │ └── styles.xml └── values │ ├── strings.xml │ └── styles.xml └── src └── com └── payegis ├── DemoActivity.java ├── RawDexClassLoader.java └── RawDexFile.java /README.md: -------------------------------------------------------------------------------- 1 | ## 通付盾第一代安全加固方案开源 2 | --- 3 | #### 项目简介 4 | APK安全加固是面向移动应用程序的深度安全保护服务,可以为您的APP穿上一层“软猬铠甲”,通过加密、加壳、RPC、动态加载等技术为您的应用进行全方位安全保护,有效防止逆向工程、反编译、嵌入病毒、非法扣费等恶意行为。 5 | 6 | 随着Android ART模式和Android 5.0系统的普及,应用加固已全面迎来第二代API定制加固时代,需要更多的开发者和研究人员一起投入到移动安全行业。为了为移动安全领域做出更大的贡献,通付盾现开源第一代安全加固方案(Dex文件整体加密),树立移动安全开放精神和开源标准。加密等级和方案优劣上与友商的企业版相当,研究人员可在此基础上进一步优化。 7 | 8 | 欢迎广大移动安全研究人员积极投入其中,一起投入安全加固技术的研究。第一代安全加固产品内容主要包含: 9 | 10 | - Dex文件保护 11 | - 资源文件保护 12 | - xml文件保护 13 | - 内存保护 14 | - so保护 15 | 16 | 与此同时,通付盾已全面推出第二代API定制加固产品,完美兼容Android ART和Android 5.0,并独家通过监管部门的安全加固保护效果检测。 17 | 18 | 欢迎使用! 19 | 20 | #### 项目构成 21 | 该项目的开源分组件进行,将第一代安全加固中使用的关键技术改造成可独立使用的安全组件,方便广大开发者对其用途进行扩展。主要的部分有: 22 | 23 | - RawDexClassLoader :自定义封装的DexClassLoader,可以实现将一段内存中Dex文件的映射加载进虚拟机。 24 | - 其余组件待发布 25 | -------------------------------------------------------------------------------- /RawDexClassLoader/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 9 | 10 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /RawDexClassLoader/README.md: -------------------------------------------------------------------------------- 1 | ## RawDexClassLoader简介 2 | --- 3 | #### 简介 4 | RawDexClassLoader是自定义封装的ClassLoader,使用方式与DexClassLoader基本类似,不过可以将内存中Dex文件的映射加载进虚拟机,目前支持Android2.2到Android4.4的Dalvik模式。 5 | 6 | #### 结构 7 | - src目录,为Java层源代码。其中`DemoActivity.java`为测试用例,与assets下的dex文件配合使用。 8 | - jni目录,为Native本地代码,用于编译动态链接库,源代码后续会放出(目前还没增加兼容ART的部分)。 9 | - assets目录,为测试用的dex文件。代码如下: 10 | 11 | ```Java 12 | public class TestClassLoader { 13 | private static int a; 14 | 15 | public TestClassLoader() { 16 | // TODO Auto-generated constructor stub 17 | } 18 | 19 | public static void setValue(int value){ 20 | a = value; 21 | } 22 | 23 | public static int getValue(){ 24 | return a; 25 | } 26 | } 27 | ``` 28 | 29 | - libs目录,为需要链接的动态链接库。 30 | 31 | #### 使用 32 | 本项目为Android工程,git clone到本地之后直接导入IDE,作为Android应用运行,如果执行成功的话会在Activity中弹出相应的Toast。 33 | 如果需要将源码集成到自己的工程中,可以将动态链接库放到自己工程的libs目录下,将除`DemoActivity.java`中的代码拷贝至自己的工程中,当然除此之外还可以将此工程导出成Jar包进行使用。 34 | 35 | #### 更新 36 | 2015-1-21: 37 | - 创建项目,更新Java层代码和动态链接库。 38 | -------------------------------------------------------------------------------- /RawDexClassLoader/assets/test.dex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanchouchou/ApkProtect/5a65fdf11f2a15a532619ec71b3f0ab72e6e4353/RawDexClassLoader/assets/test.dex -------------------------------------------------------------------------------- /RawDexClassLoader/gen/com/payegis/rawdexclassloader/BuildConfig.java: -------------------------------------------------------------------------------- 1 | /** Automatically generated file. DO NOT MODIFY */ 2 | package com.payegis.rawdexclassloader; 3 | 4 | public final class BuildConfig { 5 | public final static boolean DEBUG = true; 6 | } -------------------------------------------------------------------------------- /RawDexClassLoader/gen/com/payegis/rawdexclassloader/R.java: -------------------------------------------------------------------------------- 1 | /* AUTO-GENERATED FILE. DO NOT MODIFY. 2 | * 3 | * This class was automatically generated by the 4 | * aapt tool from the resource data it found. It 5 | * should not be modified by hand. 6 | */ 7 | 8 | package com.payegis.rawdexclassloader; 9 | 10 | public final class R { 11 | public static final class attr { 12 | } 13 | public static final class drawable { 14 | public static final int ic_launcher=0x7f020000; 15 | } 16 | public static final class id { 17 | public static final int textView1=0x7f060000; 18 | } 19 | public static final class layout { 20 | public static final int activity_main=0x7f030000; 21 | } 22 | public static final class string { 23 | public static final int app_name=0x7f040000; 24 | } 25 | public static final class style { 26 | /** 27 | Base application theme, dependent on API level. This theme is replaced 28 | by AppBaseTheme from res/values-vXX/styles.xml on newer devices. 29 | 30 | 31 | Theme customizations available in newer API levels can go in 32 | res/values-vXX/styles.xml, while customizations related to 33 | backward-compatibility can go here. 34 | 35 | 36 | Base application theme for API 11+. This theme completely replaces 37 | AppBaseTheme from res/values/styles.xml on API 11+ devices. 38 | 39 | API 11 theme customizations can go here. 40 | 41 | Base application theme for API 14+. This theme completely replaces 42 | AppBaseTheme from BOTH res/values/styles.xml and 43 | res/values-v11/styles.xml on API 14+ devices. 44 | 45 | API 14 theme customizations can go here. 46 | */ 47 | public static final int AppBaseTheme=0x7f050000; 48 | /** Application theme. 49 | All customizations that are NOT specific to a particular API-level can go here. 50 | */ 51 | public static final int AppTheme=0x7f050001; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /RawDexClassLoader/libs/armeabi-v7a/libegis.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanchouchou/ApkProtect/5a65fdf11f2a15a532619ec71b3f0ab72e6e4353/RawDexClassLoader/libs/armeabi-v7a/libegis.so -------------------------------------------------------------------------------- /RawDexClassLoader/libs/armeabi/libegis.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanchouchou/ApkProtect/5a65fdf11f2a15a532619ec71b3f0ab72e6e4353/RawDexClassLoader/libs/armeabi/libegis.so -------------------------------------------------------------------------------- /RawDexClassLoader/libs/x86/libegis.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanchouchou/ApkProtect/5a65fdf11f2a15a532619ec71b3f0ab72e6e4353/RawDexClassLoader/libs/x86/libegis.so -------------------------------------------------------------------------------- /RawDexClassLoader/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /RawDexClassLoader/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-21 15 | -------------------------------------------------------------------------------- /RawDexClassLoader/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanchouchou/ApkProtect/5a65fdf11f2a15a532619ec71b3f0ab72e6e4353/RawDexClassLoader/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /RawDexClassLoader/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanchouchou/ApkProtect/5a65fdf11f2a15a532619ec71b3f0ab72e6e4353/RawDexClassLoader/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /RawDexClassLoader/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanchouchou/ApkProtect/5a65fdf11f2a15a532619ec71b3f0ab72e6e4353/RawDexClassLoader/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /RawDexClassLoader/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | -------------------------------------------------------------------------------- /RawDexClassLoader/res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /RawDexClassLoader/res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /RawDexClassLoader/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | RawDexClassLoader 4 | 5 | 6 | -------------------------------------------------------------------------------- /RawDexClassLoader/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /RawDexClassLoader/src/com/payegis/DemoActivity.java: -------------------------------------------------------------------------------- 1 | 2 | package com.payegis; 3 | 4 | import android.app.Activity; 5 | import android.content.res.AssetManager; 6 | import android.os.Bundle; 7 | import android.widget.Toast; 8 | 9 | import com.payegis.rawdexclassloader.R; 10 | 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.lang.reflect.InvocationTargetException; 14 | import java.lang.reflect.Method; 15 | 16 | public class DemoActivity extends Activity { 17 | 18 | @Override 19 | protected void onCreate(Bundle savedInstanceState) { 20 | // TODO Auto-generated method stub 21 | super.onCreate(savedInstanceState); 22 | setContentView(R.layout.activity_main); 23 | runTest(); 24 | } 25 | 26 | 27 | public void runTest() { 28 | RawDexClassLoader cl = new RawDexClassLoader(getFromAssets("test.dex"), "test.dex", getApplicationInfo().dataDir + "/lib", 29 | getApplicationContext().getClassLoader()); 30 | Class clazz = null; 31 | try { 32 | clazz = cl.loadClass("com.android.TestClassLoader"); 33 | } catch (ClassNotFoundException e) { 34 | // TODO Auto-generated catch block 35 | e.printStackTrace(); 36 | Toast.makeText(this, "Load Class Failed!", Toast.LENGTH_LONG).show(); 37 | } 38 | 39 | Toast.makeText(this, clazz.toString(), Toast.LENGTH_LONG).show(); 40 | 41 | Method mth; 42 | try { 43 | mth = clazz.getMethod("setValue", new Class[]{int.class}); 44 | mth.invoke(null, new Object[]{5}); 45 | 46 | mth = clazz.getDeclaredMethod("getValue", new Class[]{}); 47 | int result = (int) mth.invoke(null, new Object[]{}); 48 | Toast.makeText(this, "getValue: " + String.valueOf(result), Toast.LENGTH_LONG).show(); 49 | } catch (NoSuchMethodException e) { 50 | // TODO Auto-generated catch block 51 | e.printStackTrace(); 52 | } catch (IllegalAccessException e) { 53 | // TODO Auto-generated catch block 54 | e.printStackTrace(); 55 | } catch (IllegalArgumentException e) { 56 | // TODO Auto-generated catch block 57 | e.printStackTrace(); 58 | } catch (InvocationTargetException e) { 59 | // TODO Auto-generated catch block 60 | e.printStackTrace(); 61 | } 62 | 63 | } 64 | 65 | public byte[] getFromAssets(String filename) { 66 | byte[] buffer = null; 67 | try { 68 | AssetManager am = getAssets(); 69 | InputStream in = am.open(filename); 70 | 71 | int len = in.available(); 72 | buffer = new byte[len]; 73 | in.read(buffer); 74 | in.close(); 75 | 76 | } catch (IOException e) { 77 | // TODO Auto-generated catch block 78 | e.printStackTrace(); 79 | } 80 | 81 | return buffer; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /RawDexClassLoader/src/com/payegis/RawDexClassLoader.java: -------------------------------------------------------------------------------- 1 | 2 | package com.payegis; 3 | 4 | import java.io.File; 5 | 6 | public class RawDexClassLoader extends ClassLoader { 7 | private final ClassLoader definingContext; 8 | private final RawDexFile mDex; 9 | private final String mRawLibPath; 10 | private String[] mLibPaths; 11 | 12 | public RawDexClassLoader(byte[] rawDex, String dexName, String libraryPath, ClassLoader parent) { 13 | super(parent); 14 | mDex = loadRawDex(rawDex, dexName); 15 | mRawLibPath = libraryPath; 16 | definingContext = parent; 17 | setNativeLibrary(libraryPath); 18 | } 19 | 20 | @Override 21 | protected Class findClass(String className) throws ClassNotFoundException { 22 | // TODO Auto-generated method stub 23 | Class clazz = null; 24 | if (mDex != null) { 25 | String slashName = className.replace('.', '/'); 26 | clazz = mDex.loadClass(slashName, this); 27 | } 28 | 29 | return clazz; 30 | } 31 | 32 | public String findLibrary(String libraryName) { 33 | String fileName = System.mapLibraryName(libraryName); 34 | for (int i = 0; i < mLibPaths.length; i++) { 35 | String pathName = mLibPaths[i] + fileName; 36 | File test = new File(pathName); 37 | 38 | if (test.exists()) { 39 | return pathName; 40 | } 41 | } 42 | return null; 43 | } 44 | 45 | public String[] getLoadedClasses() { 46 | return mDex.getLoadedClassName(); 47 | } 48 | 49 | @SuppressWarnings("unused") 50 | private RawDexFile loadRawDex(byte[] rawDex, String dexName) { 51 | return RawDexFile.loadDex(rawDex, dexName, 0); 52 | } 53 | 54 | private void setNativeLibrary(String libraryPath) { 55 | 56 | String pathList = System.getProperty("java.library.path", "."); 57 | String pathSep = System.getProperty("path.separator", ":"); 58 | String fileSep = System.getProperty("file.separator", "/"); 59 | 60 | if (mRawLibPath != null) { 61 | if (pathList.length() > 0) { 62 | pathList += pathSep + mRawLibPath; 63 | } 64 | else { 65 | pathList = mRawLibPath; 66 | } 67 | } 68 | 69 | mLibPaths = pathList.split(pathSep); 70 | 71 | // Add a '/' to the end so we don't have to do the property lookup 72 | // and concatenation later. 73 | for (int i = 0; i < mLibPaths.length; i++) { 74 | if (!mLibPaths[i].endsWith(fileSep)) { 75 | mLibPaths[i] += fileSep; 76 | } 77 | } 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /RawDexClassLoader/src/com/payegis/RawDexFile.java: -------------------------------------------------------------------------------- 1 | 2 | package com.payegis; 3 | 4 | public class RawDexFile { 5 | private long mCookie; 6 | private String mDexName; 7 | 8 | private RawDexFile(byte[] rawDex, String dexName, int flags) { 9 | mCookie = openRawDexFile(rawDex, dexName, 0); 10 | mDexName = dexName; 11 | } 12 | 13 | public Class loadClass(String name, ClassLoader loader) { 14 | String slashName = name.replace('.', '/'); 15 | return loadClassBinaryName(slashName, loader); 16 | } 17 | 18 | // 加载一个类名形如com/hello/world的类 19 | public Class loadClassBinaryName(String name, ClassLoader loader) { 20 | return defineClass(name, loader, mCookie); 21 | } 22 | 23 | static public RawDexFile loadDex(byte[] rawDex, String dexName, int flags) { 24 | return new RawDexFile(rawDex, dexName, flags); 25 | } 26 | 27 | private static Class defineClass(String name, ClassLoader loader, long cookie) { 28 | Class result = null; 29 | try { 30 | result = defineClassNative(name, loader, cookie); 31 | } catch (ClassNotFoundException | NoClassDefFoundError e) { 32 | // TODO Auto-generated catch block 33 | e.printStackTrace(); 34 | } 35 | return result; 36 | } 37 | 38 | public void close() { 39 | closeDexFile(mCookie); 40 | } 41 | 42 | public String[] getLoadedClassName() 43 | { 44 | return getClassNameList(mCookie); 45 | } 46 | 47 | static { 48 | System.loadLibrary("egis"); 49 | } 50 | 51 | private static native long openRawDexFile(byte[] rawDex, String dexName, int flags); 52 | 53 | private static native void closeDexFile(long cookie); 54 | 55 | private static native Class defineClassNative(String name, ClassLoader loader, long cookie) 56 | throws ClassNotFoundException, NoClassDefFoundError; 57 | 58 | private static native String[] getClassNameList(long cookie); 59 | } 60 | --------------------------------------------------------------------------------