Commit 69204d5f by LAPTOP-146U5DF5\28422

no message

parents
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
# Default ignored files
/shelf/
/workspace.xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="1.8" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="PLATFORM" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="1.8" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
<option name="useQualifiedModuleNames" value="true" />
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="BintrayJCenter" />
<option name="name" value="BintrayJCenter" />
<option name="url" value="https://jcenter.bintray.com/" />
</remote-repository>
<remote-repository>
<option name="id" value="Google" />
<option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
/build
\ No newline at end of file
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 30
defaultConfig {
applicationId "com.fear1ess.reyunadihookplugin"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
compileOnly 'de.robv.android.xposed:api:82'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
\ No newline at end of file
# 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
\ No newline at end of file
package com.fear1ess.reyunaditool;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.fear1ess.reyunadihookplugin", appContext.getPackageName());
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.fear1ess.reyunaditool">
<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/Theme.ReyunAdiHookPlugin">
<meta-data
android:name="xposedmodule"
android:value="true" />
<meta-data
android:name="xposedminversion"
android:value="40" />
<meta-data
android:name="xposeddescription"
android:value="ReyunAdi hook广告sdk接口插件" />
</application>
</manifest>
\ No newline at end of file
// IHandleDataService.aidl
package com.fear1ess.reyunaditool;
// Declare any non-default types here with import statements
interface IDoCommandService {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
// void handleData(int cmd, in Map args);
String doCommand(int cmd, String args);
}
\ No newline at end of file
com.fear1ess.reyunaditool.HookEntry
\ No newline at end of file
package com.fear1ess.reyunaditool;
public class AdsSdkExistsFlag {
public final static int ADMOB = 1;
public final static int UNITY = 2;
public final static int VUNGLE = 4;
public final static int FACEBOOK = 8;
public final static int IRONSOURCE = 16;
public final static int PANGLEMODULE = 32;
}
package com.fear1ess.reyunaditool;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class ExecuteCmdUtils {
public static String TAG = "reyunaditool_log";
public static int executeCmd(String cmd){
Process p = null;
int exitCode = 0;
try {
p = Runtime.getRuntime().exec("su -c " + cmd);
exitCode = p.waitFor();
if(exitCode != 0){
byte[] b = new byte[1024];
InputStream is = p.getErrorStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int len = 0;
while((len = is.read(b)) != -1){
bos.write(b,0,len);
bos.flush();
}
String cmdErrMsg = new String(bos.toByteArray());
bos.close();
is.close();
Log.e(TAG, cmdErrMsg + " when execute cmd: " + cmd);
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return exitCode;
}
public static int installApp(String downloadPath){
String cmd = "pm install " + downloadPath;
Log.d(TAG, "installApp " + downloadPath);
return executeCmd(cmd);
}
public static int finishApp(String packageName){
String cmd = "am force-stop " + packageName;
Log.d(TAG, "finishApp " + packageName);
return executeCmd(cmd);
}
public static int uninstallApp(String packageName){
String cmd = "pm uninstall " + packageName;
Log.d(TAG, "uninstallapp " + packageName);
return executeCmd(cmd);
}
public static int deletePkg(String downloadPath){
if(!downloadPath.startsWith("/sdcard/reyundownload")){
Log.e(TAG, "delete path is not reyundownload!!!" );
return -1;
}
String cmd = "rm -f " + downloadPath;
return executeCmd(cmd);
}
public static int startApp(Context appContext, String packageName) {
PackageManager pm = appContext.getPackageManager();
Intent intent = pm.getLaunchIntentForPackage(packageName);
if(intent == null) return -1;
ComponentName cn = intent.getComponent();
String pkgName = cn.getPackageName();
String className = cn.getClassName();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
appContext.startActivity(intent);
return 0;
// Log.d(TAG, "startApp " + packageName);
// String cmd = "am start -n " + pkgName + "/" + className;
// return executeCmd(cmd);
}
}
package com.fear1ess.reyunaditool;
import android.app.Activity;
import android.app.Application;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import com.fear1ess.reyunaditool.adsfinder.AdmobFinder;
import com.fear1ess.reyunaditool.adsfinder.Finder;
import com.fear1ess.reyunaditool.adsfinder.FinderUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import static com.fear1ess.reyunaditool.pangle.pangleModule.hook_AppID;
import static com.fear1ess.reyunaditool.pangle.pangleModule.hook_SlotID;
import static com.fear1ess.reyunaditool.pangle.pangleModule.hook_doFinal;
public class HookEntry implements IXposedHookLoadPackage {
public Context cxt = null;
public static ClassLoader cl = null;
public static ArrayList<String> admobDataList = new ArrayList<>();
public static IDoCommandService hdService = null;
public static ServiceConnection conn = null;
public static String processName = null;
public static String TAG = "adihookplugin_log";
public static String[] notNeedAppList = {"android", "system_server", "org.meowcat.edxposed.manager"};
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
processName = (String)Class.forName("android.app.ActivityThread").getDeclaredMethod("currentProcessName").invoke(null);
Log.d(TAG, "handleLoadPackage processName :" + processName);
if((lpparam.appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) return;
for(String item : notNeedAppList) {
if(item.contains(processName)) return;
}
// MLog.d(lpparam.packageName);
// if(lpparam.packageName.contains("com.union_test.internationad")){
// MLog.d(lpparam.packageName+"进入了");
//// hook_AppID(lpparam);
//// hook_SlotID(lpparam);
// hook_doFinal(lpparam);
// }
cl = lpparam.classLoader;
XposedHelpers.findAndHookMethod("android.view.ContextThemeWrapper", cl, "attachBaseContext",
Context.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.d(TAG, "enter app attach....");
cxt = (Context) param.args[0];
if(processName.equals("com.topjohnwu.magisk")){
Log.d(TAG, "open app");
ExecuteCmdUtils.startApp(cxt, "com.fear1ess.reyunaditool");
return;
}
if(lpparam.processName.contains("com.fear1ess.reyunaditool")) return;
Log.d(TAG, "start hook " + processName);
Log.d(TAG, "start bindservice...");
bindAdiToolService();
Log.d("reyunadihookplugin_adsfinder", "beforeHookedMethod: "+lpparam.packageName);
FinderUtils.doWork(cl,null);
}
});
}
public void bindAdiToolService(){
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.fear1ess.reyunaditool",
"com.fear1ess.reyunaditool.DoCommandService"));
conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
hdService = IDoCommandService.Stub.asInterface(service);
new Thread(){
@Override
public void run() {
try {
String curPkgName = hdService.doCommand(OperateCmd.QUERY_CURRENT_PKGNAME, null);
// if(!processName.equals(curPkgName)) return;
} catch (RemoteException e) {
e.printStackTrace();
}
FinderUtils.notifyServiceBound(hdService);
}
}.start();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
boolean res = cxt.bindService(intent, conn, Service.BIND_AUTO_CREATE);
if(res == false) Log.d(TAG, "bindAdiToolService failed!");
if(res == true) Log.d(TAG, "bindAdiToolService success!");
}
}
// by fear1ess 2020/12/25
package com.fear1ess.reyunaditool;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class HttpParser {
private String method;
private String path;
private Map<String, String> urlParams = new HashMap<>();
private Map<String, String> headers = new HashMap<>();
private Map<String, String> formBodyParams = null;
private Map<String, Object> jsonBodyParams = null;
private JSONObject jsonBody = null;
public String getMethod(){
return method;
}
public String getPath() {
return path;
}
public String getUrlParam(String key){
return urlParams.get(key);
}
public String getHeader(String key) {
return headers.get(key);
}
public String getFormBodyParam(String key) {
return formBodyParams.get(key);
}
public Object getjsonObjectParam(String key) {
return jsonBodyParams.get(key);
}
public JSONObject getJsonBody(){
return jsonBody;
}
public HttpParser(byte[] payload){
doParse(new String(payload));
}
public HttpParser(String payload){
doParse(payload);
}
private boolean doParse(String payload) {
String httpStr = new String(payload);
if (!httpStr.startsWith("GET") && !httpStr.startsWith("POST")) return false;
try {
String[] items = httpStr.split("\r\n\r\n");
String urlAndHeaderItem = items[0];
String[] items_1 = urlAndHeaderItem.split("\r\n", 2);
String urls = items_1[0];
String[] items_2 = urls.split(" ");
method = items_2[0];
String[] items_3 = items_2[1].split("\\?");
path = items_3[0];
if (items_3.length > 1) {
String[] urlParamStrs = items_3[1].split("&");
for (String item : urlParamStrs) {
String[] paramItem = item.split("=");
String key = URLDecoder.decode(paramItem[0], "utf-8");
String value = URLDecoder.decode(paramItem[1], "utf-8");
urlParams.put(key, value);
}
}
if(items_1.length > 1){
String headerStr = items_1[1];
String[] headerStrs = headerStr.split("\r\n");
headers = new HashMap<>();
for (String item : headerStrs) {
String[] headerItem = item.split(": ");
String key = URLDecoder.decode(headerItem[0], "utf-8");
String value = URLDecoder.decode(headerItem[1], "utf-8");
headers.put(key, value);
}
}
if (items.length > 1 && httpStr.startsWith("POST")) {
String body = items[1];
if(headers.get("Content-Type").contains("application/x-www-form-urlencoded")){
formBodyParams = new HashMap<>();
String[] urlParamStrs = body.split("&");
for (String item : urlParamStrs) {
String[] paramItem = item.split("=");
String key = URLDecoder.decode(paramItem[0], "utf-8");
String value = URLDecoder.decode(paramItem[1], "utf-8");
formBodyParams.put(key, value);
}
}
if(headers.get("Content-Type").contains("application/json")){
jsonBodyParams = new HashMap<>();
JSONObject jo = new JSONObject(body);
jsonBody = jo;
Iterator iterator = jo.keys();
while(iterator.hasNext()){
String key = (String) iterator.next();
jsonBodyParams.put(key, jo.get(key));
}
}
}
} catch (UnsupportedEncodingException | JSONException e) {
e.printStackTrace();
}
return true;
}
}
package com.fear1ess.reyunaditool;
import android.util.Log;
public class MLog {
private static final String TAG = "ReYunADI";
private static boolean is_open=true;
public static void d(Object object){
// if(is_open)return;
synchronized (object){
Log.d(TAG, ""+object);
}
}
}
package com.fear1ess.reyunaditool;
public class OperateCmd {
public final static int SHUTDOWN_APP = 0;
public final static int UPLOAD_ADSDK_DATA = 1;
public final static int QUERY_CURRENT_PKGNAME = 2;
public final static int UPLOAD_ADSDK_EXISTS_STATE = 3;
}
package com.fear1ess.reyunaditool;
public class RyTag {
public final static String TAG = "reyunadihookplugin_log";
}
package com.fear1ess.reyunaditool.adsfinder;
import android.content.Context;
import android.util.Log;
import com.fear1ess.reyunaditool.HookEntry;
import com.fear1ess.reyunaditool.HttpParser;
import com.fear1ess.reyunaditool.IDoCommandService;
import com.fear1ess.reyunaditool.OperateCmd;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
public class AdmobFinder extends Finder {
public AdmobFinder(String adsClassName, String adsName, ClassLoader cl, IDoCommandService service) {
super(adsClassName, adsName, cl, service);
}
public class AdmobApiHook extends AdsApiHook{
private AdmobApiHook(String s, String dataName, int posInArgs){
super(s, dataName, posInArgs);
}
public AdmobApiHook(String s, int posInArgs){
this(s, "data", posInArgs);
}
public Map buildAdsData(String adUnitId){
String[] vals = adUnitId.split("/");
if(vals.length != 2) return null;
Map<String,String> map = new HashMap<>();
map.put("client", vals[0]);
map.put("slotname", vals[1]);
map.put("adType", this.mAdType);
return map;
}
}
public void hookAdsApi() {
registerSSLHook(new SSLOutputStreamHookedCallback() {
@Override
public void onSSLOutputStreamHooked(HttpParser hp) {
if(!hp.getMethod().equals("GET") || !hp.getPath().contains("/mads/gma")) return;
String slotname = hp.getUrlParam("slotname");
String client = hp.getUrlParam("client");
Map<String,String> map = new HashMap<>();
map.put("client", client);
map.put("slotname", slotname);
uploadAdsData(map);
}
});
XposedHelpers.findAndHookMethod("com.google.android.gms.ads.BaseAdView", mAppClassLoader, "setAdUnitId",
String.class, new AdmobApiHook("bannerAd", 0));
XposedHelpers.findAndHookConstructor("com.google.android.gms.ads.AdLoader$Builder", mAppClassLoader,
Context.class, String.class, new AdmobApiHook("nativeAd", 1));
XposedHelpers.findAndHookConstructor("com.google.android.gms.ads.rewarded.RewardedAd", mAppClassLoader,
Context.class, String.class, new AdmobApiHook("rewardedAd", 1));
try {
XposedBridge.hookAllMethods(mAppClassLoader.loadClass("com.google.android.gms.ads.reward.RewardedVideoAd"), "loadAd",
new AdmobApiHook("rewardedAd(legacy)", 0));
XposedBridge.hookAllMethods(mAppClassLoader.loadClass("import com.google.android.gms.ads.appopen.AppOpenAd"), "load",
new AdmobApiHook("openAd", 1));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
package com.fear1ess.reyunaditool.adsfinder;
import com.fear1ess.reyunaditool.IDoCommandService;
public class DefaultFinder extends Finder {
public DefaultFinder(String adsName, String adsClassName, ClassLoader cl, IDoCommandService service) {
super(adsName, adsClassName, cl, service);
}
@Override
public void hookAdsApi() {
return;
}
}
package com.fear1ess.reyunaditool.adsfinder;
import android.util.Log;
import com.fear1ess.reyunaditool.HttpParser;
import com.fear1ess.reyunaditool.IDoCommandService;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
public class FacebookFinder extends Finder {
public FacebookFinder(String adsName, String adsClassName, ClassLoader cl, IDoCommandService service) {
super(adsName, adsClassName, cl, service);
}
@Override
public void hookAdsApi() {
registerSSLHook(new SSLOutputStreamHookedCallback() {
@Override
public void onSSLOutputStreamHooked(HttpParser hp) {
if(!hp.getMethod().equals("POST")) return;
if(!hp.getPath().contains("network_ads_common") && (!hp.getPath().contains("/adnw_sync"))) return;
Map<String, String> map = new HashMap<>();
// PLACEMENT_ID, IDFA, M_BANNER_KEY, PLACEMENT_TYPE, APPNAME, AFP, ASHAS
if(hp.getPath().contains("network_ads_common")){
String placementId = hp.getFormBodyParam("PLACEMENT_ID");
String idfa = hp.getFormBodyParam("IDFA");
String afp = hp.getFormBodyParam("AFP");
String ashas = hp.getFormBodyParam("ASHAS");
String mBannerKey = hp.getFormBodyParam("M_BANNER_KEY");
String placementType = hp.getFormBodyParam("PLACEMENT_TYPE");
map.put("PLACEMENT_ID", placementId);
map.put("IDFA", idfa);
map.put("AFP", afp);
map.put("ASHAS", ashas);
map.put("PLACEMENT_TYPE", placementType);
map.put("M_BANNER_KEY", mBannerKey);
}else{
String payload = (String) hp.getFormBodyParam("payload");
try {
JSONObject jo = new JSONObject(payload);
JSONObject context = jo.getJSONObject("context");
String placementId = context.getString("PLACEMENT_ID");
String idfa = context.getString("IDFA");
String afp = context.getString("AFP");
String ashas = context.getString("ASHAS");
map.put("PLACEMENT_ID", placementId);
map.put("IDFA", idfa);
map.put("AFP", afp);
map.put("ASHAS", ashas);
} catch (JSONException e) {
e.printStackTrace();
}
}
uploadAdsData(map);
}
});
}
}
package com.fear1ess.reyunaditool.adsfinder;
import android.graphics.Path;
import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;
import com.fear1ess.reyunaditool.AdsSdkExistsFlag;
import com.fear1ess.reyunaditool.HookEntry;
import com.fear1ess.reyunaditool.HttpParser;
import com.fear1ess.reyunaditool.IDoCommandService;
import com.fear1ess.reyunaditool.MLog;
import com.fear1ess.reyunaditool.OperateCmd;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
public abstract class Finder {
public static SSLOutputStreamHook sslHook = new SSLOutputStreamHook();
public static Map<String, Map<String, String>> adsMap = new HashMap<>();
protected String mAdsClassName;
protected String mAdsName;
protected ClassLoader mAppClassLoader;
protected IDoCommandService mDoCommandService;
protected List<Map> mRemainAdsDataList = new ArrayList<>();
protected volatile boolean isServiceBound = false;
public static String TAG = "reyunadihookplugin_adsfinder";
private static int adsSdkState = 0;
private static int adsDataState = 0;
public Finder(String adsName,String adsClassName,ClassLoader cl,IDoCommandService service){
mAdsClassName = adsClassName;
mAdsName = adsName;
mAppClassLoader = cl;
mDoCommandService = service;
}
static {
hookSSLOutputStream(sslHook);
}
public boolean isAdsExisted(){
Class<?> cls = null;
try{
Log.d(TAG, "start find " + mAdsClassName);
cls = mAppClassLoader.loadClass(mAdsClassName);
} catch (ClassNotFoundException e) {
Log.d(TAG, "not find ads: " + mAdsName);
} finally {
if(cls == null) return false;
Log.d(TAG, "find ads: " + mAdsName);
updateAdsSdkState(mAdsName);
return true;
}
}
public static int getAdsSdkState(){
return adsSdkState;
}
public static int getAdsDataState() {
return adsDataState;
}
public static void updateAdsSdkState(String adsName){
switch (adsName){
case "admob":
adsSdkState |= AdsSdkExistsFlag.ADMOB;
break;
case "unity":
adsSdkState |= AdsSdkExistsFlag.UNITY;
break;
case "vungle":
adsSdkState |= AdsSdkExistsFlag.VUNGLE;
break;
case "facebook":
adsSdkState |= AdsSdkExistsFlag.FACEBOOK;
case "ironsource":
adsSdkState |= AdsSdkExistsFlag.IRONSOURCE;
case "pangle":
adsSdkState |= AdsSdkExistsFlag.PANGLEMODULE;
default: break;
}
}
public static void updateAdsDataState(String adsName){
switch (adsName){
case "admob":
adsDataState |= AdsSdkExistsFlag.ADMOB;
break;
case "unity":
adsDataState |= AdsSdkExistsFlag.UNITY;
break;
case "vungle":
adsDataState |= AdsSdkExistsFlag.VUNGLE;
break;
case "facebook":
adsDataState |= AdsSdkExistsFlag.FACEBOOK;
break;
case "ironsource":
adsSdkState |= AdsSdkExistsFlag.IRONSOURCE;
case "pangle":
adsDataState |= AdsSdkExistsFlag.PANGLEMODULE;
default: break;
}
}
public void startWork(){
if(!isAdsExisted()) return;
hookAdsApi();
}
public void registerSSLHook(SSLOutputStreamHookedCallback cb){
sslHook.registerSSLOutputStreamCallback(cb);
}
public void hookAdsApi(){
return;
}
public void uploadRemainAdsData(IDoCommandService service){
isServiceBound = true;
mDoCommandService = service;
for(Map map : mRemainAdsDataList){
uploadAdsData(map);
}
}
public void uploadAdsData(Map<String,String> map){
//ad map to global ads map
adsMap.put(mAdsName, map);
if(isServiceBound == false){
mRemainAdsDataList.add(map);
Log.d(TAG, "uploadAdsData failed, service is not bound" );
return;
}
try {
JSONObject adsDataJson = new JSONObject();
for(Map.Entry<String,String> entry : map.entrySet()){
adsDataJson.put(entry.getKey(),entry.getValue());
}
JSONObject jo2 = new JSONObject();
jo2.put(mAdsName, adsDataJson);
JSONObject jo3 = new JSONObject();
jo2.put("package_name", HookEntry.processName);
jo3.put("data",jo2);
String uploadData = jo3.toString();
Log.d(TAG, "uploadAdsData: " + uploadData);
MLog.d("uploadAdsData: " + uploadData);
String res = mDoCommandService.doCommand(OperateCmd.UPLOAD_ADSDK_DATA, uploadData);
updateAdsDataState(mAdsName);
FinderUtils.uploadAdsSdkExistsState(mDoCommandService, adsSdkState, adsDataState);
if(res.equals("success")){
Log.d(TAG, "uploadAdsData success");
}
} catch (RemoteException | JSONException e) {
e.printStackTrace();
}
}
public static void hookSSLOutputStream(XC_MethodHook hook){
XposedHelpers.findAndHookMethod("com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLOutputStream", HookEntry.cl, "write",
byte[].class, int.class, int.class, hook);
}
public static class SSLOutputStreamHook extends XC_MethodHook {
private List<SSLOutputStreamHookedCallback> mCallbacks = new ArrayList<>();
public void registerSSLOutputStreamCallback(SSLOutputStreamHookedCallback cb){
mCallbacks.add(cb);
}
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
byte[] data = (byte[]) param.args[0];
int pos = (int) param.args[1];
int len = (int) param.args[2];
String payload = new String(data, pos, len);
Log.d(TAG, "SSLOutputSteam data: " + payload);
HttpParser hp = new HttpParser(payload);
for(SSLOutputStreamHookedCallback cb : mCallbacks){
cb.onSSLOutputStreamHooked(hp);
}
}
} JSONObject jo = new JSONObject(Finder.adsMap);
public interface SSLOutputStreamHookedCallback {
void onSSLOutputStreamHooked(HttpParser hp);
}
public class AdsApiHook extends XC_MethodHook {
public String mAdType;
public String mDataName;
public int mPos;
public AdsApiHook(String s, String dataName, int posInArgs) {
super();
mAdType = s;
mDataName = dataName;
mPos = posInArgs;
}
public Map buildAdsData(String data) {
Map<String, String> map = new HashMap<>();
map.put(mDataName, data);
map.put("adType", this.mAdType);
return map;
}
public void handleAdUnitId(String adUnitId) {
if (adUnitId == null) return;
Map map = buildAdsData(adUnitId);
if (map == null) return;
uploadAdsData(map);
}
@Override
protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
String data = (String) param.args[mPos];
Log.d(TAG, "find " + mAdsName + " " + mAdType + ", " + mDataName + ": " + data);
handleAdUnitId(data);
}
}
public String matchQueryValue(String str, String key) {
String patternStr = key + "=((.*&)|(.* ))";
String matchStr = match(str, patternStr);
if(matchStr == null) return null;
String value = matchStr.replace(key + "=","").
replace("&","").replace(" ","");
Log.d(TAG, "matchQueryValue key: " + key + ", value: " + value);
return value;
}
public String matchJsonBodyValue(String str, String key) {
String patternStr = "\"" + key + "\":" + "((.*,)|(.*\\}))";
String matchStr = match(str, patternStr);
if(matchStr == null) return null;
String value = matchStr.replace("\"" + key + "\":", "")
.replace(",", "").replace("}","");
Log.d(TAG, "matchJsonBodyValue key: " + key + ", value: " + value);
return value;
}
public String match(String str, String patternStr) {
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(str);
if(!matcher.find()) return null;
String value = matcher.group(0);
return value;
}
}
package com.fear1ess.reyunaditool.adsfinder;
import android.net.VpnManager;
import android.net.VpnService;
import android.os.RemoteException;
import android.util.Log;
import com.fear1ess.reyunaditool.HookEntry;
import com.fear1ess.reyunaditool.IDoCommandService;
import com.fear1ess.reyunaditool.MLog;
import com.fear1ess.reyunaditool.OperateCmd;
import com.fear1ess.reyunaditool.RyTag;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static com.fear1ess.reyunaditool.adsfinder.Finder.TAG;
public class FinderUtils {
public static Map<String,String> adsInfoMap = new HashMap<>();
public static List<Finder> finderArray = new ArrayList<>();
static{
adsInfoMap.put("admob", "com.google.android.gms.ads.MobileAds");
adsInfoMap.put("unity", "com.unity3d.ads.UnityAds");
adsInfoMap.put("vungle", "com.vungle.warren.Vungle");
adsInfoMap.put("facebook", "com.facebook.ads.AudienceNetworkAds");
adsInfoMap.put("ironsource", "com.ironsource.mediationsdk.IronSource");
adsInfoMap.put("pangle", "com.bytedance.sdk.openadsdk.TTAdConfig"); //海外穿山甲
}
public static Finder createFinder(String adsName, String adsClsName, ClassLoader cl, IDoCommandService service){
switch(adsName){
case "admob":
return new AdmobFinder(adsName, adsClsName, cl, service);
case "unity":
return new UnityFinder(adsName, adsClsName, cl, service);
case "vungle":
return new VungleFinder(adsName, adsClsName, cl, service);
case "facebook":
return new FacebookFinder(adsName, adsClsName, cl, service);
case "ironsource":
return new IronSourceFinder(adsName, adsClsName, cl, service);
case "pangle":
MLog.d("createFinder: PangLeFinder");
return new PangLeFinder(adsName, adsClsName, cl, service);
default:
return new DefaultFinder(adsName, adsClsName, cl, service);
}
}
public static void uploadAdsSdkExistsState(IDoCommandService service, int sdkState, int dataState){
if(service == null){
Log.d(RyTag.TAG, "uploadAdsData failed, service is not bound" );
return;
}
try {
JSONObject jo = new JSONObject();
jo.put("ads_sdk_state", sdkState);
jo.put("ads_data_state", dataState);
jo.put("package_name", HookEntry.processName);
JSONObject jo2 = new JSONObject();
jo2.put("data", jo);
String uploadData = jo2.toString();
Log.d(RyTag.TAG, "uploadAdsExistsStateData: " + uploadData);
String res = service.doCommand(OperateCmd.UPLOAD_ADSDK_EXISTS_STATE, uploadData);
if(res.equals("success")){
Log.d(RyTag.TAG, "uploadAdsExistsStateData success");
}
} catch (JSONException | RemoteException e) {
e.printStackTrace();
}
}
public static void notifyServiceBound(IDoCommandService service){
uploadAdsSdkExistsState(service, Finder.getAdsSdkState(), Finder.getAdsDataState());
for(Finder finder : finderArray){
finder.uploadRemainAdsData(service);
}
//do upload...
ExecutorService es = Executors.newSingleThreadExecutor();
es.execute(new UploadDataProceduce(service));
es.shutdown();
}
public static void doWork(ClassLoader cl, IDoCommandService service){
for(Map.Entry<String,String> entry : adsInfoMap.entrySet()){
Finder finder = createFinder(entry.getKey(), entry.getValue(), cl, service);
finderArray.add(finder);
finder.startWork();
}
}
public static class UploadDataProceduce implements Runnable {
IDoCommandService hdService;
public UploadDataProceduce(IDoCommandService service){
hdService = service;
}
@Override
public void run(){
// wait for some time
try {
Thread.sleep(50*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String curPkg = null;
try {
curPkg = hdService.doCommand(OperateCmd.QUERY_CURRENT_PKGNAME, null);
Log.d(RyTag.TAG, "currentPkg: " + curPkg);
Log.d(RyTag.TAG, "processName: " + HookEntry.processName);
// if(!HookEntry.processName.equals(curPkg)) return;
} catch (RemoteException e) {
e.printStackTrace();
}
//upload ads data
try {
JSONObject jo = new JSONObject(Finder.adsMap);
jo.put("app_id", HookEntry.processName);
String data = jo.toString();
Log.d(RyTag.TAG, "upload ads data: " + data);
MLog.d( "upload ads data: " + data);
if(!HookEntry.processName.equals(curPkg)) return;
hdService.doCommand(OperateCmd.UPLOAD_ADSDK_DATA, data);
// hdService.doCommand(OperateCmd.SHUTDOWN_APP, null);
} catch (JSONException | RemoteException e) {
e.printStackTrace();
}
}
}
}
package com.fear1ess.reyunaditool.adsfinder;
import com.fear1ess.reyunaditool.HttpParser;
import com.fear1ess.reyunaditool.IDoCommandService;
import java.util.HashMap;
import java.util.Map;
public class IronSourceFinder extends Finder {
public IronSourceFinder(String adsClassName, String adsName, ClassLoader cl, IDoCommandService service) {
super(adsClassName, adsName, cl, service);
}
@Override
public void hookAdsApi() {
registerSSLHook(new SSLOutputStreamHookedCallback() {
@Override
public void onSSLOutputStreamHooked(HttpParser hp) {
if(!hp.getMethod().equals("GET")) return;
if(!hp.getPath().contains("/gateway/sdk/request")) return;
String applicationKey = hp.getUrlParam("applicationKey");
if(applicationKey != null) {
Map<String,String> map = new HashMap<>();
map.put("applicationKey", applicationKey);
uploadAdsData(map);
}
}
});
}
}
package com.fear1ess.reyunaditool.adsfinder;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
import com.fear1ess.reyunaditool.HookEntry;
import com.fear1ess.reyunaditool.IDoCommandService;
import com.fear1ess.reyunaditool.MLog;
import com.fear1ess.reyunaditool.OperateCmd;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
public class PangLeFinder extends Finder {
private static String m_appID="";
private static String m_temp="";
private static boolean m_flag=false;
public PangLeFinder(String adsName, String adsClassName, ClassLoader cl, IDoCommandService service) {
super(adsName, adsClassName, cl, service);
}
public void hookAdsApi() {
hook_doFinal(mAppClassLoader);
hook_JSON_Put(mAppClassLoader);
}
public void hook_doFinal(ClassLoader classLoader){
XposedHelpers.findAndHookMethod("javax.crypto.Cipher",
classLoader, "doFinal",byte[].class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
try{
String content= new String((byte[]) param.args[0]);
try{
JSONObject jsonObject=new JSONObject(content);
JSONArray adslots= (JSONArray) jsonObject.get("adslots");
// JSONObject item= (JSONObject) adslots.get(0);
if( adslots!=null){
// MLog.d("打印原内容:"+content);
if((m_temp.hashCode()==content.hashCode())){
return;
}
m_temp=content;
m_flag=true;
}
}catch (Exception e){
}
// if(content.contains("\"adslots\":[{\"id\":\"")){
// if((m_temp.hashCode()==content.hashCode())){
// return;
// }
// m_temp=content;
// m_flag=true;
//// JSONObject jsonObject=new JSONObject(content);
//// String ad_sdk_version=(String) jsonObject.get("ad_sdk_version");
//// JSONObject app= (JSONObject) jsonObject.get("app");
//// String appid= (String) app.get("appid");
//// String package_name= (String) app.get("package_name");
//// String version_code= (String) app.get("version_code");
//// String version= (String) app.get("version");
////
//// JSONArray adslots= (JSONArray) jsonObject.get("adslots");
////// MLog.d("adslots-> "+adslots.toString());
//// JSONArray my_Adslots=new JSONArray();
//// for (int i = 0; i < adslots.length(); i++) {
//// JSONObject item= (JSONObject) adslots.get(i);
//// JSONObject object= new JSONObject();
//// object.put("id",item.get("id"));
//// object.put("adtype",item.get("adtype"));
//// my_Adslots.put(object);
//// }
////
//// Map<String,String> map = new HashMap<>();
//// map.put("appid", appid);
//// map.put("ad_sdk_version", ad_sdk_version);
//// map.put("package_name", package_name);
//// map.put("version_code", version_code);
//// map.put("version", version);
//// map.put("adslots", my_Adslots.toString());
//// MLog.d("穿山甲上传数据: "+map.toString());
//// uploadAdsData(map);
// }
}catch (Exception e){
MLog.d(e.toString());
}
}
}
);
}
public void hook_JSON_Put(ClassLoader classLoader){
XposedHelpers.findAndHookMethod(JSONObject.class, "put",
String.class, int.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
String key= (String) param.args[0];
if(key.equals("cypher")){
if(!m_flag){
return;
}
m_flag=false;
// MLog.d("key= "+param.args[0]+" "+param.args[1]);
JSONObject jsonObject=new JSONObject(m_temp);
String ad_sdk_version=(String) jsonObject.get("ad_sdk_version");
JSONObject app= (JSONObject) jsonObject.get("app");
String appid= (String) app.get("appid");
String package_name= (String) app.get("package_name");
String version_code= (String) app.get("version_code");
String version= (String) app.get("version");
JSONArray adslots= (JSONArray) jsonObject.get("adslots");
// MLog.d("adslots-> "+adslots.toString());
JSONArray my_Adslots=new JSONArray();
for (int i = 0; i < adslots.length(); i++) {
JSONObject item= (JSONObject) adslots.get(i);
JSONObject object= new JSONObject();
object.put("id",item.get("id"));
object.put("adtype",item.get("adtype"));
my_Adslots.put(object);
}
Map<String,String> map = new HashMap<>();
map.put("appid", appid);
map.put("ad_sdk_version", ad_sdk_version);
map.put("package_name", package_name);
map.put("version_code", version_code);
map.put("version", version);
map.put("adslots", my_Adslots.toString());
map.put("cypher", String.valueOf(param.args[1]));
MLog.d("穿山甲上传数据: "+map.toString());
uploadAdsData(map);
}
}
});
}
public void uploadAdsData(Map<String,String> map){
//ad map to global ads map
adsMap.put(mAdsName, map);
if(isServiceBound == false){
mRemainAdsDataList.add(map);
Log.d(TAG, "uploadAdsData failed, service is not bound" );
return;
}
try {
JSONObject adsDataJson = new JSONObject();
for(Map.Entry<String,String> entry : map.entrySet()){
adsDataJson.put(entry.getKey(),entry.getValue());
}
JSONObject jo2 = new JSONObject();
jo2.put(mAdsName, adsDataJson);
// JSONObject jo3 = new JSONObject();
jo2.put("app_id", HookEntry.processName+System.currentTimeMillis());
// jo3.put("data",jo2);
String uploadData = jo2.toString();
Log.d(TAG, "uploadAdsData: " + uploadData);
MLog.d("uploadAdsData: " + uploadData);
String res = mDoCommandService.doCommand(OperateCmd.UPLOAD_ADSDK_DATA, uploadData);
updateAdsDataState(mAdsName);
FinderUtils.uploadAdsSdkExistsState(mDoCommandService, 32, 32);
if(res.equals("success")){
Log.d(TAG, "uploadAdsData success");
}
} catch (RemoteException | JSONException e) {
e.printStackTrace();
}
}
private void hook_AppID(ClassLoader classLoader){
XposedHelpers.findAndHookMethod("com.bytedance.sdk.openadsdk.TTAdConfig",
classLoader, "setAppId",String.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
m_appID= (String) param.args[0];
MLog.d( "beforeHookedMethod: 穿山甲APPID: "+m_appID);
}
}
);
}
private void hook_SlotID(ClassLoader classLoader){
XposedHelpers.findAndHookMethod("com.bytedance.sdk.openadsdk.AdSlot$Builder",
classLoader, "setCodeId",String.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
String slotID= (String) param.args[0];
Map<String,String> map = new HashMap<>();
if(TextUtils.isEmpty(m_appID)){
m_appID="error";
}
map.put("appID", m_appID);
map.put("slotID", slotID);
MLog.d( "beforeHookedMethod: 上传的数据: "+map.toString());
uploadAdsData(map);
}
}
);
}
}
package com.fear1ess.reyunaditool.adsfinder;
import android.util.Log;
import com.fear1ess.reyunaditool.HttpParser;
import com.fear1ess.reyunaditool.IDoCommandService;
import org.json.JSONException;
import org.json.JSONObject;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
public class UnityFinder extends Finder {
public UnityFinder(String adsName, String adsClassName, ClassLoader cl, IDoCommandService service) {
super(adsName, adsClassName, cl, service);
}
@Override
public void hookAdsApi() {
registerSSLHook(new SSLOutputStreamHookedCallback() {
@Override
public void onSSLOutputStreamHooked(HttpParser hp) {
if(!hp.getMethod().equals("POST") || !hp.getPath().contains("/v6/games")) return;
Log.d(TAG, "onSSLOutputStreamHooked: unity0");
String unityGameId = match(hp.getPath(), "v6/games/.*/requests").replace("v6/games/","")
.replace("/requests","");
if(unityGameId == null) return;
Log.d(TAG, "onSSLOutputStreamHooked: unity1");
JSONObject jo = hp.getJsonBody();
String gameSessionId = null;
try {
gameSessionId = jo.getString("gameSessionId");
Log.d(TAG, "onSSLOutputStreamHooked: unity2");
String projectId = jo.getString("projectId");
String token = jo.getString("token");
// if(gameSessionId == null || projectId == null || token == null) return;
Map<String, String> map = new HashMap<>();
map.put("gameSessionId", gameSessionId);
map.put("token", token);
map.put("projectId", projectId);
map.put("unityGameId", unityGameId);
uploadAdsData(map);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
/*
try {
XposedBridge.hookAllMethods(mAppClassLoader.loadClass("com.unity3d.ads.UnityAds"), "initialize",
new AdsApiHook("AD", "unityGameId", 1));
XposedHelpers.findAndHookMethod("com.unity3d.services.core.request.WebRequest", mAppClassLoader,
"makeRequest", new UnityNetWorkHook("AD", "unityParam", 0));
XposedHelpers.findAndHookMethod("java.net.SocketOutputStream", mAppClassLoader, "write",
byte[].class, int.class, int.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.d(TAG, "socketos hook success!!!!");
// String data = new String((byte[])param.args[0]);
// Log.d(TAG, "SocketOutput data: " + data);
}
});
XposedHelpers.findAndHookMethod("sun.nio.cs.StreamEncoder", mAppClassLoader, "write",
String.class, int.class, int.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.d(TAG, "streamencoder hook success!!!!");
// String data = new String((byte[])param.args[0]);
Log.d(TAG, "streamencoder data: " + param.args[0]);
}
});
} catch (ClassNotFoundException e) {
e.printStackTrace();
}*/
}
public class UnityNetWorkHook extends AdsApiHook{
public UnityNetWorkHook(String s, String dataName, int posInArgs) {
super(s, dataName, posInArgs);
}
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Object o = param.thisObject;
URL url = (URL) XposedHelpers.getObjectField(o, "_url");
String urlStr = url.toString();
Log.d(TAG, "urlStr: " + urlStr);
Pattern pattern = Pattern.compile("v6/games/.*/requests");
Matcher matcher = pattern.matcher(urlStr);
if(!matcher.find()) return;
Log.d(TAG, "1");
String body = (String) XposedHelpers.getObjectField(o, "_body");
JSONObject jo = new JSONObject(body);
Log.d(TAG, "2");
if(!jo.has("gameSessionId") || !jo.has("token") || !jo.has("projectId")) return;
Log.d(TAG, "3");
Map<String,String> map = new HashMap<>();
map.put("gameSessionId", jo.getString("gameSessionId"));
map.put("token", jo.getString("token"));
map.put("projectId", jo.getString("projectId"));
String unityGameId = matcher.group(0).replace("v6/games/","").replace("/requests","");
map.put("unityGameId", unityGameId);
uploadAdsData(map);
}
}
}
package com.fear1ess.reyunaditool.adsfinder;
import android.util.Log;
import com.fear1ess.reyunaditool.HttpParser;
import com.fear1ess.reyunaditool.IDoCommandService;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
public class VungleFinder extends Finder{
public VungleFinder(String adsName, String adsClassName, ClassLoader cl, IDoCommandService service) {
super(adsName, adsClassName, cl, service);
}
@Override
public void hookAdsApi() {
registerSSLHook(new SSLOutputStreamHookedCallback() {
@Override
public void onSSLOutputStreamHooked(HttpParser hp) {
if(!hp.getMethod().equals("POST") || !hp.getPath().contains("api/v5/ads")) return;
JSONObject jo = hp.getJsonBody();
try {
JSONObject app = jo.getJSONObject("app");
String id = app.getString("id");
JSONObject request = jo.getJSONObject("request");
JSONArray pArr = request.getJSONArray("placements");
String placement = null;
for(int i = 0;i < pArr.length(); ++i){
placement = pArr.getString(i);
}
Map<String, String> map = new HashMap<>();
map.put("id", id);
map.put("placement", placement);
uploadAdsData(map);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
/*
try {
XposedBridge.hookAllMethods(mAppClassLoader.loadClass("com.vungle.warren.network.VungleApiImpl"), "createNewPostCall",
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.d(TAG, "vungle ads ua: " + param.args[0]);
Log.d(TAG, "vungle ads path: " + param.args[1]);
Log.d(TAG, "vungle ads body: " + XposedHelpers.callMethod(param.args[2],"toString"));
}
});
} catch (ClassNotFoundException e) {
e.printStackTrace();
}*/
}
}
package com.fear1ess.reyunaditool.pangle;
import android.text.TextUtils;
import android.util.Log;
import com.fear1ess.reyunaditool.MLog;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import static com.fear1ess.reyunaditool.adsfinder.Finder.TAG;
//--------------------------------------------------测试代码
public class pangleModule {
private static String m_appID="";
public static void hook_AppID(XC_LoadPackage.LoadPackageParam lpparam){
XposedHelpers.findAndHookMethod("com.bytedance.sdk.openadsdk.TTAdConfig",
lpparam.classLoader, "setAppId",String.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
m_appID= (String) param.args[0];
MLog.d( "测试:beforeHookedMethod: "+m_appID);
}
}
);
}
public static void hook_SlotID(XC_LoadPackage.LoadPackageParam lpparam){
XposedHelpers.findAndHookMethod("com.bytedance.sdk.openadsdk.AdSlot$Builder",
lpparam.classLoader, "setCodeId",String.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
String slotID= (String) param.args[0];
Map<String,String> map = new HashMap<>();
if(TextUtils.isEmpty(m_appID)){
m_appID=lpparam.packageName;
}
map.put("appID", m_appID);
map.put("slotID", slotID);
MLog.d("测试:beforeHookedMethod: "+map.toString());
}
}
);
}
public static void hook_doFinal(XC_LoadPackage.LoadPackageParam lpparam){
XposedHelpers.findAndHookMethod("javax.crypto.Cipher",
lpparam.classLoader, "doFinal",byte[].class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
try{
String content= new String((byte[]) param.args[0]);
if(content.contains("\"adslots\":[{\"id\":\"")){
// MLog.d(content);
JSONObject jsonObject=new JSONObject(content);
String ad_sdk_version=(String) jsonObject.get("ad_sdk_version");
JSONObject app= (JSONObject) jsonObject.get("app");
String appid= (String) app.get("appid");
String package_name= (String) app.get("package_name");
String version_code= (String) app.get("version_code");
String version= (String) app.get("version");
JSONArray adslots= (JSONArray) jsonObject.get("adslots");
// MLog.d("adslots-> "+adslots.toString());
JSONArray my_Adslots=new JSONArray();
for (int i = 0; i < adslots.length(); i++) {
JSONObject item= (JSONObject) adslots.get(i);
JSONObject object= new JSONObject();
object.put("id",item.get("id"));
object.put("adtype",item.get("adtype"));
my_Adslots.put(object);
}
Map<String,String> map = new HashMap<>();
if(TextUtils.isEmpty(m_appID)){
m_appID=lpparam.packageName;
}
map.put("appID", appid);
map.put("ad_sdk_version", ad_sdk_version);
map.put("package_name", package_name);
map.put("version_code", version_code);
map.put("version", version);
map.put("slotID", my_Adslots.toString());
MLog.d("测试:beforeHookedMethod: "+map.toString());
}
}catch (Exception e){
MLog.d(e.toString());
}
}
}
);
}
}
<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:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
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="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<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="#3DDC84"
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>
<?xml version="1.0" encoding="utf-8"?>
<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>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<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>
\ No newline at end of file
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.ReyunAdiHookPlugin" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_200</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>
\ No newline at end of file
<resources>
<string name="app_name">ReyunAdiHookPlugin</string>
</resources>
\ No newline at end of file
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.ReyunAdiHookPlugin" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>
\ No newline at end of file
package com.fear1ess.reyunaditool;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}
\ No newline at end of file
// 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:3.6.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
}
\ No newline at end of file
# 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=-Xmx2048m -Dfile.encoding=UTF-8
# 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
\ No newline at end of file
#Thu Jul 08 14:50:33 CST 2021
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip
#!/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" "$@"
@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
include ':app'
rootProject.name = "ReyunAdiHookPlugin"
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment