Repository: ysrc/Anti-Emulator
Branch: master
Commit: 05277af73983
Files: 37
Total size: 55.9 KB
Directory structure:
gitextract_q530vhma/
├── .gitignore
├── .idea/
│ ├── compiler.xml
│ ├── copyright/
│ │ └── profiles_settings.xml
│ ├── gradle.xml
│ ├── misc.xml
│ ├── modules.xml
│ ├── runConfigurations.xml
│ └── vcs.xml
├── README.md
├── app/
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── app-release.apk
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── com/
│ │ └── qtfreet/
│ │ └── anticheckemulator/
│ │ └── ExampleInstrumentedTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── cpp/
│ │ │ └── native-lib.cpp
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── qtfreet/
│ │ │ └── anticheckemulator/
│ │ │ ├── MainActivity.java
│ │ │ ├── emulator/
│ │ │ │ ├── Check.java
│ │ │ │ ├── GLSurfaceView.java
│ │ │ │ ├── GpuRender.java
│ │ │ │ └── JniAnti.java
│ │ │ └── utils/
│ │ │ └── Util.java
│ │ └── res/
│ │ ├── layout/
│ │ │ └── activity_main.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ └── test/
│ └── java/
│ └── com/
│ └── qtfreet/
│ └── anticheckemulator/
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild
================================================
FILE: .idea/compiler.xml
================================================
================================================
FILE: .idea/copyright/profiles_settings.xml
================================================
================================================
FILE: .idea/gradle.xml
================================================
================================================
FILE: .idea/misc.xml
================================================
================================================
FILE: .idea/modules.xml
================================================
================================================
FILE: .idea/runConfigurations.xml
================================================
================================================
FILE: .idea/vcs.xml
================================================
================================================
FILE: README.md
================================================
# Anti-Emulator
Android Anti Emulator
基于模拟器特征文件的检测方式,利用jni和java共同实现。
####原理分析
[文章地址](http://mp.weixin.qq.com/s/sl33d2pnyLMJ-fUY_DfBDw)
================================================
FILE: app/.gitignore
================================================
/build
================================================
FILE: app/CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.4.1)
add_library(native-lib SHARED src/main/cpp/native-lib.cpp )
find_library(log-lib log )
target_link_libraries(native-lib ${log-lib} )
================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.0"
defaultConfig {
applicationId "com.qtfreet.anticheckemulator"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-fexceptions"
cppFlags "-O3"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.0.1'
testCompile 'junit:junit:4.12'
}
================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in D:\sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# 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 *;
#}
================================================
FILE: app/src/androidTest/java/com/qtfreet/anticheckemulator/ExampleInstrumentedTest.java
================================================
package com.qtfreet.anticheckemulator;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumentation test, which will execute on an Android device.
*
* @see Testing documentation
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.qtfreet.anticheckemulator", appContext.getPackageName());
}
}
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
================================================
FILE: app/src/main/cpp/native-lib.cpp
================================================
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "qtfreet00", __VA_ARGS__)
extern "C" {
int i = 0;
char *jstringToChar(JNIEnv *env, jstring jstr) {
if (jstr == NULL) {
return NULL;
}
char *rtn = new char;
jclass clsstring = env->FindClass("java/lang/String");
jstring strencode = env->NewStringUTF("utf-8");
jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode);
jsize alen = env->GetArrayLength(barr);
jbyte *ba = env->GetByteArrayElements(barr, JNI_FALSE);
if (alen > 0) {
rtn = (char *) malloc(alen + 1);
memcpy(rtn, ba, alen);
rtn[alen] = 0;
} else {
rtn = "";
}
/**资源清理**/
env->ReleaseByteArrayElements(barr, ba, 0);
if (clsstring != NULL) {
env->DeleteLocalRef(clsstring);
clsstring = NULL;
}
if (strencode != NULL) {
env->DeleteLocalRef(strencode);
strencode = NULL;
}
mid = NULL;
return rtn;
}
jstring chartoJstring(JNIEnv *env, const char *pat) {
jclass strClass = env->FindClass("Ljava/lang/String;");
jmethodID ctorID = env->GetMethodID(strClass, "", "([BLjava/lang/String;)V");
jbyteArray bytes = env->NewByteArray(strlen(pat));
env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte *) pat);
jstring encoding = env->NewStringUTF("utf-8");
return (jstring) env->NewObject(strClass, ctorID, bytes, encoding);
}
jobject getApplication(JNIEnv *env) {
jclass localClass = env->FindClass("android/app/ActivityThread");
if (localClass != NULL) {
jmethodID getapplication = env->GetStaticMethodID(localClass, "currentApplication",
"()Landroid/app/Application;");
if (getapplication != NULL) {
jobject application = env->CallStaticObjectMethod(localClass, getapplication);
return application;
}
return NULL;
}
return NULL;
}
char *verifySign(JNIEnv *env) {
//此处用于获取app签名
jobject context = getApplication(env);
jclass activity = env->GetObjectClass(context);
// 得到 getPackageManager 方法的 ID
jmethodID methodID_func = env->GetMethodID(activity, "getPackageManager",
"()Landroid/content/pm/PackageManager;");
// 获得PackageManager对象
jobject packageManager = env->CallObjectMethod(context, methodID_func);
jclass packageManagerclass = env->GetObjectClass(packageManager);
//得到 getPackageName 方法的 ID
jmethodID methodID_pack = env->GetMethodID(activity, "getPackageName", "()Ljava/lang/String;");
//获取包名
jstring name_str = static_cast(env->CallObjectMethod(context, methodID_pack));
// 得到 getPackageInfo 方法的 ID
jmethodID methodID_pm = env->GetMethodID(packageManagerclass, "getPackageInfo",
"(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
// 获得应用包的信息
jobject package_info = env->CallObjectMethod(packageManager, methodID_pm, name_str, 64);
// 获得 PackageInfo 类
jclass package_infoclass = env->GetObjectClass(package_info);
// 获得签名数组属性的 ID
jfieldID fieldID_signatures = env->GetFieldID(package_infoclass, "signatures",
"[Landroid/content/pm/Signature;");
// 得到签名数组,待修改
jobject signatur = env->GetObjectField(package_info, fieldID_signatures);
jobjectArray signatures = reinterpret_cast(signatur);
// 得到签名
jobject signature = env->GetObjectArrayElement(signatures, 0);
// 获得 Signature 类,待修改
jclass signature_clazz = env->GetObjectClass(signature);
//获取sign
jmethodID toCharString = env->GetMethodID(signature_clazz, "toCharsString",
"()Ljava/lang/String;");
//获取签名字符;或者其他进行验证操作
jstring signstr = static_cast(env->CallObjectMethod(signature, toCharString));
char *ch = jstringToChar(env, signstr);
//输入签名字符串,这里可以进行相关验证
return ch;
}
jstring getDeviceID(JNIEnv *env, jobject instance) {
jobject mContext = getApplication(env);
if (mContext == NULL) {
return (env)->NewStringUTF("unknown");
}
jclass cls_context = (env)->FindClass("android/content/Context");
if (cls_context == 0) {
return (env)->NewStringUTF("unknown");
}
jmethodID getSystemService = (env)->GetMethodID(cls_context,
"getSystemService",
"(Ljava/lang/String;)Ljava/lang/Object;");
if (getSystemService == 0) {
return (env)->NewStringUTF("unknown");
}
jfieldID TELEPHONY_SERVICE = (env)->GetStaticFieldID(cls_context,
"TELEPHONY_SERVICE", "Ljava/lang/String;");
if (TELEPHONY_SERVICE == 0) {
return (env)->NewStringUTF("unknown");
}
jobject str = (env)->GetStaticObjectField(cls_context, TELEPHONY_SERVICE);
jobject telephonymanager = (env)->CallObjectMethod(mContext,
getSystemService, str);
if (telephonymanager == 0) {
return (env)->NewStringUTF("unknown");
}
jclass cls_tm = (env)->FindClass("android/telephony/TelephonyManager");
if (cls_tm == 0) {
return (env)->NewStringUTF("unknown");
}
jmethodID getDeviceId = (env)->GetMethodID(cls_tm, "getDeviceId",
"()Ljava/lang/String;");
if (getDeviceId == 0) {
return (env)->NewStringUTF("unknown");
}
jstring deviceid = static_cast((env)->CallObjectMethod(telephonymanager, getDeviceId));
char *ch = jstringToChar(env, deviceid);
return deviceid;
}
char *getCpuInfo() { //获取cpu型号
//此处在测试时去判断cpu型号是否是intel core,至强或者奔腾,AMD系列,x86手机cpu型号为intel atom,arm一般为联发科,高通,麒麟等等
//如是判断为前者,则认为当前环境为模拟器
char *info = new char[128];
memset(info, 0, 128);
// char *res = new char[256];
// memset(res,0,256);
char *split = ":";
char *cmd = "/proc/cpuinfo";
FILE *ptr;
if ((ptr = fopen(cmd, "r")) != NULL) {
while (fgets(info, 128, ptr)) {
char *tmp = NULL;
//去掉换行符
if (tmp = strstr(info, "\n"))
*tmp = '\0';
//去掉回车符
if (tmp = strstr(info, "\r"))
*tmp = '\0';
if (strstr(info,
"Hardware")) { //真机一般会获取到hardware,示例:Qualcomm MSM 8974 HAMMERHEAD (Flattened Device Tree)
strtok(info, split);
char *s = strtok(NULL, split);
return s;
} else if (strstr(info,
"model name")) { //测试了一个模拟器,取到的是model_name,示例:Intel(R) Core(TM) i5-4590 CPU @ 3.30GHz
strtok(info, split);
char *s = strtok(NULL, split);
//x86架构的移动处理器为Intel(R) Atom(TM)
if (strstr(s, "Intel(R) Core(TM)") || strstr(s, "Intel(R) Pentium(R)") ||
strstr(s, "Intel(R) Xeon(R)") ||
strstr(s, "AMD")) { //分别为最常见的酷睿,奔腾,至强,AMD处理器
}
LOGE("the cpu native info is %s", s);
return s;
}
}
} else {
LOGE("NULLLLLLLLL");
}
}
char *
getVersionInfo() {
//获取设备版本,真机示例:Linux version 3.4.0-cyanogenmod (ls@ywk) (gcc version 4.7 (GCC) ) #1 SMP PREEMPT Tue Apr 12 11:38:13 CST 2016
// 海马玩: Linux version 3.4.0-qemu+ (droid4x@CA) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #25 SMP PREEMPT Tue Sep 22 15:50:48
//腾讯模拟器中包含了tencent字眼
char *info = new char[256];
memset(info, 0, 256);
char *cmd = "/proc/version";
FILE *ptr;
if ((ptr = fopen(cmd, "r")) != NULL) {
while (fgets(info, 256, ptr)) {
char *tmp = NULL;
if (tmp = strstr(info, "\n"))
*tmp = '\0';
//去掉回车符
if (tmp = strstr(info, "\r"))
*tmp = '\0';
//包含qemu+或者tencent均为模拟器
LOGE("the kernel info is %s", info);
return info;
}
} else {
LOGE("NULLLLLLLLL");
return NULL;
}
}
void antiFile(char *res) {
struct stat buf;
int result = stat(res, &buf) == 0 ? 1 : 0;
if (result) {
LOGE("%s exsits, emulator!", res);
// kill(getpid(),SIGKILL);
i++;
}
}
void antiProperty(char *res) {
char buff[PROP_VALUE_MAX];
memset(buff, 0, PROP_VALUE_MAX);
int result =
__system_property_get(res, (char *) &buff) > 0 ? 1 : 0; //返回命令行内容的长度
if (result != 0) {
LOGE("%s %s exsits, emulator!", res, buff);
// kill(getpid(),SIGKILL);
i++;
}
}
void antiPropertyValueContains(char *res, char *val) {
char buff[PROP_VALUE_MAX + 1];
memset(buff, 0, PROP_VALUE_MAX + 1);
int lman = __system_property_get(res, buff);
if (lman > 0) {
if (strstr(buff, val) != NULL) { // match!
LOGE("%s property value contains %s . Emulator!", res, val);
i++;
}
}
}
void getDeviceInfo() {
char buff[PROP_VALUE_MAX];
memset(buff, 0, PROP_VALUE_MAX);
__system_property_get("ro.product.name", (char *) &buff);
LOGE("the model name is %s", buff);
if (!strcmp(buff, "ChangWan")) {
// kill(getpid(),SIGKILL);
} else if (!strcmp(buff, "Droid4X")) { //非0均为模拟器
// kill(getpid(),SIGKILL);
} else if (!strcmp(buff, "lgshouyou")) {
// kill(getpid(),SIGKILL);
} else if (!strcmp(buff, "nox")) {
// kill(getpid(),SIGKILL);
} else if (!strcmp(buff, "ttVM_Hdragon")) {
// kill(getpid(),SIGKILL);
}
}
char *SocketTest(char *c) {
struct sockaddr_in serv_addr;
char buff[1024];
char res[4096];
memset(res, 0, 4096);
memset(buff, 0, 1024);
memset(&serv_addr, 0, sizeof(serv_addr));
char *addr = "107.151.180.166";
int socketfd = socket(AF_INET, SOCK_STREAM, 0);
if (socketfd == -1) {
LOGE("create error");
LOGE("error (errno=%d)", errno);
exit(1);
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(6666);
serv_addr.sin_addr.s_addr = inet_addr(addr);
if (serv_addr.sin_addr.s_addr == INADDR_NONE) {
struct hostent *host = gethostbyname(addr);
if (host == NULL) {
LOGE("error (errno=%d)", errno);
exit(1);
}
serv_addr.sin_addr.s_addr = ((struct in_addr *) host->h_addr)->s_addr;
}
memset(serv_addr.sin_zero, 0, sizeof(serv_addr.sin_zero));
int conn = connect(socketfd, (struct sockaddr *) &serv_addr, sizeof(struct sockaddr));
if (conn == -1) {
LOGE("connect error");
LOGE("error (errno=%d)", errno);
exit(1);
}
int sen = send(socketfd, c, strlen(c), 0);
if (sen == -1) {
LOGE("send errorrr");
LOGE("error (errno=%d)", errno);
exit(1);
}
while (recv(socketfd, buff, 1023, 0) > 0) {
LOGE("%s", buff);
strcpy(res, buff);
}
close(socketfd);
LOGE("send successssss");
return res;
}
/*逍遥模拟器
* 12-13 12:20:58.671 1615-1615/? E/qtfreet00: the /system/bin/microvirt-prop is exist
12-13 12:20:58.671 1615-1615/? E/qtfreet00: the /system/bin/microvirtd is exist
12-13 12:20:58.671 1615-1615/? E/qtfreet00: the init.svc.vbox86-setup result is stopped
12-13 12:20:58.671 1615-1615/? E/qtfreet00: the init.svc.microvirtd result is running*/
jint check(JNIEnv *env, jobject instance) {
antiFile("/system/bin/qemu_props"); //检测原生模拟器
// antiFile("/system/bin/qemud"); //小米会检测出此项
antiFile("/system/bin/androVM-prop");
antiFile("/system/bin/microvirt-prop");//逍遥
antiFile("/system/lib/libdroid4x.so"); //海马玩
antiFile("/system/bin/windroyed");//文卓爷
antiFile("/system/bin/microvirtd");//逍遥
antiFile("/system/bin/nox-prop"); //夜神
antiFile("/system/bin/ttVM-prop"); //天天
antiFile("/system/bin/droid4x-prop"); //海马玩
antiFile("/data/.bluestacks.prop");//bluestacks
antiProperty("init.svc.vbox86-setup"); //基于vitrualbox
antiProperty("init.svc.droid4x"); //海马玩
antiProperty("init.svc.qemud");
antiProperty("init.svc.su_kpbs_daemon");
antiProperty("init.svc.noxd"); //夜神
antiProperty("init.svc.ttVM_x86-setup"); //天天
antiProperty("init.svc.xxkmsg");
antiProperty("init.svc.microvirtd");//逍遥
// antiProperty("ro.secure"); //检测selinux是否被关闭,一般手机均开启此选项
antiProperty("ro.kernel.android.qemud");
// antiProperty("ro.kernel.qemu.gles"); //三星SM-G5500误报此项
antiProperty("androVM.vbox_dpi");
antiProperty("androVM.vbox_graph_mode");
antiPropertyValueContains("ro.product.manufacturer",
"Genymotion"); // Genymotion check ,thx alinbaturn
return i;
}
jstring getCpuinfo(JNIEnv *env, jobject instance) {
char *res = getCpuInfo();
return env->NewStringUTF(res);
}
jstring getKernelVersion(JNIEnv *env, jobject /* this */) {
char *res = getVersionInfo();
return env->NewStringUTF(res);
}
jstring getApkSign(JNIEnv *env, jobject /* this */) {
char *res = verifySign(env);
return env->NewStringUTF(res);
}
static const char *gClassName = "com/qtfreet/anticheckemulator/emulator/JniAnti";
static JNINativeMethod gMethods[] = {
{"getApkSign", "()Ljava/lang/String;", (void *) getApkSign},
{"getKernelVersion", "()Ljava/lang/String;", (void *) getKernelVersion},
{"getCpuinfo", "()Ljava/lang/String;", (void *) getCpuinfo},
{"getDeviceID", "()Ljava/lang/String;", (void *) getDeviceID},
{"checkAntiFile", "()I", (void *) check},
};
static int registerNativeMethods(JNIEnv *env, const char *className,
JNINativeMethod *gMethods, int numMethods) {
jclass clazz;
clazz = env->FindClass(className);
if (clazz == NULL) {
return JNI_FALSE;
}
if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
return JNI_FALSE;
}
return JNI_TRUE;
}
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
jint result = -1;
if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
//目前已知问题,检测/sys/class/thermal/和bluetooth-jni.so不稳定,存在兼容性问题
getDeviceInfo();
if (registerNativeMethods(env, gClassName, gMethods,
sizeof(gMethods) / sizeof(gMethods[0])) == JNI_FALSE) {
return -1;
}
return JNI_VERSION_1_6;
}
}
================================================
FILE: app/src/main/java/com/qtfreet/anticheckemulator/MainActivity.java
================================================
package com.qtfreet.anticheckemulator;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.widget.TextView;
import com.qtfreet.anticheckemulator.emulator.Check;
import com.qtfreet.anticheckemulator.emulator.JniAnti;
import com.qtfreet.anticheckemulator.utils.Util;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.sample_text);
GLSurfaceView gl = (GLSurfaceView) findViewById(R.id.hwGPU);
gl.setRenderMode(0); //此处是为了加载显卡信息
Log.e("qtfreet000", "APK签名:" + JniAnti.getApkSign());
Log.e("qtfreet000", "程序包名:" + Check.getPackageName(this));
Log.e("qtfreet000", "CPU信息:" + JniAnti.getCpuinfo());
Log.e("qtfreet000", "CPU频率:" + Check.getCpuFrequency());
Log.e("qtfreet000", "CPU核心数量:" + Check.getCpuCore());
Log.e("qtfreet000", "内核信息:" + JniAnti.getKernelVersion());
Log.e("qtfreet000", "设备ID:" + JniAnti.getDeviceID());
Log.e("qtfreet000", "已安装App:" + Check.getInstalledApps(this));
Log.e("qtfreet000", "MAC地址:" + Check.getMacAddress(this));
Log.e("qtfreet000", "内存大小:" + Check.getMemorySize());
// Log.e("qtfreet000", "存在重力感应器:" + Check.checkGravity(this)); //这点不靠谱,很多手机还是检测不出来
Log.e("qtfreet000", "设备厂商:" + Check.getModelBrand());
Log.e("qtfreet000", "设备型号:" + Check.getModelName());
Log.e("qtfreet000", "支持GPS:" + Check.hasGPSDevice(this));
Log.e("qtfreet000", "支持多点触控:" + Check.checkMultiTouch(this));
Log.e("qtfreet000", "电池温度:" + Check.getBatteryTemp(this));
Log.e("qtfreet000", "电池电压:" + Check.getBatteryVolt(this));
Log.e("qtfreet000", "模拟器特征数量:" + JniAnti.checkAntiFile());
String cpu = JniAnti.getCpuinfo();
String cpuFreq = Util.convertSize(Check.getCpuMaxFrequency());
String kernel = JniAnti.getKernelVersion();
boolean gravity = Check.checkGravity(this);
String temp = Check.getBatteryTemp(this);
String volt = Check.getBatteryVolt(this);
int check = JniAnti.checkAntiFile();
boolean gps = Check.hasGPSDevice(this);
StringBuilder sb = new StringBuilder();
if (cpu.contains("Genuine Intel(R)") || cpu.contains("Intel(R) Core(TM)") || cpu.contains("Intel(R) Pentium(R)") || cpu.contains("Intel(R) Xeon(R)") || cpu.contains("AMD")) {
sb.append("特征一:" + cpu + "\n");
}
if (kernel.contains("qemu+") || kernel.contains("tencent") || kernel.contains("virtualbox")) {
sb.append("特征二:" + kernel + "\n");
}
if (gravity == false) {
sb.append("特征三:" + "无重力感应器\n");
}
if (TextUtils.isEmpty(temp)) {
sb.append("特征四:" + "无电池温度\n");
}
if (TextUtils.isEmpty(volt)) {
sb.append("特征五:" + "无电池电压\n");
}
if (check > 0) {
sb.append("特征六:" + "模拟器特征文件\n");
}
if (gps == false) {
sb.append("特征七:" + "无gps\n");
}
if (cpuFreq.equals("0M")) {
sb.append("特征八:" + "cpu无频率\n");
}
tv.setText(sb.toString());
}
}
================================================
FILE: app/src/main/java/com/qtfreet/anticheckemulator/emulator/Check.java
================================================
package com.qtfreet.anticheckemulator.emulator;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.location.LocationManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.telephony.TelephonyManager;
import com.qtfreet.anticheckemulator.utils.Util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;
import static android.content.Context.SENSOR_SERVICE;
import static android.hardware.Sensor.TYPE_GRAVITY;
import static com.qtfreet.anticheckemulator.utils.Util.tempToStr;
/**
* Created by qtfreet on 2016/12/22.
*/
public class Check {
private final static String CPUFREQ_CPUINFO_MAX_FREQ = "/cpufreq/cpuinfo_max_freq";
private final static String CPUFREQ_CPUINFO_MIN_FREQ = "/cpufreq/cpuinfo_min_freq";
private final static String CPUFREQ_SCALING_CUR_FREQ = "/cpufreq/scaling_cur_freq";
public static boolean checkGravity(Context context) {
boolean z = false;
List defaultSensor = ((SensorManager) context.getSystemService(SENSOR_SERVICE)).getSensorList(Sensor.TYPE_ALL);
for (Sensor sensor : defaultSensor) {
if (sensor.getType() == TYPE_GRAVITY) { //不能使用getName去判断是否存在重力感应器,应交与系统判断
z = true;
break;
}
}
return z;
}
public static List getAllSensors(Context context) {
List list = new ArrayList<>();
List defaultSensor = ((SensorManager) context.getSystemService(SENSOR_SERVICE)).getSensorList(Sensor.TYPE_ALL);
for (Sensor sensor : defaultSensor) {
list.add(sensor.getName());
}
return list;
}
public static int getVersionCode(Context context) {
try {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
if (packageInfo != null) {
return packageInfo.versionCode;
}
return 0;
} catch (Throwable th) {
return 0;
}
}
public static String getVersionName(Context context) {
try {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
if (packageInfo != null) {
return packageInfo.versionName;
}
return null;
} catch (Throwable th) {
return null;
}
}
public static String getInstalledApps(Context context) {
List installedPackages = context.getPackageManager().getInstalledPackages(0);
HashMap map = new HashMap<>();
for (PackageInfo p : installedPackages) {
String packageName = p.packageName;
String versionName = p.versionName;
map.put(packageName, versionName);
}
return Util.hashMapToStringNoSort(map);
}
public static String getPackageName(Context context) {
return context.getPackageName();
}
public static boolean checkMultiTouch(Context context) {
boolean z = false;
try {
z = context.getPackageManager().hasSystemFeature("android.hardware.touchscreen.multitouch");
} catch (Exception e) {
e.printStackTrace();
}
return z;
}
public static String getModelName() {
return Build.MODEL; //Mumu为网易模拟器
}
public static String getModelBrand() {
return Build.BRAND;
}
public static String getMacAddress(Context context) {
String str = "";
try {
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
if (wifiManager != null) {
WifiInfo connectionInfo = wifiManager.getConnectionInfo();
return connectionInfo == null ? "" : connectionInfo.getMacAddress();
}
} catch (Throwable th) {
}
return str;
}
public static String getDeviceID(Context context) {
String str = null;
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyManager == null) {
return str;
}
str = telephonyManager.getDeviceId();
return str;
}
public static String getMemorySize() {
String dir = "/proc/meminfo";
FileReader fr = null;
int size = 0;
try {
fr = new FileReader(dir);
BufferedReader br = new BufferedReader(fr, 2048);
String memoryLine = br.readLine();
String subMemoryLine = memoryLine.substring(memoryLine.indexOf("MemTotal:"));
br.close();
long j = Long.parseLong(subMemoryLine.substring(subMemoryLine.indexOf(58) + 1, subMemoryLine.indexOf("kB")).trim());
size = (int) (j / 1024);
} catch (FileNotFoundException e) {
// e.printStackTrace();
} catch (IOException e) {
// e.printStackTrace();
}
if (size < 768) {
return size + "M";
}
if (size < 1024) {
return "1G";
}
return String.format("%.1fG", new Object[]{Float.valueOf(((float) size) / 1024.0f)});
}
public static int getCpuCore() {
try {
return new File("/sys/devices/system/cpu/").listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return Pattern.matches("cpu[0-9]", pathname.getName());
}
}).length;
} catch (Exception e) {
return 0;
}
}
public static boolean hasGPSDevice(Context context) {
final LocationManager mgr = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
if (mgr == null)
return false;
final List providers = mgr.getAllProviders();
if (providers == null)
return false;
return providers.contains(LocationManager.GPS_PROVIDER);
}
public static String getCpuFrequency() {
String frequency = Util.convertSize(getCpuMaxFrequency());
String model = Build.MODEL;
if (Build.BRAND.equalsIgnoreCase("samsung") && (model.equalsIgnoreCase("sch-i959") || model.equalsIgnoreCase("gt-i9500"))) {
frequency = frequency + " " + "四核+四核";
return frequency;
}
switch (getCpuCore()) {
case 1:
frequency = frequency + " " + "单核";
break;
case 2:
frequency = frequency + " " + "双核";
break;
case 4:
frequency = frequency + " " + "四核";
break;
case 6:
frequency = frequency + " " + "六核";
break;
case 8:
frequency = frequency + " " + "八核";
break;
}
return frequency.trim();
}
public static int getCpuMaxFrequency() {
File file = new File("/sys/devices/system/cpu");
if (!file.exists()) {
return 0;
}
File[] listFiles = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return Pattern.matches("cpu[0-9]", pathname.getName());
}
});
if (listFiles == null || listFiles.length <= 0) {
return 0;
}
List arrayList = new ArrayList();
for (File absolutePath : listFiles) {
String path = absolutePath.getAbsolutePath();
try {
int max = Math.max(Math.max(Integer.parseInt(Util.readFile(path + CPUFREQ_CPUINFO_MAX_FREQ)), Integer.parseInt(Util.readFile(path + CPUFREQ_SCALING_CUR_FREQ))), Integer.parseInt(Util.readFile(path + CPUFREQ_CPUINFO_MIN_FREQ)));
if (max > 0) {
arrayList.add(Integer.valueOf(max));
}
} catch (Throwable th) {
}
}
if (arrayList.isEmpty()) {
return 0;
}
Collections.sort(arrayList);
return ((Integer) arrayList.get(arrayList.size() - 1)).intValue();
}
//
// public static String getCameraPixels(Context context, int size) {
// if (size == -1) {
// return null;
// }
// Camera camera = Camera.open(size);
// Camera.Parameters parameters = camera.getParameters();
// List localList = parameters.getSupportedPictureSizes();
// if (localList != null) {
// int[] heights = new int[localList.size()];
// int[] widths = new int[localList.size()];
// for (int i = 0; i < localList.size(); i++) {
// Camera.Size s = localList.get(i);
// int sizehieght = s.height;
// int sizewidth = s.width;
// heights[i] = sizehieght;
// widths[i] = sizewidth;
// }
// int pixels = getMaxNumber(heights) * getMaxNumber(widths);
// camera.release();
// return String.valueOf(pixels / 10000) + " 万";
// }
// return null;
//
// }
//
// private static int getMaxNumber(int[] paramArray) {
// int temp = paramArray[0];
// for (int i = 0; i < paramArray.length; i++) {
// if (temp < paramArray[i]) {
// temp = paramArray[i];
// }
// }
// return temp;
// }
//
// public static int HasBackCamera() {
// int numberOfCameras = Camera.getNumberOfCameras();
// Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
// for (int i = 0; i < numberOfCameras; i++) {
// Camera.getCameraInfo(i, cameraInfo);
// if (cameraInfo.facing == 0) {
// return i;
// }
// }
// return -1;
// }
//
// public static int HasFrontCamera() {
// int numberOfCameras = Camera.getNumberOfCameras();
// Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
// for (int i = 0; i < numberOfCameras; i++) {
// Camera.getCameraInfo(i, cameraInfo);
// if (cameraInfo.facing == 1) {
// return i;
// }
// }
// return -1;
// }
public static String getBatteryTemp(Context act) {
if (act == null) {
return null;
}
Intent batteryStatus = act.registerReceiver(null, new IntentFilter("android.intent.action.BATTERY_CHANGED"));
if (batteryStatus == null) {
return null;
}
int temp = batteryStatus.getIntExtra("temperature", -1);
if (temp > 0) {
return tempToStr(((float) temp) / 10.0f, 1);
}
return null;
}
public static String getBatteryVolt(Context act) {
if (act == null) {
return null;
}
Intent batteryStatus = act.registerReceiver(null, new IntentFilter("android.intent.action.BATTERY_CHANGED"));
if (batteryStatus == null) {
return null;
}
int volt = batteryStatus.getIntExtra("voltage", -1);
if (volt > 0) {
return String.valueOf(volt);
}
return null;
}
public static String toInfoString(Context context) {
HashMap map = new HashMap<>();
map.put("cpuinfo", JniAnti.getCpuinfo());
map.put("kernelVersion", JniAnti.getKernelVersion());
map.put("deviceId", JniAnti.getDeviceID());
// map.put("ApkSign", JniAnti.getApkSign());
map.put("cpuCore", String.valueOf(getCpuCore()));
map.put("cpuFreq", getCpuFrequency());
map.put("Gravity", String.valueOf(checkGravity(context)));
map.put("BatteryVolt", getBatteryVolt(context));
map.put("BatteryTemp", getBatteryTemp(context));
map.put("gps", String.valueOf(hasGPSDevice(context)));
//map.put("installedApps",getInstalledApps(context));
map.put("ModelBrand", getModelBrand());
map.put("ModelName", getModelName());
map.put("MacAddress", getMacAddress(context));
String s = Util.hashMapToStringSort(map);
return s;
}
}
================================================
FILE: app/src/main/java/com/qtfreet/anticheckemulator/emulator/GLSurfaceView.java
================================================
package com.qtfreet.anticheckemulator.emulator;
import android.content.Context;
import android.util.AttributeSet;
/**
* Created by qtfreet on 2016/12/23.
*/
public class GLSurfaceView extends android.opengl.GLSurfaceView {
public GLSurfaceView(Context context) {
super(context);
init();
}
public GLSurfaceView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
init();
}
private void init() {
setEGLConfigChooser(8, 8, 8, 8, 16, 0);
GpuRender gpuRender = new GpuRender();
setRenderer(gpuRender);
}
}
================================================
FILE: app/src/main/java/com/qtfreet/anticheckemulator/emulator/GpuRender.java
================================================
package com.qtfreet.anticheckemulator.emulator;
import android.opengl.GLSurfaceView;
import android.util.Log;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
/**
* Created by qtfreet on 2016/12/23.
*/
public class GpuRender implements GLSurfaceView.Renderer {
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(8.0f, 8.0f, 8.0f, 0.0f);
String vendor = gl.glGetString(GL10.GL_VENDOR);
String renderer = gl.glGetString(GL10.GL_RENDERER);
Log.e("qtfreet000", "显卡信息:" + vendor + " " + renderer);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
}
@Override
public void onDrawFrame(GL10 gl) {
}
}
================================================
FILE: app/src/main/java/com/qtfreet/anticheckemulator/emulator/JniAnti.java
================================================
package com.qtfreet.anticheckemulator.emulator;
/**
* Created by qtfreet on 2016/12/22.
*/
public class JniAnti {
static {
System.loadLibrary("native-lib");
}
public static native String getCpuinfo();
public static native String getApkSign();
public static native String getKernelVersion();
public static native String getDeviceID(); //优测测试时提示没有权限读取read_phone_state,这里已经Mainifest注册
public static native int checkAntiFile();
}
================================================
FILE: app/src/main/java/com/qtfreet/anticheckemulator/utils/Util.java
================================================
package com.qtfreet.anticheckemulator.utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
/**
* Created by qtfreet on 2017/2/7.
*/
public class Util {
public static String hashMapToStringNoSort(HashMap paramMap) {
Set listKeys = paramMap.keySet();
int length = listKeys.size();
List list = new ArrayList();
for (String add : listKeys) {
list.add(add);
}
String kvString = "";
for (int i = 0; i < length; i++) {
String key = list.get(i);
if (i == length - 1) {
kvString = kvString + key + "=" + paramMap.get(key);
} else {
kvString = kvString + key + "=" + paramMap.get(key) + "&";
}
}
return kvString;
}
public static String hashMapToStringSort(HashMap paramMap) {
Set listKeys = paramMap.keySet();
int length = listKeys.size();
List list = new ArrayList();
for (String add : listKeys) {
list.add(add);
}
Collections.sort(list); //进行排序
String kvString = "";
for (int i = 0; i < length; i++) {
String key = list.get(i);
if (i == length - 1) {
kvString = kvString + key + "=" + paramMap.get(key);
} else {
kvString = kvString + key + "=" + (paramMap.get(key)) + "&";
}
}
return kvString;
}
public static String readFile(String str) {
File file = new File(str);
StringBuilder sb = new StringBuilder();
if (file.exists()) {
try {
String line = null;
FileInputStream fileInputStream = new FileInputStream(file);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
bufferedReader.close();
fileInputStream.close();
return sb.toString();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return "";
}
public static String convertSize(int i) {
int size = i / 1000;
if (size > 360 && size < 440) {
return "400M";
}
if (size > 460 && size < 540) {
return "500M";
}
if (size > 560 && size < 640) {
return "600M";
}
if (size > 660 && size < 740) {
return "700M";
}
if (size > 760 && size < 840) {
return "800M";
}
if (size > 860 && size < 940) {
return "900M";
}
if (size > 960 && size < 1040) {
return "1G";
}
if (size < 1000) {
return String.format("%dM", new Object[]{Integer.valueOf(size)});
}
return String.format("%.1fG", new Object[]{Float.valueOf(((float) size) / 1000.0f)});
}
public static String tempToStr(float temp, int tempSetting) {
if (temp <= 0.0f) {
return "";
}
if (tempSetting == 2) {
return String.format("%.1f°F", new Object[]{Float.valueOf(((9.0f * temp) + 160.0f) / 5.0f)});
}
return String.format("%.1f°C", new Object[]{Float.valueOf(temp)});
}
}
================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
================================================
FILE: app/src/main/res/values/colors.xml
================================================
#3F51B5
#303F9F
#FF4081
================================================
FILE: app/src/main/res/values/dimens.xml
================================================
16dp
16dp
================================================
FILE: app/src/main/res/values/strings.xml
================================================
AntiCheckEmulator
================================================
FILE: app/src/main/res/values/styles.xml
================================================
================================================
FILE: app/src/main/res/values-w820dp/dimens.xml
================================================
64dp
================================================
FILE: app/src/test/java/com/qtfreet/anticheckemulator/ExampleUnitTest.java
================================================
package com.qtfreet.anticheckemulator;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see Testing documentation
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}
================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.0-beta3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Tue Dec 27 10:06:56 CST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
================================================
FILE: gradle.properties
================================================
## Project-wide Gradle settings.
#
# 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.
# Default value: -Xmx1024m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -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
#Mon Dec 12 16:39:56 CST 2016
systemProp.http.proxyHost=127.0.0.1
org.gradle.jvmargs=-Xmx1536m
systemProp.http.proxyPort=1080
================================================
FILE: gradlew
================================================
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# 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
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# 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
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" ] ; 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
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
================================================
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
@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=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@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 Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_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=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
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
================================================
include ':app'