Repository: OakChen/ApkShelling
Branch: master
Commit: d64125e23347
Files: 23
Total size: 31.3 KB
Directory structure:
gitextract_be4gqpa2/
├── .gitignore
├── README.md
├── app/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ └── main/
│ ├── AndroidManifest.xml
│ ├── assets/
│ │ └── xposed_init
│ ├── java/
│ │ └── com/
│ │ └── sfysoft/
│ │ └── android/
│ │ └── xposed/
│ │ └── shelling/
│ │ └── XposedEntry.java
│ └── res/
│ ├── drawable/
│ │ └── ic_launcher_background.xml
│ ├── drawable-v24/
│ │ └── ic_launcher_foreground.xml
│ ├── mipmap-anydpi-v26/
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ ├── values/
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── values-zh-rCN/
│ └── strings.xml
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.iml
.DS_Store
.externalNativeBuild
.gradle
.idea
/build
/captures
/local.properties
================================================
FILE: README.md
================================================
# 一个脱简单壳的Xposed模块
## 用法
- 搭建Xposed环境
- 在XposedEntry.java中的targetPackages数组添加需要脱壳的包名
- 编译本模块并安装到手机
- 激活模块后,打开目标应用,随便操作一会儿,等待/data/data/packageName下产生dex文件,可查看logcat看进展:logcat -s Xposed
- 把dex文件都复制到电脑上,用jadx反编译,如果有反编译失败的,先用dex2jar转成jar再用jadx反编译可解决部分失败情况
## 原理
在加载包的时候,匹配是否目标包名及是否加壳,如果是,就hook java.lang.ClassLoader类的loadClass方法,应用如下操作:
- 获得loadClass返回的Class对象
- 反射调用Class对象的getDex方法获得Dex对象
- 将Dex对象提交给写文件的线程,在此过程会去除重复的Dex对象并把不同的字节集加到队列
- 线程异步从队列中读取字节集写到文件中,避免了同步写可能导致ANR
## 限制
- 只在Android 5.1.1版本的手机上验证过,其它的版本不一定有对应的getBytes和geDex方法
- 只验证过腾讯乐固、360加固、梆梆加固、百度加固的免费加固工具,都可以脱掉,付费版本没有用过
## 参考
参考项目:https://github.com/a813630449/dumpDex
================================================
FILE: app/.gitignore
================================================
/build
================================================
FILE: app/build.gradle
================================================
/*
* Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>
* 2019-07-26 Oak Chen
*/
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
buildToolsVersion "28.0.3"
defaultConfig {
applicationId "com.sfysoft.android.xposed.shelling"
minSdkVersion 19
//noinspection OldTargetApi
targetSdkVersion 28
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
compileOnly 'de.robv.android.xposed:api:82'
compileOnly 'de.robv.android.xposed:api:82:sources'
}
================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<!--
~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>
~ 2019-07-26 Oak Chen
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" package="com.sfysoft.android.xposed.shelling"
tools:ignore="GoogleAppIndexingWarning">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme" tools:ignore="AllowBackup">
<meta-data
android:name="xposedmodule"
android:value="true"/>
<meta-data
android:name="xposeddescription"
android:value="@string/description"/>
<meta-data
android:name="xposedminversion"
android:value="53"/>
</application>
</manifest>
================================================
FILE: app/src/main/assets/xposed_init
================================================
com.sfysoft.android.xposed.shelling.XposedEntry
================================================
FILE: app/src/main/java/com/sfysoft/android/xposed/shelling/XposedEntry.java
================================================
/*
* Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>
* 2019-07-26 Oak Chen Created
*/
package com.sfysoft.android.xposed.shelling;
import android.annotation.SuppressLint;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
/**
* Xposed entry to shelling app
*
* @author Oak Chen
*/
public class XposedEntry implements IXposedHookLoadPackage {
private static final boolean DEBUG = false;
// 加固应用的初始类,对应AndroidManifests.xml里的<application android:name的值
// @formatter:off
private static final String[] PACKED_APP_ENTRIES = {
"com.stub.StubApp", // 360加固
"s.h.e.l.l.S", // 爱加密
"com.secneo.apkwrapper.ApplicationWrapper", // 梆梆加固
"com.SecShell.SecShell.ApplicationWrapper", // 梆梆加固
"com.secneo.apkwrapper.AW", // 梆梆加固
"com.tencent.StubShell.TxAppEntry", // 腾讯乐固
"com.baidu.protect.StubApplication" // 百度加固
};
// 拟脱壳的App包名,对应AndroidManifests.xml里的<manifest package的值
private static final String[] targetPackages = {
"com.sfysoft.shellingtest"
};
// @formatter:on
private static void log(String text) {
XposedBridge.log(text);
}
private static void log(Throwable throwable) {
XposedBridge.log(throwable);
}
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) {
String packageName = lpparam.packageName;
log("Load package: " + packageName);
boolean found = false;
for (String targetPackage : targetPackages) {
if (packageName.equals(targetPackage)) {
found = true;
break;
}
}
if (!found) {
return;
}
for (String application : PACKED_APP_ENTRIES) {
Class cls = XposedHelpers.findClassIfExists(application, lpparam.classLoader);
if (cls != null) {
log("Found " + application);
ClassLoaderHook hook;
try {
hook = new ClassLoaderHook(getSavingPath(packageName));
XposedHelpers.findAndHookMethod("java.lang.ClassLoader", lpparam.classLoader,
"loadClass", String.class, boolean.class, hook);
} catch (NoSuchMethodException | ClassNotFoundException e) {
log(e);
}
break;
}
}
}
@SuppressWarnings("SameParameterValue")
@SuppressLint("SdCardPath")
private String getSavingPath(String packageName) {
return "/data/data/" + packageName;
}
private static class ClassLoaderHook extends XC_MethodHook {
private DexOutputTask dexOutputTask;
private Method getDex;
private Method getBytes;
@SuppressLint("PrivateApi")
ClassLoaderHook(String dexSavingPath) throws ClassNotFoundException, NoSuchMethodException {
// 实现限制: 已知Android 5.1.1~7.1.2 同时有下列2个方法,更高版本没有了getDex方法,不可使用
// libcore/dex/src/main/java/com/android/dex/Dex.java
getBytes = Class.forName("com.android.dex.Dex").getDeclaredMethod("getBytes");
// libcore/libart/src/main/java/java/lang/Class.java
// noinspection JavaReflectionMemberAccess
getDex = Class.forName("java.lang.Class").getDeclaredMethod("getDex");
dexOutputTask = new DexOutputTask(dexSavingPath);
new Thread(dexOutputTask).start();
}
boolean shouldSkip(String className) {
if (className == null) {
return true;
}
String[] skippedClassPrefixes = new String[]{"java", "android"};
for (String prefix : skippedClassPrefixes) {
if (className.startsWith(prefix)) {
return true;
}
}
return false;
}
@Override
protected void afterHookedMethod(MethodHookParam param) {
Class cls = (Class) param.getResult();
if (cls == null) {
return;
}
if (shouldSkip(cls.getName())) {
return;
}
Object dex;
try {
dex = getDex.invoke(cls);
} catch (IllegalAccessException | InvocationTargetException e) {
log(e);
return;
}
if (DEBUG) {
log("loadClass " + cls.getName() + ", Dex: " + dex);
}
dexOutputTask.write(dex);
}
private class DexOutputTask implements Runnable {
// 字节码缓存,不立即写文件,避免写文件太慢导致ANR
private final Queue<byte[]> byteSet = new LinkedList<>();
// 跟踪哪些类已经解码过,避免重复写到文件中
private final Set<Object> dexSet = new HashSet<>();
// 保存线程自动关闭前的空闲时间,以毫秒计
private final long idleMsToQuit;
// dex文件保存目录
private String savingDirectory;
private Thread currentThread;
private long threadId;
DexOutputTask(String savingDirectory) {
// 默认5分钟后没有数据,就自动结束
this(savingDirectory, 300000);
}
DexOutputTask(String savingDirectory,
@SuppressWarnings("SameParameterValue") long idleMsToQuit) {
this.savingDirectory = savingDirectory;
this.idleMsToQuit = idleMsToQuit;
}
@Override
public void run() {
currentThread = Thread.currentThread();
threadId = currentThread.getId();
File savingDir = new File(savingDirectory);
if (!savingDir.exists()) {
if (!savingDir.mkdirs()) {
log("Can not mkdir " + savingDirectory);
return;
}
}
for (int i = 0; ; ) {
byte[] bytes;
synchronized (byteSet) {
bytes = byteSet.poll();
if (bytes == null) {
try {
long start = System.currentTimeMillis();
byteSet.wait(idleMsToQuit);
// 若是超时则退出,结束线程
if (System.currentTimeMillis() - start >= idleMsToQuit) {
break;
} else {
// 有新的数据,返回重新读取
continue;
}
} catch (InterruptedException e) {
continue;
}
}
}
i++;
@SuppressLint("DefaultLocale") String targetFile =
savingDirectory + String.format("/%05d-%02d.dex", threadId, i);
log("Thread: " + threadId + ", File: " + targetFile);
try (FileOutputStream fileOutputStream = new FileOutputStream(targetFile)) {
fileOutputStream.write(bytes);
} catch (IOException e) {
log(e);
}
}
log("Thread: " + threadId + ", Dex size: " + dexSet.size());
synchronized (byteSet) {
byteSet.clear();
}
synchronized (dexSet) {
dexSet.clear();
}
savingDirectory = null;
}
void write(Object dex) {
if (dex == null) {
return;
}
if (currentThread == null || !currentThread.isAlive()) {
log("Thread " + threadId + " is not running");
return;
}
// 避免重复保存同一个dex
synchronized (dexSet) {
if (dexSet.contains(dex)) {
return;
}
dexSet.add(dex);
}
byte[] bytes;
try {
bytes = (byte[]) getBytes.invoke(dex);
} catch (IllegalAccessException | InvocationTargetException e) {
log(e);
return;
}
if (bytes == null) {
return;
}
synchronized (byteSet) {
byteSet.offer(bytes);
byteSet.notifyAll();
}
}
}
}
}
================================================
FILE: app/src/main/res/drawable/ic_launcher_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>
~ 2019-07-26 Oak Chen
-->
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#008577"
android:pathData="M0,0h108v108h-108z"/>
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF"/>
</vector>
================================================
FILE: app/src/main/res/drawable-v24/ic_launcher_foreground.xml
================================================
<!--
~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>
~ 2019-07-26 Oak Chen
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeWidth="1"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0"/>
<item
android:color="#00000000"
android:offset="1.0"/>
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeWidth="1"
android:strokeColor="#00000000"/>
</vector>
================================================
FILE: app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>
~ 2019-07-26 Oak Chen
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>
================================================
FILE: app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>
~ 2019-07-26 Oak Chen
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>
================================================
FILE: app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>
~ 2019-07-26 Oak Chen
-->
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
</resources>
================================================
FILE: app/src/main/res/values/strings.xml
================================================
<!--
~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>
~ 2019-07-26 Oak Chen
-->
<resources>
<string name="app_name">Shelling</string>
<string name="description">Dump dex from app protected by free tools from baidu, 360, tencent, bangcle.com</string>
</resources>
================================================
FILE: app/src/main/res/values/styles.xml
================================================
<!--
~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>
~ 2019-07-26 Oak Chen
-->
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
================================================
FILE: app/src/main/res/values-zh-rCN/strings.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>
~ 2019-07-31 Oak Chen
-->
<resources>
<string name="app_name">脱壳</string>
<string name="description">从加固过的应用中提取dex文件,适用于百度、360、腾讯、梆梆等提供的免费版加固工具</string>
</resources>
================================================
FILE: build.gradle
================================================
/*
* Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>
* 2019-07-26 Oak Chen
*/
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#
# Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>
# 2019-07-26 Oak Chen
#
#Fri Jul 26 15:05:01 CST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
================================================
FILE: gradle.properties
================================================
#
# Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>
# 2019-07-26 Oak Chen
#
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
================================================
FILE: gradlew
================================================
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: settings.gradle
================================================
/*
* Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>
* 2019-07-26 Oak Chen
*/
include ':app'
gitextract_be4gqpa2/ ├── .gitignore ├── README.md ├── app/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ └── main/ │ ├── AndroidManifest.xml │ ├── assets/ │ │ └── xposed_init │ ├── java/ │ │ └── com/ │ │ └── sfysoft/ │ │ └── android/ │ │ └── xposed/ │ │ └── shelling/ │ │ └── XposedEntry.java │ └── res/ │ ├── drawable/ │ │ └── ic_launcher_background.xml │ ├── drawable-v24/ │ │ └── ic_launcher_foreground.xml │ ├── mipmap-anydpi-v26/ │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ ├── values/ │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── values-zh-rCN/ │ └── strings.xml ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle
SYMBOL INDEX (14 symbols across 1 files)
FILE: app/src/main/java/com/sfysoft/android/xposed/shelling/XposedEntry.java
class XposedEntry (line 31) | public class XposedEntry implements IXposedHookLoadPackage {
method log (line 51) | private static void log(String text) {
method log (line 55) | private static void log(Throwable throwable) {
method handleLoadPackage (line 59) | @Override
method getSavingPath (line 93) | @SuppressWarnings("SameParameterValue")
class ClassLoaderHook (line 99) | private static class ClassLoaderHook extends XC_MethodHook {
method ClassLoaderHook (line 104) | @SuppressLint("PrivateApi")
method shouldSkip (line 116) | boolean shouldSkip(String className) {
method afterHookedMethod (line 132) | @Override
class DexOutputTask (line 158) | private class DexOutputTask implements Runnable {
method DexOutputTask (line 170) | DexOutputTask(String savingDirectory) {
method DexOutputTask (line 175) | DexOutputTask(String savingDirectory,
method run (line 181) | @Override
method write (line 236) | void write(Object dex) {
Condensed preview — 23 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (36K chars).
[
{
"path": ".gitignore",
"chars": 86,
"preview": "*.iml\n.DS_Store\n.externalNativeBuild\n.gradle\n.idea\n/build\n/captures\n/local.properties\n"
},
{
"path": "README.md",
"chars": 636,
"preview": "# 一个脱简单壳的Xposed模块\n\n## 用法\n\n- 搭建Xposed环境\n- 在XposedEntry.java中的targetPackages数组添加需要脱壳的包名\n- 编译本模块并安装到手机\n- 激活模块后,打开目标应用,随便操作一"
},
{
"path": "app/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "app/build.gradle",
"chars": 840,
"preview": "/*\n * Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>\n * 2019-07-26 Oak Chen\n */\n\napply plugin: 'com.android.application"
},
{
"path": "app/proguard-rules.pro",
"chars": 751,
"preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
},
{
"path": "app/src/main/AndroidManifest.xml",
"chars": 941,
"preview": "<!--\n ~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>\n ~ 2019-07-26 Oak Chen\n -->\n\n<manifest xmlns:android=\"http://"
},
{
"path": "app/src/main/assets/xposed_init",
"chars": 48,
"preview": "com.sfysoft.android.xposed.shelling.XposedEntry\n"
},
{
"path": "app/src/main/java/com/sfysoft/android/xposed/shelling/XposedEntry.java",
"chars": 9330,
"preview": "/*\n * Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>\n * 2019-07-26 Oak Chen Created\n */\n\npackage com.sfysoft.android.x"
},
{
"path": "app/src/main/res/drawable/ic_launcher_background.xml",
"chars": 5665,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>\n ~ 2019-07-26 Oak Chen\n"
},
{
"path": "app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
"chars": 1985,
"preview": "<!--\n ~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>\n ~ 2019-07-26 Oak Chen\n -->\n\n<vector xmlns:android=\"http://sc"
},
{
"path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
"chars": 359,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>\n ~ 2019-07-26 Oak Chen\n"
},
{
"path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
"chars": 359,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>\n ~ 2019-07-26 Oak Chen\n"
},
{
"path": "app/src/main/res/values/colors.xml",
"chars": 296,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>\n ~ 2019-07-26 Oak Chen\n"
},
{
"path": "app/src/main/res/values/strings.xml",
"chars": 279,
"preview": "<!--\n ~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>\n ~ 2019-07-26 Oak Chen\n -->\n\n<resources>\n <string name=\"ap"
},
{
"path": "app/src/main/res/values/styles.xml",
"chars": 471,
"preview": "<!--\n ~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>\n ~ 2019-07-26 Oak Chen\n -->\n\n<resources>\n\n <!-- Base appli"
},
{
"path": "app/src/main/res/values-zh-rCN/strings.xml",
"chars": 274,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>\n ~ 2019-07-31 Oak Chen\n"
},
{
"path": "build.gradle",
"chars": 640,
"preview": "/*\n * Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>\n * 2019-07-26 Oak Chen\n */\n\n// Top-level build file where you can "
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 320,
"preview": "#\r\n# Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>\r\n# 2019-07-26 Oak Chen\r\n#\r\n\r\n#Fri Jul 26 15:05:01 CST 2019\r\ndistrib"
},
{
"path": "gradle.properties",
"chars": 1150,
"preview": "#\n# Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>\n# 2019-07-26 Oak Chen\n#\n\n# Project-wide Gradle settings.\n# IDE (e.g."
},
{
"path": "gradlew",
"chars": 5296,
"preview": "#!/usr/bin/env sh\n\n##############################################################################\n##\n## Gradle start up"
},
{
"path": "gradlew.bat",
"chars": 2260,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
},
{
"path": "settings.gradle",
"chars": 97,
"preview": "/*\n * Copyright (c) 2019 - Oak Chen <oak@sfysoft.com>\n * 2019-07-26 Oak Chen\n */\n\ninclude ':app'\n"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the OakChen/ApkShelling GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 23 files (31.3 KB), approximately 9.5k tokens, and a symbol index with 14 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.