├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── assets
│ │ │ └── xposed_init
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── layout
│ │ │ │ ├── dialog_search.xml
│ │ │ │ ├── dialog_wifi.xml
│ │ │ │ ├── activity_main.xml
│ │ │ │ ├── dialog_lac_cid.xml
│ │ │ │ └── activity_amap.xml
│ │ │ ├── menu
│ │ │ │ └── menu_map.xml
│ │ │ ├── drawable
│ │ │ │ ├── ic_pan_tool_blue_500_24dp.xml
│ │ │ │ └── ic_launcher_background.xml
│ │ │ └── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ ├── cpp
│ │ │ └── native-lib.cpp
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── lupinus
│ │ │ │ └── wework
│ │ │ │ ├── Module.java
│ │ │ │ ├── Common.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── DeviceInfo.java
│ │ │ │ ├── AMapActivity.java
│ │ │ │ ├── WeChatWork.java
│ │ │ │ └── RootCloak.java
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── lupinus
│ │ │ └── wework
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── lupinus
│ │ └── wework
│ │ └── ExampleInstrumentedTest.java
├── release
│ ├── wework.apk
│ └── output.json
├── libs
│ ├── AMap_2DMap_V2.8.1_20160202.jar
│ └── AMap_Search_V3.2.1_20160308.jar
├── proguard-rules.pro
├── build.gradle
└── CMakeLists.txt
├── settings.gradle
├── README.md
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .idea
├── dictionaries
│ └── luyufa.xml
├── markdown-navigator
│ └── profiles_settings.xml
├── vcs.xml
├── encodings.xml
├── modules.xml
├── runConfigurations.xml
├── gradle.xml
├── misc.xml
└── markdown-navigator.xml
├── .gitignore
├── gradle.properties
├── gradlew.bat
└── gradlew
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/app/src/main/assets/xposed_init:
--------------------------------------------------------------------------------
1 | com.lupinus.wework.Module
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Wework
2 | 微信企业版打卡
3 |
4 | 仅适用于Wi-Fi打开,不适用于定位打卡
5 |
--------------------------------------------------------------------------------
/app/release/wework.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lupinuss/Wework/HEAD/app/release/wework.apk
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 不可描述
3 |
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lupinuss/Wework/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/.idea/dictionaries/luyufa.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/libs/AMap_2DMap_V2.8.1_20160202.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lupinuss/Wework/HEAD/app/libs/AMap_2DMap_V2.8.1_20160202.jar
--------------------------------------------------------------------------------
/app/libs/AMap_Search_V3.2.1_20160308.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lupinuss/Wework/HEAD/app/libs/AMap_Search_V3.2.1_20160308.jar
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lupinuss/Wework/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lupinuss/Wework/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lupinuss/Wework/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lupinuss/Wework/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lupinuss/Wework/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lupinuss/Wework/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lupinuss/Wework/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lupinuss/Wework/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/.idea/markdown-navigator/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lupinuss/Wework/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lupinuss/Wework/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/release/output.json:
--------------------------------------------------------------------------------
1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1},"path":"app-release.apk","properties":{"packageId":"com.lupinus.wework","split":"","minSdkVersion":"22"}}]
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 10 10:37:04 CST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/cpp/native-lib.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | extern "C"
5 | JNIEXPORT jstring
6 |
7 | JNICALL
8 | Java_com_lupinus_wework_MainActivity_stringFromJNI(
9 | JNIEnv *env,
10 | jobject /* this */) {
11 | std::string hello = "Hello from C++";
12 | return env->NewStringUTF(hello.c_str());
13 | }
14 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_search.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/lupinus/wework/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.lupinus.wework;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_map.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_pan_tool_blue_500_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lupinus/wework/Module.java:
--------------------------------------------------------------------------------
1 | package com.lupinus.wework;
2 |
3 | import de.robv.android.xposed.IXposedHookLoadPackage;
4 | import de.robv.android.xposed.callbacks.XC_LoadPackage;
5 |
6 | /**
7 | * Created by luyufa on 2019/4/10.
8 | */
9 |
10 | public class Module implements IXposedHookLoadPackage {
11 |
12 |
13 | @Override
14 | public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
15 |
16 | String packetName = lpparam.packageName;
17 |
18 | String processName = lpparam.processName;
19 |
20 | //com.tencent.wework
21 | if ("com.tencent.wework".equals(packetName) && "com.tencent.wework".equals(processName)){
22 |
23 | RootCloak rootCloak = new RootCloak();
24 | rootCloak.handleLoadPackage(lpparam);
25 |
26 | WeChatWork.hook();
27 |
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/lupinus/wework/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.lupinus.wework;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.lupinus.wework", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_wifi.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
17 |
18 |
19 |
20 |
23 |
24 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
21 |
22 |
28 |
29 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_lac_cid.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
17 |
18 |
19 |
20 |
23 |
24 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 27
5 | defaultConfig {
6 | applicationId "com.lupinus.wework"
7 | minSdkVersion 22
8 | targetSdkVersion 23
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | externalNativeBuild {
13 | cmake {
14 | cppFlags ""
15 | }
16 | }
17 | }
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 | externalNativeBuild {
25 | cmake {
26 | path "CMakeLists.txt"
27 | }
28 | }
29 | }
30 |
31 | dependencies {
32 | implementation fileTree(dir: 'libs', include: ['*.jar'])
33 | implementation 'com.android.support:appcompat-v7:27.1.1'
34 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
35 | implementation 'com.android.support:design:27.1.1'
36 | implementation 'com.android.support:cardview-v7:27.1.1'
37 |
38 | provided 'de.robv.android.xposed:api:82+'
39 |
40 | compile files('libs/AMap_Search_V3.2.1_20160308.jar')
41 | compile files('libs/AMap_2DMap_V2.8.1_20160202.jar')
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_amap.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
24 |
25 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # For more information about using CMake with Android Studio, read the
2 | # documentation: https://d.android.com/studio/projects/add-native-code.html
3 |
4 | # Sets the minimum version of CMake required to build the native library.
5 |
6 | cmake_minimum_required(VERSION 3.4.1)
7 |
8 | # Creates and names a library, sets it as either STATIC
9 | # or SHARED, and provides the relative paths to its source code.
10 | # You can define multiple libraries, and CMake builds them for you.
11 | # Gradle automatically packages shared libraries with your APK.
12 |
13 | add_library( # Sets the name of the library.
14 | native-lib
15 |
16 | # Sets the library as a shared library.
17 | SHARED
18 |
19 | # Provides a relative path to your source file(s).
20 | src/main/cpp/native-lib.cpp )
21 |
22 | # Searches for a specified prebuilt library and stores the path as a
23 | # variable. Because CMake includes system libraries in the search path by
24 | # default, you only need to specify the name of the public NDK library
25 | # you want to add. CMake verifies that the library exists before
26 | # completing its build.
27 |
28 | find_library( # Sets the name of the path variable.
29 | log-lib
30 |
31 | # Specifies the name of the NDK library that
32 | # you want CMake to locate.
33 | log )
34 |
35 | # Specifies libraries CMake should link to your target library. You
36 | # can link multiple libraries, such as libraries you define in this
37 | # build script, prebuilt third-party libraries, or system libraries.
38 |
39 | target_link_libraries( # Specifies the target library.
40 | native-lib
41 |
42 | # Links the target library to the log library
43 | # included in the NDK.
44 | ${log-lib} )
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
25 |
26 |
29 |
32 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
46 |
47 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lupinus/wework/Common.java:
--------------------------------------------------------------------------------
1 | package com.lupinus.wework;
2 |
3 |
4 | import java.util.Arrays;
5 | import java.util.HashSet;
6 | import java.util.Set;
7 |
8 | /**
9 | * Created by luyufa on 2019/4/8.
10 | */
11 |
12 | public class Common {
13 |
14 |
15 | public static final String PREFS_FILE = "Device";
16 | public static final String PACKAGE_NAME = "com.lixin.hardwarecode";
17 |
18 | public static final String PREFS_APPS = "CustomizeApps";
19 | public static final String PREFS_KEYWORDS = "CustomizeKeywords";
20 | public static final String PREFS_COMMANDS = "CustomizeCommands";
21 | public static final String PREFS_LIBNAMES = "CustomizeLibnames";
22 | public static final String FIRST_RUN_KEY = "IS_FIRST_RUN";
23 |
24 | public static final String[] DEFAULT_KEYWORD_LIST = new String[]{"supersu", "superuser", "Superuser",
25 | "noshufou", "xposed", "rootcloak",
26 | "chainfire", "titanium", "Titanium",
27 | "substrate", "greenify", "daemonsu",
28 | "root", "busybox", "titanium",
29 | ".tmpsu", "su", "rootcloak2"};
30 | public static final String[] DEFAULT_APPS_LIST = { "com.fde.DomesticDigitalCopy",
31 | "com.directv.application.android.go.production",
32 | "com.res.bby",
33 | "dk.excitor.dmemail",
34 | "com.BHTV",
35 | "com.bradfordnetworks.bma",
36 | "com.apriva.mobile.bams",
37 | "com.apriva.mobile.aprivapay",
38 | "pl.pkobp.iko",
39 | "au.com.auspost",
40 | "com.rogers.citytv.phone",
41 | "com.zenprise",
42 | "net.flixster.android",
43 | "com.starfinanz.smob.android.sfinanzstatus",
44 | "com.ovidos.yuppi",
45 | "klb.android.lovelive",
46 | "klb.android.lovelive_en",
47 | "com.nintendo.zaaa",
48 | "com.incube.epub",
49 | "com.airwatch.androidagent",
50 | "com.zappware.twintv.d3",
51 | "com.starfinanz.mobile.android.pushtan",
52 | "com.stofa.webtv",
53 | "com.barclays.android.barclaysmobilebanking",
54 | "com.bskyb.skygo",
55 | "com.hanaskcard.rocomo.potal",
56 | "com.hanabank.ebk.channel.android.hananbank",
57 | "com.ahnlab.v3mobileplus",
58 | "com.good.android.gfe",
59 | "it.phoenixspa.inbank",
60 | "dk.tv2.tv2play",
61 | "com.enterproid.divideinstaller",
62 | "com.isis.mclient.verizon.activity",
63 | "com.isis.mclient.atnt.activity",
64 | "be.telenet.yelo",
65 | "no.rdml.android.mobiletv",
66 | "uk.co.barclays.barclayshomeowner",
67 | "com.mcafee.apps.emmagent",
68 | "com.virginmedia.tvanywhere",
69 | "com.amis.mobiatv",
70 | "it.telecomitalia.cubovision",
71 | "nl.ziggo.android.tv",
72 | "com.orange.fr.ocs",
73 | "com.adb.android.app.iti",
74 | "com.mobileiron"};
75 | public static final Set DEFAULT_APPS_SET = new HashSet(Arrays.asList(DEFAULT_APPS_LIST));
76 | public static final String DEBUG_KEY = "DEBUGGERPREF";
77 |
78 | public static final String APP_LIST_KEY = "APPS_LIST"; // Uses the name LIST for legacy purposes
79 |
80 | public static final String KEYWORD_SET_KEY = "KEYWORD_SET";
81 | public static final String COMMAND_SET_KEY = "APPS_SET";
82 | public static final String LIBRARY_SET_KEY = "LIBNAMES_SET";
83 |
84 | public static final Set DEFAULT_KEYWORD_SET = new HashSet(Arrays.asList(DEFAULT_KEYWORD_LIST));
85 | public static final String[] DEFAULT_COMMAND_LIST = new String[]{"su", "which", "busybox", "pm", "am", "sh", "ps"};
86 | public static final Set DEFAULT_COMMAND_SET = new HashSet(Arrays.asList(DEFAULT_COMMAND_LIST));
87 | public static final String[] DEFAULT_LIBNAME_LIST = new String[]{"tool-checker"}; // RootBearNative
88 | public static final Set DEFAULT_LIBNAME_SET = new HashSet(Arrays.asList(DEFAULT_LIBNAME_LIST));
89 |
90 | public static final String SHOW_WARNING = "SHOW_WARNING";
91 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/lupinus/wework/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.lupinus.wework;
2 |
3 | import android.app.AlertDialog;
4 | import android.content.Context;
5 | import android.content.DialogInterface;
6 | import android.content.Intent;
7 | import android.content.SharedPreferences;
8 | import android.os.Bundle;
9 | import android.support.design.widget.TextInputEditText;
10 | import android.support.v7.app.AppCompatActivity;
11 | import android.view.View;
12 |
13 | public class MainActivity extends AppCompatActivity {
14 |
15 | static {
16 | System.loadLibrary("native-lib");
17 | }
18 |
19 | @Override
20 | protected void onCreate(Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 | setContentView(R.layout.activity_main);
23 |
24 | findViewById(R.id.device).setOnClickListener(new View.OnClickListener() {
25 | @Override
26 | public void onClick(View v) {
27 |
28 | String deviceInfo = DeviceInfo.getDeviceInfo(MainActivity.this);
29 | simple(MainActivity.this, deviceInfo);
30 | }
31 | });
32 |
33 | findViewById(R.id.loaction).setOnClickListener(new View.OnClickListener() {
34 | @Override
35 | public void onClick(View v) {
36 |
37 | Intent intent = new Intent(MainActivity.this, AMapActivity.class);
38 | startActivity(intent);
39 |
40 | }
41 | });
42 |
43 | findViewById(R.id.wifi).setOnClickListener(new View.OnClickListener() {
44 | @Override
45 | public void onClick(View v) {
46 | edit(MainActivity.this);
47 | }
48 | });
49 |
50 | findViewById(R.id.config).setOnClickListener(new View.OnClickListener() {
51 | @Override
52 | public void onClick(View v) {
53 | SharedPreferences sp = getSharedPreferences("HookInfo",MODE_WORLD_READABLE);
54 |
55 | String latitude = sp.getString("latitude","");
56 | String longitude = sp.getString("longitude","");
57 | int lac = sp.getInt("lac",0);
58 | int cid = sp.getInt("cid",0);
59 | String bssid = sp.getString("bssid","");
60 | String ssid = sp.getString("ssid","");
61 |
62 | StringBuffer sb = new StringBuffer();
63 | sb.append("纬度:").append(latitude).append("\n");
64 | sb.append("经度:").append(longitude).append("\n");
65 | sb.append("小区号:").append(lac).append("\n");
66 | sb.append("基站号:").append(cid).append("\n");
67 | sb.append("Wi-Fi名称:").append(ssid).append("\n");
68 | sb.append("路由器地址:").append(bssid).append("\n");
69 |
70 | simple(MainActivity.this,sb.toString());
71 | }
72 | });
73 | }
74 |
75 | private void simple(Context context, String message) {
76 |
77 | AlertDialog.Builder builder = new AlertDialog.Builder(context);
78 | builder.setMessage(message);
79 | builder.create().show();
80 |
81 | }
82 |
83 | private void edit(Context context) {
84 |
85 | View view = getLayoutInflater().inflate(R.layout.dialog_wifi, null, false);
86 |
87 | final TextInputEditText BSSID = view.findViewById(R.id.bssid);//mac
88 | final TextInputEditText SSID = view.findViewById(R.id.ssid);//name
89 |
90 | AlertDialog.Builder builder = new AlertDialog.Builder(context);
91 | builder.setView(view);
92 |
93 | builder.setTitle("提示");
94 |
95 | builder.setNegativeButton("确定", new DialogInterface.OnClickListener() {
96 | @Override
97 | public void onClick(DialogInterface dialog, int which) {
98 | String bssid = BSSID.getText().toString().trim();
99 | String ssid = SSID.getText().toString().trim();
100 |
101 | SharedPreferences sp = getSharedPreferences("HookInfo",MODE_WORLD_READABLE);
102 | SharedPreferences.Editor editor = sp.edit();
103 |
104 | editor.putString("bssid",bssid);
105 | editor.putString("ssid",ssid);
106 | editor.commit();
107 |
108 | }
109 | });
110 |
111 | builder.setPositiveButton("取消", new DialogInterface.OnClickListener() {
112 | @Override
113 | public void onClick(DialogInterface dialog, int which) {
114 |
115 | }
116 | });
117 |
118 | builder.create().show();
119 |
120 | }
121 |
122 |
123 | public native String stringFromJNI();
124 | }
125 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | Abstraction issuesJava
36 |
37 |
38 | Android > Lint > Correctness
39 |
40 |
41 | Android > Lint > Security
42 |
43 |
44 | Android > Lint > Usability
45 |
46 |
47 | Annotations verifyingGroovy
48 |
49 |
50 | Class structureJava
51 |
52 |
53 | Declaration redundancyJava
54 |
55 |
56 | Error handlingJava
57 |
58 |
59 | GeneralJava
60 |
61 |
62 | Groovy
63 |
64 |
65 | JUnit issuesJava
66 |
67 |
68 | Java
69 |
70 |
71 | Memory issuesJava
72 |
73 |
74 | Method MetricsGroovy
75 |
76 |
77 | Method metricsJava
78 |
79 |
80 | Numeric issuesJava
81 |
82 |
83 | Performance issuesJava
84 |
85 |
86 | Probable bugsJava
87 |
88 |
89 | TestNGJava
90 |
91 |
92 |
93 |
94 | Android
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 | 1.8
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lupinus/wework/DeviceInfo.java:
--------------------------------------------------------------------------------
1 | package com.lupinus.wework;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.app.Activity;
5 | import android.net.ConnectivityManager;
6 | import android.net.NetworkInfo;
7 | import android.net.wifi.WifiManager;
8 | import android.os.Build;
9 | import android.provider.Settings;
10 | import android.telephony.CellLocation;
11 | import android.telephony.TelephonyManager;
12 | import android.telephony.cdma.CdmaCellLocation;
13 | import android.telephony.gsm.GsmCellLocation;
14 | import android.util.DisplayMetrics;
15 |
16 | import java.util.HashMap;
17 | import java.util.Map;
18 |
19 | /**
20 | * Created by luyufa on 2019/4/10.
21 | */
22 |
23 | public class DeviceInfo {
24 |
25 | public static String[] valueArr = new String[]{"getDeviceId", "getString", "getString2", "getLine1Number", "getSimSerialNumber", "getSubscriberId", "getSimCountryIso", "getSimOperator", "getSimOperatorName", "getNetworkCountryIso", "getNetworkOperator", "getNetworkOperatorName", "getNetworkType", "getPhoneType", "getSimState", "getMacAddress", "getSSID", "getBSSID", "RELEASE", "SDK", "ARCH", "getMetrics", "getRadioVersion", "BRAND", "MODEL", "PRODUCT", "MANUFACTURER", "getJiZhan", "getCpuName", "connectType", "getRadioVersion"};
26 | public static String[] valueArrName = new String[]{"序列号", "android_id", "android_id第二种方式", "手机号码", "手机卡序列号", "IMSI", "手机卡国家", "运营商", "运营商名字", "国家iso代码", "网络类型", "网络类型名", "网络类型", "手机类型", "手机卡状态", "mac地址", "无线路由器名", "无线路由器地址", "系统版本", "系统版本值", "系统架构", "屏幕分辨率", "固件版本", "品牌", "型号", "产品名", "制造商", "基站信息", "CPU名字", "联网方式", "固件版本1"};
27 | private static HashMap valueMap = new HashMap();
28 |
29 |
30 | public static String getDeviceInfo(Activity activity) {
31 | getAllData(activity);
32 | String data = "";
33 | for (Map.Entry item : valueMap.entrySet()) {
34 | String key = item.getKey();
35 | Object value = item.getValue();
36 | for (int i = 0; i < valueArr.length; i++) {
37 | if (key.equals(valueArr[i])) {
38 | key = valueArrName[i];
39 | }
40 | }
41 | data = new StringBuilder(String.valueOf(data)).append(key).append(" : ").append(value).append("\n").toString();
42 | }
43 |
44 | return data;
45 | }
46 |
47 |
48 | @SuppressLint("MissingPermission")
49 | private static void getAllData(Activity activity) {
50 | Class cl;
51 | Object invoker;
52 | @SuppressLint("WrongConstant")
53 | TelephonyManager tele = (TelephonyManager) activity.getSystemService("phone");
54 | valueMap.put("getDeviceId", tele.getDeviceId());
55 | valueMap.put("getLine1Number", tele.getLine1Number());
56 | valueMap.put("getSimSerialNumber", tele.getSimSerialNumber());
57 | valueMap.put("getSubscriberId", tele.getSubscriberId());
58 | valueMap.put("getSimCountryIso", tele.getSimCountryIso());
59 | valueMap.put("getSimOperator", tele.getSimOperator());
60 | valueMap.put("getSimOperatorName", tele.getSimOperatorName());
61 | valueMap.put("getNetworkCountryIso", tele.getNetworkCountryIso());
62 | valueMap.put("getNetworkOperator", tele.getNetworkOperator());
63 | valueMap.put("getNetworkOperatorName", tele.getNetworkOperatorName());
64 | valueMap.put("getNetworkType", Integer.valueOf(tele.getNetworkType()));
65 | valueMap.put("getPhoneType", Integer.valueOf(tele.getPhoneType()));
66 | valueMap.put("getSimState", Integer.valueOf(tele.getSimState()));
67 | valueMap.put("getRadioVersion", Build.getRadioVersion());
68 |
69 | @SuppressLint("WrongConstant") WifiManager wifi = (WifiManager) activity.getSystemService("wifi");
70 | valueMap.put("getMacAddress", wifi.getConnectionInfo().getMacAddress());
71 | valueMap.put("getSSID", wifi.getConnectionInfo().getSSID());
72 | valueMap.put("getBSSID", wifi.getConnectionInfo().getBSSID());
73 | valueMap.put("getString", Settings.Secure.getString(activity.getContentResolver(), "android_id"));
74 | valueMap.put("getString2", Settings.System.getString(activity.getContentResolver(), "android_id"));
75 | try {
76 | cl = Class.forName("android.os.SystemProperties");
77 | invoker = cl.newInstance();
78 | valueMap.put("get", cl.getMethod("get", new Class[]{String.class, String.class}).invoke(invoker, new Object[]{"gsm.version.baseband", "no message"}));
79 | } catch (Exception e) {
80 | }
81 | try {
82 | cl = Class.forName("android.os.SystemProperties");
83 | invoker = cl.newInstance();
84 | valueMap.put("getRadioVersion1", cl.getMethod("get", new Class[]{String.class}).invoke(invoker, new Object[]{"gsm.version.baseband"}));
85 | } catch (Exception e2) {
86 | }
87 | CellLocation location1 = tele.getCellLocation();
88 | String locationStr = "";
89 | int lac;
90 | if (location1 instanceof GsmCellLocation) {
91 | GsmCellLocation location = (GsmCellLocation) location1;
92 | lac = location.getLac();
93 | locationStr = new StringBuilder(String.valueOf(lac)).append("_").append(location.getCid()).toString();
94 | } else if (location1 instanceof CdmaCellLocation) {
95 | CdmaCellLocation location2 = (CdmaCellLocation) tele.getCellLocation();
96 | lac = location2.getNetworkId();
97 | locationStr = new StringBuilder(String.valueOf(lac)).append("_").append(location2.getBaseStationId()).toString();
98 | }
99 | valueMap.put("getJiZhan", new StringBuilder(String.valueOf(locationStr)).append("_").append(tele.getCallState()).toString());
100 | valueMap.put("RELEASE", Build.VERSION.RELEASE);
101 | valueMap.put("SDK", Build.VERSION.SDK);
102 | valueMap.put("ARCH", Build.CPU_ABI + "_" + Build.CPU_ABI2);
103 | valueMap.put("BRAND", Build.BRAND);
104 | valueMap.put("MODEL", Build.MODEL);
105 | valueMap.put("PRODUCT", Build.PRODUCT);
106 | valueMap.put("MANUFACTURER", Build.MANUFACTURER);
107 | valueMap.put("DEVICE", Build.DEVICE);
108 | DisplayMetrics dm = new DisplayMetrics();
109 | activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
110 | valueMap.put("getMetrics", dm.widthPixels + "x" + dm.heightPixels + " density: " + dm.density + " densityDpi: " + dm.densityDpi + " scaledDensity: " + dm.scaledDensity + " xdpi: " + dm.xdpi + " ydpi: " + dm.ydpi);
111 | @SuppressLint("WrongConstant") NetworkInfo info = ((ConnectivityManager) activity.getSystemService("connectivity")).getActiveNetworkInfo();
112 | String str = "";
113 | if (info != null) {
114 | str = info.getTypeName();
115 | } else {
116 | str = "网络未连接";
117 | }
118 | try {
119 | cl = Class.forName("android.os.SystemProperties");
120 | invoker = cl.newInstance();
121 | str = new StringBuilder(String.valueOf(str)).append("_状态:").append(cl.getMethod("get", new Class[]{String.class}).invoke(invoker, new Object[]{"gsm.sim.state"})).toString();
122 | } catch (Exception e3) {
123 | }
124 | if (tele.hasIccCard()) {
125 | str = new StringBuilder(String.valueOf(str)).append("——有sim卡").toString();
126 | } else {
127 | str = new StringBuilder(String.valueOf(str)).append("——无sim卡").toString();
128 | }
129 | valueMap.put("connectType", str);
130 | }
131 |
132 | }
133 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lupinus/wework/AMapActivity.java:
--------------------------------------------------------------------------------
1 | package com.lupinus.wework;
2 |
3 | import android.content.DialogInterface;
4 | import android.content.SharedPreferences;
5 | import android.os.Bundle;
6 | import android.support.design.widget.TextInputEditText;
7 | import android.support.v7.app.AlertDialog;
8 | import android.support.v7.app.AppCompatActivity;
9 | import android.support.v7.widget.Toolbar;
10 | import android.text.TextUtils;
11 | import android.view.LayoutInflater;
12 | import android.view.Menu;
13 | import android.view.MenuItem;
14 | import android.view.View;
15 | import android.widget.EditText;
16 | import android.widget.Toast;
17 |
18 | import com.amap.api.maps2d.AMap;
19 | import com.amap.api.maps2d.CameraUpdateFactory;
20 | import com.amap.api.maps2d.MapView;
21 | import com.amap.api.maps2d.model.LatLng;
22 | import com.amap.api.maps2d.model.MarkerOptions;
23 | import com.amap.api.services.core.PoiItem;
24 | import com.amap.api.services.poisearch.PoiResult;
25 | import com.amap.api.services.poisearch.PoiSearch;
26 |
27 | import java.lang.reflect.Field;
28 | import java.util.ArrayList;
29 |
30 |
31 | public class AMapActivity extends AppCompatActivity implements AMap.OnMapClickListener {
32 |
33 | private MapView mv;
34 | private AMap aMap;
35 | private LatLng latLng;
36 | private int lac = 0, cid = 0;
37 |
38 | private SharedPreferences sp;
39 |
40 | @Override
41 | protected void onCreate(Bundle savedInstanceState) {
42 | super.onCreate(savedInstanceState);
43 | setContentView(R.layout.activity_amap);
44 | // Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
45 | // setSupportActionBar(toolbar);
46 |
47 | sp = getSharedPreferences("HookInfo",MODE_WORLD_READABLE);
48 |
49 | mv = findViewById(R.id.mv);
50 | assert mv != null;
51 | mv.onCreate(savedInstanceState);
52 | aMap = mv.getMap();
53 | aMap.setMapType(AMap.MAP_TYPE_NORMAL);
54 | aMap.setOnMapClickListener(this);
55 | }
56 |
57 | @Override
58 | protected void onResume() {
59 | super.onResume();
60 | mv.onResume();
61 | }
62 |
63 | @Override
64 | public boolean onCreateOptionsMenu(Menu menu) {
65 | getMenuInflater().inflate(R.menu.menu_map, menu);
66 | return super.onCreateOptionsMenu(menu);
67 | }
68 |
69 | @Override
70 | public boolean onOptionsItemSelected(MenuItem item) {
71 | switch (item.getItemId()) {
72 | case R.id.ok:
73 | if (latLng == null) {
74 | Toast.makeText(this, "请点击地图选择一个地点!", Toast.LENGTH_SHORT).show();
75 | return true;
76 | }
77 | new AlertDialog.Builder(AMapActivity.this).setTitle("注意").setMessage("如果打卡时显示不在范围内,请填写基站信息")
78 | .setPositiveButton("知道了", new DialogInterface.OnClickListener() {
79 | @Override
80 | public void onClick(DialogInterface dialog, int which) {
81 | dialog.dismiss();
82 | }
83 | })
84 | .show();
85 | // ContentValues contentValues = new ContentValues();
86 | // contentValues.put("package_name", pacakgeName);
87 | // contentValues.put("latitude", latLng.latitude);
88 | // contentValues.put("longitude", latLng.longitude);
89 | // contentValues.put("lac", lac);
90 | // contentValues.put("cid", cid);
91 |
92 | SharedPreferences.Editor editor = sp.edit();
93 | editor.putString("latitude",String.valueOf(latLng.latitude));
94 | editor.putString("longitude",String.valueOf(latLng.longitude));
95 | editor.putInt("lac",lac);
96 | editor.putInt("cid",cid);
97 | editor.commit();
98 |
99 | break;
100 | case R.id.search:
101 | View view = LayoutInflater.from(this).inflate(R.layout.dialog_search, null, false);
102 | final EditText et_key = view.findViewById(R.id.key);
103 | new AlertDialog.Builder(this).setView(view)
104 | .setTitle("搜索位置")
105 | .setPositiveButton("搜索", new DialogInterface.OnClickListener() {
106 | @Override
107 | public void onClick(DialogInterface dialog, int which) {
108 | search(et_key.getText().toString());
109 | }
110 | }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
111 | @Override
112 | public void onClick(DialogInterface dialog, int which) {
113 | dialog.dismiss();
114 | }
115 | }).show();
116 | break;
117 | case R.id.lac:
118 | View view1 = getLayoutInflater().inflate(R.layout.dialog_lac_cid, null, false);
119 | final TextInputEditText etLac = view1.findViewById(R.id.lac);
120 | final TextInputEditText etCid = view1.findViewById(R.id.cid);
121 | new AlertDialog.Builder(AMapActivity.this).setTitle("填写基站信息").setView(view1).setPositiveButton("确定", new DialogInterface.OnClickListener() {
122 | @Override
123 | public void onClick(DialogInterface dialog, int which) {
124 | canCloseDialog(dialog, false);
125 | if (TextUtils.isEmpty(etLac.getText())) {
126 | etLac.setError("lac的值不应该为空");
127 | }
128 | if (TextUtils.isEmpty(etCid.getText())) {
129 | etCid.setError("cid的值不应该为空");
130 | }
131 | if (!TextUtils.isEmpty(etLac.getText()) && !TextUtils.isEmpty(etCid.getText())) {
132 | int lac1 = Integer.parseInt(etLac.getText().toString());
133 | int cid1 = Integer.parseInt(etCid.getText().toString());
134 | if (lac1 <= 0 || lac1 >= 65535) {
135 | etLac.setError("lac的值应该是0~65535");
136 | lac1 = 0;
137 | }
138 | if (cid1 <= 0 || cid1 >= 65535) {
139 | etCid.setError("cid的值应该是0~65535");
140 | cid1 = 0;
141 | }
142 | lac = lac1;
143 | cid = cid1;
144 | }
145 | // ContentValues contentValues = new ContentValues();
146 | // contentValues.put("package_name", pacakgeName);
147 | // contentValues.put("lac", lac);
148 | // contentValues.put("cid", cid);
149 |
150 | SharedPreferences.Editor editor = sp.edit();
151 | editor.putInt("lac",lac);
152 | editor.putInt("cid",cid);
153 | editor.commit();
154 | }
155 | }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
156 | @Override
157 | public void onClick(DialogInterface dialog, int which) {
158 | dialog.dismiss();
159 | }
160 | }).show();
161 | break;
162 | }
163 | return super.onOptionsItemSelected(item);
164 | }
165 |
166 | private void canCloseDialog(DialogInterface dialogInterface, boolean close) {
167 | try {
168 | Field field = dialogInterface.getClass().getSuperclass().getDeclaredField("mShowing");
169 | field.setAccessible(true);
170 | field.set(dialogInterface, close);
171 | } catch (Exception e) {
172 | e.printStackTrace();
173 | }
174 | }
175 |
176 | @Override
177 | protected void onPause() {
178 | super.onPause();
179 | mv.onPause();
180 | }
181 |
182 | private void search(final String key) {
183 | PoiSearch.Query query = new PoiSearch.Query(key, null, null);
184 | query.setPageSize(10);
185 | query.setPageNum(0);
186 | PoiSearch poiSearch = new PoiSearch(this, query);
187 | poiSearch.setOnPoiSearchListener(new PoiSearch.OnPoiSearchListener() {
188 | @Override
189 | public void onPoiSearched(PoiResult poiResult, int i) {
190 | if (i == 1000) {
191 | final ArrayList poiItems = poiResult.getPois();
192 | if (poiItems.size() != 0) {
193 | String[] keyList = new String[poiItems.size()];
194 | for (int j = 0; j < poiItems.size(); j++) {
195 | keyList[j] = poiItems.get(j).getTitle();
196 | }
197 | new AlertDialog.Builder(AMapActivity.this)
198 | .setTitle("选择位置")
199 | .setSingleChoiceItems(keyList, 0, new DialogInterface.OnClickListener() {
200 | @Override
201 | public void onClick(DialogInterface dialog, int which) {
202 | aMap.moveCamera(CameraUpdateFactory.changeLatLng(new LatLng(poiItems.get(which).getLatLonPoint().getLatitude(), poiItems.get(which).getLatLonPoint().getLongitude())));
203 | aMap.moveCamera(CameraUpdateFactory.zoomTo(aMap.getMaxZoomLevel()));
204 | dialog.dismiss();
205 | }
206 | }).show();
207 | } else {
208 | Toast.makeText(AMapActivity.this, "没有搜索结果", Toast.LENGTH_SHORT).show();
209 | }
210 |
211 | }
212 | }
213 |
214 | @Override
215 | public void onPoiItemSearched(PoiItem poiItem, int i) {
216 |
217 | }
218 | });
219 | poiSearch.searchPOIAsyn();
220 | }
221 |
222 | @Override
223 | protected void onSaveInstanceState(Bundle outState) {
224 | super.onSaveInstanceState(outState);
225 | mv.onSaveInstanceState(outState);
226 | }
227 |
228 | @Override
229 | protected void onDestroy() {
230 | super.onDestroy();
231 | mv.onDestroy();
232 | }
233 |
234 | @Override
235 | public void onMapClick(LatLng latLng) {
236 | aMap.clear();
237 | MarkerOptions markerOptions = new MarkerOptions();
238 | markerOptions.position(latLng);
239 | markerOptions.draggable(true);
240 | markerOptions.title("经度:" + latLng.longitude + ",纬度:" + latLng.latitude);
241 | aMap.addMarker(markerOptions);
242 | this.latLng = latLng;
243 | }
244 | }
245 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lupinus/wework/WeChatWork.java:
--------------------------------------------------------------------------------
1 | package com.lupinus.wework;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import android.database.Cursor;
6 | import android.location.Criteria;
7 | import android.location.GpsStatus;
8 | import android.location.Location;
9 | import android.location.LocationListener;
10 | import android.location.LocationManager;
11 | import android.net.NetworkInfo;
12 | import android.net.Uri;
13 | import android.os.Build;
14 | import android.os.SystemClock;
15 | import android.telephony.CellIdentityCdma;
16 | import android.telephony.CellIdentityGsm;
17 | import android.telephony.CellIdentityLte;
18 | import android.telephony.CellIdentityWcdma;
19 | import android.telephony.CellInfoCdma;
20 | import android.telephony.CellInfoGsm;
21 | import android.telephony.CellInfoLte;
22 | import android.telephony.CellInfoWcdma;
23 | import android.telephony.CellLocation;
24 | import android.telephony.TelephonyManager;
25 | import android.telephony.gsm.GsmCellLocation;
26 | import android.util.Log;
27 |
28 | import java.lang.reflect.Method;
29 | import java.lang.reflect.Modifier;
30 | import java.util.ArrayList;
31 | import java.util.List;
32 | import java.util.Random;
33 |
34 | import de.robv.android.xposed.XC_MethodHook;
35 | import de.robv.android.xposed.XSharedPreferences;
36 | import de.robv.android.xposed.XposedBridge;
37 | import de.robv.android.xposed.XposedHelpers;
38 | import de.robv.android.xposed.callbacks.XC_LoadPackage;
39 |
40 | /**
41 | * Created by luyufa on 2019/4/9.
42 | */
43 |
44 | public class WeChatWork {
45 |
46 | private static String TAG = "WeChatWork";
47 |
48 |
49 | public static void hook() {
50 |
51 | XposedHelpers.findAndHookMethod(Application.class, "attach", Context.class, new XC_MethodHook() {
52 | @Override
53 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
54 | super.afterHookedMethod(param);
55 |
56 | Log.e(TAG, "开始hook微信企业版");
57 |
58 | ClassLoader classLoader = ((Context) param.args[0]).getClassLoader();
59 |
60 | XSharedPreferences xsp = new XSharedPreferences("com.lupinus.wework","HookInfo");
61 | xsp.makeWorldReadable();
62 |
63 | String latitude = xsp.getString("latitude","");
64 | String longitude = xsp.getString("longitude","");
65 | int lac = xsp.getInt("lac",0);
66 | int cid = xsp.getInt("cid",0);
67 | String bssid = xsp.getString("bssid","");
68 | String ssid = xsp.getString("ssid","");
69 |
70 | Log.e(TAG,"latitude = " + latitude);
71 | Log.e(TAG,"longitude = " + longitude);
72 | Log.e(TAG,"lac = " + lac);
73 | Log.e(TAG,"cid = " + cid);
74 | Log.e(TAG,"bssid = " + bssid);
75 | Log.e(TAG,"ssid = " + ssid);
76 |
77 | wifi(classLoader,bssid,ssid);
78 | connectivity(classLoader);
79 | location(classLoader,Double.valueOf(latitude),Double.valueOf(longitude),lac,cid);
80 | }
81 | });
82 | }
83 |
84 | private static void wifi(ClassLoader classLoader, final String bssid, final String ssid){
85 | XposedHelpers.findAndHookMethod("android.net.wifi.WifiInfo", classLoader, "getBSSID", new XC_MethodHook() {
86 | @Override
87 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
88 | super.afterHookedMethod(param);
89 |
90 | //5c:c9:99:34:48:f0
91 |
92 | param.setResult(bssid);
93 | }
94 | });
95 |
96 | XposedHelpers.findAndHookMethod("android.net.wifi.WifiInfo", classLoader, "getSSID", new XC_MethodHook() {
97 | @Override
98 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
99 | super.afterHookedMethod(param);
100 |
101 | //Yatsen
102 |
103 | param.setResult("\"" + ssid + "\"");
104 | }
105 | });
106 |
107 | XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader, "getNetworkType", new XC_MethodHook() {
108 | @Override
109 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
110 | super.afterHookedMethod(param);
111 |
112 | int networkType = 13;
113 | param.setResult(networkType);
114 | }
115 | });
116 | }
117 |
118 | private static void connectivity(ClassLoader classLoader){
119 |
120 | XposedHelpers.findAndHookMethod("android.net.ConnectivityManager", classLoader, "getNetworkInfo",int.class, new XC_MethodHook() {
121 | @Override
122 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
123 | super.afterHookedMethod(param);
124 | int type = (int) param.args[0];
125 | if (type == 1){
126 | Object obj = param.getResult();
127 | XposedHelpers.setObjectField(obj,"mState", NetworkInfo.State.CONNECTED);
128 | }
129 |
130 | }
131 | });
132 | }
133 |
134 | private static void location(ClassLoader classLoader, final double latitude, final double longtitude, final int lac, final int cid) {
135 |
136 | XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader,
137 | "getCellLocation", new XC_MethodHook() {
138 | @Override
139 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
140 | GsmCellLocation gsmCellLocation = new GsmCellLocation();
141 | gsmCellLocation.setLacAndCid(lac, cid);
142 | param.setResult(gsmCellLocation);
143 | }
144 | });
145 |
146 | XposedHelpers.findAndHookMethod("android.telephony.PhoneStateListener", classLoader,
147 | "onCellLocationChanged", CellLocation.class, new XC_MethodHook() {
148 | @Override
149 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
150 | GsmCellLocation gsmCellLocation = new GsmCellLocation();
151 | gsmCellLocation.setLacAndCid(lac, cid);
152 | param.setResult(gsmCellLocation);
153 | }
154 | });
155 |
156 | if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
157 | XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader,
158 | "getPhoneCount", new XC_MethodHook() {
159 | @Override
160 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
161 | param.setResult(1);
162 | }
163 | });
164 | }
165 |
166 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
167 | XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader,
168 | "getNeighboringCellInfo", new XC_MethodHook() {
169 | @Override
170 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
171 | param.setResult(new ArrayList<>());
172 | }
173 | });
174 | }
175 |
176 | if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
177 | XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader,
178 | "getAllCellInfo", new XC_MethodHook() {
179 | @Override
180 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
181 | param.setResult(getCell(460, 0, lac, cid, 0, 0));
182 | }
183 | });
184 | XposedHelpers.findAndHookMethod("android.telephony.PhoneStateListener", classLoader,
185 | "onCellInfoChanged", List.class, new XC_MethodHook() {
186 | @Override
187 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
188 | param.setResult(getCell(460, 0, lac, cid, 0,0));
189 | }
190 | });
191 | }
192 |
193 | XposedHelpers.findAndHookMethod("android.net.wifi.WifiManager", classLoader, "getScanResults", new XC_MethodHook() {
194 | @Override
195 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
196 | param.setResult(new ArrayList<>());
197 | }
198 | });
199 |
200 | XposedHelpers.findAndHookMethod("android.net.wifi.WifiManager", classLoader, "getWifiState", new XC_MethodHook() {
201 | @Override
202 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
203 | param.setResult(1);
204 | }
205 | });
206 |
207 | XposedHelpers.findAndHookMethod("android.net.wifi.WifiManager", classLoader, "isWifiEnabled", new XC_MethodHook() {
208 | @Override
209 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
210 | param.setResult(true);
211 | }
212 | });
213 |
214 | XposedHelpers.findAndHookMethod("android.net.wifi.WifiInfo", classLoader, "getMacAddress", new XC_MethodHook() {
215 | @Override
216 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
217 | param.setResult("00-00-00-00-00-00-00-00");
218 | }
219 | });
220 |
221 |
222 | XposedHelpers.findAndHookMethod("android.net.NetworkInfo", classLoader,
223 | "getTypeName", new XC_MethodHook() {
224 | @Override
225 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
226 | param.setResult("WIFI");
227 | }
228 | });
229 | XposedHelpers.findAndHookMethod("android.net.NetworkInfo", classLoader,
230 | "isConnectedOrConnecting", new XC_MethodHook() {
231 | @Override
232 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
233 | param.setResult(true);
234 | }
235 | });
236 |
237 | XposedHelpers.findAndHookMethod("android.net.NetworkInfo", classLoader,
238 | "isConnected", new XC_MethodHook() {
239 | @Override
240 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
241 | param.setResult(true);
242 | }
243 | });
244 |
245 | XposedHelpers.findAndHookMethod("android.net.NetworkInfo", classLoader,
246 | "isAvailable", new XC_MethodHook() {
247 | @Override
248 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
249 | param.setResult(true);
250 | }
251 | });
252 |
253 | XposedHelpers.findAndHookMethod("android.telephony.CellInfo", classLoader,
254 | "isRegistered", new XC_MethodHook() {
255 | @Override
256 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
257 | param.setResult(true);
258 | }
259 | });
260 |
261 | XposedHelpers.findAndHookMethod(LocationManager.class, "getLastLocation", new XC_MethodHook() {
262 | @Override
263 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
264 | Location l = new Location(LocationManager.GPS_PROVIDER);
265 | l.setLatitude(latitude);
266 | l.setLongitude(longtitude);
267 | l.setAccuracy(100f);
268 | l.setTime(System.currentTimeMillis());
269 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
270 | l.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
271 | }
272 | param.setResult(l);
273 | }
274 | });
275 |
276 | XposedHelpers.findAndHookMethod(LocationManager.class, "getLastKnownLocation", String.class, new XC_MethodHook() {
277 | @Override
278 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
279 | Location l = new Location(LocationManager.GPS_PROVIDER);
280 | l.setLatitude(latitude);
281 | l.setLongitude(longtitude);
282 | l.setAccuracy(100f);
283 | l.setTime(System.currentTimeMillis());
284 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
285 | l.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
286 | }
287 | param.setResult(l);
288 | }
289 | });
290 |
291 |
292 | XposedBridge.hookAllMethods(LocationManager.class, "getProviders", new XC_MethodHook() {
293 | @Override
294 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
295 | ArrayList arrayList = new ArrayList<>();
296 | arrayList.add("gps");
297 | param.setResult(arrayList);
298 | }
299 | });
300 |
301 | XposedHelpers.findAndHookMethod(LocationManager.class, "getBestProvider", Criteria.class, Boolean.TYPE, new XC_MethodHook() {
302 | @Override
303 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
304 | param.setResult("gps");
305 | }
306 | });
307 |
308 | XposedHelpers.findAndHookMethod(LocationManager.class, "addGpsStatusListener", GpsStatus.Listener.class, new XC_MethodHook() {
309 | @Override
310 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
311 | if (param.args[0] != null) {
312 | XposedHelpers.callMethod(param.args[0], "onGpsStatusChanged", 1);
313 | XposedHelpers.callMethod(param.args[0], "onGpsStatusChanged", 3);
314 | }
315 | }
316 | });
317 |
318 | XposedHelpers.findAndHookMethod(LocationManager.class, "addNmeaListener", GpsStatus.NmeaListener.class, new XC_MethodHook() {
319 | @Override
320 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
321 | param.setResult(false);
322 | }
323 | });
324 |
325 | XposedHelpers.findAndHookMethod("android.location.LocationManager", classLoader,
326 | "getGpsStatus", GpsStatus.class, new XC_MethodHook() {
327 | @Override
328 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
329 | GpsStatus gss = (GpsStatus) param.getResult();
330 | if (gss == null)
331 | return;
332 |
333 | Class> clazz = GpsStatus.class;
334 | Method m = null;
335 | for (Method method : clazz.getDeclaredMethods()) {
336 | if (method.getName().equals("setStatus")) {
337 | if (method.getParameterTypes().length > 1) {
338 | m = method;
339 | break;
340 | }
341 | }
342 | }
343 | if (m == null)
344 | return;
345 |
346 | //access the private setStatus function of GpsStatus
347 | m.setAccessible(true);
348 |
349 | //make the apps belive GPS works fine now
350 | int svCount = 5;
351 | int[] prns = {1, 2, 3, 4, 5};
352 | float[] snrs = {0, 0, 0, 0, 0};
353 | float[] elevations = {0, 0, 0, 0, 0};
354 | float[] azimuths = {0, 0, 0, 0, 0};
355 | int ephemerisMask = 0x1f;
356 | int almanacMask = 0x1f;
357 |
358 | //5 satellites are fixed
359 | int usedInFixMask = 0x1f;
360 |
361 | XposedHelpers.callMethod(gss, "setStatus", svCount, prns, snrs, elevations, azimuths, ephemerisMask, almanacMask, usedInFixMask);
362 | param.args[0] = gss;
363 | param.setResult(gss);
364 | try {
365 | m.invoke(gss, svCount, prns, snrs, elevations, azimuths, ephemerisMask, almanacMask, usedInFixMask);
366 | param.setResult(gss);
367 | } catch (Exception e) {
368 | XposedBridge.log(e);
369 | }
370 | }
371 | });
372 |
373 | for (Method method : LocationManager.class.getDeclaredMethods()) {
374 | if (method.getName().equals("requestLocationUpdates")
375 | && !Modifier.isAbstract(method.getModifiers())
376 | && Modifier.isPublic(method.getModifiers())) {
377 | XposedBridge.hookMethod(method, new XC_MethodHook() {
378 | @Override
379 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
380 | if (param.args.length >= 4 && (param.args[3] instanceof LocationListener)) {
381 |
382 | LocationListener ll = (LocationListener) param.args[3];
383 |
384 | Class> clazz = LocationListener.class;
385 | Method m = null;
386 | for (Method method : clazz.getDeclaredMethods()) {
387 | if (method.getName().equals("onLocationChanged") && !Modifier.isAbstract(method.getModifiers())) {
388 | m = method;
389 | break;
390 | }
391 | }
392 | Location l = new Location(LocationManager.GPS_PROVIDER);
393 | l.setLatitude(latitude);
394 | l.setLongitude(longtitude);
395 | l.setAccuracy(10.00f);
396 | l.setTime(System.currentTimeMillis());
397 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
398 | l.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
399 | }
400 | XposedHelpers.callMethod(ll, "onLocationChanged", l);
401 | try {
402 | if (m != null) {
403 | m.invoke(ll, l);
404 | }
405 | } catch (Exception e) {
406 | XposedBridge.log(e);
407 | }
408 | }
409 | }
410 | });
411 | }
412 |
413 | if (method.getName().equals("requestSingleUpdate ")
414 | && !Modifier.isAbstract(method.getModifiers())
415 | && Modifier.isPublic(method.getModifiers())) {
416 | XposedBridge.hookMethod(method, new XC_MethodHook() {
417 | @Override
418 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
419 | if (param.args.length >= 3 && (param.args[1] instanceof LocationListener)) {
420 |
421 | LocationListener ll = (LocationListener) param.args[3];
422 |
423 | Class> clazz = LocationListener.class;
424 | Method m = null;
425 | for (Method method : clazz.getDeclaredMethods()) {
426 | if (method.getName().equals("onLocationChanged") && !Modifier.isAbstract(method.getModifiers())) {
427 | m = method;
428 | break;
429 | }
430 | }
431 |
432 | try {
433 | if (m != null) {
434 | Location l = new Location(LocationManager.GPS_PROVIDER);
435 | l.setLatitude(latitude);
436 | l.setLongitude(longtitude);
437 | l.setAccuracy(100f);
438 | l.setTime(System.currentTimeMillis());
439 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
440 | l.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
441 | }
442 | m.invoke(ll, l);
443 | }
444 | } catch (Exception e) {
445 | XposedBridge.log(e);
446 | }
447 | }
448 | }
449 | });
450 | }
451 | }
452 | }
453 |
454 | private static ArrayList getCell(int mcc, int mnc, int lac, int cid, int sid, int networkType) {
455 | ArrayList arrayList = new ArrayList();
456 | CellInfoGsm cellInfoGsm = (CellInfoGsm) XposedHelpers.newInstance(CellInfoGsm.class);
457 | XposedHelpers.callMethod(cellInfoGsm, "setCellIdentity", XposedHelpers.newInstance(CellIdentityGsm.class, new Object[]{Integer.valueOf(mcc), Integer.valueOf(mnc), Integer.valueOf(
458 | lac), Integer.valueOf(cid)}));
459 | CellInfoCdma cellInfoCdma = (CellInfoCdma) XposedHelpers.newInstance(CellInfoCdma.class);
460 | XposedHelpers.callMethod(cellInfoCdma, "setCellIdentity", XposedHelpers.newInstance(CellIdentityCdma.class, new Object[]{Integer.valueOf(lac), Integer.valueOf(sid), Integer.valueOf(cid), Integer.valueOf(0), Integer.valueOf(0)}));
461 | CellInfoWcdma cellInfoWcdma = (CellInfoWcdma) XposedHelpers.newInstance(CellInfoWcdma.class);
462 | XposedHelpers.callMethod(cellInfoWcdma, "setCellIdentity", XposedHelpers.newInstance(CellIdentityWcdma.class, new Object[]{Integer.valueOf(mcc), Integer.valueOf(mnc), Integer.valueOf(lac), Integer.valueOf(cid), Integer.valueOf(300)}));
463 | CellInfoLte cellInfoLte = (CellInfoLte) XposedHelpers.newInstance(CellInfoLte.class);
464 | XposedHelpers.callMethod(cellInfoLte, "setCellIdentity", XposedHelpers.newInstance(CellIdentityLte.class, new Object[]{Integer.valueOf(mcc), Integer.valueOf(mnc), Integer.valueOf(cid), Integer.valueOf(300), Integer.valueOf(lac)}));
465 | if (networkType == 1 || networkType == 2) {
466 | arrayList.add(cellInfoGsm);
467 | } else if (networkType == 13) {
468 | arrayList.add(cellInfoLte);
469 | } else if (networkType == 4 || networkType == 5 || networkType == 6 || networkType == 7 || networkType == 12 || networkType == 14) {
470 | arrayList.add(cellInfoCdma);
471 | } else if (networkType == 3 || networkType == 8 || networkType == 9 || networkType == 10 || networkType == 15) {
472 | arrayList.add(cellInfoWcdma);
473 | }
474 | return arrayList;
475 | }
476 | }
477 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lupinus/wework/RootCloak.java:
--------------------------------------------------------------------------------
1 | package com.lupinus.wework;
2 |
3 | import android.app.ActivityManager.RunningAppProcessInfo;
4 | import android.app.ActivityManager.RunningServiceInfo;
5 | import android.app.ActivityManager.RunningTaskInfo;
6 | import android.content.ContentResolver;
7 | import android.content.pm.ApplicationInfo;
8 | import android.content.pm.PackageInfo;
9 | import android.os.Build;
10 | import android.os.StrictMode;
11 | import android.provider.Settings;
12 | import android.text.TextUtils;
13 |
14 | import java.io.File;
15 | import java.io.IOException;
16 | import java.lang.reflect.Constructor;
17 | import java.net.URI;
18 | import java.util.ArrayList;
19 | import java.util.Arrays;
20 | import java.util.HashSet;
21 | import java.util.Iterator;
22 | import java.util.List;
23 | import java.util.Set;
24 |
25 | import de.robv.android.xposed.IXposedHookLoadPackage;
26 | import de.robv.android.xposed.XC_MethodHook;
27 | import de.robv.android.xposed.XC_MethodReplacement;
28 | import de.robv.android.xposed.XposedBridge;
29 | import de.robv.android.xposed.XposedHelpers;
30 | import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
31 | import de.robv.android.xposed.callbacks.XCallback;
32 |
33 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
34 | import static de.robv.android.xposed.XposedHelpers.findConstructorExact;
35 |
36 | /**
37 | * Created by luyufa on 2019/4/8.
38 | */
39 |
40 | public class RootCloak implements IXposedHookLoadPackage {
41 | private static final String FAKE_COMMAND = "FAKEJUNKCOMMAND";
42 | private static final String FAKE_FILE = "FAKEJUNKFILE";
43 | private static final String FAKE_PACKAGE = "FAKE.JUNK.PACKAGE";
44 | private static final String FAKE_APPLICATION = "FAKE.JUNK.APPLICATION";
45 |
46 | private Set appSet;
47 | private Set keywordSet;
48 | private Set commandSet;
49 | private Set libnameSet;
50 | private boolean debugPref;
51 | private boolean isRootCloakLoadingPref = false;
52 | private String listApp;
53 |
54 | public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
55 | loadPrefs(); // 加载首选项为任何应用程序。 这样我们可以确定它是否匹配应用程序列表以隐藏根。
56 | /* if (debugPref) {
57 | XposedBridge.log("Found app: " + lpparam.packageName);
58 | }*/
59 |
60 | if (!(appSet.contains(lpparam.packageName))) { // 如果应用程序不匹配,请勿钩住任何东西,只需返回。
61 | return;
62 | }
63 |
64 | if (debugPref) {
65 | XposedBridge.log("加载应用程式:" + lpparam.packageName);
66 | }
67 |
68 | // 做所有的钩子
69 | initOther(lpparam);
70 | initFile(lpparam);
71 | initPackageManager(lpparam);
72 | initActivityManager(lpparam);
73 | initRuntime(lpparam);
74 | initProcessBuilder(lpparam);
75 | initSettingsGlobal(lpparam);
76 | }
77 |
78 | /**
79 | * 处理一堆杂项钩。
80 | */
81 | private void initOther(final LoadPackageParam lpparam) {
82 | // 检查调试是否开启时始终返回false
83 | XposedHelpers.findAndHookMethod("android.os.Debug", lpparam.classLoader, "isDebuggerConnected", XC_MethodReplacement.returnConstant(false));
84 |
85 | //如果测试键,更改为释放键
86 | if (!Build.TAGS.equals("release-keys")) {
87 | if (debugPref) {
88 | XposedBridge.log("原始构建标签: " + Build.TAGS);
89 | }
90 | XposedHelpers.setStaticObjectField(Build.class, "TAGS", "release-keys");
91 | if (debugPref) {
92 | XposedBridge.log("新建标签: " + Build.TAGS);
93 | }
94 | } else {
95 | if (debugPref) {
96 | XposedBridge.log("无需更改构建标签: " + Build.TAGS);
97 | }
98 | }
99 |
100 | // 告诉SELinux正在执行的应用程序,即使不是。
101 | findAndHookMethod("android.os.SystemProperties", lpparam.classLoader, "get", String.class , new XC_MethodHook() {
102 | @Override
103 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
104 | if (((String) param.args[0]).equals("ro.build.selinux")) {
105 | param.setResult("1");
106 | if (debugPref) {
107 | XposedBridge.log("SELinux is enforced.");
108 | }
109 | }
110 | }
111 | });
112 |
113 | // 从应用程序隐藏Xposed类
114 | findAndHookMethod("java.lang.Class", lpparam.classLoader, "forName", String.class, boolean.class, ClassLoader.class, new XC_MethodHook() {
115 | @Override
116 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
117 | String classname = (String) param.args[0];
118 |
119 | if (classname != null && (classname.equals("de.robv.android.xposed.XposedBridge") || classname.equals("de.robv.android.xposed.XC_MethodReplacement"))) {
120 | param.setThrowable(new ClassNotFoundException());
121 | if (debugPref) {
122 | XposedBridge.log("找到并隐藏Xposed类名称:" + classname);
123 | }
124 | }
125 | }
126 | });
127 | }
128 |
129 | /**
130 | * 处理与java.io.File相关的所有钩子。
131 | */
132 | private void initFile(final LoadPackageParam lpparam) {
133 | /**
134 | 挂钩File文件的一个版本。
135 | 一个应用程序可能会使用文件检查存在的文件,如su,busybox或其他文件。
136 | */
137 | Constructor> constructLayoutParams = findConstructorExact(File.class, String.class);
138 | XposedBridge.hookMethod(constructLayoutParams, new XC_MethodHook(XCallback.PRIORITY_HIGHEST) {
139 | @Override
140 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
141 | if (param.args[0] != null) {
142 | if (debugPref) {
143 | XposedBridge.log("File: Found a File constructor: " + ((String) param.args[0]));
144 | }
145 | }
146 |
147 | if (isRootCloakLoadingPref) {
148 | // RootCloak试图加载它的首选项,我们不应该阻止这个。
149 | return;
150 | }
151 |
152 | if (((String) param.args[0]).endsWith("su")) {
153 | if (debugPref) {
154 | XposedBridge.log("File: Found a File constructor ending with su");
155 | }
156 | param.args[0] = "/system/xbin/" + FAKE_FILE;
157 | } else if (((String) param.args[0]).endsWith("busybox")) {
158 | if (debugPref) {
159 | XposedBridge.log("File: Found a File constructor ending with busybox");
160 | }
161 | param.args[0] = "/system/xbin/" + FAKE_FILE;
162 | } else if (stringContainsFromSet(((String) param.args[0]), keywordSet)) {
163 | if (debugPref) {
164 | XposedBridge.log("File: Found a File constructor with word super, noshufou, or chainfire");
165 | }
166 | param.args[0] = "/system/app/" + FAKE_FILE + ".apk";
167 | }
168 | }
169 | });
170 |
171 | /**
172 | 钩住File构造函数的一个版本。
173 | 一个应用程序可能会使用文件检查存在的文件,如su,busybox或其他文件。
174 | */
175 | Constructor> extendedFileConstructor = findConstructorExact(File.class, String.class, String.class);
176 | XposedBridge.hookMethod(extendedFileConstructor, new XC_MethodHook(XCallback.PRIORITY_HIGHEST) {
177 | @Override
178 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
179 | if (param.args[0] != null && param.args[1] != null) {
180 | if (debugPref) {
181 | XposedBridge.log("File: Found a File constructor: " + ((String) param.args[0]) + ", with: " + ((String) param.args[1]));
182 | }
183 | }
184 |
185 | if (isRootCloakLoadingPref) {
186 | // RootCloak试图加载它的首选项,我们不应该阻止这个。
187 | return;
188 | }
189 |
190 | if (((String) param.args[1]).equalsIgnoreCase("su")) {
191 | if (debugPref) {
192 | XposedBridge.log("文件:找到一个文件名为su的File构造函数");
193 | }
194 | param.args[1] = FAKE_FILE;
195 | } else if (((String) param.args[1]).contains("busybox")) {
196 | if (debugPref) {
197 | XposedBridge.log("文件:找到一个以busybox结尾的文件构造函数");
198 | }
199 | param.args[1] = FAKE_FILE;
200 | } else if (stringContainsFromSet(((String) param.args[1]), keywordSet)) {
201 | if (debugPref) {
202 | XposedBridge.log("文件:找到一个文件构造函数,带有super,noshufou或chainfire");
203 | }
204 | param.args[1] = FAKE_FILE + ".apk";
205 | }
206 | }
207 | });
208 |
209 | /**
210 | 钩住使用URI的File构造函数的一个版本。
211 | 一个应用程序可能会使用文件检查存在的文件,如su,busybox或其他文件。
212 | 注意:目前仅用于调试目的,通常不会使用。
213 | */
214 | Constructor> uriFileConstructor = findConstructorExact(File.class, URI.class);
215 | XposedBridge.hookMethod(uriFileConstructor, new XC_MethodHook(XCallback.PRIORITY_HIGHEST) {
216 | @Override
217 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
218 | if (param.args[0] != null) {
219 | if (debugPref) {
220 | XposedBridge.log("文件:找到一个URI文件构造函数: " + ((URI) param.args[0]).toString());
221 | }
222 | }
223 | }
224 | });
225 | }
226 |
227 | /**
228 | * 处理与PackageManager相关的所有挂钩。
229 | */
230 | private void initPackageManager(final LoadPackageParam lpparam) {
231 | /**
232 | 钩子在PackageManager中获取安装应用程序。
233 | *应用程式可以通过这种方式检查其他应用程式。 在有根设备的上下文中,应用程序可能会查找SuperSU,Xposed,Superuser或其他。
234 | *匹配关键字集中的条目的结果将被隐藏。
235 | */
236 | findAndHookMethod("android.app.ApplicationPackageManager", lpparam.classLoader, "getInstalledApplications", int.class, new XC_MethodHook() {
237 | @SuppressWarnings("unchecked")
238 | @Override
239 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { // Hook after getIntalledApplications is called
240 | if (debugPref) {
241 | XposedBridge.log("Hooked getInstalledApplications");
242 | }
243 |
244 | List packages = (List) param.getResult(); // Get the results from the method call
245 | Iterator iter = packages.iterator();
246 | ApplicationInfo tempAppInfo;
247 | String tempPackageName;
248 |
249 | // 通过ApplicationInfo列表迭代,并删除与keywordSet中的关键字匹配的任何提及
250 | while (iter.hasNext()) {
251 | tempAppInfo = iter.next();
252 | tempPackageName = tempAppInfo.packageName;
253 | if (tempPackageName != null && stringContainsFromSet(tempPackageName, keywordSet)) {
254 | iter.remove();
255 | if (debugPref) {
256 | XposedBridge.log("找到并隐藏包:" + tempPackageName);
257 | }
258 | }
259 | }
260 |
261 | param.setResult(packages); // 将返回值设置为干净列表
262 | }
263 | });
264 |
265 | /**
266 | Hooks在PackageManager中getInstalledPackages。
267 | 应用程式可以通过这种方式检查其他应用程式。 在有根设备的上下文中,应用程序可能会查找SuperSU,Xposed,Superuser或其他。
268 | 匹配关键字集中的条目的结果将被隐藏。
269 | */
270 | findAndHookMethod("android.app.ApplicationPackageManager", lpparam.classLoader, "getInstalledPackages", int.class, new XC_MethodHook() {
271 | @SuppressWarnings("unchecked")
272 | @Override
273 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { // Hook after getInstalledPackages is called
274 | if (debugPref) {
275 | XposedBridge.log("Hooked getInstalledPackages");
276 | }
277 |
278 | List packages = (List) param.getResult(); // Get the results from the method call
279 | Iterator iter = packages.iterator();
280 | PackageInfo tempPackageInfo;
281 | String tempPackageName;
282 |
283 | // 通过PackageInfo列表迭代,并删除与keywordSet中的关键字匹配的任何提及
284 | while (iter.hasNext()) {
285 | tempPackageInfo = iter.next();
286 | tempPackageName = tempPackageInfo.packageName;
287 | if (tempPackageName != null && stringContainsFromSet(tempPackageName, keywordSet)) {
288 | iter.remove();
289 | if (debugPref) {
290 | XposedBridge.log("找到并隐藏包:" + tempPackageName);
291 | }
292 | }
293 | }
294 |
295 | param.setResult(packages); // 将返回值设置为干净列表
296 | }
297 | });
298 |
299 | /**
300 | 在PackageManager中挂钩getPackageInfo。
301 | *应用程序可以以这种方式检查其他包。 我们在getPackageInfo被调用之前钩。
302 | *如果正在查看的包与keywordSet中的条目匹配,则替换假包名称。
303 | *这将最终抛出一个PackageManager.NameNotFoundException。
304 | */
305 | findAndHookMethod("android.app.ApplicationPackageManager", lpparam.classLoader, "getPackageInfo", String.class, int.class, new XC_MethodHook() {
306 | @Override
307 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
308 | if (debugPref) {
309 | XposedBridge.log("Hooked getPackageInfo");
310 | }
311 | String name = (String) param.args[0];
312 |
313 | if (name != null && stringContainsFromSet(name, keywordSet)) {
314 | param.args[0] = FAKE_PACKAGE; // 设置假包名称
315 | if (debugPref) {
316 | XposedBridge.log("设置假包名称: " + name);
317 | }
318 | }
319 | }
320 | });
321 |
322 | /**
323 | Hooks在PackageManager中获取getApplicationInfo。
324 | *应用程序可以通过这种方式检查其他应用程序。 我们在getApplicationInfo被调用之前钩。
325 | *如果正在查看的应用程序与keywordSet中的条目匹配,则替换假冒的应用程序名称。
326 | *这将最终抛出一个PackageManager.NameNotFoundException。
327 | */
328 | findAndHookMethod("android.app.ApplicationPackageManager", lpparam.classLoader, "getApplicationInfo", String.class, int.class, new XC_MethodHook() {
329 | @Override
330 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
331 |
332 | String name = (String) param.args[0];
333 | if (debugPref) {
334 | XposedBridge.log("Hooked getApplicationInfo : " + name);
335 | }
336 |
337 | if (name != null && stringContainsFromSet(name, keywordSet)) {
338 | param.args[0] = FAKE_APPLICATION; // 设置一个假的应用程序名称
339 | if (debugPref) {
340 | XposedBridge.log("发现和隐藏应用程序: " + name);
341 | }
342 | }
343 | }
344 | });
345 | }
346 |
347 | /**
348 | * 处理与ActivityManager相关的所有挂钩。
349 | */
350 | private void initActivityManager(final LoadPackageParam lpparam) {
351 | /**
352 | Hooks在ActivityManager中getRunningServices。
353 | *应用程式可以通过这种方式检查其他应用程式。 在有根设备的上下文中,应用程序可能会查找SuperSU,Xposed,Superuser或其他。
354 | *匹配关键字集中的条目的结果将被隐藏。
355 | */
356 | findAndHookMethod("android.app.ActivityManager", lpparam.classLoader, "getRunningServices", int.class, new XC_MethodHook() {
357 | @SuppressWarnings("unchecked")
358 | @Override
359 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { // Hook after getRunningServices is called
360 | if (debugPref) {
361 | XposedBridge.log("Hooked getRunningServices");
362 | }
363 |
364 | List services = (List) param.getResult(); // 从方法调用获取结果
365 | Iterator iter = services.iterator();
366 | RunningServiceInfo tempService;
367 | String tempProcessName;
368 |
369 | // 通过RunningServiceInfo列表迭代,并删除与keywordSet中的关键字匹配的任何提及
370 | while (iter.hasNext()) {
371 | tempService = iter.next();
372 | tempProcessName = tempService.process;
373 | if (tempProcessName != null && stringContainsFromSet(tempProcessName, keywordSet)) {
374 | iter.remove();
375 | if (debugPref) {
376 | XposedBridge.log("发现和隐藏服务: " + tempProcessName);
377 | }
378 | }
379 | }
380 |
381 | param.setResult(services); //将返回值设置为干净列表
382 | }
383 | });
384 |
385 | /**
386 | Hooks在ActivityManager中getRunningTasks。
387 | *应用程式可以通过这种方式检查其他应用程式。 在有根设备的上下文中,应用程序可能会查找SuperSU,Xposed,Superuser或其他。
388 | *匹配关键字集中的条目的结果将被隐藏。
389 | */
390 | findAndHookMethod("android.app.ActivityManager", lpparam.classLoader, "getRunningTasks", int.class, new XC_MethodHook() {
391 | @SuppressWarnings("unchecked")
392 | @Override
393 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { // Hook after getRunningTasks is called
394 | if (debugPref) {
395 | XposedBridge.log("Hooked getRunningTasks");
396 | }
397 |
398 | List services = (List) param.getResult(); // 从方法调用获取结果
399 | Iterator iter = services.iterator();
400 | RunningTaskInfo tempTask;
401 | String tempBaseActivity;
402 |
403 | // 通过RunningTaskInfo列表迭代,并删除与keywordSet中的关键字匹配的任何提及
404 | while (iter.hasNext()) {
405 | tempTask = iter.next();
406 | tempBaseActivity = tempTask.baseActivity.flattenToString(); // Need to make it a string for comparison
407 | if (tempBaseActivity != null && stringContainsFromSet(tempBaseActivity, keywordSet)) {
408 | iter.remove();
409 | if (debugPref) {
410 | XposedBridge.log("找到并隐藏BaseActivity: " + tempBaseActivity);
411 | }
412 | }
413 | }
414 |
415 | param.setResult(services); // 将返回值设置为干净列表
416 | }
417 | });
418 |
419 | /**
420 | Hooks在ActivityManager中getRunningAppProcesses。
421 | 应用程式可以通过这种方式检查其他应用程式。 在有根设备的上下文中,
422 | 应用程序可能会查找SuperSU,Xposed,Superuser或其他。 匹配关键字集中的条目的结果将被隐藏。
423 |
424 | */
425 | findAndHookMethod("android.app.ActivityManager", lpparam.classLoader, "getRunningAppProcesses", new XC_MethodHook() {
426 | @SuppressWarnings("unchecked")
427 | @Override
428 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { // Hook after getRunningAppProcesses is called
429 | if (debugPref) {
430 | XposedBridge.log("Hooked getRunningAppProcesses");
431 | }
432 |
433 | List processes = (List) param.getResult(); // Get the results from the method call
434 | Iterator iter = processes.iterator();
435 | RunningAppProcessInfo tempProcess;
436 | String tempProcessName;
437 |
438 | // 通过RunningAppProcessInfo列表迭代,并删除与keywordSet中的关键字匹配的任何提及
439 | while (iter.hasNext()) {
440 | tempProcess = iter.next();
441 | tempProcessName = tempProcess.processName;
442 | if (tempProcessName != null && stringContainsFromSet(tempProcessName, keywordSet)) {
443 | iter.remove();
444 | if (debugPref) {
445 | XposedBridge.log("发现和隐藏过程: " + tempProcessName);
446 | }
447 | }
448 | }
449 |
450 | param.setResult(processes); // 将返回值设置为干净列表
451 | }
452 | });
453 | }
454 |
455 | /**
456 | * 处理与java.lang.Runtime相关的所有钩子,它用于执行其他程序或shell命令。
457 | */
458 | private void initRuntime(final LoadPackageParam lpparam) {
459 | /**
460 | 钩住java.lang.Runtime中的exec()。
461 | *这是唯一需要挂钩的版本,因为所有其他版本都是“方便”的变体。
462 | *形式为:exec(String [] cmdarray,String [] envp,File dir)。
463 | *有很多不同的方式可以使用exec来检查根设备。
464 | */
465 | findAndHookMethod("java.lang.Runtime", lpparam.classLoader, "exec", String[].class, String[].class, File.class, new XC_MethodHook() {
466 | @Override
467 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
468 | if (debugPref) {
469 | XposedBridge.log("Hooked Runtime.exec");
470 | }
471 |
472 | String[] execArray = (String[]) param.args[0]; //抓住令牌化的命令数组
473 | if ((execArray != null) && (execArray.length >= 1)) { // Do some checking so we don't break anything
474 | String firstParam = execArray[0]; // firstParam将是正在运行的主要命令/程序
475 | if (debugPref) { // 如果调试已打开,请打印出所调用的内容
476 | String tempString = "Exec Command:";
477 | for (String temp : execArray) {
478 | tempString = tempString + " " + temp;
479 | }
480 | XposedBridge.log(tempString);
481 | }
482 |
483 | if (stringEndsWithFromSet(firstParam, commandSet)) { // 检查firstParam是否是我们要过滤的关键字之一
484 | if (debugPref) {
485 | XposedBridge.log("Found blacklisted command at the end of the string: " + firstParam);
486 | }
487 |
488 | // 解决方案依赖于哪个命令被调用了一堆逻辑
489 | // TODO: ***Clean up this logic***
490 | if (firstParam.equals("su") || firstParam.endsWith("/su")) { // 如果它的su或以su结尾(/ bin / su,/ xbin / su等)
491 | param.setThrowable(new IOException()); //抛出异常,暗示没有找到命令
492 | } else if (commandSet.contains("pm") && (firstParam.equals("pm") || firstParam.endsWith("/pm"))) {
493 | // 尝试使用exec运行pm(包管理器)。 现在我们来处理这些子句
494 | if (execArray.length >= 3 && execArray[1].equalsIgnoreCase("list") && execArray[2].equalsIgnoreCase("packages")) {
495 | // 试图列出所有的软件包,所以我们将筛选出与关键字匹配的任何内容
496 | //param.args[0] = new String[] {"pm", "list", "packages", "-v", "grep", "-v", "\"su\""};
497 | param.args[0] = buildGrepArraySingle(execArray, true);
498 | } else if (execArray.length >= 3 && (execArray[1].equalsIgnoreCase("dump") || execArray[1].equalsIgnoreCase("path"))) {
499 |
500 | if (stringContainsFromSet(execArray[2], keywordSet)) {
501 | param.args[0] = new String[]{execArray[0], execArray[1], FAKE_PACKAGE};
502 | }
503 | }
504 | } else if (commandSet.contains("ps") && (firstParam.equals("ps") || firstParam.endsWith("/ps"))) { // This is a process list command
505 | // 尝试运行ps命令以查看正在运行的进程(例如,查找以su或daemonsu运行的方式)。 过滤出来
506 | param.args[0] = buildGrepArraySingle(execArray, true);
507 | } else if (commandSet.contains("which") && (firstParam.equals("which") || firstParam.endsWith("/which"))) {
508 | // Busybox“哪个”命令。 抛出异常
509 | param.setThrowable(new IOException());
510 | } else if (commandSet.contains("busybox") && anyWordEndingWithKeyword("busybox", execArray)) {
511 | param.setThrowable(new IOException());
512 | } else if (commandSet.contains("sh") && (firstParam.equals("sh") || firstParam.endsWith("/sh"))) {
513 | param.setThrowable(new IOException());
514 | } else {
515 | param.setThrowable(new IOException());
516 | }
517 |
518 | if (debugPref && param.getThrowable() == null) { // Print out the new command if debugging is on
519 | String tempString = "New Exec Command:";
520 | for (String temp : (String[]) param.args[0]) {
521 | tempString = tempString + " " + temp;
522 | }
523 | XposedBridge.log(tempString);
524 | }
525 | }
526 |
527 |
528 | } else {
529 | if (debugPref) {
530 | XposedBridge.log("执行时空或空数组");
531 | }
532 | }
533 | }
534 | });
535 |
536 | /**
537 | * 挂钩在java.lang.Runtime中loadLibrary()。
538 | 有专门为检查根目录的库。 这有助于我们阻止
539 | */
540 | findAndHookMethod("java.lang.Runtime", lpparam.classLoader, "loadLibrary", String.class, ClassLoader.class, new XC_MethodHook() {
541 | @Override
542 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
543 | if (debugPref) {
544 | XposedBridge.log("Hooked loadLibrary");
545 | }
546 | String libname = (String) param.args[0];
547 |
548 | if (libname != null && stringContainsFromSet(libname, libnameSet)) {
549 | // 如果我们找到我们阻止的一个库,那么我们来防止它被加载
550 | param.setResult(null);
551 | if (debugPref) {
552 | XposedBridge.log("Loading of library " + libname + " disabled.");
553 | }
554 | }
555 | }
556 | });
557 | }
558 |
559 | private void initProcessBuilder(final LoadPackageParam lpparam) {
560 | // Hook ProcessBuilder并防止运行某些命令
561 | Constructor> processBuilderConstructor2 = findConstructorExact(ProcessBuilder.class, String[].class);
562 | XposedBridge.hookMethod(processBuilderConstructor2, new XC_MethodHook(XCallback.PRIORITY_HIGHEST) {
563 | @Override
564 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
565 | XposedBridge.log("Hooked ProcessBuilder");
566 | if (param.args[0] != null) {
567 | String[] cmdArray = (String[]) param.args[0];
568 | if (debugPref) {
569 | String tempString = "ProcessBuilder Command:";
570 | for (String temp : cmdArray) {
571 | tempString = tempString + " " + temp;
572 | }
573 | XposedBridge.log(tempString);
574 | }
575 | if (stringEndsWithFromSet(cmdArray[0], commandSet)) {
576 | cmdArray[0] = FAKE_COMMAND;
577 | param.args[0] = cmdArray;
578 | }
579 |
580 | if (debugPref) {
581 | String tempString = "New ProcessBuilder Command:";
582 | for (String temp : (String[]) param.args[0]) {
583 | tempString = tempString + " " + temp;
584 | }
585 | XposedBridge.log(tempString);
586 | }
587 | }
588 | }
589 | });
590 | }
591 |
592 | /**
593 | * 挂钩设备设置。
594 | */
595 | private void initSettingsGlobal(final LoadPackageParam lpparam) {
596 | // Hooks Settings.Global.getInt。 对于这种方法,我们将阻止列表中任何应用程序获取包信息
597 | findAndHookMethod(Settings.Global.class, "getInt", ContentResolver.class, String.class, int.class, new XC_MethodHook() {
598 | @Override
599 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
600 |
601 | String setting = (String) param.args[1];
602 | if (setting != null && Settings.Global.ADB_ENABLED.equals(setting)) { // Hide ADB being on from an app
603 | param.setResult(0);
604 | if (debugPref) {
605 | XposedBridge.log("挂钩ADB调试信息,adb状态关闭");
606 | }
607 | }
608 | }
609 | });
610 | }
611 |
612 | /**
613 | * 加载所有首选项,如关键字,命令等。
614 | */
615 | public void loadPrefs() {
616 | StrictMode.ThreadPolicy old = StrictMode.getThreadPolicy();
617 | StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder(old)
618 | .permitDiskReads()
619 | .permitDiskWrites()
620 | .build());
621 |
622 | isRootCloakLoadingPref = true;
623 |
624 | try {
625 |
626 | keywordSet = new HashSet();
627 | commandSet = new HashSet();
628 | libnameSet = new HashSet();
629 |
630 | keywordSet.isEmpty();
631 | commandSet.isEmpty();
632 | libnameSet.isEmpty();
633 |
634 | appSet = Common.DEFAULT_APPS_SET;
635 |
636 | if (keywordSet.isEmpty()) {
637 | keywordSet = Common.DEFAULT_KEYWORD_SET;
638 | }
639 | if (commandSet.isEmpty()) {
640 | commandSet = Common.DEFAULT_COMMAND_SET;
641 | }
642 | if (libnameSet.isEmpty()) {
643 | libnameSet = Common.DEFAULT_LIBNAME_SET;
644 | }
645 | } finally {
646 | StrictMode.setThreadPolicy(old);
647 |
648 | isRootCloakLoadingPref = false;
649 | }
650 |
651 | }
652 |
653 | public static List getAppset(String parramString) {
654 | if (TextUtils.isEmpty(parramString)) {
655 | return null;
656 | }
657 | return Arrays.asList(TextUtils.split(parramString.replace(" ", ""), ","));
658 | }
659 |
660 |
661 |
662 |
663 | /**
664 | * 获取一个关键字字符串和一个字符串数组,并检查该数组中的任何值是否以关键字结尾
665 | */
666 | private Boolean anyWordEndingWithKeyword(String keyword, String[] wordArray) {
667 | for (String tempString : wordArray) {
668 | if (tempString.endsWith(keyword)) {
669 | return true;
670 | }
671 | }
672 | return false;
673 | }
674 |
675 | /**
676 | * 获取字符串和一组字符串,并检查基本字符串是否包含集合中的任何值。
677 | */
678 | public boolean stringContainsFromSet(String base, Set values) {
679 | if (base != null && values != null) {
680 | for (String tempString : values) {
681 | if (base.matches(".*(\\W|^)" + tempString + "(\\W|$).*")) {
682 | return true;
683 | }
684 | }
685 | }
686 |
687 | return false;
688 | }
689 |
690 | /**
691 | * 使用字符串和一组字符串,并检查基本字符串是否以该集合中的任何值结尾。
692 | */
693 | public boolean stringEndsWithFromSet(String base, Set values) {
694 | if (base != null && values != null) {
695 | for (String tempString : values) {
696 | if (base.endsWith(tempString)) {
697 | return true;
698 | }
699 | }
700 | }
701 |
702 | return false;
703 | }
704 |
705 | /**
706 | * 这个帮手需要一个命令,并附加了很多的grep。 这个想法是过滤出与keywordSet匹配的任何内容。
707 | */
708 | private String[] buildGrepArraySingle(String[] original, boolean addSH) {
709 | StringBuilder builder = new StringBuilder();
710 | ArrayList originalList = new ArrayList();
711 | if (addSH) {
712 | originalList.add("sh");
713 | originalList.add("-c");
714 | }
715 | for (String temp : original) {
716 | builder.append(" ");
717 | builder.append(temp);
718 | }
719 |
720 |
721 | for (String temp : keywordSet) {
722 | builder.append(" | grep -v ");
723 | builder.append(temp);
724 | }
725 |
726 |
727 | originalList.add(builder.toString());
728 | return originalList.toArray(new String[0]);
729 | }
730 |
731 | }
732 |
--------------------------------------------------------------------------------