131 |
132 |
133 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/AndHook/dexmaker/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'java'
2 | //apply from: "$rootDir/gradle/publishing.gradle"
3 |
4 | //version = VERSION_NAME
5 | description = "A utility for doing compile or runtime code generation targeting Android's Dalvik VM"
6 |
7 | targetCompatibility = '1.7'
8 | sourceCompatibility = '1.7'
9 |
10 | repositories {
11 | jcenter()
12 | }
13 |
14 | dependencies {
15 | compile 'com.jakewharton.android.repackaged:dalvik-dx:7.1.0_r7'
16 |
17 | testCompile 'junit:junit:4.12'
18 | }
19 |
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/AppDataDirGuesser.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/AppDataDirGuesser.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$1.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$10.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$10.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$11.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$11.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$2.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$3.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$3.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$4.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$4.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$5.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$5.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$6.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$6.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$7.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$7.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$8.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$8.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$9.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp$9.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/BinaryOp.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/Code.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/Code.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/Comparison$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/Comparison$1.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/Comparison$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/Comparison$2.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/Comparison$3.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/Comparison$3.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/Comparison$4.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/Comparison$4.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/Comparison$5.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/Comparison$5.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/Comparison$6.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/Comparison$6.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/Comparison.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/Comparison.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/Constants.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/Constants.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/DexMaker$FieldDeclaration.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/DexMaker$FieldDeclaration.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/DexMaker$MethodDeclaration.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/DexMaker$MethodDeclaration.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/DexMaker$TypeDeclaration.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/DexMaker$TypeDeclaration.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/DexMaker.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/DexMaker.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/FieldId.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/FieldId.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/Label.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/Label.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/Local.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/Local.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/MethodId.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/MethodId.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/TypeId.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/TypeId.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/TypeList.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/TypeList.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/UnaryOp$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/UnaryOp$1.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/UnaryOp$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/UnaryOp$2.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/UnaryOp.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/UnaryOp.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/stock/ProxyBuilder$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/stock/ProxyBuilder$1.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/stock/ProxyBuilder$MethodSetEntry.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/stock/ProxyBuilder$MethodSetEntry.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/classes/main/com/android/dx/stock/ProxyBuilder.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/classes/main/com/android/dx/stock/ProxyBuilder.class
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/libs/dexmaker.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/build/libs/dexmaker.jar
--------------------------------------------------------------------------------
/AndHook/dexmaker/build/tmp/jar/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 |
3 |
--------------------------------------------------------------------------------
/AndHook/dexmaker/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/panhongwei/AndroidMethodHook/c2b351790654b08e93a1fbadb7d5e6cb4ba043ed/AndHook/dexmaker/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/AndHook/dexmaker/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
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-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/AndHook/dexmaker/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 |
--------------------------------------------------------------------------------
/AndHook/dexmaker/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 |
--------------------------------------------------------------------------------
/AndHook/dexmaker/local.properties:
--------------------------------------------------------------------------------
1 | ## This file is automatically generated by Android Studio.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked into Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 | #
7 | # Location of the SDK. This is only used by Gradle.
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | #Mon Aug 07 17:51:55 CST 2017
11 | ndk.dir=/Users/panda/myenv/android-sdk-macosx/ndk-bundle
12 | sdk.dir=/Users/panda/myenv/android-sdk-macosx
13 |
--------------------------------------------------------------------------------
/AndHook/dexmaker/src/main/java/com/android/dx/AppDataDirGuesser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2012 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.dx;
18 |
19 | import java.io.File;
20 | import java.lang.reflect.Field;
21 | import java.util.ArrayList;
22 | import java.util.List;
23 |
24 | /**
25 | * Uses heuristics to guess the application's private data directory.
26 | */
27 | class AppDataDirGuesser {
28 | public File guess() {
29 | try {
30 | ClassLoader classLoader = guessSuitableClassLoader();
31 | // Check that we have an instance of the PathClassLoader.
32 | Class> clazz = Class.forName("dalvik.system.PathClassLoader");
33 | clazz.cast(classLoader);
34 | // Use the toString() method to calculate the data directory.
35 | String pathFromThisClassLoader = getPathFromThisClassLoader(classLoader, clazz);
36 | File[] results = guessPath(pathFromThisClassLoader);
37 | if (results.length > 0) {
38 | return results[0];
39 | }
40 | } catch (ClassCastException ignored) {
41 | } catch (ClassNotFoundException ignored) {
42 | }
43 | return null;
44 | }
45 |
46 | private ClassLoader guessSuitableClassLoader() {
47 | return AppDataDirGuesser.class.getClassLoader();
48 | }
49 |
50 | private String getPathFromThisClassLoader(ClassLoader classLoader, Class> pathClassLoaderClass) {
51 | // Prior to ICS, we can simply read the "path" field of the
52 | // PathClassLoader.
53 | try {
54 | Field pathField = pathClassLoaderClass.getDeclaredField("path");
55 | pathField.setAccessible(true);
56 | return (String) pathField.get(classLoader);
57 | } catch (NoSuchFieldException ignored) {
58 | } catch (IllegalAccessException ignored) {
59 | } catch (ClassCastException ignored) {
60 | }
61 |
62 | // Parsing toString() method: yuck. But no other way to get the path.
63 | String result = classLoader.toString();
64 | return processClassLoaderString(result);
65 | }
66 |
67 | /**
68 | * Given the result of a ClassLoader.toString() call, process the result so that guessPath
69 | * can use it. There are currently two variants. For Android 4.3 and later, the string
70 | * "DexPathList" should be recognized and the array of dex path elements is parsed. for
71 | * earlier versions, the last nested array ('[' ... ']') is enclosing the string we are
72 | * interested in.
73 | */
74 | static String processClassLoaderString(String input) {
75 | if (input.contains("DexPathList")) {
76 | return processClassLoaderString43OrLater(input);
77 | } else {
78 | return processClassLoaderString42OrEarlier(input);
79 | }
80 | }
81 |
82 | private static String processClassLoaderString42OrEarlier(String input) {
83 | /* The toString output looks like this:
84 | * dalvik.system.PathClassLoader[dexPath=path/to/apk,libraryPath=path/to/libs]
85 | */
86 | int index = input.lastIndexOf('[');
87 | input = (index == -1) ? input : input.substring(index + 1);
88 | index = input.indexOf(']');
89 | input = (index == -1) ? input : input.substring(0, index);
90 | return input;
91 | }
92 |
93 | private static String processClassLoaderString43OrLater(String input) {
94 | /* The toString output looks like this:
95 | * dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/{NAME}", ...], nativeLibraryDirectories=[...]]]
96 | */
97 | int start = input.indexOf("DexPathList") + "DexPathList".length();
98 | if (input.length() > start + 4) { // [[ + ]]
99 | String trimmed = input.substring(start);
100 | int end = trimmed.indexOf(']');
101 | if (trimmed.charAt(0) == '[' && trimmed.charAt(1) == '[' && end >= 0) {
102 | trimmed = trimmed.substring(2, end);
103 | // Comma-separated list, Arrays.toString output.
104 | String split[] = trimmed.split(",");
105 |
106 | // Clean up parts. Each path element is the type of the element plus the path in
107 | // quotes.
108 | for (int i = 0; i < split.length; i++) {
109 | int quoteStart = split[i].indexOf('"');
110 | int quoteEnd = split[i].lastIndexOf('"');
111 | if (quoteStart > 0 && quoteStart < quoteEnd) {
112 | split[i] = split[i].substring(quoteStart + 1, quoteEnd);
113 | }
114 | }
115 |
116 | // Need to rejoin components.
117 | StringBuilder sb = new StringBuilder();
118 | for (String s : split) {
119 | if (sb.length() > 0) {
120 | sb.append(':');
121 | }
122 | sb.append(s);
123 | }
124 | return sb.toString();
125 | }
126 | }
127 |
128 | // This is technically a parsing failure. Return the original string, maybe a later
129 | // stage can still salvage this.
130 | return input;
131 | }
132 |
133 | File[] guessPath(String input) {
134 | List results = new ArrayList<>();
135 | for (String potential : splitPathList(input)) {
136 | if (!potential.startsWith("/data/app/")) {
137 | continue;
138 | }
139 | int start = "/data/app/".length();
140 | int end = potential.lastIndexOf(".apk");
141 | if (end != potential.length() - 4) {
142 | continue;
143 | }
144 | int dash = potential.indexOf("-");
145 | if (dash != -1) {
146 | end = dash;
147 | }
148 | String packageName = potential.substring(start, end);
149 | File dataDir = new File("/data/data/" + packageName);
150 | if (isWriteableDirectory(dataDir)) {
151 | File cacheDir = new File(dataDir, "cache");
152 | // The cache directory might not exist -- create if necessary
153 | if (fileOrDirExists(cacheDir) || cacheDir.mkdir()) {
154 | if (isWriteableDirectory(cacheDir)) {
155 | results.add(cacheDir);
156 | }
157 | }
158 | }
159 | }
160 | return results.toArray(new File[results.size()]);
161 | }
162 |
163 | static String[] splitPathList(String input) {
164 | String trimmed = input;
165 | if (input.startsWith("dexPath=")) {
166 | int start = "dexPath=".length();
167 | int end = input.indexOf(',');
168 |
169 | trimmed = (end == -1) ? input.substring(start) : input.substring(start, end);
170 | }
171 |
172 | return trimmed.split(":");
173 | }
174 |
175 | boolean fileOrDirExists(File file) {
176 | return file.exists();
177 | }
178 |
179 | boolean isWriteableDirectory(File file) {
180 | return file.isDirectory() && file.canWrite();
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/AndHook/dexmaker/src/main/java/com/android/dx/BinaryOp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.dx;
18 |
19 | import com.android.dx.rop.code.Rop;
20 | import com.android.dx.rop.code.Rops;
21 | import com.android.dx.rop.type.TypeList;
22 |
23 | /**
24 | * An operation on two values of the same type.
25 | *
26 | *
Math operations ({@link #ADD}, {@link #SUBTRACT}, {@link #MULTIPLY},
27 | * {@link #DIVIDE}, and {@link #REMAINDER}) support ints, longs, floats and
28 | * doubles.
29 | *
30 | *
Bit operations ({@link #AND}, {@link #OR}, {@link #XOR}, {@link
31 | * #SHIFT_LEFT}, {@link #SHIFT_RIGHT}, {@link #UNSIGNED_SHIFT_RIGHT}) support
32 | * ints and longs.
33 | *
34 | *
Division by zero behaves differently depending on the operand type.
35 | * For int and long operands, {@link #DIVIDE} and {@link #REMAINDER} throw
36 | * {@link ArithmeticException} if {@code b == 0}. For float and double operands,
37 | * the operations return {@code NaN}.
38 | */
39 | public enum BinaryOp {
40 | /** {@code a + b} */
41 | ADD() {
42 | @Override
43 | Rop rop(TypeList types) {
44 | return Rops.opAdd(types);
45 | }
46 | },
47 |
48 | /** {@code a - b} */
49 | SUBTRACT() {
50 | @Override
51 | Rop rop(TypeList types) {
52 | return Rops.opSub(types);
53 | }
54 | },
55 |
56 | /** {@code a * b} */
57 | MULTIPLY() {
58 | @Override
59 | Rop rop(TypeList types) {
60 | return Rops.opMul(types);
61 | }
62 | },
63 |
64 | /** {@code a / b} */
65 | DIVIDE() {
66 | @Override
67 | Rop rop(TypeList types) {
68 | return Rops.opDiv(types);
69 | }
70 | },
71 |
72 | /** {@code a % b} */
73 | REMAINDER() {
74 | @Override
75 | Rop rop(TypeList types) {
76 | return Rops.opRem(types);
77 | }
78 | },
79 |
80 | /** {@code a & b} */
81 | AND() {
82 | @Override
83 | Rop rop(TypeList types) {
84 | return Rops.opAnd(types);
85 | }
86 | },
87 |
88 | /** {@code a | b} */
89 | OR() {
90 | @Override
91 | Rop rop(TypeList types) {
92 | return Rops.opOr(types);
93 | }
94 | },
95 |
96 | /** {@code a ^ b} */
97 | XOR() {
98 | @Override
99 | Rop rop(TypeList types) {
100 | return Rops.opXor(types);
101 | }
102 | },
103 |
104 | /** {@code a << b} */
105 | SHIFT_LEFT() {
106 | @Override
107 | Rop rop(TypeList types) {
108 | return Rops.opShl(types);
109 | }
110 | },
111 |
112 | /** {@code a >> b} */
113 | SHIFT_RIGHT() {
114 | @Override
115 | Rop rop(TypeList types) {
116 | return Rops.opShr(types);
117 | }
118 | },
119 |
120 | /** {@code a >>> b} */
121 | UNSIGNED_SHIFT_RIGHT() {
122 | @Override
123 | Rop rop(TypeList types) {
124 | return Rops.opUshr(types);
125 | }
126 | };
127 |
128 | abstract Rop rop(com.android.dx.rop.type.TypeList types);
129 | }
130 |
--------------------------------------------------------------------------------
/AndHook/dexmaker/src/main/java/com/android/dx/Comparison.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.dx;
18 |
19 | import com.android.dx.rop.code.Rop;
20 | import com.android.dx.rop.code.Rops;
21 | import com.android.dx.rop.type.TypeList;
22 |
23 | /**
24 | * A comparison between two values of the same type.
25 | */
26 | public enum Comparison {
27 |
28 | /** {@code a < b}. Supports int only. */
29 | LT() {
30 | @Override
31 | Rop rop(TypeList types) {
32 | return Rops.opIfLt(types);
33 | }
34 | },
35 |
36 | /** {@code a <= b}. Supports int only. */
37 | LE() {
38 | @Override
39 | Rop rop(TypeList types) {
40 | return Rops.opIfLe(types);
41 | }
42 | },
43 |
44 | /** {@code a == b}. Supports int and reference types. */
45 | EQ() {
46 | @Override
47 | Rop rop(TypeList types) {
48 | return Rops.opIfEq(types);
49 | }
50 | },
51 |
52 | /** {@code a >= b}. Supports int only. */
53 | GE() {
54 | @Override
55 | Rop rop(TypeList types) {
56 | return Rops.opIfGe(types);
57 | }
58 | },
59 |
60 | /** {@code a > b}. Supports int only. */
61 | GT() {
62 | @Override
63 | Rop rop(TypeList types) {
64 | return Rops.opIfGt(types);
65 | }
66 | },
67 |
68 | /** {@code a != b}. Supports int and reference types. */
69 | NE() {
70 | @Override
71 | Rop rop(TypeList types) {
72 | return Rops.opIfNe(types);
73 | }
74 | };
75 |
76 | abstract Rop rop(TypeList types);
77 | }
78 |
--------------------------------------------------------------------------------
/AndHook/dexmaker/src/main/java/com/android/dx/Constants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.dx;
18 |
19 | import com.android.dx.rop.cst.CstBoolean;
20 | import com.android.dx.rop.cst.CstByte;
21 | import com.android.dx.rop.cst.CstChar;
22 | import com.android.dx.rop.cst.CstDouble;
23 | import com.android.dx.rop.cst.CstFloat;
24 | import com.android.dx.rop.cst.CstInteger;
25 | import com.android.dx.rop.cst.CstKnownNull;
26 | import com.android.dx.rop.cst.CstLong;
27 | import com.android.dx.rop.cst.CstShort;
28 | import com.android.dx.rop.cst.CstString;
29 | import com.android.dx.rop.cst.CstType;
30 | import com.android.dx.rop.cst.TypedConstant;
31 |
32 | /**
33 | * Factory for rop constants.
34 | */
35 | final class Constants {
36 | private Constants() {}
37 |
38 | /**
39 | * Returns a rop constant for the specified value.
40 | *
41 | * @param value null, a boxed primitive, String, Class, or TypeId.
42 | */
43 | static TypedConstant getConstant(Object value) {
44 | if (value == null) {
45 | return CstKnownNull.THE_ONE;
46 | } else if (value instanceof Boolean) {
47 | return CstBoolean.make((Boolean) value);
48 | } else if (value instanceof Byte) {
49 | return CstByte.make((Byte) value);
50 | } else if (value instanceof Character) {
51 | return CstChar.make((Character) value);
52 | } else if (value instanceof Double) {
53 | return CstDouble.make(Double.doubleToLongBits((Double) value));
54 | } else if (value instanceof Float) {
55 | return CstFloat.make(Float.floatToIntBits((Float) value));
56 | } else if (value instanceof Integer) {
57 | return CstInteger.make((Integer) value);
58 | } else if (value instanceof Long) {
59 | return CstLong.make((Long) value);
60 | } else if (value instanceof Short) {
61 | return CstShort.make((Short) value);
62 | } else if (value instanceof String) {
63 | return new CstString((String) value);
64 | } else if (value instanceof Class) {
65 | return new CstType(TypeId.get((Class>) value).ropType);
66 | } else if (value instanceof TypeId) {
67 | return new CstType(((TypeId) value).ropType);
68 | } else {
69 | throw new UnsupportedOperationException("Not a constant: " + value);
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/AndHook/dexmaker/src/main/java/com/android/dx/DexMaker.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.dx;
18 |
19 | import com.android.dex.DexFormat;
20 | import com.android.dx.dex.DexOptions;
21 | import com.android.dx.dex.code.DalvCode;
22 | import com.android.dx.dex.code.PositionList;
23 | import com.android.dx.dex.code.RopTranslator;
24 | import com.android.dx.dex.file.ClassDefItem;
25 | import com.android.dx.dex.file.DexFile;
26 | import com.android.dx.dex.file.EncodedField;
27 | import com.android.dx.dex.file.EncodedMethod;
28 | import com.android.dx.rop.code.AccessFlags;
29 | import com.android.dx.rop.code.LocalVariableInfo;
30 | import com.android.dx.rop.code.RopMethod;
31 | import com.android.dx.rop.cst.CstString;
32 | import com.android.dx.rop.cst.CstType;
33 | import com.android.dx.rop.type.StdTypeList;
34 |
35 | import java.io.File;
36 | import java.io.FileOutputStream;
37 | import java.io.IOException;
38 | import java.lang.reflect.InvocationTargetException;
39 | import java.lang.reflect.Modifier;
40 | import java.util.Arrays;
41 | import java.util.Iterator;
42 | import java.util.LinkedHashMap;
43 | import java.util.Map;
44 | import java.util.Set;
45 | import java.util.jar.JarEntry;
46 | import java.util.jar.JarOutputStream;
47 |
48 | import static com.android.dx.rop.code.AccessFlags.ACC_CONSTRUCTOR;
49 | import static java.lang.reflect.Modifier.PRIVATE;
50 | import static java.lang.reflect.Modifier.STATIC;
51 |
52 | /**
53 | * Generates a Dalvik EXecutable (dex)
54 | * file for execution on Android. Dex files define classes and interfaces,
55 | * including their member methods and fields, executable code, and debugging
56 | * information. They also define annotations, though this API currently has no
57 | * facility to create a dex file that contains annotations.
58 | *
59 | *
This library is intended to satisfy two use cases:
60 | *
61 | *
For runtime code generation. By embedding this library
62 | * in your Android application, you can dynamically generate and load
63 | * executable code. This approach takes advantage of the fact that the
64 | * host environment and target environment are both Android.
65 | *
For compile time code generation. You may use this
66 | * library as a part of a compiler that targets Android. In this scenario
67 | * the generated dex file must be installed on an Android device before it
68 | * can be executed.
69 | *
70 | *
71 | *
Example: Fibonacci
72 | * To illustrate how this API is used, we'll use DexMaker to generate a class
73 | * equivalent to the following Java source:
We start by creating a {@link TypeId} to identify the generated {@code
87 | * Fibonacci} class. DexMaker identifies types by their internal names like
88 | * {@code Ljava/lang/Object;} rather than their Java identifiers like {@code
89 | * java.lang.Object}.
Next we declare the class. It allows us to specify the type's source file
95 | * for stack traces, its modifiers, its superclass, and the interfaces it
96 | * implements. In this case, {@code Fibonacci} is a public class that extends
97 | * from {@code Object}:
103 | * It is illegal to declare members of a class without also declaring the class
104 | * itself.
105 | *
106 | *
To make it easier to go from our Java method to dex instructions, we'll
107 | * manually translate it to pseudocode fit for an assembler. We need to replace
108 | * control flow like {@code if()} blocks and {@code for()} loops with labels and
109 | * branches. We'll also avoid performing multiple operations in one statement,
110 | * using local variables to hold intermediate values as necessary:
111 | *
{@code
112 | *
113 | * int constant1 = 1;
114 | * int constant2 = 2;
115 | * if (i < constant2) goto baseCase;
116 | * int a = i - constant1;
117 | * int b = i - constant2;
118 | * int c = fib(a);
119 | * int d = fib(b);
120 | * int result = c + d;
121 | * return result;
122 | * baseCase:
123 | * return i;
124 | * }
125 | *
126 | *
We look up the {@code MethodId} for the method on the declaring type. This
127 | * takes the method's return type (possibly {@link TypeId#VOID}), its name and
128 | * its parameters types. Next we declare the method, specifying its modifiers by
129 | * bitwise ORing constants from {@link java.lang.reflect.Modifier}. The declare
130 | * call returns a {@link Code} object, which we'll use to define the method's
131 | * instructions.
One limitation of {@code DexMaker}'s API is that it requires all local
138 | * variables to be created before any instructions are emitted. Use {@link
139 | * Code#newLocal newLocal()} to create a new local variable. The method's
140 | * parameters are exposed as locals using {@link Code#getParameter
141 | * getParameter()}. For non-static methods the {@code this} pointer is exposed
142 | * using {@link Code#getThis getThis()}. Here we declare all of the local
143 | * variables that we'll need for our {@code fib()} method:
{@code
144 | *
145 | * Local i = code.getParameter(0, TypeId.INT);
146 | * Local constant1 = code.newLocal(TypeId.INT);
147 | * Local constant2 = code.newLocal(TypeId.INT);
148 | * Local a = code.newLocal(TypeId.INT);
149 | * Local b = code.newLocal(TypeId.INT);
150 | * Local c = code.newLocal(TypeId.INT);
151 | * Local d = code.newLocal(TypeId.INT);
152 | * Local result = code.newLocal(TypeId.INT);
153 | * }
154 | *
155 | *
Notice that {@link Local} has a type parameter of {@code Integer}. This is
156 | * useful for generating code that works with existing types like {@code String}
157 | * and {@code Integer}, but it can be a hindrance when generating code that
158 | * involves new types. For this reason you may prefer to use raw types only and
159 | * add {@code @SuppressWarnings("unsafe")} on your calling code. This will yield
160 | * the same result but you won't get IDE support if you make a type error.
161 | *
162 | *
We're ready to start defining our method's instructions. The {@link Code}
163 | * class catalogs the available instructions and their use.
We're done defining the dex file. We just need to write it to the
180 | * filesystem or load it into the current process. For this example we'll load
181 | * the generated code into the current process. This only works when the current
182 | * process is running on Android. We use {@link #generateAndLoad
183 | * generateAndLoad()} which takes the class loader that will be used as our
184 | * generated code's parent class loader. It also requires a directory where
185 | * temporary files can be written.
197 | */
198 | public final class DexMaker {
199 | private final Map, TypeDeclaration> types = new LinkedHashMap<>();
200 |
201 | /**
202 | * Creates a new {@code DexMaker} instance, which can be used to create a
203 | * single dex file.
204 | */
205 | public DexMaker() {
206 | }
207 |
208 | private TypeDeclaration getTypeDeclaration(TypeId> type) {
209 | TypeDeclaration result = types.get(type);
210 | if (result == null) {
211 | result = new TypeDeclaration(type);
212 | types.put(type, result);
213 | }
214 | return result;
215 | }
216 |
217 | /**
218 | * Declares {@code type}.
219 | *
220 | * @param flags a bitwise combination of {@link Modifier#PUBLIC}, {@link
221 | * Modifier#FINAL} and {@link Modifier#ABSTRACT}.
222 | */
223 | public void declare(TypeId> type, String sourceFile, int flags,
224 | TypeId> supertype, TypeId>... interfaces) {
225 | TypeDeclaration declaration = getTypeDeclaration(type);
226 | int supportedFlags = Modifier.PUBLIC | Modifier.FINAL | Modifier.ABSTRACT;
227 | if ((flags & ~supportedFlags) != 0) {
228 | throw new IllegalArgumentException("Unexpected flag: "
229 | + Integer.toHexString(flags));
230 | }
231 | if (declaration.declared) {
232 | throw new IllegalStateException("already declared: " + type);
233 | }
234 | declaration.declared = true;
235 | declaration.flags = flags;
236 | declaration.supertype = supertype;
237 | declaration.sourceFile = sourceFile;
238 | declaration.interfaces = new TypeList(interfaces);
239 | }
240 |
241 | /**
242 | * Declares a method or constructor.
243 | *
244 | * @param flags a bitwise combination of {@link Modifier#PUBLIC}, {@link
245 | * Modifier#PRIVATE}, {@link Modifier#PROTECTED}, {@link Modifier#STATIC},
246 | * {@link Modifier#FINAL} and {@link Modifier#SYNCHRONIZED}.
247 | *
Warning: the {@link Modifier#SYNCHRONIZED} flag
248 | * is insufficient to generate a synchronized method. You must also use
249 | * {@link Code#monitorEnter} and {@link Code#monitorExit} to acquire
250 | * a monitor.
251 | */
252 | public Code declare(MethodId, ?> method, int flags) {
253 | TypeDeclaration typeDeclaration = getTypeDeclaration(method.declaringType);
254 | if (typeDeclaration.methods.containsKey(method)) {
255 | throw new IllegalStateException("already declared: " + method);
256 | }
257 |
258 | int supportedFlags = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED
259 | | Modifier.STATIC | Modifier.FINAL | Modifier.SYNCHRONIZED;
260 | if ((flags & ~supportedFlags) != 0) {
261 | throw new IllegalArgumentException("Unexpected flag: "
262 | + Integer.toHexString(flags));
263 | }
264 |
265 | // replace the SYNCHRONIZED flag with the DECLARED_SYNCHRONIZED flag
266 | if ((flags & Modifier.SYNCHRONIZED) != 0) {
267 | flags = (flags & ~Modifier.SYNCHRONIZED) | AccessFlags.ACC_DECLARED_SYNCHRONIZED;
268 | }
269 |
270 | if (method.isConstructor() || method.isStaticInitializer()) {
271 | flags |= ACC_CONSTRUCTOR;
272 | }
273 |
274 | MethodDeclaration methodDeclaration = new MethodDeclaration(method, flags);
275 | typeDeclaration.methods.put(method, methodDeclaration);
276 | return methodDeclaration.code;
277 | }
278 |
279 | /**
280 | * Declares a field.
281 | *
282 | * @param flags a bitwise combination of {@link Modifier#PUBLIC}, {@link
283 | * Modifier#PRIVATE}, {@link Modifier#PROTECTED}, {@link Modifier#STATIC},
284 | * {@link Modifier#FINAL}, {@link Modifier#VOLATILE}, and {@link
285 | * Modifier#TRANSIENT}.
286 | * @param staticValue a constant representing the initial value for the
287 | * static field, possibly null. This must be null if this field is
288 | * non-static.
289 | */
290 | public void declare(FieldId, ?> fieldId, int flags, Object staticValue) {
291 | TypeDeclaration typeDeclaration = getTypeDeclaration(fieldId.declaringType);
292 | if (typeDeclaration.fields.containsKey(fieldId)) {
293 | throw new IllegalStateException("already declared: " + fieldId);
294 | }
295 |
296 | int supportedFlags = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED
297 | | Modifier.STATIC | Modifier.FINAL | Modifier.VOLATILE | Modifier.TRANSIENT;
298 | if ((flags & ~supportedFlags) != 0) {
299 | throw new IllegalArgumentException("Unexpected flag: "
300 | + Integer.toHexString(flags));
301 | }
302 |
303 | if ((flags & Modifier.STATIC) == 0 && staticValue != null) {
304 | throw new IllegalArgumentException("staticValue is non-null, but field is not static");
305 | }
306 |
307 | FieldDeclaration fieldDeclaration = new FieldDeclaration(fieldId, flags, staticValue);
308 | typeDeclaration.fields.put(fieldId, fieldDeclaration);
309 | }
310 |
311 | /**
312 | * Generates a dex file and returns its bytes.
313 | */
314 | public byte[] generate() {
315 | DexOptions options = new DexOptions();
316 | options.targetApiLevel = DexFormat.API_NO_EXTENDED_OPCODES;
317 | DexFile outputDex = new DexFile(options);
318 |
319 | for (TypeDeclaration typeDeclaration : types.values()) {
320 | outputDex.add(typeDeclaration.toClassDefItem());
321 | }
322 |
323 | try {
324 | return outputDex.toDex(null, false);
325 | } catch (IOException e) {
326 | throw new RuntimeException(e);
327 | }
328 | }
329 |
330 | // Generate a file name for the jar by taking a checksum of MethodIds and
331 | // parent class types.
332 | private String generateFileName() {
333 | int checksum = 1;
334 |
335 | Set> typesKeySet = types.keySet();
336 | Iterator> it = typesKeySet.iterator();
337 | int[] checksums = new int[typesKeySet.size()];
338 | int i = 0;
339 |
340 | while (it.hasNext()) {
341 | TypeId> typeId = it.next();
342 | TypeDeclaration decl = getTypeDeclaration(typeId);
343 | Set methodSet = decl.methods.keySet();
344 | if (decl.supertype != null) {
345 | checksums[i++] = 31 * decl.supertype.hashCode() + methodSet.hashCode();
346 | }
347 | }
348 | Arrays.sort(checksums);
349 |
350 | for (int sum : checksums) {
351 | checksum *= 31;
352 | checksum += sum;
353 | }
354 |
355 | return "Generated_" + checksum +".jar";
356 | }
357 |
358 | private ClassLoader generateClassLoader(File result, File dexCache, ClassLoader parent) {
359 | try {
360 | return (ClassLoader) Class.forName("dalvik.system.DexClassLoader")
361 | .getConstructor(String.class, String.class, String.class, ClassLoader.class)
362 | .newInstance(result.getPath(), dexCache.getAbsolutePath(), null, parent);
363 | } catch (ClassNotFoundException e) {
364 | throw new UnsupportedOperationException("load() requires a Dalvik VM", e);
365 | } catch (InvocationTargetException e) {
366 | throw new RuntimeException(e.getCause());
367 | } catch (InstantiationException e) {
368 | throw new AssertionError();
369 | } catch (NoSuchMethodException e) {
370 | throw new AssertionError();
371 | } catch (IllegalAccessException e) {
372 | throw new AssertionError();
373 | }
374 | }
375 |
376 | /**
377 | * Generates a dex file and loads its types into the current process.
378 | *
379 | *
Picking a dex cache directory
380 | * The {@code dexCache} should be an application-private directory. If
381 | * you pass a world-writable directory like {@code /sdcard} a malicious app
382 | * could inject code into your process. Most applications should use this:
383 | *