├── .gitignore ├── .gitmodules ├── README.md ├── build.gradle ├── gradle ├── functions.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── shaka ├── apktool ├── build.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── rover12421 │ │ │ └── shaka │ │ │ └── apktool │ │ │ ├── cli │ │ │ ├── ApktoolMain.aj │ │ │ └── ApktoolMainAj.java │ │ │ ├── directory │ │ │ ├── ZipRODirectory0.aj │ │ │ ├── ZipRODirectoryAj.java │ │ │ └── ZipRODirectoryEx.java │ │ │ ├── lib │ │ │ ├── ARSCDecoder0.aj │ │ │ ├── ARSCDecoderAj.java │ │ │ ├── AXmlResourceParser0.aj │ │ │ ├── AXmlResourceParserAj.java │ │ │ ├── Androlib0.aj │ │ │ ├── AndrolibAj.java │ │ │ ├── AndrolibResourcesAj.java │ │ │ ├── ApkDecoderAj.java │ │ │ ├── LoggerAj.java │ │ │ ├── ResAttrDecoderAj.java │ │ │ ├── ResFileDecoder0.aj │ │ │ ├── ResFileDecoderAj.java │ │ │ ├── ResFileValueAj.java │ │ │ ├── ResPackageAj.java │ │ │ ├── ResReferenceValueAj.java │ │ │ ├── ResResSpecAj.java │ │ │ ├── ResResourceAj.java │ │ │ ├── ResStyleValue0.aj │ │ │ ├── ResStyleValueAj.java │ │ │ ├── ResTypeAj.java │ │ │ ├── ResTypeSpecAj.java │ │ │ ├── ResValueFactoryAj.java │ │ │ ├── ResXmlEncodersAj.java │ │ │ ├── StringBlock0.aj │ │ │ └── StringBlockAj.java │ │ │ ├── meta │ │ │ └── MetaInfo0.aj │ │ │ └── util │ │ │ └── Global.java │ └── resources │ │ ├── png │ │ ├── Shaka.9.png │ │ └── Shaka.png │ │ └── xml │ │ └── Shaka.xml │ └── test │ └── java │ └── com │ └── rover12421 │ └── shaka │ └── apktool │ └── test │ ├── BuildAndDecodeTest0.aj │ └── SkipPlatformBuildVersionAj.java ├── build.gradle ├── cli ├── build.gradle └── src │ └── main │ ├── java │ └── com │ │ └── rover12421 │ │ └── shaka │ │ └── cli │ │ ├── Main.java │ │ ├── MainOld.java │ │ ├── apktool │ │ ├── BuildCommand.java │ │ ├── DecodeCommand.java │ │ ├── EmptyFrameworkDirCommand.java │ │ ├── InstallFrameworkCommand.java │ │ └── PublicizeResourcesCommand.java │ │ ├── baksmali │ │ ├── DeodexCommand.java │ │ ├── DisassembleCommand.java │ │ ├── DumpCommand.java │ │ └── ListCommand.java │ │ ├── base │ │ ├── ApktoolDefaultCommand.java │ │ ├── ApktoolUsingFrameworkCommand.java │ │ └── HelpAndLanguageCommand.java │ │ ├── smali │ │ └── AssembleCommand.java │ │ └── util │ │ └── CommandUtil.java │ └── resources │ └── i18n │ ├── Messages_en_US.properties │ └── Messages_zh_CN.properties ├── lib ├── build.gradle └── src │ └── main │ ├── java │ └── com │ │ └── rover12421 │ │ └── shaka │ │ └── lib │ │ ├── AbsProperties.java │ │ ├── AndroidZip.java │ │ ├── CRC32Util.java │ │ ├── DebugInfo.java │ │ ├── EnvironmentDetection.java │ │ ├── HookMain.java │ │ ├── JarUtil.java │ │ ├── LogHelper.java │ │ ├── ShakaAaptProperties.java │ │ ├── ShakaApktoolFiles.java │ │ ├── ShakaBuildOption.java │ │ ├── ShakaDecodeOption.java │ │ ├── ShakaException.java │ │ ├── ShakaIO.java │ │ ├── ShakaProperties.java │ │ ├── ShakaRuntimeException.java │ │ ├── ShakaStringUtil.java │ │ ├── cli │ │ └── CommandLineArgEnum.java │ │ ├── compress │ │ ├── ZipFile.java │ │ ├── ZipFileAj.java │ │ ├── ZipOutputStream.java │ │ └── ZipOutputStreamAj.java │ │ ├── multiLanguage │ │ ├── MultiLanguageAj.java │ │ └── MultiLanguageSupport.java │ │ └── reflect │ │ ├── Reflect.java │ │ └── ReflectException.java │ └── resources │ ├── ShakaAapt │ ├── darwin-x86 │ │ └── bin │ │ │ └── aapt │ ├── darwin-x86_64 │ │ └── bin │ │ │ └── aapt │ ├── linux-x86 │ │ └── bin │ │ │ └── aapt │ ├── linux-x86_64 │ │ └── bin │ │ │ └── aapt │ └── windows-x86 │ │ └── bin │ │ └── aapt.exe │ ├── lang │ ├── en_US.lng │ ├── zh_CN.lng │ └── zh_TW.lng │ └── properties │ ├── ShakaAapt.properties │ └── shaka.properties └── smali ├── accessorTestGenerator ├── .gitignore └── build.gradle ├── build.gradle ├── generated ├── accessor │ └── test │ │ └── org │ │ └── jf │ │ └── dexlib2 │ │ └── AccessorTypes.java ├── main │ ├── antlr │ │ └── org │ │ │ └── jf │ │ │ └── smali │ │ │ ├── smaliParser.java │ │ │ ├── smaliParser.tokens │ │ │ ├── smaliTreeWalker.java │ │ │ └── smaliTreeWalker.tokens │ └── jflex │ │ └── org │ │ └── jf │ │ └── smali │ │ └── smaliFlexLexer.java └── test │ └── antlr │ └── org │ └── jf │ └── smali │ ├── expectedTokensTestGrammar.tokens │ ├── expectedTokensTestGrammarLexer.java │ └── expectedTokensTestGrammarParser.java └── src ├── main └── java │ └── com │ └── rover12421 │ └── shaka │ └── smali │ ├── baksmali │ ├── ClassDefinitionAj.java │ ├── InlineMethodResolverFromFile.java │ ├── RegisterFormatterAj.java │ ├── ShakaBaksmaliOption.java │ ├── baksmaliAj.java │ ├── baksmaliMain.aj │ └── baksmaliMainAj.java │ ├── dexlib2 │ ├── AnnotationsDirectoryAj.java │ ├── BaseDexBuffer0.aj │ ├── BaseDexBufferAj.java │ ├── BaseDexReaderAj.java │ ├── DexBackedDexFile0.aj │ ├── DexBackedDexFileAj.java │ ├── DexBackedMethod0.aj │ ├── DexBackedMethodAj.java │ ├── DexBackedMethodImplementation0.aj │ ├── DexBackedMethodImplementationAj.java │ └── InlineMethodResolverAj.java │ ├── smali │ ├── smaliMain.aj │ └── smaliMainAj.java │ └── util │ ├── NIOIndentingWriter.java │ └── StringUtilsAj.java └── test └── java └── com └── rover12421 └── shaka └── smali └── test ├── BaseDexBufferTestAj.java └── BaseDexReaderLeb128TestAj.java /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle/ 2 | build/ 3 | private/ 4 | *.kate-swp 5 | *~ 6 | *.project 7 | *.classpath 8 | *.settings 9 | *.setting 10 | bin/ 11 | *.iml 12 | *.ipr 13 | *.iws 14 | .idea/ 15 | /out 16 | ApkSample/ 17 | libs/ 18 | shaka/cli/src/test/ 19 | !**/src/main/resources/**/bin/ 20 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "shaka/apktool/apktool"] 2 | path = shaka/apktool/apktool 3 | url = https://github.com/iBotPeaches/Apktool.git 4 | [submodule "shaka/smali/smali"] 5 | path = shaka/smali/smali 6 | url = https://github.com/JesusFreke/smali.git 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### About 2 | 3 | [![Join the chat at https://gitter.im/rover12421/ShakaApktool](https://badges.gitter.im/rover12421/ShakaApktool.svg)](https://gitter.im/rover12421/ShakaApktool?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 4 | You know and not know are in progress. 5 | 6 | 7 | It is NOT intended for piracy and other non-legal uses. It could be used for localizing, adding some features or support for custom platforms and other GOOD purposes. Just try to be fair with authors of an app, that you use and probably like. 8 | 9 | 10 | #### Link 11 | - [Project Page](http://www.rover12421.com/shakaapktool) 12 | - [Apktool Project Page](http://ibotpeaches.github.io/Apktool/) 13 | - [Smali Project Page](https://github.com/JesusFreke/smali/) 14 | - [Source (Github)](https://github.com/rover12421/ShakaApktool/) 15 | - [Source (Bitbucket)](https://bitbucket.org/Rover12421/shakaapktool) 16 | - [Source (OsChina)](http://git.oschina.net/rover12421/ShakaApktool) 17 | - [Source (CSDN)](https://code.csdn.net/rover12421/shakaapktool) 18 | - [Source (CODING)](https://coding.net/u/rover12421/p/ShakaApktool) 19 | - [How To Build](https://github.com/rover12421/ShakaApktool/wiki/How-To-Build) 20 | - [Download](https://pan.baidu.com/s/1jIPOHZg)(ht4j) 21 | 22 | #### Other 23 | - QQ Group : 198996891 24 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | apply from : 'gradle/functions.gradle' 18 | 19 | ext.langLevel = '1.8' 20 | ext.aspectjVersion = '1.8.10' 21 | ext.ver = '4.0.0' 22 | 23 | ext.branch = getCheckedOutBranchFromProject() 24 | ext.hash = getCheckedOutGitCommitHashFromProject() 25 | ext.date = new Date().format("yyyyMMdd") 26 | 27 | allprojects { 28 | apply plugin: 'java' 29 | apply plugin: 'idea' 30 | 31 | repositories { 32 | mavenCentral() 33 | jcenter() 34 | } 35 | 36 | sourceCompatibility = langLevel 37 | targetCompatibility = langLevel 38 | 39 | task deleteProperties(type: Delete) { 40 | delete buildDir.getAbsolutePath() + '/resources/main' 41 | } 42 | 43 | processResources.dependsOn deleteProperties 44 | } 45 | 46 | subprojects { 47 | ext { 48 | depends = [ 49 | antlr : 'org.antlr:antlr:3.5.2', 50 | antlr_runtime : 'org.antlr:antlr-runtime:3.5.2', 51 | commons_cli : 'commons-cli:commons-cli:1.4', 52 | commons_compress: 'org.apache.commons:commons-compress:1.11', 53 | commons_io : 'commons-io:commons-io:2.4', 54 | commons_lang : 'org.apache.commons:commons-lang3:3.4', 55 | dx : 'com.google.android.tools:dx:1.7', 56 | findbugs : 'com.google.code.findbugs:jsr305:1.3.9', 57 | gson : 'com.google.code.gson:gson:2.3.1', 58 | guava : 'com.google.guava:guava:18.0', 59 | jcommander : 'com.beust:jcommander:1.64', 60 | jflex_plugin : 'org.xbib.gradle.plugin:gradle-plugin-jflex:1.1.0', 61 | junit : 'junit:junit:4.11', 62 | mockito : 'org.mockito:mockito-core:1.10.19', 63 | proguard : 'net.sf.proguard:proguard-gradle:5.2.1', 64 | snakeyaml : 'org.yaml:snakeyaml:1.17', 65 | stringtemplate : 'org.antlr:stringtemplate:3.2.1', 66 | ST4 : 'org.antlr:ST4:4.0.7', 67 | xmlunit : 'xmlunit:xmlunit:1.3', 68 | xmlpull : 'xpp3:xpp3:1.1.4c', 69 | ] 70 | } 71 | 72 | dependencies { 73 | testCompile depends.junit 74 | } 75 | } 76 | 77 | idea { 78 | project { 79 | languageLevel = langLevel 80 | } 81 | 82 | module { 83 | excludeDirs += files( 84 | 'ApkSample', 85 | 'src/test/resources/temp' 86 | ) 87 | } 88 | } 89 | 90 | task wrapper(type: Wrapper) { 91 | gradleVersion = '3.5' 92 | } 93 | 94 | // used for official releases only. Please don't use 95 | task release { 96 | } 97 | 98 | -------------------------------------------------------------------------------- /gradle/functions.gradle: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | gradle.allprojects { 18 | 19 | ext.getCheckedOutGitCommitHashFromGit = { gitFolder -> 20 | def takeFromHash = 7 21 | 22 | def head 23 | try { 24 | head = new File(gitFolder, "HEAD").text.split(":") 25 | } catch(Exception e) { 26 | return null; 27 | } 28 | 29 | def isCommit = head.length == 1 30 | if(isCommit) return head[0].trim().take(takeFromHash) 31 | 32 | def refHead = new File(gitFolder + head[1].trim()) 33 | refHead.text.trim().take takeFromHash 34 | } 35 | 36 | ext.getCheckedOutBranchFromGit = { gitFolder -> 37 | def head 38 | try { 39 | head = new File(gitFolder, "HEAD").text.split("/") 40 | return head[2].trim(); 41 | } catch(Exception e) { 42 | return "SNAPSHOT"; 43 | } 44 | } 45 | 46 | ext.getCheckedOutGitCommitHashFromProject = {getCheckedOutGitCommitHashFromGit("$projectDir/.git/")} 47 | ext.getCheckedOutBranchFromProject = {getCheckedOutBranchFromGit("$projectDir/.git/")} 48 | 49 | ext.getCheckedOutGitCommitHashFromModule = { moduleName -> 50 | getCheckedOutGitCommitHashFromGit("$rootProject.projectDir/.git/modules/$moduleName/") 51 | } 52 | 53 | ext.getCheckedOutBranchFromModule = { moduleName -> 54 | getCheckedOutBranchFromGit("$rootProject.projectDir/.git/modules/$moduleName/") 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rover12421/ShakaApktool/158767230d533d4a9e4b9f74d571705d77701c1f/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 02 18:45:31 CST 2017 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-3.5-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save ( ) { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rover12421 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 | include 'shaka:lib', 18 | 'shaka:cli', 19 | 'shaka:smali', 20 | 'shaka:apktool', 21 | 'shaka:smali:accessorTestGenerator' 22 | 23 | -------------------------------------------------------------------------------- /shaka/apktool/build.gradle: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | sourceSets { 17 | main { 18 | java { 19 | srcDirs = [ 20 | 'src/main/java', 21 | 'apktool/brut.j.common/src/main/java', 22 | 'apktool/brut.j.util/src/main/java', 23 | 'apktool/brut.j.dir/src/main/java', 24 | 'apktool/brut.apktool/apktool-lib/src/main/java', 25 | 'apktool/brut.apktool/apktool-cli/src/main/java' 26 | ] 27 | } 28 | resources { 29 | srcDirs = [ 30 | 'src/main/resources', 31 | 'apktool/brut.j.common/src/main/resources', 32 | 'apktool/brut.j.util/src/main/resources', 33 | 'apktool/brut.j.dir/src/main/resources', 34 | 'apktool/brut.apktool/apktool-lib/src/main/resources', 35 | 'apktool/brut.apktool/apktool-cli/src/main/resources' 36 | ] 37 | exclude '**/prebuilt/**' 38 | } 39 | } 40 | 41 | test { 42 | java { 43 | srcDirs = [ 44 | 'src/test/java', 45 | 'apktool/brut.apktool/apktool-lib/src/test/java', 46 | ] 47 | } 48 | resources { 49 | srcDirs = [ 50 | 'src/test/resources', 51 | 'apktool/brut.j.common/src/test/resources', 52 | 'apktool/brut.j.util/src/test/resources', 53 | 'apktool/brut.j.dir/src/test/resources', 54 | 'apktool/brut.apktool/apktool-lib/src/test/resources', 55 | 'apktool/brut.apktool/apktool-cli/src/test/resources' 56 | ] 57 | } 58 | } 59 | } 60 | 61 | dependencies { 62 | compile project(':shaka:smali'), 63 | depends.snakeyaml, 64 | depends.xmlpull, 65 | depends.guava, 66 | depends.commons_lang, 67 | depends.commons_io, 68 | depends.commons_cli, 69 | depends.commons_compress 70 | 71 | testCompile depends.xmlunit 72 | } 73 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/cli/ApktoolMain.aj: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.apktool.cli; 2 | 3 | import brut.apktool.Main; 4 | import org.apache.commons.cli.Options; 5 | 6 | /** 7 | * Created by rover12421 on 12/5/15. 8 | */ 9 | privileged public aspect ApktoolMain { 10 | public static Options Main.getNormalOptions() { 11 | return Main.normalOptions; 12 | } 13 | 14 | public static Options Main.getDecodeOptions() { 15 | return Main.DecodeOptions; 16 | } 17 | 18 | public static Options Main.getBuildOptions() { 19 | return Main.BuildOptions; 20 | } 21 | 22 | public static Options Main.getFrameOptions() { 23 | return Main.frameOptions; 24 | } 25 | 26 | public static Options Main.getAllOptions() { 27 | return Main.allOptions; 28 | } 29 | 30 | public static Options Main.getEmptyOptions() { 31 | return Main.emptyOptions; 32 | } 33 | 34 | public static void Main._Options0() { 35 | Main._Options(); 36 | } 37 | 38 | public static String Main.verbosityHelp0() { 39 | return Main.verbosityHelp(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/directory/ZipRODirectory0.aj: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.apktool.directory; 2 | 3 | import brut.directory.ZipRODirectory; 4 | 5 | /** 6 | * Created by rover12421 on 1/29/16. 7 | */ 8 | public aspect ZipRODirectory0 { 9 | public ZipRODirectory.new() {} 10 | } 11 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/directory/ZipRODirectoryAj.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.apktool.directory; 2 | 3 | import org.aspectj.lang.annotation.Aspect; 4 | 5 | /** 6 | * Created by rover12421 on 1/29/16. 7 | */ 8 | @Aspect 9 | public class ZipRODirectoryAj { 10 | // @Around("call(brut.directory.ZipRODirectory.new(..))" + 11 | // "&& args(zipFileName)") 12 | // public ZipRODirectory _new(String zipFileName) throws DirectoryException { 13 | // return new ZipRODirectoryEx(zipFileName); 14 | // } 15 | // 16 | // @Around("call(brut.directory.ZipRODirectory.new(..))" + 17 | // "&& args(zipFile)") 18 | // public ZipRODirectory _new(File zipFile) throws DirectoryException { 19 | // return new ZipRODirectoryEx(zipFile); 20 | // } 21 | // 22 | // @Around("call(brut.directory.ZipRODirectory.new(..))" + 23 | // "&& args(zipFile)") 24 | // public ZipRODirectory ZipRODirectory(ZipFile zipFile) throws DirectoryException { 25 | // return new ZipRODirectoryEx(zipFile); 26 | // } 27 | // 28 | // @Around("call(brut.directory.ZipRODirectory.new(..))" + 29 | // "&& args(zipFileName, path)") 30 | // public ZipRODirectory ZipRODirectory(String zipFileName, String path) 31 | // throws DirectoryException { 32 | // return new ZipRODirectoryEx(zipFileName, path); 33 | // } 34 | // 35 | // @Around("call(brut.directory.ZipRODirectory.new(..))" + 36 | // "&& args(zipFile, path)") 37 | // public ZipRODirectory ZipRODirectory(File zipFile, String path) throws DirectoryException { 38 | // return new ZipRODirectoryEx(zipFile, path); 39 | // } 40 | // 41 | // @Around("call(brut.directory.ZipRODirectory.new(..))" + 42 | // "&& args(zipFile, path)") 43 | // public ZipRODirectory ZipRODirectory(ZipFile zipFile, String path) throws DirectoryException { 44 | // return new ZipRODirectoryEx(zipFile, path); 45 | // } 46 | } 47 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/directory/ZipRODirectoryEx.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.apktool.directory; 2 | 3 | import brut.directory.AbstractDirectory; 4 | import brut.directory.DirectoryException; 5 | import brut.directory.PathNotExist; 6 | import brut.directory.ZipRODirectory; 7 | import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; 8 | 9 | import java.io.File; 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.util.Enumeration; 13 | import java.util.LinkedHashMap; 14 | import java.util.LinkedHashSet; 15 | import java.util.zip.ZipEntry; 16 | import java.util.zip.ZipFile; 17 | 18 | /** 19 | * Created by rover12421 on 1/29/16. 20 | */ 21 | public class ZipRODirectoryEx extends ZipRODirectory { 22 | private org.apache.commons.compress.archivers.zip.ZipFile mZipFile; 23 | private String mPath; 24 | 25 | public ZipRODirectoryEx(String zipFileName) throws DirectoryException { 26 | this(zipFileName, ""); 27 | } 28 | 29 | public ZipRODirectoryEx(File zipFile) throws DirectoryException { 30 | this(zipFile, ""); 31 | } 32 | 33 | public ZipRODirectoryEx(ZipFile zipFile) throws DirectoryException { 34 | this(zipFile, ""); 35 | } 36 | 37 | public ZipRODirectoryEx(String zipFileName, String path) throws DirectoryException { 38 | this(new File(zipFileName), path); 39 | } 40 | 41 | public ZipRODirectoryEx(File zipFile, String path) throws DirectoryException { 42 | super(); 43 | try { 44 | mZipFile = new org.apache.commons.compress.archivers.zip.ZipFile(zipFile); 45 | } catch (IOException e) { 46 | throw new DirectoryException(e); 47 | } 48 | mPath = path; 49 | } 50 | 51 | public ZipRODirectoryEx(ZipFile zipFile, String path) throws DirectoryException { 52 | this(zipFile.getName(), path); 53 | } 54 | 55 | public ZipRODirectoryEx(org.apache.commons.compress.archivers.zip.ZipFile zipFile, String path) { 56 | mZipFile = zipFile; 57 | mPath = path; 58 | } 59 | 60 | // @Override 61 | // protected AbstractDirectory createDirLocal(String name) throws DirectoryException { 62 | // return super.createDirLocal(name); 63 | // } 64 | 65 | @Override 66 | protected InputStream getFileInputLocal(String name) throws DirectoryException { 67 | try { 68 | System.out.println("getFileInputLocal : " + mPath + name); 69 | return mZipFile.getInputStream(mZipFile.getEntry(mPath + name)); 70 | } catch (IOException e) { 71 | throw new PathNotExist(name, e); 72 | } 73 | } 74 | 75 | // @Override 76 | // protected OutputStream getFileOutputLocal(String name) throws DirectoryException { 77 | // return super.getFileOutputLocal(name); 78 | // } 79 | 80 | @Override 81 | protected void loadDirs() { 82 | loadAll(); 83 | } 84 | 85 | @Override 86 | protected void loadFiles() { 87 | loadAll(); 88 | } 89 | 90 | // @Override 91 | // protected void removeFileLocal(String name) { 92 | // super.removeFileLocal(name); 93 | // } 94 | 95 | @Override 96 | public int getCompressionLevel(String fileName) throws DirectoryException { 97 | System.out.println("getCompressionLevel : " + fileName); 98 | ZipArchiveEntry entry = mZipFile.getEntry(fileName); 99 | return entry.getMethod(); 100 | } 101 | 102 | private void loadAll() { 103 | mFiles = new LinkedHashSet(); 104 | mDirs = new LinkedHashMap(); 105 | 106 | int prefixLen = getPath().length(); 107 | Enumeration entries = getZipFile().getEntries(); 108 | while (entries.hasMoreElements()) { 109 | ZipEntry entry = entries.nextElement(); 110 | String name = entry.getName(); 111 | 112 | if (name.equals(getPath()) || ! name.startsWith(getPath())) { 113 | continue; 114 | } 115 | 116 | String subname = name.substring(prefixLen); 117 | 118 | int pos = subname.indexOf(separator); 119 | if (pos == -1) { 120 | if (! entry.isDirectory()) { 121 | mFiles.add(subname); 122 | continue; 123 | } 124 | } else { 125 | subname = subname.substring(0, pos); 126 | } 127 | 128 | if (! mDirs.containsKey(subname)) { 129 | AbstractDirectory dir = new ZipRODirectoryEx(getZipFile(), getPath() + subname + separator); 130 | mDirs.put(subname, dir); 131 | } 132 | } 133 | } 134 | 135 | private String getPath() { 136 | return mPath; 137 | } 138 | 139 | private org.apache.commons.compress.archivers.zip.ZipFile getZipFile() { 140 | return mZipFile; 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/ARSCDecoder0.aj: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.apktool.lib; 2 | 3 | import brut.androlib.AndrolibException; 4 | import brut.androlib.res.data.ResPackage; 5 | import brut.androlib.res.data.ResType; 6 | import brut.androlib.res.data.ResTypeSpec; 7 | import brut.androlib.res.decoder.ARSCDecoder; 8 | import brut.androlib.res.decoder.StringBlock; 9 | import brut.util.ExtDataInput; 10 | 11 | import java.io.IOException; 12 | 13 | /** 14 | * Created by rover12421 on 12/5/15. 15 | */ 16 | privileged public aspect ARSCDecoder0 { 17 | public Header ARSCDecoder.getHeader() { 18 | return this.mHeader; 19 | } 20 | 21 | public ExtDataInput ARSCDecoder.getIn() { 22 | return this.mIn; 23 | } 24 | 25 | public ResPackage ARSCDecoder.getPkg() { 26 | return this.mPkg; 27 | } 28 | 29 | public StringBlock ARSCDecoder.getTableStrings() { 30 | return this.mTableStrings; 31 | } 32 | 33 | public void ARSCDecoder.setTableStrings(StringBlock stringBlock) { 34 | this.mTableStrings = stringBlock; 35 | } 36 | 37 | public ResType ARSCDecoder.getType() { 38 | return mType; 39 | } 40 | 41 | public ResTypeSpec ARSCDecoder.getTypeSpec() { 42 | return mTypeSpec; 43 | } 44 | 45 | public void ARSCDecoder.nextChunkCheckType0(int expectedType) throws IOException, 46 | AndrolibException { 47 | this.nextChunkCheckType(expectedType); 48 | } 49 | 50 | public Header ARSCDecoder.nextChunk0() throws IOException { 51 | return this.nextChunk(); 52 | } 53 | 54 | public ResPackage ARSCDecoder.readTablePackage0() throws IOException, AndrolibException { 55 | return this.readTablePackage(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/ARSCDecoderAj.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.apktool.lib; 17 | 18 | import android.util.TypedValue; 19 | import brut.androlib.res.data.ResPackage; 20 | import brut.androlib.res.data.ResTypeSpec; 21 | import brut.androlib.res.data.value.ResIntBasedValue; 22 | import brut.androlib.res.decoder.ARSCDecoder; 23 | import brut.androlib.res.decoder.StringBlock; 24 | import brut.util.ExtDataInput; 25 | import com.rover12421.shaka.lib.LogHelper; 26 | import com.rover12421.shaka.lib.ShakaDecodeOption; 27 | import org.aspectj.lang.ProceedingJoinPoint; 28 | import org.aspectj.lang.annotation.Around; 29 | import org.aspectj.lang.annotation.Aspect; 30 | 31 | /** 32 | * Created by rover12421 on 8/16/14. 33 | */ 34 | @Aspect 35 | public class ARSCDecoderAj { 36 | 37 | //ResTable_header 结构的标准长度 38 | private final static int ResTable_header_SIZE= 12; 39 | 40 | @Around("execution(* brut.androlib.res.decoder.ARSCDecoder.addMissingResSpecs())") 41 | public void addMissingResSpecs(ProceedingJoinPoint joinPoint) throws Throwable { 42 | if (!ShakaDecodeOption.getInstance().isFuckUnkownId()) { 43 | joinPoint.proceed(joinPoint.getArgs()); 44 | } 45 | } 46 | 47 | @Around("execution(* brut.androlib.res.decoder.ARSCDecoder.readTableHeader())") 48 | public ResPackage[] readTableHeader(ProceedingJoinPoint joinPoint) throws Exception { 49 | ARSCDecoder decoder = (ARSCDecoder) joinPoint.getThis(); 50 | ExtDataInput mIn = decoder.getIn(); 51 | 52 | // nextChunkCheckType(ARSCDecoder.Header.TYPE_TABLE); 53 | decoder.nextChunkCheckType0(ARSCDecoder.Header.TYPE_TABLE); 54 | int packageCount = mIn.readInt(); 55 | 56 | try { 57 | ARSCDecoder.Header header = decoder.getHeader(); 58 | if (header.headerSize > ResTable_header_SIZE) { 59 | int skip = header.headerSize - ResTable_header_SIZE; 60 | LogHelper.warning("ResChunk_header exception : read size = " + header.headerSize + ", skip " + skip); 61 | mIn.skipBytes(skip); 62 | } 63 | } catch (Throwable e) { 64 | e.printStackTrace(); 65 | } 66 | 67 | 68 | StringBlock mTableStrings = StringBlock.read(mIn); 69 | decoder.setTableStrings(mTableStrings); 70 | 71 | ResPackage[] packages = new ResPackage[packageCount]; 72 | 73 | // nextChunk(); 74 | decoder.nextChunk0(); 75 | 76 | for (int i = 0; i < packageCount; i++) { 77 | // packages[i] = readTablePackage(); 78 | packages[i] = decoder.readTablePackage0(); 79 | } 80 | return packages; 81 | } 82 | 83 | @Around("execution(* brut.androlib.res.decoder.ARSCDecoder.readValue())") 84 | public ResIntBasedValue readValue(ProceedingJoinPoint joinPoint) throws Exception { 85 | ARSCDecoder decoder = (ARSCDecoder) joinPoint.getThis(); 86 | ExtDataInput mIn = decoder.getIn(); 87 | ResPackage mPkg = decoder.getPkg(); 88 | 89 | /* size */mIn.skipCheckShort((short) 8); 90 | /* zero */mIn.skipCheckByte((byte) 0); 91 | byte type = mIn.readByte(); 92 | int data = mIn.readInt(); 93 | 94 | ResTypeSpec mTypeSpec = decoder.getTypeSpec(); 95 | StringBlock stringBlock = decoder.getTableStrings(); 96 | 97 | return type == TypedValue.TYPE_STRING 98 | // ? mPkg.getValueFactory().factory(mTableStrings(decoder).getHTML(data), data) 99 | ? ResValueFactoryAj.factory(mTypeSpec, stringBlock.getHTML(data), data) 100 | : mPkg.getValueFactory().factory(type, data, null); 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/AXmlResourceParser0.aj: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.apktool.lib; 2 | 3 | import brut.androlib.res.decoder.AXmlResourceParser; 4 | import brut.androlib.res.decoder.StringBlock; 5 | 6 | /** 7 | * Created by rover12421 on 12/5/15. 8 | */ 9 | privileged public aspect AXmlResourceParser0 { 10 | public int AXmlResourceParser.getAttributeOffset0(int index) { 11 | return this.getAttributeOffset(index); 12 | } 13 | 14 | public int[] AXmlResourceParser.getAttributes() { 15 | return m_attributes; 16 | } 17 | 18 | public StringBlock AXmlResourceParser.getStrings0() { 19 | return this.m_strings; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/Androlib0.aj: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.apktool.lib; 2 | 3 | import brut.androlib.Androlib; 4 | import brut.androlib.res.data.ResUnknownFiles; 5 | 6 | /** 7 | * Created by rover12421 on 12/5/15. 8 | */ 9 | privileged public aspect Androlib0 { 10 | public ResUnknownFiles Androlib.getResUnknownFiles() { 11 | return this.mResUnknownFiles; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/ApkDecoderAj.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.apktool.lib; 17 | 18 | import com.rover12421.shaka.lib.LogHelper; 19 | import com.rover12421.shaka.lib.ShakaProperties; 20 | import org.aspectj.lang.annotation.Aspect; 21 | import org.aspectj.lang.annotation.Before; 22 | 23 | /** 24 | * Created by rover12421 on 8/9/14. 25 | * brut.androlib.ApkDecoder 26 | */ 27 | @Aspect 28 | public class ApkDecoderAj { 29 | 30 | @Before("execution(void brut.androlib.ApkDecoder.decode())") 31 | public void decode_before() { 32 | LogHelper.info("Using ShakaApktool " + ShakaProperties.getVersion()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/LoggerAj.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.apktool.lib; 2 | 3 | import org.aspectj.lang.ProceedingJoinPoint; 4 | import org.aspectj.lang.annotation.Around; 5 | import org.aspectj.lang.annotation.Aspect; 6 | 7 | /** 8 | * Created by rover12421 on 8/7/15. 9 | */ 10 | @Aspect 11 | public class LoggerAj { 12 | 13 | @Around("call(* java.util.logging.Logger.info(..)) " + 14 | "&& args(msg)" + 15 | "&& (" + 16 | "withincode(* brut.androlib.Androlib.build(..))" + 17 | "|| withincode(* brut.androlib.ApkDecoder.decode(..))" + 18 | ")") 19 | public void info(ProceedingJoinPoint joinPoint, String msg) { 20 | if (!msg.contains("Apktool")) { 21 | try { 22 | joinPoint.proceed(joinPoint.getArgs()); 23 | } catch (Throwable throwable) { 24 | throwable.printStackTrace(); 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/ResAttrDecoderAj.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.apktool.lib; 17 | 18 | import brut.androlib.res.data.ResResSpec; 19 | import brut.androlib.res.data.ResResource; 20 | import brut.androlib.res.data.value.ResFileValue; 21 | import com.rover12421.shaka.lib.LogHelper; 22 | import org.aspectj.lang.annotation.AfterReturning; 23 | import org.aspectj.lang.annotation.Aspect; 24 | 25 | import java.io.File; 26 | 27 | /** 28 | * Created by rover12421 on 8/9/14. 29 | * brut.androlib.res.decoder.ResAttrDecoder 30 | */ 31 | @Aspect 32 | public class ResAttrDecoderAj { 33 | 34 | private String getResSpecName(String name) { 35 | /** 36 | * 过滤包名 37 | */ 38 | int index = name.indexOf(":"); 39 | if (index > 0) { 40 | name = name.substring(index+1); 41 | } 42 | return name; 43 | } 44 | 45 | @AfterReturning(pointcut = "execution(* brut.androlib.res.decoder.ResAttrDecoder.decode(..))" + 46 | "&& args(type, value, rawValue, attrResId)", returning = "ret") 47 | public void decode_afterRetruning(int type, int value, String rawValue, int attrResId, String ret) throws Exception { 48 | if (ResFileDecoderAj.DonotRecord) { 49 | return; 50 | } 51 | ResResSpec spec = ResTypeSpecAj.AllSpecs.get(value); 52 | if (spec != null) { 53 | //查找到ResResSpec 54 | String oldName = spec.getName(); 55 | int index = ret.indexOf("/"); // type/name.ext 56 | if (index > 0) { 57 | String newName = ret.substring(index + 1); 58 | newName = getResSpecName(newName); 59 | if (!oldName.equals(newName)) { 60 | LogHelper.warning("Rename ResResSpec " + oldName + " to " + newName); 61 | ResResSpecAj.setName(spec, newName); 62 | ResTypeSpecAj.addSpecToResType(spec); 63 | 64 | /** 65 | * 需要再次Decode 66 | * 可能有些值已经写入到文件了,需要重新Decode来纠正 67 | */ 68 | ResFileDecoderAj.NeedReDecodeFiles = true; 69 | 70 | ResResource res = ResTypeAj.MultopleResFileValue.get(spec.getId().id); 71 | if (res != null) { 72 | ResFileValue fileValue = (ResFileValue) res.getValue(); 73 | String mapPath = AndrolibAj.metaInfo.getDecodeFileMap(fileValue.getPath()); 74 | File outfile = new File(AndrolibResourcesAj.getOutDir().getAbsolutePath() + File.separator + mapPath); 75 | if (outfile.exists()) { 76 | String fileName = outfile.getName(); 77 | int extIndex = fileName.lastIndexOf("."); 78 | String ext = ""; 79 | if (extIndex > 0) { 80 | ext = fileName.substring(extIndex); 81 | } 82 | File renamefile = new File(outfile.getParent() + File.separator + newName + ext); 83 | outfile.renameTo(renamefile); 84 | 85 | String newMapFile = renamefile.getAbsolutePath().substring(AndrolibResourcesAj.getOutDir().getAbsolutePath().length()+1); 86 | AndrolibAj.metaInfo.addDecodeFileMap(fileValue.getPath(), newMapFile); 87 | LogHelper.warning("Rename resource file " + fileValue.getPath() + " to " + newMapFile); 88 | } 89 | } 90 | } 91 | } 92 | 93 | } 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/ResFileDecoder0.aj: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.apktool.lib; 2 | 3 | import brut.androlib.res.decoder.ResFileDecoder; 4 | import brut.androlib.res.decoder.ResStreamDecoderContainer; 5 | 6 | /** 7 | * Created by rover12421 on 12/5/15. 8 | */ 9 | privileged public aspect ResFileDecoder0 { 10 | public ResStreamDecoderContainer ResFileDecoder.getDecoders() { 11 | return this.mDecoders; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/ResFileValueAj.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.apktool.lib; 17 | 18 | import brut.androlib.res.data.value.ResFileValue; 19 | import org.aspectj.lang.ProceedingJoinPoint; 20 | import org.aspectj.lang.annotation.Around; 21 | import org.aspectj.lang.annotation.Aspect; 22 | 23 | /** 24 | * Created by rover12421 on 7/31/15. 25 | */ 26 | @Aspect 27 | public class ResFileValueAj { 28 | @Around("execution(* brut.androlib.res.data.value.ResFileValue.getStrippedPath())") 29 | public String getStrippedPath(ProceedingJoinPoint joinPoint) { 30 | try { 31 | return (String) joinPoint.proceed(joinPoint.getArgs()); 32 | } catch (Throwable throwable) { 33 | //不是标准res目录结构,返回完整路径 34 | //添加"/"前缀,后面用来区分是完整路径,还是资源相对路径 35 | return "/" + ((ResFileValue)joinPoint.getThis()).getPath(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/ResPackageAj.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.apktool.lib; 17 | 18 | import brut.androlib.err.UndefinedResObject; 19 | import brut.androlib.res.data.ResID; 20 | import brut.androlib.res.data.ResPackage; 21 | import brut.androlib.res.data.ResResSpec; 22 | import brut.androlib.res.data.ResTypeSpec; 23 | import com.rover12421.shaka.lib.LogHelper; 24 | import com.rover12421.shaka.lib.ShakaDecodeOption; 25 | import org.aspectj.lang.ProceedingJoinPoint; 26 | import org.aspectj.lang.annotation.Around; 27 | import org.aspectj.lang.annotation.Aspect; 28 | 29 | /** 30 | * Created by rover12421 on 4/21/15. 31 | */ 32 | @Aspect 33 | public class ResPackageAj { 34 | 35 | @Around("execution(* brut.androlib.res.data.ResPackage.getResSpec(..))" + 36 | "&& args(resID)") 37 | public ResResSpec getResSpec(ProceedingJoinPoint joinPoint, ResID resID) throws Throwable { 38 | try { 39 | return (ResResSpec) joinPoint.proceed(joinPoint.getArgs()); 40 | } catch (UndefinedResObject e) { 41 | if (ShakaDecodeOption.getInstance().isFuckUnkownId()) { 42 | ResPackage thiz = (ResPackage) joinPoint.getThis(); 43 | return new ResResSpec(resID, String.format("[%08x]", resID.id), thiz, new ResTypeSpec("FuckUnkownId", thiz.getResTable(), thiz, (byte) (resID.id&0xFF), 0)); 44 | } else { 45 | throw e; 46 | } 47 | } 48 | } 49 | 50 | @Around("execution(* brut.androlib.res.data.ResPackage.addResSpec(..))") 51 | public void addResSpec(ProceedingJoinPoint joinPoint) { 52 | try { 53 | joinPoint.proceed(joinPoint.getArgs()); 54 | } catch (Throwable throwable) { 55 | LogHelper.warning(throwable.getMessage()); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/ResReferenceValueAj.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.apktool.lib; 2 | 3 | import com.rover12421.shaka.lib.ShakaDecodeOption; 4 | import org.aspectj.lang.ProceedingJoinPoint; 5 | import org.aspectj.lang.annotation.Around; 6 | import org.aspectj.lang.annotation.Aspect; 7 | 8 | /** 9 | * Created by rover12421 on 11/20/15. 10 | */ 11 | @Aspect 12 | public class ResReferenceValueAj { 13 | @Around("execution(* brut.androlib.res.data.value.ResReferenceValue.encodeAsResXml())") 14 | public String encodeAsResXml(ProceedingJoinPoint joinPoint) throws Throwable { 15 | try { 16 | return (String) joinPoint.proceed(joinPoint.getArgs()); 17 | } catch (Throwable e) { 18 | if (ShakaDecodeOption.getInstance().isIgnoreResDecodeError()) { 19 | return "@null"; 20 | } else { 21 | throw e; 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/ResResSpecAj.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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.rover12421.shaka.apktool.lib; 18 | 19 | import brut.androlib.AndrolibException; 20 | import brut.androlib.res.data.ResResSpec; 21 | import brut.androlib.res.data.ResResource; 22 | import com.rover12421.shaka.lib.LogHelper; 23 | import com.rover12421.shaka.lib.reflect.Reflect; 24 | import org.aspectj.lang.ProceedingJoinPoint; 25 | import org.aspectj.lang.annotation.Around; 26 | import org.aspectj.lang.annotation.Aspect; 27 | 28 | /** 29 | * Created by rover12421 on 8/2/14. 30 | */ 31 | @Aspect 32 | public class ResResSpecAj { 33 | public static boolean RenameResResSpec = false; 34 | 35 | @Around("execution(void brut.androlib.res.data.ResResSpec.addResource(..))" + 36 | "&& args(res, overwrite)") 37 | public void addResource(ProceedingJoinPoint joinPoint, ResResource res, boolean overwrite) throws Throwable { 38 | try { 39 | joinPoint.proceed(joinPoint.getArgs()); 40 | } catch (AndrolibException e) { 41 | LogHelper.warning(e.getMessage()); 42 | } 43 | } 44 | 45 | public static void setName(ResResSpec spec, String name) { 46 | RenameResResSpec = true; 47 | Reflect.on(spec).set("mName", name); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/ResResourceAj.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.apktool.lib; 17 | 18 | import brut.androlib.res.data.value.ResValue; 19 | import com.rover12421.shaka.lib.ShakaDecodeOption; 20 | import org.aspectj.lang.ProceedingJoinPoint; 21 | import org.aspectj.lang.annotation.Around; 22 | import org.aspectj.lang.annotation.Aspect; 23 | 24 | /** 25 | * Created by rover12421 on 4/21/15. 26 | */ 27 | @Aspect 28 | public class ResResourceAj { 29 | 30 | @Around("execution(* brut.androlib.res.data.ResResource.replace(..))" + 31 | "&& args(value)") 32 | public void replace(ProceedingJoinPoint joinPoint, ResValue value) throws Throwable { 33 | if (!ShakaDecodeOption.getInstance().isIgnoreResDecodeError()) { 34 | joinPoint.proceed(joinPoint.getArgs()); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/ResStyleValue0.aj: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.apktool.lib; 2 | 3 | import brut.androlib.res.data.value.ResStyleValue; 4 | 5 | /** 6 | * Created by rover12421 on 12/5/15. 7 | */ 8 | privileged public aspect ResStyleValue0 { 9 | /** 10 | * 返回值需要调用的时候强转成 Duo[] 11 | * aspectj 1.8.4 以后,写成Duo[]编译失败 12 | * @return 13 | */ 14 | public Object ResStyleValue.getItems() { 15 | return this.mItems; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/ResStyleValueAj.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.apktool.lib; 17 | 18 | import brut.androlib.AndrolibException; 19 | import brut.androlib.res.data.ResResSpec; 20 | import brut.androlib.res.data.ResResource; 21 | import brut.androlib.res.data.value.*; 22 | import brut.util.Duo; 23 | import org.aspectj.lang.ProceedingJoinPoint; 24 | import org.aspectj.lang.annotation.Around; 25 | import org.aspectj.lang.annotation.Aspect; 26 | import org.xmlpull.v1.XmlSerializer; 27 | 28 | import java.io.IOException; 29 | 30 | /** 31 | * Created by rover12421 on 8/9/14. 32 | */ 33 | @Aspect 34 | public class ResStyleValueAj { 35 | /** 36 | * package brut.androlib.res.data.value 37 | * public class ResStyleValue extends ResBagValue implements ResValuesXmlSerializable 38 | * public void serializeToResValuesXml(XmlSerializer serializer,ResResource res) 39 | * 40 | 41 | com.carrot.carrotfantasy.apk 42 | 43 | Exception in thread "main" java.lang.ClassCastException: brut.androlib.res.data.value.ResStyleValue cannot be cast to brut.androlib.res.data.value.ResAttr 44 | at brut.androlib.res.data.value.ResStyleValue.serializeToResValuesXml(ResStyleValue.java:65) 45 | at brut.androlib.res.AndrolibResources.generateValuesFile(AndrolibResources.java:564) 46 | at brut.androlib.res.AndrolibResources.decode(AndrolibResources.java:327) 47 | at brut.androlib.Androlib.decodeResourcesFull(Androlib.java:123) 48 | at brut.androlib.ApkDecoder.decode(ApkDecoder.java:102) 49 | at brut.apktool.Main.cmdDecode(Main.java:170) 50 | at brut.apktool.Main.main(Main.java:86) 51 | 52 | */ 53 | @Around("execution(void brut.androlib.res.data.value.ResStyleValue.serializeToResValuesXml(..))" + 54 | "&& args(serializer, res)") 55 | public void serializeToResValuesXml(ProceedingJoinPoint joinPoint, XmlSerializer serializer, 56 | ResResource res) throws IOException, AndrolibException { 57 | try { 58 | ResStyleValue thiz = (ResStyleValue) joinPoint.getThis(); 59 | ResReferenceValue mParent = thiz.getParent(); 60 | Duo[] mItems = (Duo[])thiz.getItems(); 61 | serializer.startTag(null, "style"); 62 | serializer.attribute(null, "name", res.getResSpec().getName()); 63 | if (!mParent.isNull() && !mParent.referentIsNull()) { 64 | serializer.attribute(null, "parent", mParent.encodeAsResXmlAttr()); 65 | } else if (res.getResSpec().getName().indexOf('.') != -1) { 66 | serializer.attribute(null, "parent", ""); 67 | } 68 | for (int i = 0; i < mItems.length; i++) { 69 | ResResSpec spec = mItems[i].m1.getReferent(); 70 | String name; 71 | String value = null; 72 | 73 | String resource = spec.getDefaultResource().getValue().toString(); 74 | // hacky-fix remove bad ReferenceVars 75 | if (resource.contains("ResReferenceValue@")) { 76 | continue; 77 | } else if (resource.contains("ResStringValue@")) { 78 | name = "@" + spec.getFullName(res.getResSpec().getPackage(), false); 79 | } else { 80 | // ResAttr attr = (ResAttr) spec.getDefaultResource().getValue(); 81 | ResValue resValue = spec.getDefaultResource().getValue(); 82 | if (!(resValue instanceof ResAttr)) { 83 | //异常跳过 84 | continue; 85 | } 86 | ResAttr attr = (ResAttr)resValue; 87 | value = attr.convertToResXmlFormat(mItems[i].m2); 88 | name = spec.getFullName(res.getResSpec().getPackage(), true); 89 | } 90 | 91 | if (value == null) { 92 | value = mItems[i].m2.encodeAsResXmlValue(); 93 | } 94 | 95 | if (value == null) { 96 | continue; 97 | } 98 | 99 | serializer.startTag(null, "item"); 100 | serializer.attribute(null, "name", name); 101 | serializer.text(value); 102 | serializer.endTag(null, "item"); 103 | } 104 | serializer.endTag(null, "style"); 105 | } catch (Throwable e) { 106 | e.printStackTrace(); 107 | } 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/ResTypeAj.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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.rover12421.shaka.apktool.lib; 18 | 19 | import brut.androlib.AndrolibException; 20 | import brut.androlib.res.data.ResResSpec; 21 | import brut.androlib.res.data.ResResource; 22 | import brut.androlib.res.data.value.ResFileValue; 23 | import brut.androlib.res.data.value.ResValue; 24 | import com.rover12421.shaka.lib.LogHelper; 25 | import org.aspectj.lang.ProceedingJoinPoint; 26 | import org.aspectj.lang.annotation.Around; 27 | import org.aspectj.lang.annotation.Aspect; 28 | 29 | import java.util.HashMap; 30 | import java.util.Map; 31 | 32 | /** 33 | * Created by rover12421 on 8/2/14. 34 | */ 35 | @Aspect 36 | public class ResTypeAj { 37 | 38 | public final static Map MultopleResFileValue = new HashMap<>(); 39 | 40 | //重复资源前缀 41 | public final static String MultipleSpec_Perfix = "_?m@"; 42 | 43 | @Around("execution(void brut.androlib.res.data.ResType.addResource(..))" + 44 | "&& args(res, overwrite)") 45 | public void addResource(ProceedingJoinPoint joinPoint, ResResource res, boolean overwrite) throws Throwable { 46 | ResResSpec spec = res.getResSpec(); 47 | 48 | ResResSpec resSpec = ResTypeSpecAj.MultipleSpecs.get(spec.getId().id); 49 | if (resSpec != null) { 50 | //有重复的ResResSpec 51 | ResValue resValue = res.getValue(); 52 | String rename; 53 | if (resValue instanceof ResFileValue) { 54 | ResFileValue fileValue = (ResFileValue) resValue; 55 | rename = fileValue.getPath().replaceAll("/|\\\\|\\.", "_"); 56 | MultopleResFileValue.put(spec.getId().id, res); 57 | } else { 58 | rename = MultipleSpec_Perfix + spec.getId(); 59 | } 60 | 61 | if (rename != null) { 62 | // LogHelper.warning("Rename ResResSpec " + spec.getName() + " to " + rename); 63 | ResResSpecAj.setName(spec, rename); 64 | ResTypeSpecAj.addSpecToResType(spec); 65 | } 66 | } 67 | 68 | try { 69 | joinPoint.proceed(joinPoint.getArgs()); 70 | } catch (AndrolibException e) { 71 | LogHelper.warning(e.getMessage()); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/ResTypeSpecAj.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.apktool.lib; 17 | 18 | import brut.androlib.AndrolibException; 19 | import brut.androlib.res.data.ResResSpec; 20 | import brut.androlib.res.data.ResTypeSpec; 21 | import com.rover12421.shaka.lib.LogHelper; 22 | import org.aspectj.lang.ProceedingJoinPoint; 23 | import org.aspectj.lang.annotation.Around; 24 | import org.aspectj.lang.annotation.Aspect; 25 | 26 | import java.util.HashMap; 27 | import java.util.Map; 28 | 29 | /** 30 | * Created by rover12421 on 7/30/15. 31 | */ 32 | @Aspect 33 | public class ResTypeSpecAj { 34 | 35 | public final static Map MultipleSpecs = new HashMap<>(); 36 | public final static Map AllSpecs = new HashMap<>(); 37 | 38 | public static void addMultipleResResSpec(ResResSpec spec) { 39 | MultipleSpecs.put(spec.getId().id, spec); 40 | } 41 | 42 | public static void addAllResResSpec(ResResSpec spec) { 43 | AllSpecs.put(spec.getId().id, spec); 44 | } 45 | 46 | @Around("execution(* brut.androlib.res.data.ResTypeSpec.addResSpec(..))" + 47 | "&& args(spec)") 48 | public void addResSpec(ProceedingJoinPoint joinPoint, ResResSpec spec) throws Throwable { 49 | ResTypeSpec thiz = (ResTypeSpec) joinPoint.getThis(); 50 | 51 | addAllResResSpec(spec); 52 | 53 | ResResSpec exitsSpec = null; 54 | try { 55 | exitsSpec = thiz.getResSpec(spec.getName()); 56 | } catch (Exception e) { 57 | } 58 | 59 | if (exitsSpec == null) { 60 | joinPoint.proceed(joinPoint.getArgs()); 61 | } else { 62 | LogHelper.warning(String.format( 63 | "Multiple res specs: %s/%s", thiz.getName(), spec.getName())); 64 | if (exitsSpec.getId() != spec.getId()) { 65 | addMultipleResResSpec(spec); 66 | addMultipleResResSpec(exitsSpec); 67 | } 68 | } 69 | } 70 | 71 | public static void addSpecToResType(ResResSpec spec) { 72 | ResTypeSpec type = spec.getType(); 73 | ResResSpec findSpec = null; 74 | try { 75 | findSpec = type.getResSpec(spec.getName()); 76 | } catch (Exception e) { 77 | } 78 | if (findSpec == null) { 79 | try { 80 | type.addResSpec(spec); 81 | } catch (AndrolibException e) { 82 | } 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/ResValueFactoryAj.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.apktool.lib; 17 | 18 | import brut.androlib.res.data.ResTypeSpec; 19 | import brut.androlib.res.data.value.ResFileValue; 20 | import brut.androlib.res.data.value.ResIntBasedValue; 21 | import brut.androlib.res.data.value.ResStringValue; 22 | import org.aspectj.lang.annotation.Aspect; 23 | 24 | import java.util.Arrays; 25 | import java.util.List; 26 | 27 | /** 28 | * Created by rover12421 on 7/31/15. 29 | */ 30 | @Aspect 31 | public class ResValueFactoryAj { 32 | /** 33 | * 可能是文件的资源类型 34 | */ 35 | private static final List HavaFileTypes = Arrays.asList( 36 | "anim", 37 | "animator", 38 | "color", 39 | "drawable", 40 | "interpolator", 41 | "layout", 42 | "menu", 43 | "mipmap", 44 | "raw", 45 | "transition", 46 | "xml" 47 | ); 48 | 49 | public static ResIntBasedValue factory(ResTypeSpec mTypeSpec, String value, int rawValue) { 50 | String typeName = mTypeSpec.getName(); 51 | if (HavaFileTypes.contains(typeName) && 52 | ( 53 | !typeName.startsWith("@") || 54 | !typeName.startsWith("#") || 55 | !typeName.startsWith("?") 56 | ) 57 | ) { 58 | return new ResFileValue(value, rawValue); 59 | } 60 | return new ResStringValue(value, rawValue); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/ResXmlEncodersAj.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.apktool.lib; 2 | 3 | import org.aspectj.lang.ProceedingJoinPoint; 4 | import org.aspectj.lang.annotation.Around; 5 | import org.aspectj.lang.annotation.Aspect; 6 | 7 | /** 8 | * Created by rover12421 on 9/22/15. 9 | * 10 | * brut.androlib.res.xml.ResXmlEncoders 11 | */ 12 | @Aspect 13 | public class ResXmlEncodersAj { 14 | 15 | @Around("execution(* brut.androlib.res.xml.ResXmlEncoders.encodeAsXmlValue(..))" + 16 | "&& args(str)") 17 | public String encodeAsXmlValue(ProceedingJoinPoint joinPoint, String str) throws Throwable { 18 | if (str == null) { 19 | return ""; 20 | } 21 | return (String) joinPoint.proceed(joinPoint.getArgs()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/StringBlock0.aj: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.apktool.lib; 2 | 3 | import brut.androlib.res.decoder.StringBlock; 4 | 5 | /** 6 | * Created by rover12421 on 2/1/16. 7 | */ 8 | privileged public aspect StringBlock0 { 9 | public int[] StringBlock.getStyles() { 10 | return m_styles; 11 | } 12 | 13 | public int[] StringBlock.getStyleOffsets() { 14 | return m_styleOffsets; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/lib/StringBlockAj.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.apktool.lib; 17 | 18 | import brut.androlib.res.decoder.StringBlock; 19 | import com.rover12421.shaka.lib.LogHelper; 20 | import org.aspectj.lang.ProceedingJoinPoint; 21 | import org.aspectj.lang.annotation.Around; 22 | import org.aspectj.lang.annotation.Aspect; 23 | 24 | /** 25 | * Created by rover12421 on 4/1/15. 26 | */ 27 | @Aspect 28 | public class StringBlockAj { 29 | @Around("execution(* brut.androlib.res.decoder.StringBlock.outputStyleTag(..))" + 30 | "&& args(tag, builder, close)") 31 | public void outputStyleTag(ProceedingJoinPoint joinPoint, String tag, StringBuilder builder, boolean close) throws Throwable { 32 | String newTag = tag.replaceAll(";+", ";"); 33 | if (!newTag.equals(tag)) { 34 | LogHelper.info("outputStyleTag " + tag + " >>> " + newTag); 35 | } 36 | 37 | joinPoint.proceed(new Object[]{newTag, builder, close}); 38 | } 39 | 40 | @Around("execution(* brut.androlib.res.decoder.StringBlock.getStyle(..))" + 41 | "&& args(index)") 42 | public int[] getStyle(ProceedingJoinPoint joinPoint, int index) throws Throwable { 43 | StringBlock thiz = (StringBlock) joinPoint.getThis(); 44 | int[] m_styleOffsets = thiz.getStyleOffsets(); 45 | int[] m_styles = thiz.getStyles(); 46 | if (m_styleOffsets == null || m_styles == null|| index >= m_styleOffsets.length) { 47 | return null; 48 | } 49 | int offset = m_styleOffsets[index] / 4; 50 | if (offset < 0 || offset > m_styles.length) { 51 | return null; 52 | } 53 | return (int[]) joinPoint.proceed(joinPoint.getArgs()); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/meta/MetaInfo0.aj: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.apktool.meta; 2 | 3 | import brut.androlib.meta.MetaInfo; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * Created by rover12421 on 1/21/16. 10 | */ 11 | public aspect MetaInfo0 { 12 | public Map MetaInfo.decodeFileMaps; 13 | public Map MetaInfo.dexMaps; 14 | public String MetaInfo.shakaVer; 15 | 16 | public String MetaInfo.addDexMap(String key, String val) { 17 | if (dexMaps == null) { 18 | dexMaps = new HashMap(); 19 | } 20 | return dexMaps.put(key, val); 21 | } 22 | 23 | public String MetaInfo.getDexMap(String key) { 24 | if (dexMaps == null) { 25 | return null; 26 | } 27 | 28 | return dexMaps.get(key); 29 | } 30 | 31 | public String MetaInfo.addDecodeFileMap(String key, String val) { 32 | if (decodeFileMaps == null) { 33 | decodeFileMaps = new HashMap<>(); 34 | } 35 | 36 | return decodeFileMaps.put(key, val); 37 | } 38 | 39 | public String MetaInfo.getDecodeFileMap(String key) { 40 | if (decodeFileMaps == null) { 41 | return null; 42 | } 43 | 44 | return decodeFileMaps.get(key); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/java/com/rover12421/shaka/apktool/util/Global.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.apktool.util; 2 | 3 | import org.aspectj.lang.annotation.Aspect; 4 | import org.aspectj.lang.annotation.Before; 5 | 6 | /** 7 | * Created by rover12421 on 11/20/15. 8 | */ 9 | @Aspect 10 | public class Global { 11 | private static String packageName; 12 | 13 | public static String getPackageName() { 14 | return packageName; 15 | } 16 | 17 | public static void setPackageName(String packageName) { 18 | Global.packageName = packageName; 19 | } 20 | 21 | /************************************************/ 22 | @Before("execution(* brut.androlib.res.data.ResTable.setPackageRenamed(..))" + 23 | "&& args(pkg)") 24 | public void setPackageRenamed(String pkg) { 25 | setPackageName(pkg); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /shaka/apktool/src/main/resources/png/Shaka.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rover12421/ShakaApktool/158767230d533d4a9e4b9f74d571705d77701c1f/shaka/apktool/src/main/resources/png/Shaka.9.png -------------------------------------------------------------------------------- /shaka/apktool/src/main/resources/png/Shaka.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rover12421/ShakaApktool/158767230d533d4a9e4b9f74d571705d77701c1f/shaka/apktool/src/main/resources/png/Shaka.png -------------------------------------------------------------------------------- /shaka/apktool/src/main/resources/xml/Shaka.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /shaka/apktool/src/test/java/com/rover12421/shaka/apktool/test/BuildAndDecodeTest0.aj: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.apktool.test; 2 | 3 | import brut.androlib.BuildAndDecodeTest; 4 | import brut.directory.ExtFile; 5 | 6 | /** 7 | * Created by rover12421 on 12/5/15. 8 | */ 9 | privileged public aspect BuildAndDecodeTest0 { 10 | public static ExtFile BuildAndDecodeTest.getTestOrigDir() { 11 | return BuildAndDecodeTest.sTestOrigDir; 12 | } 13 | 14 | public static ExtFile BuildAndDecodeTest.getTestNewDir() { 15 | return BuildAndDecodeTest.sTestNewDir; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /shaka/apktool/src/test/java/com/rover12421/shaka/apktool/test/SkipPlatformBuildVersionAj.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.apktool.test; 2 | 3 | import brut.androlib.BuildAndDecodeTest; 4 | import brut.directory.ExtFile; 5 | import org.aspectj.lang.ProceedingJoinPoint; 6 | import org.aspectj.lang.annotation.Around; 7 | import org.aspectj.lang.annotation.Aspect; 8 | import org.aspectj.lang.annotation.Before; 9 | import org.custommonkey.xmlunit.ElementQualifier; 10 | 11 | import java.io.IOException; 12 | import java.nio.file.Files; 13 | import java.nio.file.Path; 14 | import java.nio.file.Paths; 15 | 16 | /** 17 | * Created by rover12421 on 11/19/15. 18 | * 19 | * 目前已经发现`Linux`平台下, `aapt 21.0.0`之后,打包会使用`aapt`自带版本覆盖原有的 `platformBuildVersion` 20 | * 等待官方修复 21 | * 因该属性不重要,暂时强制修正,仅用于`test case` 22 | */ 23 | @Aspect 24 | public class SkipPlatformBuildVersionAj { 25 | 26 | private String replacePlatformBuildVersion(String src, 27 | String platformBuildVersionCode, 28 | String platformBuildVersionName) { 29 | return src 30 | .replaceAll("(.+?platformBuildVersionCode=\")([^\"]+?)(\".+?)", "$1" + platformBuildVersionCode + "$3") 31 | .replaceAll("(.+?platformBuildVersionName=\")([^\"]+?)(\".+?)", "$1" + platformBuildVersionName + "$3"); 32 | } 33 | 34 | @Before("execution(* brut.androlib.BuildAndDecodeTest.compareXmlFiles(..))" + 35 | "&& args(path, qualifier)") 36 | public void compareXmlFiles(String path, ElementQualifier qualifier) { 37 | try { 38 | ExtFile sTestOrigDir = BuildAndDecodeTest.getTestOrigDir(); 39 | ExtFile sTestNewDir = BuildAndDecodeTest.getTestNewDir(); 40 | Path originPath = Paths.get(sTestOrigDir.getAbsolutePath(), path); 41 | Path newPath = Paths.get(sTestNewDir.getAbsolutePath(), path); 42 | String originString = new String(Files.readAllBytes(originPath)); 43 | String newString = new String(Files.readAllBytes(newPath)); 44 | 45 | String platformBuildVersionCode = originString 46 | .replaceAll("[\\r\\n]", "") 47 | .replaceAll(".+platformBuildVersionCode=\"([^\"]+?)\".+", "$1"); 48 | String platformBuildVersionName = originString 49 | .replaceAll("[\\r\\n]", "") 50 | .replaceAll(".+platformBuildVersionName=\"([^\"]+?)\".+", "$1"); 51 | newString = replacePlatformBuildVersion(newString, platformBuildVersionCode, platformBuildVersionName); 52 | 53 | Files.write(newPath, newString.getBytes()); 54 | } catch (IOException e) { 55 | e.printStackTrace(); 56 | } 57 | } 58 | 59 | @Around("execution(* brut.androlib.ProviderAttributeTest.replaceNewlines(..))" + 60 | "&& args(value)") 61 | public String replaceNewlines(ProceedingJoinPoint joinPoint, String value) throws Throwable { 62 | value = replacePlatformBuildVersion(value, "22", "5.1-1756733"); 63 | return (String) joinPoint.proceed(new Object[]{value}); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /shaka/build.gradle: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | ext.shakaVersion = "$ver-$branch-$hash-$date" 18 | ext.shakaDebug = false 19 | 20 | buildscript { 21 | repositories { 22 | jcenter() 23 | maven { 24 | url "https://maven.eveoh.nl/content/repositories/releases" 25 | } 26 | } 27 | tasks.withType(JavaCompile) { 28 | options.encoding = "UTF-8" 29 | options.incremental = true 30 | } 31 | dependencies { 32 | classpath 'eu.appsatori:gradle-fatjar-plugin:0.3' 33 | classpath 'nl.eveoh:gradle-aspectj:1.6' 34 | } 35 | } 36 | 37 | subprojects { 38 | apply plugin: 'aspectj' 39 | } 40 | 41 | // 过滤shaka:lib 42 | configure(subprojects - project(':shaka:lib')) { 43 | dependencies { 44 | compile project(':shaka:lib') 45 | // acj 的全局注入 46 | aspectpath files(project(':shaka:lib').buildDir) 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /shaka/cli/build.gradle: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | apply plugin: 'eu.appsatori.fatjar' 18 | 19 | configurations { 20 | proguard 21 | } 22 | 23 | dependencies { 24 | compile project(':shaka:apktool') 25 | 26 | proguard depends.proguard 27 | } 28 | 29 | gradle.taskGraph.whenReady { 30 | fatJar { 31 | manifest { 32 | attributes("Main-Class": "com.rover12421.shaka.cli.Main") 33 | } 34 | } 35 | } 36 | 37 | task proguard(type: JavaExec, dependsOn: fatJar) { 38 | def outFile = jar.destinationDir.getPath() + '/' + "ShakaApktool" + '_' + shakaVersion + '-release' + '.' + jar.extension 39 | inputs.file jar.archivePath 40 | outputs.file outFile 41 | 42 | def mappingFile = new File(outFile + ".mapping.txt"); 43 | 44 | classpath = configurations.proguard 45 | main = 'proguard.ProGuard' 46 | args '-injars ' + "${jar.archivePath}" + ' (!META-INF/LICENSE.txt,!META-INF/NOTICE.txt,!README)' 47 | args "-outjars ${outFile}" 48 | args "-libraryjars ${System.properties['java.home']}/lib/rt.jar" 49 | args "-printmapping ${mappingFile}" 50 | // args '-dontobfuscate' 51 | args '-dontoptimize' 52 | args '-dontnote **' 53 | args '-dontwarn **' 54 | args '-keep public class Main { public static void main(java.lang.String[]); }' 55 | args '-keep public class com.rover12421.shaka.cli.Main { public static void main(java.lang.String[]); }' 56 | args '-keep class org.yaml.snakeyaml.** { public protected private *; }' 57 | args '-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); }' 58 | args '-keepclassmembers class brut.androlib.res.data.ResResSpec { *** mName; }' 59 | args '-keepclassmembers class brut.androlib.res.data.value.ResFileValue { *** mPath; }' 60 | args '-keepclassmembers class brut.androlib.meta.** { public ; }' 61 | } 62 | 63 | tasks.getByPath(':release').dependsOn(proguard) 64 | -------------------------------------------------------------------------------- /shaka/cli/src/main/java/com/rover12421/shaka/cli/MainOld.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.cli; 17 | 18 | import com.rover12421.shaka.apktool.cli.ApktoolMainAj; 19 | import com.rover12421.shaka.lib.cli.CommandLineArgEnum; 20 | import com.rover12421.shaka.lib.multiLanguage.MultiLanguageSupport; 21 | import com.rover12421.shaka.smali.baksmali.baksmaliMainAj; 22 | import com.rover12421.shaka.smali.smali.smaliMainAj; 23 | import org.apache.commons.cli.*; 24 | 25 | import java.util.ArrayList; 26 | import java.util.ListIterator; 27 | import java.util.Locale; 28 | 29 | /** 30 | * Created by rover12421 on 7/11/14. 31 | */ 32 | public class MainOld { 33 | 34 | public static class IgnoreUnkownArgsPosixParser extends PosixParser { 35 | @Override 36 | protected void processOption(String arg, ListIterator iter) throws ParseException 37 | { 38 | try { 39 | super.processOption(arg, iter); 40 | } catch (ParseException e) { 41 | } 42 | } 43 | } 44 | 45 | public static void main(String[] args) throws Exception { 46 | boolean smali = false; 47 | boolean baksmali = false; 48 | 49 | String[] realyArgs = args; 50 | 51 | if (args.length > 0) { 52 | String cmd = args[0]; 53 | if (cmd.equalsIgnoreCase("s") || cmd.equalsIgnoreCase("smali")) { 54 | smali = true; 55 | } else if (cmd.equalsIgnoreCase("bs") || cmd.equalsIgnoreCase("baksmali")) { 56 | baksmali = true; 57 | } 58 | 59 | if (smali || baksmali) { 60 | realyArgs = new String[args.length-1]; 61 | System.arraycopy(args, 1, realyArgs, 0, realyArgs.length); 62 | } 63 | } 64 | 65 | // cli parser 66 | CommandLineParser parser = new IgnoreUnkownArgsPosixParser(); 67 | CommandLine commandLine; 68 | 69 | Option language = CommandLineArgEnum.LANGUAGE.getOption(); 70 | 71 | Options options = new Options(); 72 | options.addOption(language); 73 | 74 | try { 75 | commandLine = parser.parse(options, args, false); 76 | if (CommandLineArgEnum.LANGUAGE.hasMatch(commandLine)) { 77 | String lngStr = commandLine.getOptionValue(CommandLineArgEnum.LANGUAGE.getOpt()); 78 | Locale locale = Locale.forLanguageTag(lngStr); 79 | if (locale.toString().isEmpty()) { 80 | lngStr = lngStr.replaceAll("_", "-"); 81 | locale = Locale.forLanguageTag(lngStr); 82 | } 83 | MultiLanguageSupport.getInstance().setLang(locale); 84 | } 85 | } catch (Exception ex) { 86 | } 87 | 88 | if (smali) { 89 | smaliMainAj.setHookMain(ApktoolMainAj.getHookMain()); 90 | org.jf.smali.Main.main(realyArgs); 91 | } else if (baksmali) { 92 | baksmaliMainAj.setHookMain(ApktoolMainAj.getHookMain()); 93 | org.jf.baksmali.Main.main(realyArgs); 94 | } else { 95 | brut.apktool.Main.main(realyArgs); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /shaka/cli/src/main/java/com/rover12421/shaka/cli/apktool/BuildCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rover12421 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.rover12421.shaka.cli.apktool; 18 | 19 | import brut.androlib.Androlib; 20 | import brut.common.BrutException; 21 | import com.beust.jcommander.JCommander; 22 | import com.beust.jcommander.Parameter; 23 | import com.beust.jcommander.Parameters; 24 | import com.google.common.collect.Lists; 25 | import com.rover12421.shaka.cli.base.ApktoolUsingFrameworkCommand; 26 | import com.rover12421.shaka.cli.util.CommandUtil; 27 | import org.jf.util.jcommander.ExtendedParameter; 28 | import org.jf.util.jcommander.ExtendedParameters; 29 | 30 | import javax.annotation.Nonnull; 31 | import java.io.File; 32 | import java.util.List; 33 | 34 | /** 35 | * Created by rover12421 on 05/06/2017. 36 | */ 37 | @Parameters(commandDescription = "build files into a apk file.") 38 | @ExtendedParameters( 39 | commandName = "build", 40 | commandAliases = { "b" }) 41 | public class BuildCommand extends ApktoolUsingFrameworkCommand { 42 | 43 | public BuildCommand(@Nonnull List commandAncestors) { 44 | super(commandAncestors); 45 | } 46 | 47 | @Parameter(names = {"-c", "--copy-original"}, 48 | description = "Copies original AndroidManifest.xml and META-INF. See project page for more info.") 49 | private boolean copyOriginal = false; 50 | 51 | @Parameter(names = {"-a", "--aapt"}, 52 | description = "Loads aapt from specified location.") 53 | @ExtendedParameter(argumentNames = "loc") 54 | private String aaptPath; 55 | 56 | @Parameter(names = {"-df", "--default-framework"}, 57 | description = "Using default framework file.") 58 | private boolean defaultFramework = false; 59 | 60 | @Parameter(names = {"-f", "--force-all"}, 61 | description = "Skip changes detection and build all files.") 62 | private boolean forceAll = false; 63 | 64 | @Parameter(names = {"-o", "--output"}, 65 | description = "The name of apk that gets written. Default is dist/name.apk") 66 | @ExtendedParameter(argumentNames = "loc") 67 | private String output; 68 | 69 | @Parameter(description = "decode directory.") 70 | @ExtendedParameter(argumentNames = "dir") 71 | protected List inputList = Lists.newArrayList(); 72 | 73 | @Override 74 | public void run() { 75 | super.run(); 76 | 77 | String input = CommandUtil.getInput(this, inputList); 78 | apkOptions.forceBuildAll = forceAll; 79 | apkOptions.aaptPath = aaptPath; 80 | apkOptions.copyOriginalFiles = copyOriginal; 81 | File outFile = null; 82 | if (output != null) { 83 | outFile = new File(output); 84 | } 85 | 86 | try { 87 | new Androlib(apkOptions).build(new File(input), outFile); 88 | } catch (BrutException e) { 89 | CommandUtil.exceptionExit(e); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /shaka/cli/src/main/java/com/rover12421/shaka/cli/apktool/EmptyFrameworkDirCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rover12421 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.rover12421.shaka.cli.apktool; 18 | 19 | import brut.androlib.Androlib; 20 | import brut.androlib.AndrolibException; 21 | import com.beust.jcommander.JCommander; 22 | import com.beust.jcommander.Parameter; 23 | import com.beust.jcommander.Parameters; 24 | import com.rover12421.shaka.cli.base.ApktoolUsingFrameworkCommand; 25 | import com.rover12421.shaka.cli.util.CommandUtil; 26 | import org.jf.util.jcommander.ExtendedParameters; 27 | 28 | import javax.annotation.Nonnull; 29 | import java.util.List; 30 | 31 | /** 32 | * Created by rover12421 on 6/6/17. 33 | */ 34 | @Parameters(commandDescription = "empty framework dir") 35 | @ExtendedParameters( 36 | commandName = "empty-framework-dir", 37 | commandAliases = { "ef" }) 38 | public class EmptyFrameworkDirCommand extends ApktoolUsingFrameworkCommand { 39 | public EmptyFrameworkDirCommand(@Nonnull List commandAncestors) { 40 | super(commandAncestors); 41 | } 42 | 43 | @Parameter(names = {"-f", "--force"}, 44 | description = "Force delete destination directory.") 45 | private boolean force = false; 46 | 47 | @Override 48 | public void run() { 49 | super.run(); 50 | 51 | apkOptions.forceDeleteFramework = force; 52 | try { 53 | new Androlib(apkOptions).emptyFrameworkDirectory(); 54 | } catch (AndrolibException e) { 55 | CommandUtil.exceptionExit(e); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /shaka/cli/src/main/java/com/rover12421/shaka/cli/apktool/InstallFrameworkCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rover12421 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.rover12421.shaka.cli.apktool; 18 | 19 | import brut.androlib.Androlib; 20 | import brut.androlib.AndrolibException; 21 | import brut.androlib.ApkOptions; 22 | import com.beust.jcommander.JCommander; 23 | import com.beust.jcommander.Parameter; 24 | import com.beust.jcommander.Parameters; 25 | import com.google.common.collect.Lists; 26 | import com.rover12421.shaka.cli.base.ApktoolUsingFrameworkCommand; 27 | import com.rover12421.shaka.cli.util.CommandUtil; 28 | import org.jf.util.jcommander.ExtendedParameter; 29 | import org.jf.util.jcommander.ExtendedParameters; 30 | 31 | import javax.annotation.Nonnull; 32 | import java.io.File; 33 | import java.util.List; 34 | 35 | /** 36 | * Created by rover12421 on 6/6/17. 37 | */ 38 | @Parameters(commandDescription = "install framework file.") 39 | @ExtendedParameters( 40 | commandName = "install-framework", 41 | commandAliases = { "if" }) 42 | public class InstallFrameworkCommand extends ApktoolUsingFrameworkCommand { 43 | public InstallFrameworkCommand(@Nonnull List commandAncestors) { 44 | super(commandAncestors); 45 | } 46 | 47 | @Parameter(names = {"-t", "--tag"}, 48 | description = "Tag frameworks using .") 49 | @ExtendedParameter(argumentNames = "tag") 50 | private String tag; 51 | 52 | @Parameter(description = "A apk file.") 53 | @ExtendedParameter(argumentNames = "apk") 54 | protected List inputList = Lists.newArrayList(); 55 | 56 | @Override 57 | public void run() { 58 | super.run(); 59 | 60 | String input = CommandUtil.getInput(this, inputList); 61 | 62 | apkOptions.frameworkTag = tag; 63 | try { 64 | new Androlib(apkOptions).installFramework(new File(input)); 65 | } catch (AndrolibException e) { 66 | CommandUtil.exceptionExit(e); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /shaka/cli/src/main/java/com/rover12421/shaka/cli/apktool/PublicizeResourcesCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rover12421 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.rover12421.shaka.cli.apktool; 18 | 19 | import brut.androlib.Androlib; 20 | import brut.androlib.AndrolibException; 21 | import com.beust.jcommander.JCommander; 22 | import com.beust.jcommander.Parameter; 23 | import com.beust.jcommander.Parameters; 24 | import com.google.common.collect.Lists; 25 | import com.rover12421.shaka.cli.base.ApktoolDefaultCommand; 26 | import com.rover12421.shaka.cli.util.CommandUtil; 27 | import org.jf.util.jcommander.ExtendedParameter; 28 | import org.jf.util.jcommander.ExtendedParameters; 29 | 30 | import javax.annotation.Nonnull; 31 | import java.io.File; 32 | import java.util.List; 33 | 34 | /** 35 | * Created by rover12421 on 6/6/17. 36 | */ 37 | @Parameters(commandDescription = "publicize resources file") 38 | @ExtendedParameters( 39 | commandName = "publicize-resources", 40 | commandAliases = { "pr" }) 41 | public class PublicizeResourcesCommand extends ApktoolDefaultCommand { 42 | public PublicizeResourcesCommand(@Nonnull List commandAncestors) { 43 | super(commandAncestors); 44 | } 45 | 46 | @Parameter(description = "A arsc file.") 47 | @ExtendedParameter(argumentNames = "arsc") 48 | protected List inputList = Lists.newArrayList(); 49 | 50 | @Override 51 | public void run() { 52 | super.run(); 53 | 54 | String input = CommandUtil.getInput(this, inputList); 55 | try { 56 | new Androlib().publicizeResources(new File(input)); 57 | } catch (AndrolibException e) { 58 | CommandUtil.exceptionExit(e); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /shaka/cli/src/main/java/com/rover12421/shaka/cli/baksmali/DeodexCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rover12421 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.rover12421.shaka.cli.baksmali; 18 | 19 | import com.beust.jcommander.JCommander; 20 | import com.beust.jcommander.Parameter; 21 | import com.beust.jcommander.Parameters; 22 | import org.jf.util.jcommander.ExtendedParameter; 23 | import org.jf.util.jcommander.ExtendedParameters; 24 | 25 | import javax.annotation.Nonnull; 26 | import java.util.List; 27 | import java.util.Locale; 28 | 29 | /** 30 | * Created by rover12421 on 06/06/2017. 31 | */ 32 | @Parameters(commandDescription = "Deodexes an odex/oat file") 33 | @ExtendedParameters( 34 | commandName = "deodex", 35 | commandAliases = { "de", "x" }) 36 | public class DeodexCommand extends org.jf.baksmali.DeodexCommand { 37 | public DeodexCommand(@Nonnull List commandAncestors) { 38 | super(commandAncestors); 39 | } 40 | 41 | @Parameter(names = {"-lng", "--language"}, help = true, 42 | description = "Display language, e.g. zh-CN, zh-TW.") 43 | @ExtendedParameter(argumentNames = "Locale") 44 | protected String localeStr = Locale.getDefault().toLanguageTag(); 45 | } 46 | -------------------------------------------------------------------------------- /shaka/cli/src/main/java/com/rover12421/shaka/cli/baksmali/DisassembleCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rover12421 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.rover12421.shaka.cli.baksmali; 18 | 19 | import com.beust.jcommander.JCommander; 20 | import com.beust.jcommander.Parameter; 21 | import com.beust.jcommander.Parameters; 22 | import org.jf.util.jcommander.ExtendedParameter; 23 | import org.jf.util.jcommander.ExtendedParameters; 24 | 25 | import javax.annotation.Nonnull; 26 | import java.util.List; 27 | import java.util.Locale; 28 | 29 | /** 30 | * Created by rover12421 on 06/06/2017. 31 | */ 32 | @Parameters(commandDescription = "Disassembles a dex file.") 33 | @ExtendedParameters( 34 | commandName = "disassemble", 35 | commandAliases = { "dis", "dex", "baksmali", "bs" }) 36 | public class DisassembleCommand extends org.jf.baksmali.DisassembleCommand { 37 | public DisassembleCommand(@Nonnull List commandAncestors) { 38 | super(commandAncestors); 39 | } 40 | 41 | @Parameter(names = {"-lng", "--language"}, help = true, 42 | description = "Display language, e.g. zh-CN, zh-TW.") 43 | @ExtendedParameter(argumentNames = "Locale") 44 | protected String localeStr = Locale.getDefault().toLanguageTag(); 45 | } 46 | -------------------------------------------------------------------------------- /shaka/cli/src/main/java/com/rover12421/shaka/cli/baksmali/DumpCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rover12421 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.rover12421.shaka.cli.baksmali; 18 | 19 | import com.beust.jcommander.JCommander; 20 | import com.beust.jcommander.Parameter; 21 | import com.beust.jcommander.Parameters; 22 | import org.jf.util.jcommander.ExtendedParameter; 23 | import org.jf.util.jcommander.ExtendedParameters; 24 | 25 | import javax.annotation.Nonnull; 26 | import java.util.List; 27 | import java.util.Locale; 28 | 29 | /** 30 | * Created by rover12421 on 06/06/2017. 31 | */ 32 | @Parameters(commandDescription = "Prints an annotated hex dump for the given dex file") 33 | @ExtendedParameters( 34 | commandName = "dump", 35 | commandAliases = "du") 36 | public class DumpCommand extends org.jf.baksmali.DumpCommand { 37 | public DumpCommand(@Nonnull List commandAncestors) { 38 | super(commandAncestors); 39 | } 40 | 41 | @Parameter(names = {"-lng", "--language"}, help = true, 42 | description = "Display language, e.g. zh-CN, zh-TW.") 43 | @ExtendedParameter(argumentNames = "Locale") 44 | protected String localeStr = Locale.getDefault().toLanguageTag(); 45 | } 46 | -------------------------------------------------------------------------------- /shaka/cli/src/main/java/com/rover12421/shaka/cli/baksmali/ListCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rover12421 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.rover12421.shaka.cli.baksmali; 18 | 19 | import com.beust.jcommander.JCommander; 20 | import com.beust.jcommander.Parameter; 21 | import com.beust.jcommander.Parameters; 22 | import org.jf.util.jcommander.ExtendedParameter; 23 | import org.jf.util.jcommander.ExtendedParameters; 24 | 25 | import javax.annotation.Nonnull; 26 | import java.util.List; 27 | import java.util.Locale; 28 | 29 | /** 30 | * Created by rover12421 on 06/06/2017. 31 | */ 32 | @Parameters(commandDescription = "Lists various objects in a dex file.") 33 | @ExtendedParameters( 34 | commandName = "list", 35 | commandAliases = "l") 36 | public class ListCommand extends org.jf.baksmali.ListCommand { 37 | public ListCommand(@Nonnull List commandAncestors) { 38 | super(commandAncestors); 39 | } 40 | 41 | @Parameter(names = {"-lng", "--language"}, help = true, 42 | description = "Display language, e.g. zh-CN, zh-TW.") 43 | @ExtendedParameter(argumentNames = "Locale") 44 | protected String localeStr = Locale.getDefault().toLanguageTag(); 45 | } 46 | -------------------------------------------------------------------------------- /shaka/cli/src/main/java/com/rover12421/shaka/cli/base/ApktoolDefaultCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rover12421 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.rover12421.shaka.cli.base; 18 | 19 | import brut.androlib.ApkOptions; 20 | import com.beust.jcommander.JCommander; 21 | import com.beust.jcommander.Parameter; 22 | import com.rover12421.shaka.cli.Main; 23 | 24 | import javax.annotation.Nonnull; 25 | import java.util.List; 26 | 27 | /** 28 | * Created by rover12421 on 6/6/17. 29 | */ 30 | public abstract class ApktoolDefaultCommand extends HelpAndLanguageCommand { 31 | public ApktoolDefaultCommand(@Nonnull List commandAncestors) { 32 | super(commandAncestors); 33 | } 34 | 35 | protected ApkOptions apkOptions = new ApkOptions(); 36 | 37 | @Parameter(names = {"-q", "--quiet"}, 38 | description = "suppress all output including errors.") 39 | protected boolean quiet = false; 40 | 41 | @Parameter(names = {"-v", "--verbose"}, 42 | description = "Generate verbose error messages.") 43 | protected boolean verbose = false; 44 | 45 | @Override 46 | public void run() { 47 | super.run(); 48 | // ApktoolMain.setupLogging(); 49 | 50 | apkOptions.verbose = verbose; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /shaka/cli/src/main/java/com/rover12421/shaka/cli/base/ApktoolUsingFrameworkCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rover12421 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.rover12421.shaka.cli.base; 18 | 19 | import brut.util.OSDetection; 20 | import com.beust.jcommander.JCommander; 21 | import com.beust.jcommander.Parameter; 22 | import org.jf.util.jcommander.ExtendedParameter; 23 | 24 | import javax.annotation.Nonnull; 25 | import java.io.File; 26 | import java.util.List; 27 | 28 | /** 29 | * Created by rover12421 on 6/6/17. 30 | */ 31 | public abstract class ApktoolUsingFrameworkCommand extends ApktoolDefaultCommand { 32 | public ApktoolUsingFrameworkCommand(@Nonnull List commandAncestors) { 33 | super(commandAncestors); 34 | } 35 | 36 | @Parameter(names = {"-p", "--frame-path"}, 37 | description = "Uses framework files located in .") 38 | @ExtendedParameter(argumentNames = "dir") 39 | protected String framePath = getDefaultFrameworkDir(); 40 | 41 | @Override 42 | public void run() { 43 | super.run(); 44 | 45 | apkOptions.frameworkFolderLocation = framePath; 46 | } 47 | 48 | private String getDefaultFrameworkDir() { 49 | File parentPath = new File(System.getProperty("user.home")); 50 | if (! parentPath.canWrite()) { 51 | parentPath = new File(System.getProperty("java.io.tmpdir")); 52 | } 53 | 54 | String path; 55 | if (OSDetection.isMacOSX()) { 56 | path = parentPath.getAbsolutePath() + String.format("%1$sLibrary%1$sShakaApktool%1$sframework", File.separatorChar); 57 | } else if (OSDetection.isWindows()) { 58 | path = parentPath.getAbsolutePath() + String.format("%1$sAppData%1$sLocal%1$sShakaApktool%1$sframework", File.separatorChar); 59 | } else { 60 | path = parentPath.getAbsolutePath() + String.format("%1$s.local%1$sshare%1$sShakaApktool%1$sframework", File.separatorChar); 61 | } 62 | return path; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /shaka/cli/src/main/java/com/rover12421/shaka/cli/base/HelpAndLanguageCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rover12421 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.rover12421.shaka.cli.base; 18 | 19 | import com.beust.jcommander.JCommander; 20 | import com.beust.jcommander.Parameter; 21 | import org.jf.util.jcommander.Command; 22 | import org.jf.util.jcommander.ExtendedParameter; 23 | 24 | import javax.annotation.Nonnull; 25 | import java.util.List; 26 | import java.util.Locale; 27 | 28 | /** 29 | * Created by rover12421 on 6/6/17. 30 | */ 31 | public abstract class HelpAndLanguageCommand extends Command { 32 | protected HelpAndLanguageCommand(@Nonnull List commandAncestors) { 33 | super(commandAncestors); 34 | } 35 | 36 | @Parameter(names = {"-h", "-?", "--help"}, help = true, 37 | description = "Show usage information for this command.") 38 | protected boolean help; 39 | 40 | @Parameter(names = {"-lng", "--language"}, help = true, 41 | description = "Display language, e.g. zh-CN, zh-TW.") 42 | @ExtendedParameter(argumentNames = "Locale") 43 | protected String localeStr = Locale.getDefault().toLanguageTag(); 44 | 45 | @Override 46 | public void run() { 47 | if (help) { 48 | usage(); 49 | System.exit(0); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /shaka/cli/src/main/java/com/rover12421/shaka/cli/smali/AssembleCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rover12421 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.rover12421.shaka.cli.smali; 18 | 19 | import com.beust.jcommander.JCommander; 20 | import com.beust.jcommander.Parameter; 21 | import com.beust.jcommander.Parameters; 22 | import org.jf.util.jcommander.ExtendedParameter; 23 | import org.jf.util.jcommander.ExtendedParameters; 24 | 25 | import javax.annotation.Nonnull; 26 | import java.util.List; 27 | import java.util.Locale; 28 | 29 | /** 30 | * Created by rover12421 on 06/06/2017. 31 | */ 32 | @Parameters(commandDescription = "Assembles smali files into a dex file.") 33 | @ExtendedParameters( 34 | commandName = "assemble", 35 | commandAliases = { "ass", "as", "a", "smali", "s" }) 36 | public class AssembleCommand extends org.jf.smali.AssembleCommand { 37 | public AssembleCommand(@Nonnull List commandAncestors) { 38 | super(commandAncestors); 39 | } 40 | 41 | @Parameter(names = {"-lng", "--language"}, help = true, 42 | description = "Display language, e.g. zh-CN, zh-TW.") 43 | @ExtendedParameter(argumentNames = "Locale") 44 | protected String localeStr = Locale.getDefault().toLanguageTag(); 45 | } 46 | -------------------------------------------------------------------------------- /shaka/cli/src/main/java/com/rover12421/shaka/cli/util/CommandUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rover12421 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.rover12421.shaka.cli.util; 18 | 19 | import com.beust.jcommander.JCommander; 20 | import com.beust.jcommander.Parameter; 21 | import com.beust.jcommander.Parameters; 22 | import org.jf.util.jcommander.Command; 23 | import org.jf.util.jcommander.ExtendedCommands; 24 | 25 | import java.lang.annotation.Annotation; 26 | import java.lang.reflect.Field; 27 | import java.lang.reflect.Proxy; 28 | import java.util.List; 29 | import java.util.Map; 30 | 31 | /** 32 | * Created by rover12421 on 6/6/17. 33 | */ 34 | public class CommandUtil { 35 | public static final int ExceptionExitCode = 1; 36 | 37 | public static String getInput(Command command, List inputList) { 38 | if (inputList == null || inputList.isEmpty()) { 39 | exceptionExit(command, ""); 40 | } 41 | 42 | if (inputList.size() > 1) { 43 | exceptionExit(command, "Too many files specified"); 44 | } 45 | 46 | return inputList.get(0); 47 | } 48 | 49 | public static void exceptionExit(JCommander command, Throwable throwable) { 50 | System.err.println(throwable.getMessage()); 51 | command.usage(); 52 | System.exit(ExceptionExitCode); 53 | } 54 | 55 | public static void exceptionExit(Command command, String msg) { 56 | System.err.println(msg); 57 | command.usage(); 58 | System.exit(ExceptionExitCode); 59 | } 60 | 61 | public static void exceptionExit(Throwable throwable) { 62 | System.err.println(throwable.getMessage()); 63 | System.exit(ExceptionExitCode); 64 | } 65 | 66 | public static void exceptionExit(String msg) { 67 | System.err.println(msg); 68 | System.exit(ExceptionExitCode); 69 | } 70 | 71 | public static void modifyAnnotationValue(Annotation annotation, String key, Object value) { 72 | try { 73 | Object handler = Proxy.getInvocationHandler(annotation); 74 | Field f = handler.getClass().getDeclaredField("memberValues"); 75 | f.setAccessible(true); 76 | Map memberValues = (Map) f.get(handler); 77 | memberValues.put(key, value); 78 | } catch (Throwable e) { 79 | throw new IllegalStateException(e); 80 | } 81 | } 82 | 83 | private static void setParameterDescriptionKey(Parameter parameter, String descriptionKey){ 84 | modifyAnnotationValue(parameter, "descriptionKey", descriptionKey); 85 | } 86 | 87 | private static void setParametersCommandDescriptionKey(Parameters parameters, String commandDescriptionKey){ 88 | modifyAnnotationValue(parameters, "commandDescriptionKey", commandDescriptionKey); 89 | } 90 | 91 | public static void addExtendedCommand(JCommander jc, Command command) { 92 | Class commandClass = command.getClass(); 93 | String commandName = ExtendedCommands.commandName(command); 94 | String prefix = "Command." + commandName; 95 | Parameters commandClassParameters = commandClass.getAnnotation(Parameters.class); 96 | if (commandClassParameters != null && commandClassParameters.commandDescriptionKey().isEmpty()) { 97 | //System.out.println(prefix + "=" + commandClassParameters.commandDescription()); 98 | setParametersCommandDescriptionKey(commandClassParameters, prefix); 99 | } 100 | prefix = prefix + "."; 101 | 102 | while (Command.class.isAssignableFrom(commandClass)) { 103 | Field[] declaredFields = commandClass.getDeclaredFields(); 104 | for (Field field : declaredFields) { 105 | Parameter parameterAnnotation = field.getAnnotation(Parameter.class); 106 | if (parameterAnnotation != null && parameterAnnotation.descriptionKey().isEmpty()) { 107 | String descriptionKey = prefix + field.getName(); 108 | //System.out.println(descriptionKey + "=" + parameterAnnotation.description()); 109 | setParameterDescriptionKey(parameterAnnotation, descriptionKey); 110 | } 111 | } 112 | 113 | commandClass = commandClass.getSuperclass(); 114 | } 115 | 116 | ExtendedCommands.addExtendedCommand(jc, command); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /shaka/lib/build.gradle: -------------------------------------------------------------------------------- 1 | import groovy.io.FileType 2 | import org.apache.tools.ant.filters.ReplaceTokens 3 | 4 | import java.nio.charset.StandardCharsets 5 | import java.nio.file.Files 6 | import java.nio.file.Paths 7 | import java.util.zip.CRC32 8 | 9 | /** 10 | * Copyright 2015 Rover12421 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | */ 24 | 25 | 26 | task genShakaAaptCrc32 { 27 | /** 28 | * 生成ShakaAapt下所有文件的Crc32值到属性文件 29 | */ 30 | def binDir = file('src/main/resources/ShakaAapt') 31 | def binDir_len = binDir.absolutePath.length() + 1 32 | def ShakaAaptProperties = file('src/main/resources/properties/ShakaAapt.properties') 33 | def props = new ArrayList() 34 | 35 | binDir.eachFileRecurse(FileType.FILES) { 36 | def crc32 = new CRC32() 37 | def buff = new byte[4096] 38 | def fis = it.newInputStream() 39 | def len 40 | while ((len = fis.read(buff)) != -1) { 41 | crc32.update(buff, 0, len) 42 | } 43 | fis.close() 44 | String name = it.absolutePath.substring(binDir_len).replace("/", ".").replace("\\", ".") 45 | String prop = name + "=" + Long.toHexString(crc32.value) 46 | props.add(prop) 47 | } 48 | Collections.sort(props, new Comparator() { 49 | @Override 50 | int compare(String s1, String s2) { 51 | if (s1.length() == s2.length()) { 52 | return s1.compareTo(s2) 53 | } else { 54 | return s1.length() - s2.length() 55 | } 56 | } 57 | }) 58 | Files.write(Paths.get(ShakaAaptProperties.absolutePath), props, StandardCharsets.UTF_8) 59 | } 60 | 61 | processResources { 62 | from('src/main/resources/properties') { 63 | include '**/*.properties' 64 | into 'properties' 65 | filter(ReplaceTokens, tokens: [shakaVersion: shakaVersion.toString(), shakaDebug: shakaDebug.toString()] ) 66 | } 67 | } 68 | 69 | processResources.dependsOn genShakaAaptCrc32 70 | 71 | dependencies { 72 | compile depends.commons_cli, 73 | depends.commons_io, 74 | depends.commons_compress 75 | } 76 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/AbsProperties.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.lib; 17 | 18 | import java.io.IOException; 19 | import java.io.InputStream; 20 | import java.util.Properties; 21 | 22 | /** 23 | * Created by rover12421 on 7/22/15. 24 | */ 25 | public abstract class AbsProperties { 26 | private Properties sProps; 27 | 28 | public String get(String key) { 29 | return get().getProperty(key); 30 | } 31 | 32 | private Properties get() { 33 | if (sProps == null) { 34 | loadProps(); 35 | } 36 | return sProps; 37 | } 38 | 39 | protected abstract String getPropertiesPath(); 40 | 41 | protected Properties getProps() { 42 | return get(); 43 | } 44 | 45 | private void loadProps() { 46 | sProps = new Properties(); 47 | try ( 48 | InputStream in = ShakaProperties.class.getResourceAsStream(getPropertiesPath()) 49 | ){ 50 | sProps.load(in); 51 | } catch (IOException e) { 52 | LogHelper.warning("Can't load properties."); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/AndroidZip.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.lib; 17 | 18 | import java.util.zip.ZipEntry; 19 | 20 | /** 21 | * Created by rover12421 on 1/1/14. 22 | */ 23 | public class AndroidZip { 24 | /** 25 | * 来源于aapt源代码 26 | * 位置: 27 | * /frameworks/base/tools/aapt/Package.cpp 28 | */ 29 | /* these formats are already compressed, or don't compress well */ 30 | private final static String kNoCompressExt[] = { 31 | ".jpg", ".jpeg", ".png", ".gif", 32 | ".wav", ".mp2", ".mp3", ".ogg", ".aac", 33 | ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet", 34 | ".rtttl", ".imy", ".xmf", ".mp4", ".m4a", 35 | ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2", 36 | ".amr", ".awb", ".wma", ".wmv" 37 | }; 38 | 39 | /** 40 | * 是否需要压缩 41 | * true : 需要压缩 42 | * false : 不需要压缩 43 | * @param path 44 | * @return 45 | */ 46 | public static boolean needCompress(String path) { 47 | String minPath = path.toLowerCase(); 48 | for (String ext : kNoCompressExt) { 49 | if (minPath.endsWith(ext)) { 50 | return false; 51 | } 52 | } 53 | 54 | return true; 55 | } 56 | 57 | /** 58 | * zip中的压缩方式 59 | * 需要压缩为ZipEntry.DEFLATED 60 | * 不需要压缩为ZipEntry.STORED 61 | * @param path 62 | * @return 63 | */ 64 | public static int getZipMethod(String path) { 65 | if (needCompress(path)) { 66 | return ZipEntry.STORED; 67 | } else { 68 | return ZipEntry.DEFLATED; 69 | } 70 | } 71 | 72 | private final static String[] APK_STANDARD_ALL_FILENAMES = new String[] { 73 | "classes.dex", "AndroidManifest.xml", "resources.arsc", "res", "lib", "libs", "assets", "META-INF" }; 74 | public static boolean isAPKFileNames(String file) { 75 | for (String apkFile : APK_STANDARD_ALL_FILENAMES) { 76 | if (apkFile.equals(file) || file.startsWith(apkFile + "/")) { 77 | return true; 78 | } 79 | } 80 | return false; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/CRC32Util.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.lib; 17 | 18 | import java.io.File; 19 | import java.io.FileInputStream; 20 | import java.io.IOException; 21 | import java.io.InputStream; 22 | import java.util.zip.CRC32; 23 | 24 | /** 25 | * Created by rover12421 on 7/22/15. 26 | */ 27 | public class CRC32Util { 28 | public static long getCRC32(InputStream is) throws IOException { 29 | byte[] buff = new byte[4096]; 30 | CRC32 crc32 = new CRC32(); 31 | int len; 32 | while ((len = is.read(buff)) != -1) { 33 | crc32.update(buff, 0, len); 34 | } 35 | 36 | return crc32.getValue(); 37 | } 38 | 39 | public static long getCRC32(File file) throws IOException { 40 | try ( 41 | FileInputStream fis = new FileInputStream(file) 42 | ){ 43 | return getCRC32(fis); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/DebugInfo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.lib; 17 | 18 | /** 19 | * Created by rover12421 on 12/25/13. 20 | */ 21 | public class DebugInfo { 22 | private static Boolean DEBUG = null; 23 | 24 | public static boolean isDEBUG() { 25 | if (DEBUG == null) { 26 | DEBUG = ShakaProperties.isDebug(); 27 | } 28 | return DEBUG; 29 | } 30 | 31 | public static void info(String info) { 32 | if (isDEBUG()) { 33 | System.out.println(info); 34 | } 35 | } 36 | 37 | public static void error(String info) { 38 | if (isDEBUG()) { 39 | System.err.println(info); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/EnvironmentDetection.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.lib; 17 | 18 | /** 19 | * Created by rover12421 on 7/22/15. 20 | */ 21 | public class EnvironmentDetection { 22 | private static final String OS = System.getProperty("os.name").toLowerCase(); 23 | private static final String JVM_ARCH = System.getProperty("sun.arch.data.model").toLowerCase(); 24 | 25 | private static String LIBEXT; 26 | private static String BINEXT = ""; 27 | private static String LIBPATHNAME; 28 | private static String ARCH; 29 | private static String OSNAME; 30 | 31 | static { 32 | if (isRunning64Bit()) { 33 | ARCH = "x86_64"; 34 | LIBPATHNAME = "lib64"; 35 | } else if (isRunning32Bit()) { 36 | ARCH = "x86"; 37 | LIBPATHNAME = "lib"; 38 | } 39 | 40 | if (isWindows()) { 41 | LIBEXT = ".dll"; 42 | BINEXT = ".exe"; 43 | OSNAME = "windows"; 44 | 45 | //windows 暂时还没有64bit版本 46 | ARCH = "x86"; 47 | } else if (isUnix()) { 48 | LIBEXT = ".so"; 49 | OSNAME = "linux"; 50 | } else if (isMacOSX()) { 51 | LIBEXT = ".dylib"; 52 | OSNAME = "darwin"; 53 | } 54 | } 55 | 56 | public static boolean isWindows() { 57 | return OS.contains("win"); 58 | } 59 | 60 | public static boolean isMacOSX() { 61 | return OS.contains("mac"); 62 | } 63 | 64 | public static boolean isUnix() { 65 | return (OS.contains("nix") || OS.contains("nux") || OS.indexOf("aix") > 0 || (OS.contains("sunos"))); 66 | } 67 | 68 | public static boolean isRunning64Bit() { 69 | return JVM_ARCH.equals("64"); 70 | } 71 | 72 | public static boolean isRunning32Bit() { 73 | return JVM_ARCH.equals("32"); 74 | } 75 | 76 | public static String getOS() { 77 | return OS; 78 | } 79 | 80 | public static String getJvmArch() { 81 | return JVM_ARCH; 82 | } 83 | 84 | public static String getLIBEXT() { 85 | return LIBEXT; 86 | } 87 | 88 | public static String getLIBPATHNAME() { 89 | return LIBPATHNAME; 90 | } 91 | 92 | public static String getARCH() { 93 | return ARCH; 94 | } 95 | 96 | public static String getOSNAME() { 97 | return OSNAME; 98 | } 99 | 100 | public static String getBINEXT() { 101 | return BINEXT; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/HookMain.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.lib; 17 | 18 | /** 19 | * Created by rover12421 on 5/18/15. 20 | */ 21 | public interface HookMain { 22 | void version(); 23 | void usage(); 24 | } 25 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/JarUtil.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.lib; 17 | 18 | import org.apache.commons.io.IOUtils; 19 | 20 | import java.io.File; 21 | import java.io.FileOutputStream; 22 | import java.io.IOException; 23 | import java.io.InputStream; 24 | 25 | /** 26 | * Created by rover12421 on 7/22/15. 27 | */ 28 | public class JarUtil { 29 | public static void getResourceAsFile(String resourcePath, String desPath) throws IOException { 30 | File parentFile = new File(desPath).getParentFile(); 31 | if (!parentFile.exists()) { 32 | parentFile.mkdirs(); 33 | } 34 | try ( 35 | InputStream in = Class.class.getResourceAsStream(resourcePath); 36 | FileOutputStream fos = new FileOutputStream(desPath) 37 | ) { 38 | IOUtils.copy(in, fos); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/LogHelper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.lib; 17 | 18 | import java.util.logging.Logger; 19 | 20 | /** 21 | * Created by rover12421 on 1/22/15. 22 | */ 23 | public class LogHelper { 24 | private final static Logger LOGGER = Logger.getLogger("ShakaApktool"); 25 | 26 | private static Logger getLogger() { 27 | return LOGGER; 28 | } 29 | 30 | public static void warning(String msg) { 31 | getLogger().warning(msg); 32 | } 33 | 34 | public static void info(String msg) { 35 | getLogger().info(msg); 36 | } 37 | 38 | public static void fine(String msg) { 39 | getLogger().fine(msg); 40 | } 41 | 42 | public static void severe(String msg) { 43 | getLogger().severe(msg); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/ShakaAaptProperties.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.lib; 17 | 18 | /** 19 | * Created by rover12421 on 7/22/15. 20 | */ 21 | public class ShakaAaptProperties extends AbsProperties { 22 | 23 | private final static ShakaAaptProperties shakaAaptProperties = new ShakaAaptProperties(); 24 | 25 | private ShakaAaptProperties() { 26 | } 27 | 28 | @Override 29 | protected String getPropertiesPath() { 30 | return "/properties/ShakaAapt.properties"; 31 | } 32 | 33 | public static long getFileCrc32(String filePath) { 34 | String covertFilePath = filePath.replaceAll("/|\\\\", "."); 35 | for (Object key : shakaAaptProperties.getProps().keySet()) { 36 | if (covertFilePath.endsWith(key.toString())) { 37 | String value = (String) shakaAaptProperties.getProps().get(key); 38 | if (value != null) { 39 | return Long.parseLong(value, 16); 40 | } 41 | } 42 | } 43 | 44 | return -1; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/ShakaApktoolFiles.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.lib; 17 | 18 | import java.io.File; 19 | import java.io.IOException; 20 | 21 | /** 22 | * Created by rover12421 on 7/22/15. 23 | */ 24 | public class ShakaApktoolFiles { 25 | private static String ShakaAaptBinPath; 26 | private static String ShakaAaptlibPath; 27 | private static String ShakaAaktoolDir; 28 | 29 | private static String getShakaApktoolDir() throws ShakaException { 30 | if (ShakaAaktoolDir != null) { 31 | return ShakaAaktoolDir; 32 | } 33 | String path; 34 | 35 | File parentPath = new File(System.getProperty("user.home")); 36 | if (! parentPath.canWrite()) { 37 | LogHelper.severe(String.format("WARNING: Could not write to $HOME (%s), using %s instead...", 38 | parentPath.getAbsolutePath(), System.getProperty("java.io.tmpdir"))); 39 | LogHelper.severe("Please be aware this is a volatile directory and frameworks could go missing, " + 40 | "please utilize --frame-path if the default storage directory is unavailable"); 41 | 42 | parentPath = new File(System.getProperty("java.io.tmpdir")); 43 | } 44 | 45 | if (EnvironmentDetection.isMacOSX()) { 46 | path = parentPath.getAbsolutePath() + String.format("%1$sLibrary%1$sShakaApktool", File.separatorChar); 47 | } else { 48 | path = parentPath.getAbsolutePath() + String.format("%1$sShakaApktool", File.separatorChar); 49 | } 50 | 51 | File dir = new File(path); 52 | 53 | if (dir.getParentFile() != null && dir.getParentFile().isFile()) { 54 | LogHelper.severe("Please remove file at " + dir.getParentFile()); 55 | System.exit(1); 56 | } 57 | 58 | if (! dir.exists()) { 59 | if (! dir.mkdirs()) { 60 | throw new ShakaException("Can't create directory: " + dir); 61 | } 62 | } 63 | 64 | ShakaAaktoolDir = path; 65 | return ShakaAaktoolDir; 66 | } 67 | 68 | private static void checkShakaAapt(String fileStr) throws ShakaException { 69 | boolean skip = false; 70 | File file = new File(fileStr); 71 | 72 | long crc32 = ShakaAaptProperties.getFileCrc32(fileStr); 73 | if (crc32 == -1) { 74 | file.delete(); 75 | return; 76 | } 77 | 78 | if (file.exists()) { 79 | try { 80 | if (CRC32Util.getCRC32(file) == crc32) { 81 | skip = true; 82 | } 83 | } catch (IOException e) { 84 | e.printStackTrace(); 85 | } 86 | } 87 | if (!skip) { 88 | String respath = "/ShakaAapt" + 89 | file.getAbsolutePath().substring(getShakaApktoolDir().length()).replaceAll("\\\\", "/"); 90 | try { 91 | JarUtil.getResourceAsFile(respath, fileStr); 92 | } catch (IOException e) { 93 | throw new ShakaException(e); 94 | } 95 | } 96 | if (!file.canExecute()) { 97 | file.setExecutable(true); 98 | } 99 | } 100 | private static void checkShakaAapt() throws ShakaException { 101 | //检查bin文件 102 | checkShakaAapt(ShakaAaptBinPath); 103 | 104 | //检查lib库 105 | checkShakaAapt(ShakaAaptlibPath); 106 | } 107 | 108 | public static String getShakaAaptBinPath() throws ShakaException { 109 | if (ShakaAaptBinPath == null) { 110 | ShakaAaptBinPath = getShakaApktoolDir() + 111 | String.format("%1$s%2$s-%3$s%1$sbin%1$saapt%4$s", 112 | File.separatorChar, 113 | EnvironmentDetection.getOSNAME(), 114 | EnvironmentDetection.getARCH(), 115 | EnvironmentDetection.getBINEXT()); 116 | 117 | ShakaAaptlibPath = getShakaApktoolDir() + 118 | String.format("%1$s%2$s-%3$s%1$s%4$s%1$slibc++%5$s", 119 | File.separatorChar, 120 | EnvironmentDetection.getOSNAME(), 121 | EnvironmentDetection.getARCH(), 122 | EnvironmentDetection.getLIBPATHNAME(), 123 | EnvironmentDetection.getLIBEXT()); 124 | 125 | checkShakaAapt(); 126 | } 127 | return ShakaAaptBinPath; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/ShakaBuildOption.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.lib; 2 | 3 | /** 4 | * Created by rover12421 on 3/30/15. 5 | */ 6 | public class ShakaBuildOption { 7 | private static final ShakaBuildOption option = new ShakaBuildOption(); 8 | private boolean usingDefaultFramework = false; 9 | 10 | public static ShakaBuildOption getInstance() { 11 | return option; 12 | } 13 | 14 | private ShakaBuildOption() { 15 | } 16 | 17 | private boolean fuckNotDefinedRes = false; 18 | 19 | public boolean isFuckNotDefinedRes() { 20 | return fuckNotDefinedRes; 21 | } 22 | 23 | public void setFuckNotDefinedRes(boolean fuckNotDefinedRes) { 24 | this.fuckNotDefinedRes = fuckNotDefinedRes; 25 | } 26 | 27 | public boolean isUsingDefaultFramework() { 28 | return usingDefaultFramework; 29 | } 30 | 31 | public void setUsingDefaultFramework(boolean usingDefaultFramework) { 32 | this.usingDefaultFramework = usingDefaultFramework; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/ShakaDecodeOption.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.lib; 17 | 18 | /** 19 | * Created by rover12421 on 3/30/15. 20 | */ 21 | public class ShakaDecodeOption { 22 | private static final ShakaDecodeOption option = new ShakaDecodeOption(); 23 | 24 | public static ShakaDecodeOption getInstance() { 25 | return option; 26 | } 27 | 28 | private ShakaDecodeOption() { 29 | } 30 | 31 | private boolean no9png = false; 32 | private boolean usingDefaultFramework = false; 33 | //显示更多可识别字符 34 | private boolean showMoreRecognizableCharacters = false; 35 | 36 | private boolean fuckUnkownId = false; 37 | private boolean ignoreResDecodeError = false; 38 | 39 | private boolean xmlAttributeNameCorrect = false; 40 | 41 | public boolean isNo9png() { 42 | return no9png; 43 | } 44 | 45 | public void setNo9png(boolean no9png) { 46 | this.no9png = no9png; 47 | } 48 | 49 | public boolean isUsingDefaultFramework() { 50 | return usingDefaultFramework; 51 | } 52 | 53 | public void setUsingDefaultFramework(boolean usingDefaultFramework) { 54 | this.usingDefaultFramework = usingDefaultFramework; 55 | } 56 | 57 | public boolean isShowMoreRecognizableCharacters() { 58 | return showMoreRecognizableCharacters; 59 | } 60 | 61 | public void setShowMoreRecognizableCharacters(boolean showMoreRecognizableCharacters) { 62 | this.showMoreRecognizableCharacters = showMoreRecognizableCharacters; 63 | } 64 | 65 | public boolean isFuckUnkownId() { 66 | return fuckUnkownId; 67 | } 68 | 69 | public void setFuckUnkownId(boolean fuckUnkownId) { 70 | this.fuckUnkownId = fuckUnkownId; 71 | } 72 | 73 | public boolean isIgnoreResDecodeError() { 74 | return ignoreResDecodeError; 75 | } 76 | 77 | public void setIgnoreResDecodeError(boolean ignoreResDecodeError) { 78 | this.ignoreResDecodeError = ignoreResDecodeError; 79 | } 80 | 81 | public boolean isXmlAttributeNameCorrect() { 82 | return xmlAttributeNameCorrect; 83 | } 84 | 85 | public void setXmlAttributeNameCorrect(boolean xmlAttributeNameCorrect) { 86 | this.xmlAttributeNameCorrect = xmlAttributeNameCorrect; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/ShakaException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.lib; 17 | 18 | /** 19 | * Created by rover12421 on 12/29/13. 20 | */ 21 | public class ShakaException extends Exception { 22 | public ShakaException(Throwable cause) { 23 | super(cause); 24 | } 25 | 26 | public ShakaException(String message, Throwable cause) { 27 | super(message, cause); 28 | } 29 | 30 | public ShakaException(String message) { 31 | super(message); 32 | } 33 | 34 | public ShakaException() { 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/ShakaIO.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.lib; 2 | 3 | import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; 4 | import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; 5 | import org.apache.commons.compress.archivers.zip.ZipFile; 6 | import org.apache.commons.io.IOUtils; 7 | 8 | import java.io.File; 9 | import java.io.FileInputStream; 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | 13 | 14 | /** 15 | * Created by rover12421 on 1/30/16. 16 | */ 17 | public class ShakaIO { 18 | public static void copy(ZipFile inputFile, ZipArchiveOutputStream outputFile, ZipArchiveEntry entry) throws IOException { 19 | try ( 20 | InputStream is = inputFile.getInputStream(entry) 21 | ) { 22 | IOUtils.copy(is, outputFile); 23 | } 24 | } 25 | 26 | public static void copy(File inputFile, ZipArchiveOutputStream outputFile) throws IOException { 27 | try ( 28 | FileInputStream fis = new FileInputStream(inputFile) 29 | ) { 30 | IOUtils.copy(fis, outputFile); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/ShakaProperties.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.lib; 17 | 18 | public class ShakaProperties extends AbsProperties { 19 | 20 | private static final ShakaProperties shakaProperties = new ShakaProperties(); 21 | 22 | private ShakaProperties() { 23 | } 24 | 25 | public static boolean isDebug() { 26 | String str = shakaProperties.get("debug"); 27 | return str != null && str.equalsIgnoreCase("true"); 28 | } 29 | 30 | 31 | public static String getVersion() { 32 | return shakaProperties.get("version"); 33 | } 34 | 35 | @Override 36 | protected String getPropertiesPath() { 37 | return "/properties/shaka.properties"; 38 | } 39 | } -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/ShakaRuntimeException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.lib; 17 | 18 | /** 19 | * Created by rover12421 on 12/29/13. 20 | */ 21 | public class ShakaRuntimeException extends RuntimeException { 22 | public ShakaRuntimeException(Throwable cause) { 23 | super(cause); 24 | } 25 | 26 | public ShakaRuntimeException(String message, Throwable cause) { 27 | super(message, cause); 28 | } 29 | 30 | public ShakaRuntimeException(String message) { 31 | super(message); 32 | } 33 | 34 | public ShakaRuntimeException() { 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/ShakaStringUtil.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.lib; 17 | 18 | /** 19 | * Created by rover12421 on 5/25/15. 20 | */ 21 | public class ShakaStringUtil { 22 | public static String escaped(char c) { 23 | String ret; 24 | int type = Character.getType(c); 25 | if (Character.isJavaIdentifierPart(c) 26 | || ((c >= ' ') && (c < 0x7f)) 27 | || (type >= 20 && type <= 28) //[20-24]是所有标点PUNCTUATION,[25-28]是所有符号SYMBOL 28 | ) { 29 | ret = String.valueOf(c); 30 | 31 | if ((c == '\'') || (c == '\"') || (c == '\\')) { 32 | ret = "\\" + ret; 33 | } 34 | } else { 35 | switch (c) { 36 | case '\n': 37 | ret = "\\n"; 38 | break; 39 | case '\r': 40 | ret = "\\r"; 41 | break; 42 | case '\t': 43 | ret = "\\t"; 44 | break; 45 | default: 46 | ret = "\\u" 47 | + Character.forDigit(c >> 12, 16) 48 | + Character.forDigit((c >> 8) & 0x0f, 16) 49 | + Character.forDigit((c >> 4) & 0x0f, 16) 50 | + Character.forDigit(c & 0x0f, 16); 51 | break; 52 | } 53 | } 54 | 55 | return ret; 56 | } 57 | 58 | public static String escaped(String str) throws Throwable { 59 | StringBuilder sb = new StringBuilder(); 60 | for (int i = 0; i < str.length(); i++) { 61 | sb.append(escaped(str.charAt(i))); 62 | } 63 | return sb.toString(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/cli/CommandLineArgEnum.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.lib.cli; 2 | 3 | import org.apache.commons.cli.CommandLine; 4 | import org.apache.commons.cli.Option; 5 | import org.apache.commons.cli.OptionBuilder; 6 | 7 | /** 8 | * Created by rover12421 on 8/26/15. 9 | */ 10 | public enum CommandLineArgEnum { 11 | LANGUAGE("lng", "language", true, "Locale", "Display language, e.g. zh-CN, zh-TW"), 12 | NO_9_PNG("n9", "no-9png", "Do not decode .9 png file."), 13 | USING_DEFAULT_FRAMEWORK("df", "default-framework", "Using default framework file."), 14 | SHOW_MORE_RECOGNIZABLE_CHARACTERS("mc", "more-recognizable-characters", "Show more recognizable characters."), 15 | FUCK_UNKOWN_ID("fui", "fuck-unkown-id", "Fuck unkown id"), 16 | IGNORE_RES_DECODE_ERROR("ir", "ignore-res-decode-error", "ignore res decode error."), 17 | XML_ATTRIBUTE_NAME_CORRECT("xn", "xml-attribute-name-correct", "xml attribute name correct. May be has problem, not recommended."), 18 | FUCK_NOT_DEFINED_RES("fnd", "fuck-not-defined-res", "Fuck the `Public symbol drawable/? declared here is not defined`."), 19 | InlieMethodResolverFromFile("li", "load-inline-method", true, "file", "load inline method resolver from file"), 20 | ; 21 | 22 | private Option option; 23 | private String longOpt; 24 | private String opt; 25 | private String desc; 26 | private boolean hasArg; 27 | private String argName; 28 | 29 | CommandLineArgEnum(String opt, String longOpt, boolean hasArg, String argName, String desc) { 30 | this.longOpt = longOpt; 31 | this.opt = opt; 32 | this.desc = desc; 33 | this.hasArg = hasArg; 34 | this.argName = argName; 35 | 36 | option = OptionBuilder.withLongOpt(longOpt) 37 | .withDescription(desc) 38 | .hasArg(hasArg) 39 | .withArgName(argName) 40 | .create(opt); 41 | } 42 | 43 | CommandLineArgEnum(String opt, String longOpt, String desc) { 44 | this.longOpt = longOpt; 45 | this.opt = opt; 46 | this.desc = desc; 47 | hasArg = false; 48 | 49 | option = OptionBuilder.withLongOpt(longOpt) 50 | .withDescription(desc) 51 | .create(opt); 52 | } 53 | 54 | public Option getOption() { 55 | return option; 56 | } 57 | 58 | public String getDesc() { 59 | return desc; 60 | } 61 | 62 | /** 63 | * 是否匹配 64 | * @param cli 65 | * @return 66 | */ 67 | public boolean hasMatch(CommandLine cli) { 68 | return cli.hasOption(opt) || cli.hasOption(longOpt); 69 | } 70 | 71 | public String getLongOpt() { 72 | return longOpt; 73 | } 74 | 75 | public String getOpt() { 76 | return opt; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/compress/ZipFile.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.lib.compress; 2 | 3 | import org.apache.commons.compress.archivers.ArchiveEntry; 4 | import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; 5 | import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; 6 | 7 | import java.io.File; 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.nio.charset.Charset; 11 | import java.util.Enumeration; 12 | import java.util.zip.ZipEntry; 13 | import java.util.zip.ZipException; 14 | 15 | /** 16 | * Created by rover12421 on 1/30/16. 17 | */ 18 | public class ZipFile extends java.util.zip.ZipFile { 19 | 20 | private String archiveName; 21 | private org.apache.commons.compress.archivers.zip.ZipFile zipFile; 22 | private static File tmpFile; 23 | 24 | static { 25 | try { 26 | tmpFile = File.createTempFile("ZipFile", "zip"); 27 | tmpFile.deleteOnExit(); 28 | new ZipArchiveOutputStream(tmpFile).close(); 29 | } catch (IOException e) { 30 | e.printStackTrace(); 31 | } 32 | } 33 | 34 | public ZipFile(String name) throws IOException { 35 | this(new File(name)); 36 | } 37 | 38 | public ZipFile(File file, int mode) throws IOException { 39 | this(file); 40 | } 41 | 42 | public ZipFile(File file) throws ZipException, IOException { 43 | super(tmpFile); 44 | zipFile = new org.apache.commons.compress.archivers.zip.ZipFile(file); 45 | archiveName = file.getAbsolutePath(); 46 | } 47 | 48 | public ZipFile(File file, int mode, Charset charset) throws IOException { 49 | this(file, charset); 50 | } 51 | 52 | public ZipFile(String name, Charset charset) throws IOException { 53 | this(new File(name), charset); 54 | } 55 | 56 | public ZipFile(File file, Charset charset) throws IOException { 57 | super(tmpFile); 58 | zipFile = new org.apache.commons.compress.archivers.zip.ZipFile(file, charset.name()); 59 | archiveName = file.getAbsolutePath(); 60 | } 61 | 62 | @Override 63 | public String getComment() { 64 | /** 65 | * apache compress 默然不提供该方法 66 | * 暂时没有找到好的方式获取 67 | */ 68 | return ""; 69 | } 70 | 71 | @Override 72 | public InputStream getInputStream(ZipEntry entry) throws IOException { 73 | if (entry instanceof ZipArchiveEntry) { 74 | return zipFile.getInputStream((ZipArchiveEntry) entry); 75 | } else { 76 | return zipFile.getInputStream(zipFile.getEntry(entry.getName())); 77 | } 78 | } 79 | 80 | @Override 81 | public String getName() { 82 | return archiveName; 83 | } 84 | 85 | @Override 86 | public Enumeration entries() { 87 | return zipFile.getEntries(); 88 | } 89 | 90 | private int total = 0; 91 | @Override 92 | public int size() { 93 | if (total > 0) { 94 | return total; 95 | } 96 | Enumeration enumeration = zipFile.getEntries(); 97 | while (enumeration.hasMoreElements()) { 98 | enumeration.nextElement(); 99 | total++; 100 | } 101 | return total; 102 | } 103 | 104 | @Override 105 | public ZipArchiveEntry getEntry(String name) { 106 | return zipFile.getEntry(name); 107 | } 108 | 109 | @Override 110 | public void close() throws IOException { 111 | zipFile.close(); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/compress/ZipFileAj.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.lib.compress; 2 | 3 | import org.aspectj.lang.annotation.Around; 4 | import org.aspectj.lang.annotation.Aspect; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.nio.charset.Charset; 9 | import java.util.zip.ZipException; 10 | 11 | /** 12 | * Created by rover12421 on 1/30/16. 13 | */ 14 | @Aspect 15 | public class ZipFileAj { 16 | @Around("call(java.util.zip.ZipFile.new(..))" + 17 | "&& args(name)") 18 | public ZipFile _new(String name) throws IOException { 19 | return new ZipFile(name); 20 | } 21 | 22 | @Around("call(java.util.zip.ZipFile.new(..))" + 23 | "&& args(file, mode)") 24 | public ZipFile _new(File file, int mode) throws IOException { 25 | return new ZipFile(file, mode); 26 | } 27 | 28 | @Around("call(java.util.zip.ZipFile.new(..))" + 29 | "&& args(file)") 30 | public ZipFile _new(File file) throws ZipException, IOException { 31 | return new ZipFile(file); 32 | } 33 | 34 | @Around("call(java.util.zip.ZipFile.new(..))" + 35 | "&& args(file, mode, charset)") 36 | public ZipFile _new(File file, int mode, Charset charset) throws IOException { 37 | return new ZipFile(file, mode, charset); 38 | } 39 | 40 | @Around("call(java.util.zip.ZipFile.new(..))" + 41 | "&& args(name, charset)") 42 | public ZipFile _new(String name, Charset charset) throws IOException { 43 | return new ZipFile(name, charset); 44 | } 45 | 46 | @Around("call(java.util.zip.ZipFile.new(..))" + 47 | "&& args(file, charset)") 48 | public ZipFile _new(File file, Charset charset) throws IOException { 49 | return new ZipFile(file, charset); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/compress/ZipOutputStream.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.lib.compress; 2 | 3 | import com.rover12421.shaka.lib.AndroidZip; 4 | import org.apache.commons.compress.archivers.ArchiveEntry; 5 | import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; 6 | import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; 7 | import org.apache.commons.io.output.ByteArrayOutputStream; 8 | 9 | import java.io.IOException; 10 | import java.io.OutputStream; 11 | import java.nio.charset.Charset; 12 | import java.util.zip.ZipEntry; 13 | 14 | /** 15 | * Created by rover12421 on 9/5/16. 16 | */ 17 | public class ZipOutputStream extends java.util.zip.ZipOutputStream { 18 | private ZipArchiveOutputStream zos; 19 | 20 | public ZipOutputStream(OutputStream out) { 21 | super(new ByteArrayOutputStream()); 22 | zos = new ZipArchiveOutputStream(out); 23 | } 24 | 25 | public ZipOutputStream(OutputStream out, Charset charset) { 26 | this(out); 27 | } 28 | 29 | @Override 30 | public void setComment(String comment) { 31 | zos.setComment(comment); 32 | } 33 | 34 | @Override 35 | public void setMethod(int method) { 36 | zos.setMethod(method); 37 | } 38 | 39 | @Override 40 | public void setLevel(int level) { 41 | zos.setLevel(level); 42 | } 43 | 44 | @Override 45 | public void putNextEntry(ZipEntry e) throws IOException { 46 | if (e instanceof ZipArchiveEntry) { 47 | zos.putArchiveEntry((ArchiveEntry) e); 48 | } else { 49 | if (e.getMethod() == -1) { 50 | e.setMethod(AndroidZip.getZipMethod(e.getName())); 51 | } 52 | zos.putArchiveEntry(new ZipArchiveEntry(e)); 53 | } 54 | } 55 | 56 | @Override 57 | public void closeEntry() throws IOException { 58 | zos.closeArchiveEntry(); 59 | } 60 | 61 | @Override 62 | public synchronized void write(byte[] b, int off, int len) throws IOException { 63 | zos.write(b, off, len); 64 | } 65 | 66 | @Override 67 | public void finish() throws IOException { 68 | zos.finish(); 69 | } 70 | 71 | @Override 72 | public void close() throws IOException { 73 | zos.close(); 74 | } 75 | 76 | @Override 77 | public void write(int b) throws IOException { 78 | zos.write(b); 79 | } 80 | 81 | // @Override 82 | // protected void deflate() throws IOException { 83 | // zos.deflate(); 84 | // } 85 | 86 | @Override 87 | public void flush() throws IOException { 88 | zos.flush(); 89 | } 90 | 91 | @Override 92 | public void write(byte[] b) throws IOException { 93 | zos.write(b); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/compress/ZipOutputStreamAj.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.lib.compress; 2 | 3 | import org.aspectj.lang.annotation.Around; 4 | import org.aspectj.lang.annotation.Aspect; 5 | 6 | import java.io.IOException; 7 | import java.io.OutputStream; 8 | import java.nio.charset.Charset; 9 | 10 | /** 11 | * Created by rover12421 on 9/5/16. 12 | */ 13 | @Aspect 14 | public class ZipOutputStreamAj { 15 | @Around("call(java.util.zip.ZipOutputStream.new(..))" + 16 | "&& args(out)") 17 | public ZipOutputStream _new(OutputStream out) throws IOException { 18 | return new ZipOutputStream(out); 19 | } 20 | 21 | @Around("call(java.util.zip.ZipOutputStream.new(..))" + 22 | "&& args(out, charset)") 23 | public ZipOutputStream _new(OutputStream out, Charset charset) throws IOException { 24 | return new ZipOutputStream(out, charset); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/multiLanguage/MultiLanguageAj.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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.rover12421.shaka.lib.multiLanguage; 18 | 19 | import org.apache.commons.cli.OptionBuilder; 20 | import org.apache.commons.cli.Options; 21 | import org.aspectj.lang.ProceedingJoinPoint; 22 | import org.aspectj.lang.annotation.Around; 23 | import org.aspectj.lang.annotation.Aspect; 24 | 25 | /** 26 | * Created by rover12421 on 2/9/15. 27 | */ 28 | @Aspect 29 | public class MultiLanguageAj { 30 | 31 | private final MultiLanguageSupport mts = MultiLanguageSupport.getInstance(); 32 | 33 | @Around("call(void java.io.PrintStream.println(..))" + 34 | "&& args(x)" + 35 | "&& !within(com.rover12421.shaka.lib.multiLanguage.* +)" + 36 | "&& !within(com.rover12421.shaka.apktool.test.*)") 37 | public void around_sout_println(ProceedingJoinPoint joinPoint, String x) throws Throwable { 38 | joinPoint.proceed(new Object[]{MultiLanguageSupport.covertLocaleInfo(x)}); 39 | } 40 | 41 | @Around("call(* org.apache.commons.cli.OptionBuilder.withDescription(..))" + 42 | "&& args(newDescription)" + 43 | "&& !within(com.rover12421.shaka.lib.multiLanguage.* +)") 44 | public OptionBuilder around_OptionBuilder_withDescription(ProceedingJoinPoint joinPoint, String newDescription) throws Throwable { 45 | return (OptionBuilder) joinPoint.proceed(new Object[]{MultiLanguageSupport.covertLocaleInfo(newDescription)}); 46 | } 47 | 48 | @Around("call(void org.apache.commons.cli.HelpFormatter.printHelp(..))" + 49 | "&& args(cmdLineSyntax, header, options, footer)" + 50 | "&& !within(com.rover12421.shaka.lib.multiLanguage.* +)") 51 | public void around_HelpFormatter_printHelp(ProceedingJoinPoint joinPoint, 52 | String cmdLineSyntax, String header, Options options, String footer) throws Throwable { 53 | joinPoint.proceed(new Object[]{MultiLanguageSupport.covertLocaleInfo(cmdLineSyntax), MultiLanguageSupport.covertLocaleInfo(header), options, footer}); 54 | } 55 | 56 | @Around("call(* java.lang.String.format(..))" + 57 | "&& args(format, args)" + 58 | "&& !within(com.rover12421.shaka.lib.multiLanguage.* +)" + 59 | "&& !within(org.jf.dexlib2.util.* +)") 60 | public String around_String_format(ProceedingJoinPoint joinPoint, 61 | String format, Object... args) throws Throwable { 62 | return MultiLanguageSupport.covertLocaleInfo((String) joinPoint.proceed(joinPoint.getArgs())); 63 | } 64 | 65 | 66 | @Around("call(void java.util.logging.Logger.*(String))" + 67 | "&& args(msg)" + 68 | "&& !within(com.rover12421.shaka.lib.multiLanguage.* +)") 69 | public void around_Logger_msg(ProceedingJoinPoint joinPoint, 70 | String msg) throws Throwable { 71 | joinPoint.proceed(new Object[]{MultiLanguageSupport.covertLocaleInfo(msg)}); 72 | } 73 | } 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /shaka/lib/src/main/java/com/rover12421/shaka/lib/reflect/ReflectException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.lib.reflect; 17 | 18 | public class ReflectException extends RuntimeException { 19 | 20 | public ReflectException(String message) { 21 | super(message); 22 | } 23 | 24 | public ReflectException(String message, Throwable cause) { 25 | super(message, cause); 26 | } 27 | 28 | public ReflectException() { 29 | super(); 30 | } 31 | 32 | public ReflectException(Throwable cause) { 33 | super(cause); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /shaka/lib/src/main/resources/ShakaAapt/darwin-x86/bin/aapt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rover12421/ShakaApktool/158767230d533d4a9e4b9f74d571705d77701c1f/shaka/lib/src/main/resources/ShakaAapt/darwin-x86/bin/aapt -------------------------------------------------------------------------------- /shaka/lib/src/main/resources/ShakaAapt/darwin-x86_64/bin/aapt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rover12421/ShakaApktool/158767230d533d4a9e4b9f74d571705d77701c1f/shaka/lib/src/main/resources/ShakaAapt/darwin-x86_64/bin/aapt -------------------------------------------------------------------------------- /shaka/lib/src/main/resources/ShakaAapt/linux-x86/bin/aapt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rover12421/ShakaApktool/158767230d533d4a9e4b9f74d571705d77701c1f/shaka/lib/src/main/resources/ShakaAapt/linux-x86/bin/aapt -------------------------------------------------------------------------------- /shaka/lib/src/main/resources/ShakaAapt/linux-x86_64/bin/aapt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rover12421/ShakaApktool/158767230d533d4a9e4b9f74d571705d77701c1f/shaka/lib/src/main/resources/ShakaAapt/linux-x86_64/bin/aapt -------------------------------------------------------------------------------- /shaka/lib/src/main/resources/ShakaAapt/windows-x86/bin/aapt.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rover12421/ShakaApktool/158767230d533d4a9e4b9f74d571705d77701c1f/shaka/lib/src/main/resources/ShakaAapt/windows-x86/bin/aapt.exe -------------------------------------------------------------------------------- /shaka/lib/src/main/resources/properties/ShakaAapt.properties: -------------------------------------------------------------------------------- 1 | linux-x86.bin.aapt=e617c811 2 | darwin-x86.bin.aapt=18c77516 3 | linux-x86_64.bin.aapt=8263cfe7 4 | darwin-x86_64.bin.aapt=e9f590f6 5 | windows-x86.bin.aapt.exe=f56520d4 6 | -------------------------------------------------------------------------------- /shaka/lib/src/main/resources/properties/shaka.properties: -------------------------------------------------------------------------------- 1 | version=@shakaVersion@ 2 | debug=@shakaDebug@ -------------------------------------------------------------------------------- /shaka/smali/accessorTestGenerator/.gitignore: -------------------------------------------------------------------------------- 1 | src/ 2 | -------------------------------------------------------------------------------- /shaka/smali/accessorTestGenerator/build.gradle: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | //task delSrcDir(type: Delete) { 18 | // delete 'src' 19 | //} 20 | //task copySrcDir(type: Copy) { 21 | // from '../smali/dexlib2/accessorTestGenerator/src' 22 | // into 'src' 23 | //} 24 | // 25 | //copySrcDir.dependsOn delSrcDir 26 | //compileJava.dependsOn copySrcDir 27 | 28 | dependencies { 29 | compile depends.findbugs, 30 | depends.guava, 31 | depends.ST4 32 | 33 | testCompile depends.junit 34 | } -------------------------------------------------------------------------------- /shaka/smali/generated/main/antlr/org/jf/smali/smaliParser.tokens: -------------------------------------------------------------------------------- 1 | ACCESS_SPEC=4 2 | ANNOTATION_DIRECTIVE=5 3 | ANNOTATION_VISIBILITY=6 4 | ARRAY_DATA_DIRECTIVE=7 5 | ARRAY_TYPE_PREFIX=8 6 | ARROW=9 7 | BOOL_LITERAL=10 8 | BYTE_LITERAL=11 9 | CATCHALL_DIRECTIVE=12 10 | CATCH_DIRECTIVE=13 11 | CHAR_LITERAL=14 12 | CLASS_DESCRIPTOR=15 13 | CLASS_DIRECTIVE=16 14 | CLOSE_BRACE=17 15 | CLOSE_PAREN=18 16 | COLON=19 17 | COMMA=20 18 | DOTDOT=21 19 | DOUBLE_LITERAL=22 20 | DOUBLE_LITERAL_OR_ID=23 21 | END_ANNOTATION_DIRECTIVE=24 22 | END_ARRAY_DATA_DIRECTIVE=25 23 | END_FIELD_DIRECTIVE=26 24 | END_LOCAL_DIRECTIVE=27 25 | END_METHOD_DIRECTIVE=28 26 | END_PACKED_SWITCH_DIRECTIVE=29 27 | END_PARAMETER_DIRECTIVE=30 28 | END_SPARSE_SWITCH_DIRECTIVE=31 29 | END_SUBANNOTATION_DIRECTIVE=32 30 | ENUM_DIRECTIVE=33 31 | EPILOGUE_DIRECTIVE=34 32 | EQUAL=35 33 | FIELD_DIRECTIVE=36 34 | FIELD_OFFSET=37 35 | FLOAT_LITERAL=38 36 | FLOAT_LITERAL_OR_ID=39 37 | IMPLEMENTS_DIRECTIVE=40 38 | INLINE_INDEX=41 39 | INSTRUCTION_FORMAT10t=42 40 | INSTRUCTION_FORMAT10x=43 41 | INSTRUCTION_FORMAT10x_ODEX=44 42 | INSTRUCTION_FORMAT11n=45 43 | INSTRUCTION_FORMAT11x=46 44 | INSTRUCTION_FORMAT12x=47 45 | INSTRUCTION_FORMAT12x_OR_ID=48 46 | INSTRUCTION_FORMAT20bc=49 47 | INSTRUCTION_FORMAT20t=50 48 | INSTRUCTION_FORMAT21c_FIELD=51 49 | INSTRUCTION_FORMAT21c_FIELD_ODEX=52 50 | INSTRUCTION_FORMAT21c_STRING=53 51 | INSTRUCTION_FORMAT21c_TYPE=54 52 | INSTRUCTION_FORMAT21ih=55 53 | INSTRUCTION_FORMAT21lh=56 54 | INSTRUCTION_FORMAT21s=57 55 | INSTRUCTION_FORMAT21t=58 56 | INSTRUCTION_FORMAT22b=59 57 | INSTRUCTION_FORMAT22c_FIELD=60 58 | INSTRUCTION_FORMAT22c_FIELD_ODEX=61 59 | INSTRUCTION_FORMAT22c_TYPE=62 60 | INSTRUCTION_FORMAT22cs_FIELD=63 61 | INSTRUCTION_FORMAT22s=64 62 | INSTRUCTION_FORMAT22s_OR_ID=65 63 | INSTRUCTION_FORMAT22t=66 64 | INSTRUCTION_FORMAT22x=67 65 | INSTRUCTION_FORMAT23x=68 66 | INSTRUCTION_FORMAT30t=69 67 | INSTRUCTION_FORMAT31c=70 68 | INSTRUCTION_FORMAT31i=71 69 | INSTRUCTION_FORMAT31i_OR_ID=72 70 | INSTRUCTION_FORMAT31t=73 71 | INSTRUCTION_FORMAT32x=74 72 | INSTRUCTION_FORMAT35c_METHOD=75 73 | INSTRUCTION_FORMAT35c_METHOD_ODEX=76 74 | INSTRUCTION_FORMAT35c_TYPE=77 75 | INSTRUCTION_FORMAT35mi_METHOD=78 76 | INSTRUCTION_FORMAT35ms_METHOD=79 77 | INSTRUCTION_FORMAT3rc_METHOD=80 78 | INSTRUCTION_FORMAT3rc_METHOD_ODEX=81 79 | INSTRUCTION_FORMAT3rc_TYPE=82 80 | INSTRUCTION_FORMAT3rmi_METHOD=83 81 | INSTRUCTION_FORMAT3rms_METHOD=84 82 | INSTRUCTION_FORMAT45cc_METHOD=85 83 | INSTRUCTION_FORMAT4rcc_METHOD=86 84 | INSTRUCTION_FORMAT51l=87 85 | INTEGER_LITERAL=88 86 | INVALID_TOKEN=89 87 | I_ACCESS_LIST=90 88 | I_ANNOTATION=91 89 | I_ANNOTATIONS=92 90 | I_ANNOTATION_ELEMENT=93 91 | I_ARRAY_ELEMENTS=94 92 | I_ARRAY_ELEMENT_SIZE=95 93 | I_CATCH=96 94 | I_CATCHALL=97 95 | I_CATCHES=98 96 | I_CLASS_DEF=99 97 | I_ENCODED_ARRAY=100 98 | I_ENCODED_ENUM=101 99 | I_ENCODED_FIELD=102 100 | I_ENCODED_METHOD=103 101 | I_END_LOCAL=104 102 | I_EPILOGUE=105 103 | I_FIELD=106 104 | I_FIELDS=107 105 | I_FIELD_INITIAL_VALUE=108 106 | I_FIELD_TYPE=109 107 | I_IMPLEMENTS=110 108 | I_LABEL=111 109 | I_LINE=112 110 | I_LOCAL=113 111 | I_LOCALS=114 112 | I_METHOD=115 113 | I_METHODS=116 114 | I_METHOD_PROTOTYPE=117 115 | I_METHOD_RETURN_TYPE=118 116 | I_ORDERED_METHOD_ITEMS=119 117 | I_PACKED_SWITCH_ELEMENTS=120 118 | I_PACKED_SWITCH_START_KEY=121 119 | I_PARAMETER=122 120 | I_PARAMETERS=123 121 | I_PARAMETER_NOT_SPECIFIED=124 122 | I_PROLOGUE=125 123 | I_REGISTERS=126 124 | I_REGISTER_LIST=127 125 | I_REGISTER_RANGE=128 126 | I_RESTART_LOCAL=129 127 | I_SOURCE=130 128 | I_SPARSE_SWITCH_ELEMENTS=131 129 | I_STATEMENT_ARRAY_DATA=132 130 | I_STATEMENT_FORMAT10t=133 131 | I_STATEMENT_FORMAT10x=134 132 | I_STATEMENT_FORMAT11n=135 133 | I_STATEMENT_FORMAT11x=136 134 | I_STATEMENT_FORMAT12x=137 135 | I_STATEMENT_FORMAT20bc=138 136 | I_STATEMENT_FORMAT20t=139 137 | I_STATEMENT_FORMAT21c_FIELD=140 138 | I_STATEMENT_FORMAT21c_STRING=141 139 | I_STATEMENT_FORMAT21c_TYPE=142 140 | I_STATEMENT_FORMAT21ih=143 141 | I_STATEMENT_FORMAT21lh=144 142 | I_STATEMENT_FORMAT21s=145 143 | I_STATEMENT_FORMAT21t=146 144 | I_STATEMENT_FORMAT22b=147 145 | I_STATEMENT_FORMAT22c_FIELD=148 146 | I_STATEMENT_FORMAT22c_TYPE=149 147 | I_STATEMENT_FORMAT22s=150 148 | I_STATEMENT_FORMAT22t=151 149 | I_STATEMENT_FORMAT22x=152 150 | I_STATEMENT_FORMAT23x=153 151 | I_STATEMENT_FORMAT30t=154 152 | I_STATEMENT_FORMAT31c=155 153 | I_STATEMENT_FORMAT31i=156 154 | I_STATEMENT_FORMAT31t=157 155 | I_STATEMENT_FORMAT32x=158 156 | I_STATEMENT_FORMAT35c_METHOD=159 157 | I_STATEMENT_FORMAT35c_TYPE=160 158 | I_STATEMENT_FORMAT3rc_METHOD=161 159 | I_STATEMENT_FORMAT3rc_TYPE=162 160 | I_STATEMENT_FORMAT45cc_METHOD=163 161 | I_STATEMENT_FORMAT4rcc_METHOD=164 162 | I_STATEMENT_FORMAT51l=165 163 | I_STATEMENT_PACKED_SWITCH=166 164 | I_STATEMENT_SPARSE_SWITCH=167 165 | I_SUBANNOTATION=168 166 | I_SUPER=169 167 | LINE_COMMENT=170 168 | LINE_DIRECTIVE=171 169 | LOCALS_DIRECTIVE=172 170 | LOCAL_DIRECTIVE=173 171 | LONG_LITERAL=174 172 | MEMBER_NAME=175 173 | METHOD_DIRECTIVE=176 174 | NEGATIVE_INTEGER_LITERAL=177 175 | NULL_LITERAL=178 176 | OPEN_BRACE=179 177 | OPEN_PAREN=180 178 | PACKED_SWITCH_DIRECTIVE=181 179 | PARAMETER_DIRECTIVE=182 180 | PARAM_LIST_OR_ID_PRIMITIVE_TYPE=183 181 | POSITIVE_INTEGER_LITERAL=184 182 | PRIMITIVE_TYPE=185 183 | PROLOGUE_DIRECTIVE=186 184 | REGISTER=187 185 | REGISTERS_DIRECTIVE=188 186 | RESTART_LOCAL_DIRECTIVE=189 187 | SHORT_LITERAL=190 188 | SIMPLE_NAME=191 189 | SOURCE_DIRECTIVE=192 190 | SPARSE_SWITCH_DIRECTIVE=193 191 | STRING_LITERAL=194 192 | SUBANNOTATION_DIRECTIVE=195 193 | SUPER_DIRECTIVE=196 194 | VERIFICATION_ERROR_TYPE=197 195 | VOID_TYPE=198 196 | VTABLE_INDEX=199 197 | WHITE_SPACE=200 198 | -------------------------------------------------------------------------------- /shaka/smali/generated/main/antlr/org/jf/smali/smaliTreeWalker.tokens: -------------------------------------------------------------------------------- 1 | ACCESS_SPEC=4 2 | ANNOTATION_DIRECTIVE=5 3 | ANNOTATION_VISIBILITY=6 4 | ARRAY_DATA_DIRECTIVE=7 5 | ARRAY_TYPE_PREFIX=8 6 | ARROW=9 7 | BOOL_LITERAL=10 8 | BYTE_LITERAL=11 9 | CATCHALL_DIRECTIVE=12 10 | CATCH_DIRECTIVE=13 11 | CHAR_LITERAL=14 12 | CLASS_DESCRIPTOR=15 13 | CLASS_DIRECTIVE=16 14 | CLOSE_BRACE=17 15 | CLOSE_PAREN=18 16 | COLON=19 17 | COMMA=20 18 | DOTDOT=21 19 | DOUBLE_LITERAL=22 20 | DOUBLE_LITERAL_OR_ID=23 21 | END_ANNOTATION_DIRECTIVE=24 22 | END_ARRAY_DATA_DIRECTIVE=25 23 | END_FIELD_DIRECTIVE=26 24 | END_LOCAL_DIRECTIVE=27 25 | END_METHOD_DIRECTIVE=28 26 | END_PACKED_SWITCH_DIRECTIVE=29 27 | END_PARAMETER_DIRECTIVE=30 28 | END_SPARSE_SWITCH_DIRECTIVE=31 29 | END_SUBANNOTATION_DIRECTIVE=32 30 | ENUM_DIRECTIVE=33 31 | EPILOGUE_DIRECTIVE=34 32 | EQUAL=35 33 | FIELD_DIRECTIVE=36 34 | FIELD_OFFSET=37 35 | FLOAT_LITERAL=38 36 | FLOAT_LITERAL_OR_ID=39 37 | IMPLEMENTS_DIRECTIVE=40 38 | INLINE_INDEX=41 39 | INSTRUCTION_FORMAT10t=42 40 | INSTRUCTION_FORMAT10x=43 41 | INSTRUCTION_FORMAT10x_ODEX=44 42 | INSTRUCTION_FORMAT11n=45 43 | INSTRUCTION_FORMAT11x=46 44 | INSTRUCTION_FORMAT12x=47 45 | INSTRUCTION_FORMAT12x_OR_ID=48 46 | INSTRUCTION_FORMAT20bc=49 47 | INSTRUCTION_FORMAT20t=50 48 | INSTRUCTION_FORMAT21c_FIELD=51 49 | INSTRUCTION_FORMAT21c_FIELD_ODEX=52 50 | INSTRUCTION_FORMAT21c_STRING=53 51 | INSTRUCTION_FORMAT21c_TYPE=54 52 | INSTRUCTION_FORMAT21ih=55 53 | INSTRUCTION_FORMAT21lh=56 54 | INSTRUCTION_FORMAT21s=57 55 | INSTRUCTION_FORMAT21t=58 56 | INSTRUCTION_FORMAT22b=59 57 | INSTRUCTION_FORMAT22c_FIELD=60 58 | INSTRUCTION_FORMAT22c_FIELD_ODEX=61 59 | INSTRUCTION_FORMAT22c_TYPE=62 60 | INSTRUCTION_FORMAT22cs_FIELD=63 61 | INSTRUCTION_FORMAT22s=64 62 | INSTRUCTION_FORMAT22s_OR_ID=65 63 | INSTRUCTION_FORMAT22t=66 64 | INSTRUCTION_FORMAT22x=67 65 | INSTRUCTION_FORMAT23x=68 66 | INSTRUCTION_FORMAT30t=69 67 | INSTRUCTION_FORMAT31c=70 68 | INSTRUCTION_FORMAT31i=71 69 | INSTRUCTION_FORMAT31i_OR_ID=72 70 | INSTRUCTION_FORMAT31t=73 71 | INSTRUCTION_FORMAT32x=74 72 | INSTRUCTION_FORMAT35c_METHOD=75 73 | INSTRUCTION_FORMAT35c_METHOD_ODEX=76 74 | INSTRUCTION_FORMAT35c_TYPE=77 75 | INSTRUCTION_FORMAT35mi_METHOD=78 76 | INSTRUCTION_FORMAT35ms_METHOD=79 77 | INSTRUCTION_FORMAT3rc_METHOD=80 78 | INSTRUCTION_FORMAT3rc_METHOD_ODEX=81 79 | INSTRUCTION_FORMAT3rc_TYPE=82 80 | INSTRUCTION_FORMAT3rmi_METHOD=83 81 | INSTRUCTION_FORMAT3rms_METHOD=84 82 | INSTRUCTION_FORMAT45cc_METHOD=85 83 | INSTRUCTION_FORMAT4rcc_METHOD=86 84 | INSTRUCTION_FORMAT51l=87 85 | INTEGER_LITERAL=88 86 | INVALID_TOKEN=89 87 | I_ACCESS_LIST=90 88 | I_ANNOTATION=91 89 | I_ANNOTATIONS=92 90 | I_ANNOTATION_ELEMENT=93 91 | I_ARRAY_ELEMENTS=94 92 | I_ARRAY_ELEMENT_SIZE=95 93 | I_CATCH=96 94 | I_CATCHALL=97 95 | I_CATCHES=98 96 | I_CLASS_DEF=99 97 | I_ENCODED_ARRAY=100 98 | I_ENCODED_ENUM=101 99 | I_ENCODED_FIELD=102 100 | I_ENCODED_METHOD=103 101 | I_END_LOCAL=104 102 | I_EPILOGUE=105 103 | I_FIELD=106 104 | I_FIELDS=107 105 | I_FIELD_INITIAL_VALUE=108 106 | I_FIELD_TYPE=109 107 | I_IMPLEMENTS=110 108 | I_LABEL=111 109 | I_LINE=112 110 | I_LOCAL=113 111 | I_LOCALS=114 112 | I_METHOD=115 113 | I_METHODS=116 114 | I_METHOD_PROTOTYPE=117 115 | I_METHOD_RETURN_TYPE=118 116 | I_ORDERED_METHOD_ITEMS=119 117 | I_PACKED_SWITCH_ELEMENTS=120 118 | I_PACKED_SWITCH_START_KEY=121 119 | I_PARAMETER=122 120 | I_PARAMETERS=123 121 | I_PARAMETER_NOT_SPECIFIED=124 122 | I_PROLOGUE=125 123 | I_REGISTERS=126 124 | I_REGISTER_LIST=127 125 | I_REGISTER_RANGE=128 126 | I_RESTART_LOCAL=129 127 | I_SOURCE=130 128 | I_SPARSE_SWITCH_ELEMENTS=131 129 | I_STATEMENT_ARRAY_DATA=132 130 | I_STATEMENT_FORMAT10t=133 131 | I_STATEMENT_FORMAT10x=134 132 | I_STATEMENT_FORMAT11n=135 133 | I_STATEMENT_FORMAT11x=136 134 | I_STATEMENT_FORMAT12x=137 135 | I_STATEMENT_FORMAT20bc=138 136 | I_STATEMENT_FORMAT20t=139 137 | I_STATEMENT_FORMAT21c_FIELD=140 138 | I_STATEMENT_FORMAT21c_STRING=141 139 | I_STATEMENT_FORMAT21c_TYPE=142 140 | I_STATEMENT_FORMAT21ih=143 141 | I_STATEMENT_FORMAT21lh=144 142 | I_STATEMENT_FORMAT21s=145 143 | I_STATEMENT_FORMAT21t=146 144 | I_STATEMENT_FORMAT22b=147 145 | I_STATEMENT_FORMAT22c_FIELD=148 146 | I_STATEMENT_FORMAT22c_TYPE=149 147 | I_STATEMENT_FORMAT22s=150 148 | I_STATEMENT_FORMAT22t=151 149 | I_STATEMENT_FORMAT22x=152 150 | I_STATEMENT_FORMAT23x=153 151 | I_STATEMENT_FORMAT30t=154 152 | I_STATEMENT_FORMAT31c=155 153 | I_STATEMENT_FORMAT31i=156 154 | I_STATEMENT_FORMAT31t=157 155 | I_STATEMENT_FORMAT32x=158 156 | I_STATEMENT_FORMAT35c_METHOD=159 157 | I_STATEMENT_FORMAT35c_TYPE=160 158 | I_STATEMENT_FORMAT3rc_METHOD=161 159 | I_STATEMENT_FORMAT3rc_TYPE=162 160 | I_STATEMENT_FORMAT45cc_METHOD=163 161 | I_STATEMENT_FORMAT4rcc_METHOD=164 162 | I_STATEMENT_FORMAT51l=165 163 | I_STATEMENT_PACKED_SWITCH=166 164 | I_STATEMENT_SPARSE_SWITCH=167 165 | I_SUBANNOTATION=168 166 | I_SUPER=169 167 | LINE_COMMENT=170 168 | LINE_DIRECTIVE=171 169 | LOCALS_DIRECTIVE=172 170 | LOCAL_DIRECTIVE=173 171 | LONG_LITERAL=174 172 | MEMBER_NAME=175 173 | METHOD_DIRECTIVE=176 174 | NEGATIVE_INTEGER_LITERAL=177 175 | NULL_LITERAL=178 176 | OPEN_BRACE=179 177 | OPEN_PAREN=180 178 | PACKED_SWITCH_DIRECTIVE=181 179 | PARAMETER_DIRECTIVE=182 180 | PARAM_LIST_OR_ID_PRIMITIVE_TYPE=183 181 | POSITIVE_INTEGER_LITERAL=184 182 | PRIMITIVE_TYPE=185 183 | PROLOGUE_DIRECTIVE=186 184 | REGISTER=187 185 | REGISTERS_DIRECTIVE=188 186 | RESTART_LOCAL_DIRECTIVE=189 187 | SHORT_LITERAL=190 188 | SIMPLE_NAME=191 189 | SOURCE_DIRECTIVE=192 190 | SPARSE_SWITCH_DIRECTIVE=193 191 | STRING_LITERAL=194 192 | SUBANNOTATION_DIRECTIVE=195 193 | SUPER_DIRECTIVE=196 194 | VERIFICATION_ERROR_TYPE=197 195 | VOID_TYPE=198 196 | VTABLE_INDEX=199 197 | WHITE_SPACE=200 198 | -------------------------------------------------------------------------------- /shaka/smali/generated/test/antlr/org/jf/smali/expectedTokensTestGrammar.tokens: -------------------------------------------------------------------------------- 1 | T__11=11 2 | T__12=12 3 | BASE_STRING_LITERAL=4 4 | ESCAPE_SEQUENCE=5 5 | HEX_DIGIT=6 6 | HEX_DIGITS=7 7 | STRING_LITERAL=8 8 | TOKEN_NAME=9 9 | WHITE_SPACE=10 10 | '('=11 11 | ')'=12 12 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/baksmali/InlineMethodResolverFromFile.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.smali.baksmali; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import com.rover12421.shaka.lib.LogHelper; 5 | import org.jf.dexlib2.analysis.AnalyzedInstruction; 6 | import org.jf.dexlib2.analysis.InlineMethodResolver; 7 | import org.jf.dexlib2.iface.Method; 8 | import org.jf.dexlib2.iface.instruction.InlineIndexInstruction; 9 | import org.jf.dexlib2.immutable.ImmutableMethod; 10 | import org.jf.dexlib2.immutable.ImmutableMethodParameter; 11 | import org.jf.dexlib2.immutable.util.ParamUtil; 12 | 13 | import javax.annotation.Nonnull; 14 | import java.io.IOException; 15 | import java.nio.charset.StandardCharsets; 16 | import java.nio.file.Files; 17 | import java.nio.file.Paths; 18 | import java.util.ArrayList; 19 | import java.util.Arrays; 20 | import java.util.List; 21 | 22 | /** 23 | * Created by rover12421 on 9/12/15. 24 | * 从文件读取InlineMethod的配置信息 25 | */ 26 | public class InlineMethodResolverFromFile extends InlineMethodResolver { 27 | private List inlineMethods; 28 | 29 | @Nonnull 30 | private static Method inlineMethod(int accessFlags, @Nonnull String cls, @Nonnull String name, 31 | @Nonnull String params, @Nonnull String returnType) { 32 | ImmutableList paramList = ImmutableList.copyOf(ParamUtil.parseParamString(params)); 33 | return new ImmutableMethod(cls, name, paramList, returnType, accessFlags, null, null); 34 | } 35 | 36 | public InlineMethodResolverFromFile(String file) { 37 | inlineMethods = new ArrayList<>(); 38 | try { 39 | List lines = Files.readAllLines(Paths.get(file), StandardCharsets.UTF_8); 40 | int lineNum = 0; 41 | for (String line : lines) { 42 | lineNum++; 43 | line = line.trim(); 44 | if (!line.startsWith("#")) { 45 | String[] info = line.split(","); 46 | if (info.length != 5) { 47 | LogHelper.warning("Error line (" + lineNum + "): " + line); 48 | continue; 49 | } 50 | 51 | LogHelper.info("Add InlineMethodResolver : " + Arrays.toString(info)); 52 | 53 | // public static final int STATIC = 0x8; // AccessFlags.STATIC.value; 54 | // public static final int VIRTUAL = 0x1; // AccessFlags.PUBLIC.value; 55 | // public static final int DIRECT = 0x2; // AccessFlags.PRIVATE.value; 56 | int accessFlags; 57 | String accessFlagsStr = info[0].trim().toUpperCase(); 58 | if (accessFlagsStr.equals("STATIC")) { 59 | accessFlags = InlineMethodResolver.STATIC; 60 | } else if (accessFlagsStr.equals("VIRTUAL")) { 61 | accessFlags = InlineMethodResolver.VIRTUAL; 62 | } else if (accessFlagsStr.equals("DIRECT")) { 63 | accessFlags = InlineMethodResolver.DIRECT; 64 | } else { 65 | LogHelper.warning("Error access flags : " + info[0]); 66 | continue; 67 | } 68 | 69 | String cls = info[1].trim(); 70 | String name = info[2].trim(); 71 | String params = info[3].trim(); 72 | String returnType = info[4].trim(); 73 | 74 | Method method = inlineMethod(accessFlags, cls, name, params, returnType); 75 | inlineMethods.add(method); 76 | } 77 | } 78 | } catch (IOException e) { 79 | e.printStackTrace(); 80 | } 81 | } 82 | 83 | @Override 84 | @Nonnull 85 | public Method resolveExecuteInline(@Nonnull AnalyzedInstruction analyzedInstruction) { 86 | InlineIndexInstruction instruction = (InlineIndexInstruction) analyzedInstruction.getInstruction(); 87 | int inlineIndex = instruction.getInlineIndex(); 88 | 89 | if (inlineIndex < 0 || inlineIndex >= inlineMethods.size()) { 90 | throw new RuntimeException("Invalid inline index: " + inlineIndex); 91 | } 92 | return inlineMethods.get(inlineIndex); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/baksmali/RegisterFormatterAj.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.smali.baksmali; 2 | 3 | import org.aspectj.lang.ProceedingJoinPoint; 4 | import org.aspectj.lang.annotation.Around; 5 | import org.aspectj.lang.annotation.Aspect; 6 | import org.jf.baksmali.Adaptors.RegisterFormatter; 7 | import org.jf.util.IndentingWriter; 8 | 9 | import java.io.IOException; 10 | 11 | /** 12 | * Created by rover12421 on 9/22/15. 13 | * org.jf.baksmali.Adaptors.RegisterFormatter 14 | */ 15 | @Aspect 16 | public class RegisterFormatterAj { 17 | // @Around("execution(* org.jf.baksmali.Adaptors.RegisterFormatter.writeTo(..))" + 18 | // "&& args(writer, register)") 19 | public void writeTo(ProceedingJoinPoint joinPoint, IndentingWriter writer, int register) throws Throwable { 20 | RegisterFormatter thiz = (RegisterFormatter) joinPoint.getThis(); 21 | if (register > thiz.registerCount) { 22 | throw new IOException("register > registerCount"); 23 | } else { 24 | joinPoint.proceed(joinPoint.getArgs()); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/baksmali/ShakaBaksmaliOption.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.smali.baksmali; 2 | 3 | /** 4 | * Created by rover12421 on 9/14/15. 5 | */ 6 | public class ShakaBaksmaliOption { 7 | private static String InlineMethodResolverFile = null; 8 | 9 | public static String getInlineMethodResolverFile() { 10 | return InlineMethodResolverFile; 11 | } 12 | 13 | public static void setInlineMethodResolverFile(String inlineMethodResolverFile) { 14 | InlineMethodResolverFile = inlineMethodResolverFile; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/baksmali/baksmaliAj.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.smali.baksmali; 2 | 3 | import com.rover12421.shaka.lib.reflect.Reflect; 4 | import com.rover12421.shaka.smali.util.NIOIndentingWriter; 5 | import org.aspectj.lang.ProceedingJoinPoint; 6 | import org.aspectj.lang.annotation.Around; 7 | import org.aspectj.lang.annotation.Aspect; 8 | import org.jf.util.IndentingWriter; 9 | 10 | import java.io.*; 11 | 12 | /** 13 | * Created by rover12421 on 11/24/15. 14 | */ 15 | @Aspect 16 | public class baksmaliAj { 17 | @Around("call(org.jf.util.IndentingWriter.new(..))" + 18 | "&& args(writer)" + 19 | "&& withincode(* org.jf.baksmali.baksmali.disassembleClass(..))") 20 | public IndentingWriter IndentingWriter_new(ProceedingJoinPoint joinPoint, Writer writer) throws Throwable { 21 | if (writer instanceof BufferedWriter) { 22 | Writer out = Reflect.on(writer).get("out"); 23 | if (out instanceof OutputStreamWriter) { 24 | Object lock = Reflect.on(out).get("lock"); 25 | if (lock instanceof FileOutputStream) { 26 | return new NIOIndentingWriter((FileOutputStream) lock); 27 | } 28 | } 29 | } 30 | return (IndentingWriter) joinPoint.proceed(joinPoint.getArgs()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/baksmali/baksmaliMain.aj: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.smali.baksmali; 2 | 3 | import com.beust.jcommander.JCommander; 4 | import org.jf.baksmali.Main; 5 | 6 | /** 7 | * Created by rover12421 on 12/5/15. 8 | */ 9 | privileged public aspect baksmaliMain { 10 | public JCommander Main.getJcommander() { 11 | return this.jc; 12 | } 13 | 14 | public static Main Main.getInstance() { 15 | return baksmaliMainAj.Instance; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/baksmali/baksmaliMainAj.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.smali.baksmali; 17 | 18 | import com.rover12421.shaka.lib.HookMain; 19 | import com.rover12421.shaka.lib.LogHelper; 20 | import com.rover12421.shaka.lib.cli.CommandLineArgEnum; 21 | import org.apache.commons.cli.CommandLine; 22 | import org.apache.commons.cli.CommandLineParser; 23 | import org.apache.commons.cli.PosixParser; 24 | import org.aspectj.lang.JoinPoint; 25 | import org.aspectj.lang.ProceedingJoinPoint; 26 | import org.aspectj.lang.annotation.After; 27 | import org.aspectj.lang.annotation.Around; 28 | import org.aspectj.lang.annotation.Aspect; 29 | import org.jf.baksmali.Main; 30 | 31 | import java.util.Arrays; 32 | 33 | /** 34 | * Created by rover12421 on 5/17/15. 35 | */ 36 | @Aspect 37 | public class baksmaliMainAj { 38 | private static HookMain hookMain; 39 | public static Main Instance; 40 | 41 | public static void setHookMain(HookMain hookMain) { 42 | baksmaliMainAj.hookMain = hookMain; 43 | } 44 | 45 | @After("execution(org.jf.baksmali.Main.new())") 46 | public void newInstance(JoinPoint point) { 47 | Instance = (Main) point.getThis(); 48 | } 49 | 50 | @Around("execution(* org.jf.baksmali.Main.usage(..))" + 51 | "&& args(printDebugOptions)") 52 | public void usage(boolean printDebugOptions) { 53 | hookMain.usage(); 54 | } 55 | 56 | @Around("execution(* org.jf.baksmali.Main.version())") 57 | public void version() { 58 | hookMain.version(); 59 | } 60 | 61 | // @After("execution(* org.jf.baksmali.Main.buildOptions(..))") 62 | // public void buildOptions() { 63 | // //Instance.getJcommander().addCommand(); 64 | // org.jf.baksmali.main.getBasicOptions().addOption(CommandLineArgEnum.InlieMethodResolverFromFile.getOption()); 65 | // org.jf.baksmali.main.getOptions().addOption(CommandLineArgEnum.InlieMethodResolverFromFile.getOption()); 66 | // } 67 | // 68 | // @Around("execution(* org.jf.baksmali.main.main(..))" + 69 | // "&& args(args)") 70 | // public void main(ProceedingJoinPoint joinPoint, String[] args) throws Throwable { 71 | // try { 72 | // CommandLineParser parser = new PosixParser(); 73 | // CommandLine cli = parser.parse(org.jf.baksmali.Main.getOptions(), args); 74 | // if (CommandLineArgEnum.InlieMethodResolverFromFile.hasMatch(cli)) { 75 | // ShakaBaksmaliOption.setInlineMethodResolverFile(cli.getOptionValue(CommandLineArgEnum.InlieMethodResolverFromFile.getOpt())); 76 | // int index = Arrays.binarySearch(args, CommandLineArgEnum.InlieMethodResolverFromFile.getOpt()); 77 | // if (index < 0) { 78 | // index = Arrays.binarySearch(args, CommandLineArgEnum.InlieMethodResolverFromFile.getLongOpt()); 79 | // } 80 | // 81 | // if (index >= 0) { 82 | // String[] nArgs = new String[args.length - 2]; 83 | // if (index > 0) { 84 | // System.arraycopy(args, 0, nArgs, 0, index); 85 | // } 86 | // System.arraycopy(args, index + 2, nArgs, index, nArgs.length - index); 87 | // joinPoint.proceed(nArgs); 88 | // } else { 89 | // LogHelper.warning("args error!!!"); 90 | // } 91 | // } 92 | // } catch (Throwable e) { 93 | // e.printStackTrace(); 94 | // } 95 | // 96 | // joinPoint.proceed(joinPoint.getArgs()); 97 | // } 98 | } 99 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/dexlib2/AnnotationsDirectoryAj.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.smali.dexlib2; 2 | 3 | import com.google.common.collect.ImmutableSet; 4 | import org.aspectj.lang.ProceedingJoinPoint; 5 | import org.aspectj.lang.annotation.Around; 6 | import org.aspectj.lang.annotation.Aspect; 7 | import org.jf.dexlib2.dexbacked.DexBackedAnnotation; 8 | 9 | import java.util.Set; 10 | 11 | /** 12 | * Created by rover12421 on 11/9/15. 13 | */ 14 | @Aspect 15 | public class AnnotationsDirectoryAj { 16 | 17 | @Around("execution(* org.jf.dexlib2.dexbacked.util.AnnotationsDirectory.getAnnotations(..))") 18 | public Set getAnnotations(ProceedingJoinPoint joinPoint) { 19 | try { 20 | return (Set) joinPoint.proceed(joinPoint.getArgs()); 21 | } catch (Throwable throwable) { 22 | return ImmutableSet.of(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/dexlib2/BaseDexBuffer0.aj: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.smali.dexlib2; 2 | 3 | import org.jf.dexlib2.dexbacked.BaseDexBuffer; 4 | 5 | /** 6 | * Created by rover12421 on 12/5/15. 7 | */ 8 | privileged public aspect BaseDexBuffer0 { 9 | public int BaseDexBuffer.getBaseOffset0() { 10 | return this.getBaseOffset(); 11 | } 12 | 13 | public byte[] org.jf.dexlib2.dexbacked.BaseDexBuffer.getBuf0() { 14 | return this.getBuf(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/dexlib2/BaseDexBufferAj.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.smali.dexlib2; 2 | 3 | import com.rover12421.shaka.lib.LogHelper; 4 | import org.aspectj.lang.ProceedingJoinPoint; 5 | import org.aspectj.lang.annotation.Around; 6 | import org.aspectj.lang.annotation.Aspect; 7 | import org.jf.dexlib2.dexbacked.BaseDexBuffer; 8 | 9 | /** 10 | * Created by rover12421 on 11/10/15. 11 | */ 12 | @Aspect 13 | public class BaseDexBufferAj { 14 | 15 | @Around("execution(* org.jf.dexlib2.dexbacked.BaseDexBuffer.readSmallUint(..))" + 16 | "&& args(offset)") 17 | public int readSmallUint(ProceedingJoinPoint joinPoint, int offset) { 18 | BaseDexBuffer thiz = (BaseDexBuffer) joinPoint.getThis(); 19 | 20 | byte[] buf = thiz.getBuf0(); 21 | offset += thiz.getBaseOffset0(); 22 | int result = (buf[offset] & 0xff) | 23 | ((buf[offset+1] & 0xff) << 8) | 24 | ((buf[offset+2] & 0xff) << 16) | 25 | ((buf[offset+3]) << 24); 26 | if (result < 0) { 27 | LogHelper.warning(String.format("Encountered small uint that is out of range at offset 0x%x. Set result to 0", offset)); 28 | result = 0; 29 | } 30 | return result; 31 | } 32 | 33 | @Around("execution(* org.jf.dexlib2.dexbacked.BaseDexBuffer.readOptionalUint(..))" + 34 | "&& args(offset)") 35 | public int readOptionalUint(ProceedingJoinPoint joinPoint, int offset) { 36 | BaseDexBuffer thiz = (BaseDexBuffer) joinPoint.getThis(); 37 | 38 | byte[] buf = thiz.getBuf0(); 39 | offset += thiz.getBaseOffset0(); 40 | int result = (buf[offset] & 0xff) | 41 | ((buf[offset+1] & 0xff) << 8) | 42 | ((buf[offset+2] & 0xff) << 16) | 43 | ((buf[offset+3]) << 24); 44 | if (result < -1) { 45 | LogHelper.warning(String.format("Encountered optional uint that is out of range at offset 0x%x. Set result to 0", offset)); 46 | result = 0; 47 | } 48 | return result; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/dexlib2/DexBackedDexFile0.aj: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.smali.dexlib2; 2 | 3 | import org.jf.dexlib2.Opcodes; 4 | import org.jf.dexlib2.dexbacked.DexBackedDexFile; 5 | 6 | import javax.annotation.Nonnull; 7 | 8 | /** 9 | * Created by rover12421 on 12/5/15. 10 | */ 11 | privileged public aspect DexBackedDexFile0 { 12 | public DexBackedDexFile.new(@Nonnull Opcodes opcodes, @Nonnull byte[] buf, int offset, boolean verifyMagic 13 | , Object ____) { 14 | this(opcodes, buf, offset, verifyMagic); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/dexlib2/DexBackedDexFileAj.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.smali.dexlib2; 2 | 3 | import com.google.common.io.ByteStreams; 4 | import com.rover12421.shaka.lib.LogHelper; 5 | import org.aspectj.lang.ProceedingJoinPoint; 6 | import org.aspectj.lang.annotation.Around; 7 | import org.aspectj.lang.annotation.Aspect; 8 | import org.jf.baksmali.Main; 9 | import org.jf.dexlib2.Opcodes; 10 | import org.jf.dexlib2.dexbacked.DexBackedDexFile; 11 | import org.jf.dexlib2.dexbacked.raw.HeaderItem; 12 | import org.jf.util.ExceptionWithContext; 13 | 14 | import javax.annotation.Nonnull; 15 | import java.io.EOFException; 16 | import java.io.InputStream; 17 | import java.util.Arrays; 18 | 19 | /** 20 | * Created by rover12421 on 11/10/15. 21 | */ 22 | @Aspect 23 | public class DexBackedDexFileAj { 24 | public static void verifyMagicAndByteOrder(@Nonnull byte[] buf, int offset) { 25 | if (!HeaderItem.verifyMagic(buf, offset)) { 26 | StringBuilder sb = new StringBuilder("Invalid magic value:"); 27 | for (int i=0; i<8; i++) { 28 | sb.append(String.format(" %02x", buf[i])); 29 | } 30 | throw new DexBackedDexFile.NotADexFile(sb.toString()); 31 | } 32 | 33 | int endian = HeaderItem.getEndian(buf, offset); 34 | if (endian == HeaderItem.BIG_ENDIAN_TAG) { 35 | throw new ExceptionWithContext("Big endian dex files are not currently supported"); 36 | } 37 | 38 | if (endian != HeaderItem.LITTLE_ENDIAN_TAG) { 39 | throw new ExceptionWithContext("Invalid endian tag: 0x%x", endian); 40 | } 41 | } 42 | 43 | private static final byte[] MAGIC = new byte[]{0x64, 0x65, 0x78, 0x0a, 0x30, 0x33}; 44 | 45 | /** 46 | * 需要修复!!! 47 | * @param joinPoint 48 | * @param opcodes 49 | * @param is 50 | * @return 51 | * @throws Throwable 52 | */ 53 | // @Around("execution(org.jf.dexlib2.dexbacked.DexBackedDexFile org.jf.dexlib2.dexbacked.DexBackedDexFile.fromInputStream(..))" + 54 | // "&& args(opcodes, is)") 55 | public DexBackedDexFile fromInputStream(ProceedingJoinPoint joinPoint, Opcodes opcodes, InputStream is) 56 | throws Throwable { 57 | 58 | //如果是反odex,使用原逻辑 59 | if (Main.getInstance().getJcommander().getCommands().get("deodex") != null) { 60 | return (DexBackedDexFile) joinPoint.proceed(joinPoint.getArgs()); 61 | } 62 | 63 | if (!is.markSupported()) { 64 | throw new IllegalArgumentException("InputStream must support mark"); 65 | } 66 | byte[] flag = new byte[MAGIC.length]; 67 | int skip = 0; 68 | int len = is.available() - 44; 69 | for (int i=0; i= 0x35 && ver <= 0x36) { 78 | skip = i; 79 | if (skip != 0) { 80 | LogHelper.info("Search Dex Offset : " + skip); 81 | } 82 | is.reset(); 83 | break; 84 | } 85 | } 86 | is.reset(); 87 | } 88 | 89 | is.mark(44+skip); 90 | is.skip(skip); 91 | byte[] partialHeader = new byte[44]; 92 | try { 93 | ByteStreams.readFully(is, partialHeader); 94 | } catch (EOFException ex) { 95 | throw new DexBackedDexFile.NotADexFile("File is too short"); 96 | } finally { 97 | is.reset(); 98 | } 99 | 100 | verifyMagicAndByteOrder(partialHeader, 0); 101 | 102 | byte[] buf = ByteStreams.toByteArray(is); 103 | // return new DexBackedDexFile(opcodes, buf, 0, false); 104 | return new DexBackedDexFile(opcodes, buf, skip, false, null); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/dexlib2/DexBackedMethod0.aj: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.smali.dexlib2; 2 | 3 | import org.jf.dexlib2.dexbacked.DexBackedMethod; 4 | 5 | /** 6 | * Created by rover12421 on 12/5/15. 7 | */ 8 | privileged public aspect DexBackedMethod0 { 9 | public int DexBackedMethod.getCodeOffset() { 10 | return this.codeOffset; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/dexlib2/DexBackedMethodAj.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.smali.dexlib2; 2 | 3 | import org.aspectj.lang.ProceedingJoinPoint; 4 | import org.aspectj.lang.annotation.Around; 5 | import org.aspectj.lang.annotation.Aspect; 6 | import org.jf.dexlib2.dexbacked.DexBackedMethod; 7 | import org.jf.dexlib2.dexbacked.DexBackedMethodImplementation; 8 | 9 | /** 10 | * Created by rover12421 on 11/10/15. 11 | */ 12 | @Aspect 13 | public class DexBackedMethodAj { 14 | @Around("execution(* org.jf.dexlib2.dexbacked.DexBackedMethod.getImplementation())") 15 | public DexBackedMethodImplementation getImplementation(ProceedingJoinPoint joinPoint) { 16 | DexBackedMethod thiz = (DexBackedMethod) joinPoint.getThis(); 17 | int codeOffset = thiz.getCodeOffset(); 18 | if (codeOffset != 0) { 19 | return new DexBackedMethodImplementation(thiz.dexFile, thiz, codeOffset); 20 | } 21 | return null; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/dexlib2/DexBackedMethodImplementation0.aj: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.smali.dexlib2; 2 | 3 | import org.jf.dexlib2.dexbacked.DexBackedMethodImplementation; 4 | 5 | /** 6 | * Created by rover12421 on 12/6/15. 7 | */ 8 | privileged public aspect DexBackedMethodImplementation0 { 9 | public int DexBackedMethodImplementation.getCodeOffset() { 10 | return this.codeOffset; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/dexlib2/DexBackedMethodImplementationAj.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.smali.dexlib2; 17 | 18 | import com.rover12421.shaka.lib.LogHelper; 19 | import org.aspectj.lang.ProceedingJoinPoint; 20 | import org.aspectj.lang.annotation.Around; 21 | import org.aspectj.lang.annotation.Aspect; 22 | import org.jf.dexlib2.Opcode; 23 | import org.jf.dexlib2.dexbacked.DexBackedDexFile; 24 | import org.jf.dexlib2.dexbacked.DexBackedMethodImplementation; 25 | import org.jf.dexlib2.dexbacked.DexReader; 26 | import org.jf.dexlib2.dexbacked.instruction.DexBackedInstruction; 27 | import org.jf.dexlib2.dexbacked.instruction.DexBackedInstruction10x; 28 | import org.jf.dexlib2.dexbacked.raw.CodeItem; 29 | import org.jf.dexlib2.dexbacked.util.DebugInfo; 30 | import org.jf.dexlib2.iface.instruction.Instruction; 31 | import org.jf.dexlib2.iface.instruction.OffsetInstruction; 32 | 33 | import java.util.ArrayList; 34 | import java.util.List; 35 | 36 | /** 37 | * Created by rover12421 on 4/12/15. 38 | */ 39 | @Aspect 40 | public class DexBackedMethodImplementationAj { 41 | 42 | @Around("execution(* org.jf.dexlib2.dexbacked.DexBackedMethodImplementation.getInstructions(..))") 43 | public Iterable getInstructions(ProceedingJoinPoint joinPoint) throws Exception { 44 | DexBackedMethodImplementation thiz = (DexBackedMethodImplementation) joinPoint.getThis(); 45 | 46 | int codeOffset = thiz.getCodeOffset(); 47 | 48 | // instructionsSize is the number of 16-bit code units in the instruction list, not the number of instructions 49 | int instructionsSize = thiz.dexFile.readSmallUint(codeOffset + CodeItem.INSTRUCTION_COUNT_OFFSET); 50 | 51 | final int instructionsStartOffset = codeOffset + CodeItem.INSTRUCTION_START_OFFSET; 52 | final int endOffset = instructionsStartOffset + (instructionsSize*2); 53 | 54 | List instructions = new ArrayList<>(); 55 | DexReader reader = thiz.dexFile.readerAt(instructionsStartOffset); 56 | while (reader.getOffset() < endOffset) { 57 | Instruction instruction = DexBackedInstruction.readFrom(reader); 58 | instructions.add(instruction); 59 | } 60 | if (instructions.size() == 3 61 | && instructions.get(0) instanceof OffsetInstruction 62 | && instructions.get(1).getOpcode() == Opcode.FILL_ARRAY_DATA 63 | && instructions.get(2).getOpcode() == Opcode.ARRAY_PAYLOAD) { 64 | /** 65 | * 检测到dalvik-obfuscator代码快 66 | * 先重置instructions和reader 67 | * dalvik-obfuscator用nop替换,再继续读取正常的指令数据 68 | */ 69 | LogHelper.warning("Detected dalvik-obfuscator code block : " + thiz.method.getDefiningClass() + "->" + thiz.method.getName()); 70 | instructions.clear(); 71 | reader = thiz.dexFile.readerAt(instructionsStartOffset); 72 | /** 73 | * dalvik-obfuscator最少要9个nop宽度的数据,可多不可少 74 | */ 75 | for (int i=0; i<9; i++) { 76 | DexBackedInstruction10x nop = new DexBackedInstruction10x(thiz.dexFile, Opcode.NOP, instructionsStartOffset + i*2); 77 | instructions.add(nop); 78 | reader.moveRelative(2); 79 | } 80 | while (reader.getOffset() < endOffset) { 81 | Instruction instruction = DexBackedInstruction.readFrom(reader); 82 | instructions.add(instruction); 83 | } 84 | } 85 | return instructions; 86 | } 87 | 88 | @Around("execution(* org.jf.dexlib2.dexbacked.DexBackedMethodImplementation.getDebugInfo())") 89 | public DebugInfo getDebugInfo(ProceedingJoinPoint joinPoint) { 90 | DexBackedMethodImplementation thiz = (DexBackedMethodImplementation) joinPoint.getThis(); 91 | DexBackedDexFile dexFile = thiz.dexFile; 92 | int codeOffset = thiz.getCodeOffset(); 93 | 94 | int debugOffset = dexFile.readInt(codeOffset + CodeItem.DEBUG_INFO_OFFSET); 95 | try { 96 | return DebugInfo.newOrEmpty(dexFile, debugOffset, thiz); 97 | } catch (Throwable e) { 98 | return DebugInfo.newOrEmpty(dexFile, 0, thiz); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/dexlib2/InlineMethodResolverAj.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.smali.dexlib2; 2 | 3 | import com.rover12421.shaka.smali.baksmali.InlineMethodResolverFromFile; 4 | import com.rover12421.shaka.smali.baksmali.ShakaBaksmaliOption; 5 | import org.aspectj.lang.ProceedingJoinPoint; 6 | import org.aspectj.lang.annotation.Around; 7 | import org.aspectj.lang.annotation.Aspect; 8 | import org.jf.dexlib2.analysis.InlineMethodResolver; 9 | 10 | import java.io.File; 11 | 12 | /** 13 | * Created by rover12421 on 9/13/15. 14 | */ 15 | @Aspect 16 | public class InlineMethodResolverAj { 17 | 18 | @Around("execution(* org.jf.dexlib2.analysis.InlineMethodResolver.createInlineMethodResolver(..))") 19 | public InlineMethodResolver createInlineMethodResolver(ProceedingJoinPoint joinPoint) throws Throwable { 20 | String file = ShakaBaksmaliOption.getInlineMethodResolverFile(); 21 | if (file != null && new File(file).exists()) { 22 | return new InlineMethodResolverFromFile(file); 23 | } 24 | 25 | return (InlineMethodResolver) joinPoint.proceed(joinPoint.getArgs()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/smali/smaliMain.aj: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.smali.smali; 2 | 3 | import org.apache.commons.cli.Options; 4 | 5 | /** 6 | * Created by rover12421 on 12/6/15. 7 | */ 8 | privileged public aspect smaliMain { 9 | // public static Options org.jf.smali.Main.getBasicOptions() { 10 | // return org.jf.smali.Main.basicOptions; 11 | // } 12 | // 13 | // public static Options org.jf.smali.main.getDebugOptions() { 14 | // return org.jf.smali.main.debugOptions; 15 | // } 16 | // 17 | // public static Options org.jf.smali.main.getOptions() { 18 | // return org.jf.smali.main.options; 19 | // } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/smali/smaliMainAj.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.smali.smali; 17 | 18 | import com.rover12421.shaka.lib.HookMain; 19 | import org.aspectj.lang.annotation.Around; 20 | import org.aspectj.lang.annotation.Aspect; 21 | 22 | /** 23 | * Created by rover12421 on 5/17/15. 24 | */ 25 | @Aspect 26 | public class smaliMainAj { 27 | private static HookMain hookMain; 28 | 29 | public static void setHookMain(HookMain hookMain) { 30 | smaliMainAj.hookMain = hookMain; 31 | } 32 | 33 | @Around("execution(* org.jf.smali.main.usage(..))" + 34 | "&& args(printDebugOptions)") 35 | public void usage(boolean printDebugOptions) { 36 | hookMain.usage(); 37 | } 38 | 39 | @Around("execution(* org.jf.smali.main.version())") 40 | public void version() { 41 | hookMain.version(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /shaka/smali/src/main/java/com/rover12421/shaka/smali/util/StringUtilsAj.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Rover12421 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 | package com.rover12421.shaka.smali.util; 17 | 18 | import com.rover12421.shaka.lib.ShakaDecodeOption; 19 | import com.rover12421.shaka.lib.ShakaStringUtil; 20 | import org.aspectj.lang.ProceedingJoinPoint; 21 | import org.aspectj.lang.annotation.Around; 22 | import org.aspectj.lang.annotation.Aspect; 23 | 24 | import java.io.Writer; 25 | 26 | /** 27 | * Created by rover12421 on 4/10/15. 28 | */ 29 | @Aspect 30 | public class StringUtilsAj { 31 | @Around("execution(* org.jf.util.StringUtils.writeEscapedChar(..))" + 32 | "&& args(writer, c)") 33 | public void writeEscapedChar(ProceedingJoinPoint joinPoint, Writer writer, char c) throws Throwable { 34 | 35 | if (!ShakaDecodeOption.getInstance().isShowMoreRecognizableCharacters()) { 36 | joinPoint.proceed(joinPoint.getArgs()); 37 | return; 38 | } 39 | 40 | writer.write(ShakaStringUtil.escaped(c)); 41 | } 42 | 43 | @Around("execution(* org.jf.util.StringUtils.writeEscapedString(..))" + 44 | "&& args(writer, value)") 45 | public void writeEscapedString(ProceedingJoinPoint joinPoint, Writer writer, String value) throws Throwable { 46 | if (!ShakaDecodeOption.getInstance().isShowMoreRecognizableCharacters()) { 47 | joinPoint.proceed(joinPoint.getArgs()); 48 | return; 49 | } 50 | 51 | for (int i = 0; i < value.length(); i++) { 52 | char c = value.charAt(i); 53 | writer.write(ShakaStringUtil.escaped(c)); 54 | } 55 | } 56 | 57 | @Around("execution(* org.jf.util.StringUtils.escapeString(..))" + 58 | "&& args(value)") 59 | public String escapeString(ProceedingJoinPoint joinPoint, String value) throws Throwable { 60 | if (!ShakaDecodeOption.getInstance().isShowMoreRecognizableCharacters()) { 61 | return (String) joinPoint.proceed(joinPoint.getArgs()); 62 | } 63 | 64 | int len = value.length(); 65 | StringBuilder sb = new StringBuilder(len * 3 / 2); 66 | 67 | for (int i = 0; i < len; i++) { 68 | char c = value.charAt(i); 69 | sb.append(ShakaStringUtil.escaped(c)); 70 | } 71 | 72 | return sb.toString(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /shaka/smali/src/test/java/com/rover12421/shaka/smali/test/BaseDexBufferTestAj.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.smali.test; 2 | 3 | import org.aspectj.lang.annotation.Around; 4 | import org.aspectj.lang.annotation.Aspect; 5 | import org.jf.util.ExceptionWithContext; 6 | 7 | /** 8 | * Created by rover12421 on 1/26/16. 9 | */ 10 | @Aspect 11 | public class BaseDexBufferTestAj { 12 | @Around("execution(* org.jf.dexlib2.dexbacked.BaseDexBufferTest.testReadRandom(..))") 13 | public void skip_testReadRandom() { 14 | /** 15 | * 测试随机异常. 16 | * readSmallUint 已经skip了异常.没法测试faild情况 17 | */ 18 | } 19 | 20 | @Around("execution(* org.jf.dexlib2.dexbacked.BaseDexBufferTest.testReadSmallUintTooLarge*(..))") 21 | public void skip_testReadSmallUintTooLarge() { 22 | /** 23 | * readSmallUint 已经skip了异常.没法测试faild情况 24 | */ 25 | throw new ExceptionWithContext("skip test"); 26 | } 27 | 28 | @Around("execution(* org.jf.dexlib2.dexbacked.BaseDexBufferTest.testReadOptionalUintTooLarge*(..))") 29 | public void skip_testReadOptionalUintTooLarge() { 30 | /** 31 | * readSmallUint 已经skip了异常.没法测试faild情况 32 | */ 33 | throw new ExceptionWithContext("skip test"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /shaka/smali/src/test/java/com/rover12421/shaka/smali/test/BaseDexReaderLeb128TestAj.java: -------------------------------------------------------------------------------- 1 | package com.rover12421.shaka.smali.test; 2 | 3 | import org.aspectj.lang.ProceedingJoinPoint; 4 | import org.aspectj.lang.annotation.Around; 5 | import org.aspectj.lang.annotation.Aspect; 6 | 7 | /** 8 | * Created by rover12421 on 11/19/15. 9 | */ 10 | @Aspect 11 | public class BaseDexReaderLeb128TestAj { 12 | @Around("execution(* org.jf.dexlib2.dexbacked.BaseDexReaderLeb128Test.performFailureTest(..))") 13 | public void performFailureTest(ProceedingJoinPoint joinPoint) { 14 | try { 15 | joinPoint.proceed(joinPoint.getArgs()); 16 | } catch (Throwable e) { 17 | /** 18 | * 为了支持方向搜索,这里是没有异常的 19 | */ 20 | } 21 | } 22 | } 23 | --------------------------------------------------------------------------------