├── .gitignore ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── swift │ │ └── sandhook │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ ├── com │ │ │ ├── droid │ │ │ │ ├── dx │ │ │ │ │ ├── AnnotationId.java │ │ │ │ │ ├── AppDataDirGuesser.java │ │ │ │ │ ├── BinaryOp.java │ │ │ │ │ ├── Code.java │ │ │ │ │ ├── Comparison.java │ │ │ │ │ ├── Constants.java │ │ │ │ │ ├── DexMaker.java │ │ │ │ │ ├── FieldId.java │ │ │ │ │ ├── Label.java │ │ │ │ │ ├── Local.java │ │ │ │ │ ├── MethodId.java │ │ │ │ │ ├── TypeId.java │ │ │ │ │ ├── TypeList.java │ │ │ │ │ ├── UnaryOp.java │ │ │ │ │ └── stock │ │ │ │ │ │ └── ProxyBuilder.java │ │ │ │ └── internal │ │ │ │ │ └── util │ │ │ │ │ └── XmlUtils.java │ │ │ └── swift │ │ │ │ └── sandhook │ │ │ │ ├── FirstFragment.kt │ │ │ │ ├── Main.java │ │ │ │ ├── MainActivity.kt │ │ │ │ └── SecondFragment.kt │ │ └── ext │ │ │ └── org │ │ │ └── apache │ │ │ └── commons │ │ │ └── lang3 │ │ │ ├── ArrayUtils.java │ │ │ ├── CharSequenceUtils.java │ │ │ ├── CharUtils.java │ │ │ ├── ClassUtils.java │ │ │ ├── JavaVersion.java │ │ │ ├── ObjectUtils.java │ │ │ ├── StringUtils.java │ │ │ ├── SystemUtils.java │ │ │ ├── Validate.java │ │ │ ├── builder │ │ │ ├── Builder.java │ │ │ ├── CompareToBuilder.java │ │ │ ├── EqualsBuilder.java │ │ │ ├── HashCodeBuilder.java │ │ │ ├── IDKey.java │ │ │ ├── ReflectionToStringBuilder.java │ │ │ ├── ToStringBuilder.java │ │ │ └── ToStringStyle.java │ │ │ ├── exception │ │ │ └── CloneFailedException.java │ │ │ ├── mutable │ │ │ ├── Mutable.java │ │ │ └── MutableInt.java │ │ │ ├── reflect │ │ │ ├── MemberUtils.java │ │ │ └── MethodUtils.java │ │ │ └── tuple │ │ │ ├── ImmutablePair.java │ │ │ └── Pair.java │ ├── native │ │ ├── CMakeLists.txt │ │ ├── common │ │ │ ├── cow_vector.h │ │ │ ├── dlfcn_nougat.cc │ │ │ ├── dlfcn_nougat.h │ │ │ ├── elf_util.cc │ │ │ ├── elf_util.h │ │ │ ├── log.h │ │ │ ├── types.cc │ │ │ └── types.h │ │ ├── exts │ │ │ ├── distorm │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── config.h │ │ │ │ ├── decoder.c │ │ │ │ ├── decoder.h │ │ │ │ ├── distorm.c │ │ │ │ ├── distorm.h │ │ │ │ ├── instructions.c │ │ │ │ ├── instructions.h │ │ │ │ ├── insts.c │ │ │ │ ├── insts.h │ │ │ │ ├── mnemonics.c │ │ │ │ ├── mnemonics.h │ │ │ │ ├── operands.c │ │ │ │ ├── operands.h │ │ │ │ ├── prefix.c │ │ │ │ ├── prefix.h │ │ │ │ ├── textdefs.c │ │ │ │ ├── textdefs.h │ │ │ │ ├── wstring.c │ │ │ │ ├── wstring.h │ │ │ │ └── x86defs.h │ │ │ ├── ucontext │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── aarch64 │ │ │ │ │ ├── common │ │ │ │ │ │ └── sysdep.h │ │ │ │ │ ├── config.h │ │ │ │ │ ├── getcontext.S │ │ │ │ │ ├── kernel_rt_sigframe.h │ │ │ │ │ ├── libc-symbols.h │ │ │ │ │ ├── makecontext.c │ │ │ │ │ ├── setcontext.S │ │ │ │ │ ├── swapcontext.S │ │ │ │ │ ├── sysdep.c │ │ │ │ │ ├── sysdep.h │ │ │ │ │ ├── ucontext-internal.h │ │ │ │ │ ├── ucontext_i.h │ │ │ │ │ └── ucontext_i.sym │ │ │ │ ├── arm │ │ │ │ │ ├── arm_bx.h │ │ │ │ │ ├── common │ │ │ │ │ │ └── sysdep.h │ │ │ │ │ ├── getcontext.S │ │ │ │ │ ├── makecontext.c │ │ │ │ │ ├── scripts │ │ │ │ │ │ └── gen-as-const.awk │ │ │ │ │ ├── setcontext.S │ │ │ │ │ ├── swapcontext.S │ │ │ │ │ ├── sysdep.h │ │ │ │ │ ├── ucontext.mk │ │ │ │ │ ├── ucontext_i.h │ │ │ │ │ └── ucontext_i.sym │ │ │ │ ├── breakpad_getcontext.S │ │ │ │ └── ucontext_constants.h │ │ │ └── vixl │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── aarch32 │ │ │ │ ├── assembler-aarch32.cc │ │ │ │ ├── assembler-aarch32.h │ │ │ │ ├── constants-aarch32.cc │ │ │ │ ├── constants-aarch32.h │ │ │ │ ├── disasm-aarch32.cc │ │ │ │ ├── disasm-aarch32.h │ │ │ │ ├── instructions-aarch32.cc │ │ │ │ ├── instructions-aarch32.h │ │ │ │ ├── location-aarch32.cc │ │ │ │ ├── location-aarch32.h │ │ │ │ ├── macro-assembler-aarch32.cc │ │ │ │ ├── macro-assembler-aarch32.h │ │ │ │ ├── operands-aarch32.cc │ │ │ │ └── operands-aarch32.h │ │ │ │ ├── aarch64 │ │ │ │ ├── abi-aarch64.h │ │ │ │ ├── assembler-aarch64.cc │ │ │ │ ├── assembler-aarch64.h │ │ │ │ ├── constants-aarch64.h │ │ │ │ ├── cpu-aarch64.cc │ │ │ │ ├── cpu-aarch64.h │ │ │ │ ├── cpu-features-auditor-aarch64.cc │ │ │ │ ├── cpu-features-auditor-aarch64.h │ │ │ │ ├── decoder-aarch64.cc │ │ │ │ ├── decoder-aarch64.h │ │ │ │ ├── decoder-constants-aarch64.h │ │ │ │ ├── disasm-aarch64.cc │ │ │ │ ├── disasm-aarch64.h │ │ │ │ ├── instructions-aarch64.cc │ │ │ │ ├── instructions-aarch64.h │ │ │ │ ├── instrument-aarch64.cc │ │ │ │ ├── instrument-aarch64.h │ │ │ │ ├── logic-aarch64.cc │ │ │ │ ├── macro-assembler-aarch64.cc │ │ │ │ ├── macro-assembler-aarch64.h │ │ │ │ ├── operands-aarch64.cc │ │ │ │ ├── operands-aarch64.h │ │ │ │ ├── pointer-auth-aarch64.cc │ │ │ │ ├── simulator-aarch64.cc │ │ │ │ ├── simulator-aarch64.h │ │ │ │ └── simulator-constants-aarch64.h │ │ │ │ ├── assembler-base-vixl.h │ │ │ │ ├── code-buffer-vixl.cc │ │ │ │ ├── code-buffer-vixl.h │ │ │ │ ├── code-generation-scopes-vixl.h │ │ │ │ ├── compiler-intrinsics-vixl.cc │ │ │ │ ├── compiler-intrinsics-vixl.h │ │ │ │ ├── cpu-features.cc │ │ │ │ ├── cpu-features.h │ │ │ │ ├── globals-vixl.h │ │ │ │ ├── invalset-vixl.h │ │ │ │ ├── macro-assembler-interface.h │ │ │ │ ├── platform-vixl.h │ │ │ │ ├── pool-manager-impl.h │ │ │ │ ├── pool-manager.h │ │ │ │ ├── utils-vixl.cc │ │ │ │ └── utils-vixl.h │ │ ├── include │ │ │ └── inline_hook.h │ │ ├── inline │ │ │ ├── arm32 │ │ │ │ └── inline_hook_arm32.cpp │ │ │ ├── arm64 │ │ │ │ └── inline_hook_arm64.cc │ │ │ └── inline_hook.cc │ │ ├── instrcache │ │ │ ├── arm32 │ │ │ │ ├── translator.cc │ │ │ │ └── translator.h │ │ │ ├── arm64 │ │ │ │ ├── translator.cc │ │ │ │ └── translator.h │ │ │ └── instr_cache.h │ │ ├── main.cc │ │ ├── main.h │ │ ├── memory │ │ │ ├── code_buffer.cc │ │ │ └── code_buffer.h │ │ └── platform │ │ │ ├── memory.cc │ │ │ └── memory.h │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── content_main.xml │ │ ├── fragment_first.xml │ │ └── fragment_second.xml │ │ ├── menu │ │ └── menu_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── navigation │ │ └── nav_graph.xml │ │ ├── values-night │ │ └── themes.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── themes.xml │ └── test │ └── java │ └── com │ └── swift │ └── sandhook │ └── ExampleUnitTest.kt ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'kotlin-android' 4 | } 5 | 6 | android { 7 | compileSdkVersion 30 8 | buildToolsVersion "30.0.3" 9 | 10 | defaultConfig { 11 | applicationId "com.swift.sandhook" 12 | minSdkVersion 16 13 | targetSdkVersion 30 14 | versionCode 1 15 | versionName "1.0" 16 | 17 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 18 | 19 | ndk { 20 | abiFilters "arm64-v8a" 21 | } 22 | } 23 | 24 | buildTypes { 25 | release { 26 | minifyEnabled false 27 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 28 | } 29 | } 30 | 31 | externalNativeBuild { 32 | cmake { 33 | path "src/main/native/CMakeLists.txt" 34 | version "3.10.2" 35 | } 36 | } 37 | 38 | compileOptions { 39 | sourceCompatibility JavaVersion.VERSION_1_8 40 | targetCompatibility JavaVersion.VERSION_1_8 41 | } 42 | kotlinOptions { 43 | jvmTarget = '1.8' 44 | } 45 | } 46 | 47 | dependencies { 48 | 49 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 50 | implementation 'androidx.core:core-ktx:1.2.0' 51 | implementation 'androidx.appcompat:appcompat:1.1.0' 52 | implementation 'com.google.android.material:material:1.1.0' 53 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 54 | implementation 'androidx.navigation:navigation-fragment-ktx:2.2.2' 55 | implementation 'androidx.navigation:navigation-ui-ktx:2.2.2' 56 | implementation 'com.jakewharton.android.repackaged:dalvik-dx:9.0.0_r3' 57 | testImplementation 'junit:junit:4.+' 58 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 59 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 60 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/androidTest/java/com/swift/sandhook/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.swift.sandhook 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.swift.sandhook", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/droid/dx/BinaryOp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.droid.dx; 18 | 19 | import com.android.dx.rop.code.Rop; 20 | import com.android.dx.rop.code.Rops; 21 | import com.android.dx.rop.type.TypeList; 22 | 23 | /** 24 | * An operation on two values of the same type. 25 | * 26 | *

Math operations ({@link #ADD}, {@link #SUBTRACT}, {@link #MULTIPLY}, 27 | * {@link #DIVIDE}, and {@link #REMAINDER}) support ints, longs, floats and 28 | * doubles. 29 | * 30 | *

Bit operations ({@link #AND}, {@link #OR}, {@link #XOR}, {@link 31 | * #SHIFT_LEFT}, {@link #SHIFT_RIGHT}, {@link #UNSIGNED_SHIFT_RIGHT}) support 32 | * ints and longs. 33 | * 34 | *

Division by zero behaves differently depending on the operand type. 35 | * For int and long operands, {@link #DIVIDE} and {@link #REMAINDER} throw 36 | * {@link ArithmeticException} if {@code b == 0}. For float and double operands, 37 | * the operations return {@code NaN}. 38 | */ 39 | public enum BinaryOp { 40 | /** {@code a + b} */ 41 | ADD() { 42 | @Override 43 | Rop rop(TypeList types) { 44 | return Rops.opAdd(types); 45 | } 46 | }, 47 | 48 | /** {@code a - b} */ 49 | SUBTRACT() { 50 | @Override 51 | Rop rop(TypeList types) { 52 | return Rops.opSub(types); 53 | } 54 | }, 55 | 56 | /** {@code a * b} */ 57 | MULTIPLY() { 58 | @Override 59 | Rop rop(TypeList types) { 60 | return Rops.opMul(types); 61 | } 62 | }, 63 | 64 | /** {@code a / b} */ 65 | DIVIDE() { 66 | @Override 67 | Rop rop(TypeList types) { 68 | return Rops.opDiv(types); 69 | } 70 | }, 71 | 72 | /** {@code a % b} */ 73 | REMAINDER() { 74 | @Override 75 | Rop rop(TypeList types) { 76 | return Rops.opRem(types); 77 | } 78 | }, 79 | 80 | /** {@code a & b} */ 81 | AND() { 82 | @Override 83 | Rop rop(TypeList types) { 84 | return Rops.opAnd(types); 85 | } 86 | }, 87 | 88 | /** {@code a | b} */ 89 | OR() { 90 | @Override 91 | Rop rop(TypeList types) { 92 | return Rops.opOr(types); 93 | } 94 | }, 95 | 96 | /** {@code a ^ b} */ 97 | XOR() { 98 | @Override 99 | Rop rop(TypeList types) { 100 | return Rops.opXor(types); 101 | } 102 | }, 103 | 104 | /** {@code a << b} */ 105 | SHIFT_LEFT() { 106 | @Override 107 | Rop rop(TypeList types) { 108 | return Rops.opShl(types); 109 | } 110 | }, 111 | 112 | /** {@code a >> b} */ 113 | SHIFT_RIGHT() { 114 | @Override 115 | Rop rop(TypeList types) { 116 | return Rops.opShr(types); 117 | } 118 | }, 119 | 120 | /** {@code a >>> b} */ 121 | UNSIGNED_SHIFT_RIGHT() { 122 | @Override 123 | Rop rop(TypeList types) { 124 | return Rops.opUshr(types); 125 | } 126 | }; 127 | 128 | abstract Rop rop(TypeList types); 129 | } 130 | -------------------------------------------------------------------------------- /app/src/main/java/com/droid/dx/Comparison.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.droid.dx; 18 | 19 | import com.android.dx.rop.code.Rop; 20 | import com.android.dx.rop.code.Rops; 21 | import com.android.dx.rop.type.TypeList; 22 | 23 | /** 24 | * A comparison between two values of the same type. 25 | */ 26 | public enum Comparison { 27 | 28 | /** {@code a < b}. Supports int only. */ 29 | LT() { 30 | @Override 31 | Rop rop(TypeList types) { 32 | return Rops.opIfLt(types); 33 | } 34 | }, 35 | 36 | /** {@code a <= b}. Supports int only. */ 37 | LE() { 38 | @Override 39 | Rop rop(TypeList types) { 40 | return Rops.opIfLe(types); 41 | } 42 | }, 43 | 44 | /** {@code a == b}. Supports int and reference types. */ 45 | EQ() { 46 | @Override 47 | Rop rop(TypeList types) { 48 | return Rops.opIfEq(types); 49 | } 50 | }, 51 | 52 | /** {@code a >= b}. Supports int only. */ 53 | GE() { 54 | @Override 55 | Rop rop(TypeList types) { 56 | return Rops.opIfGe(types); 57 | } 58 | }, 59 | 60 | /** {@code a > b}. Supports int only. */ 61 | GT() { 62 | @Override 63 | Rop rop(TypeList types) { 64 | return Rops.opIfGt(types); 65 | } 66 | }, 67 | 68 | /** {@code a != b}. Supports int and reference types. */ 69 | NE() { 70 | @Override 71 | Rop rop(TypeList types) { 72 | return Rops.opIfNe(types); 73 | } 74 | }; 75 | 76 | abstract Rop rop(TypeList types); 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/com/droid/dx/Constants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.droid.dx; 18 | 19 | import com.android.dx.rop.cst.CstBoolean; 20 | import com.android.dx.rop.cst.CstByte; 21 | import com.android.dx.rop.cst.CstChar; 22 | import com.android.dx.rop.cst.CstDouble; 23 | import com.android.dx.rop.cst.CstFloat; 24 | import com.android.dx.rop.cst.CstInteger; 25 | import com.android.dx.rop.cst.CstKnownNull; 26 | import com.android.dx.rop.cst.CstLong; 27 | import com.android.dx.rop.cst.CstShort; 28 | import com.android.dx.rop.cst.CstString; 29 | import com.android.dx.rop.cst.CstType; 30 | import com.android.dx.rop.cst.TypedConstant; 31 | 32 | /** 33 | * Factory for rop constants. 34 | */ 35 | final class Constants { 36 | private Constants() {} 37 | 38 | /** 39 | * Returns a rop constant for the specified value. 40 | * 41 | * @param value null, a boxed primitive, String, Class, or TypeId. 42 | */ 43 | static TypedConstant getConstant(Object value) { 44 | if (value == null) { 45 | return CstKnownNull.THE_ONE; 46 | } else if (value instanceof Boolean) { 47 | return CstBoolean.make((Boolean) value); 48 | } else if (value instanceof Byte) { 49 | return CstByte.make((Byte) value); 50 | } else if (value instanceof Character) { 51 | return CstChar.make((Character) value); 52 | } else if (value instanceof Double) { 53 | return CstDouble.make(Double.doubleToLongBits((Double) value)); 54 | } else if (value instanceof Float) { 55 | return CstFloat.make(Float.floatToIntBits((Float) value)); 56 | } else if (value instanceof Integer) { 57 | return CstInteger.make((Integer) value); 58 | } else if (value instanceof Long) { 59 | return CstLong.make((Long) value); 60 | } else if (value instanceof Short) { 61 | return CstShort.make((Short) value); 62 | } else if (value instanceof String) { 63 | return new CstString((String) value); 64 | } else if (value instanceof Class) { 65 | return new CstType(TypeId.get((Class) value).ropType); 66 | } else if (value instanceof TypeId) { 67 | return new CstType(((TypeId) value).ropType); 68 | } else { 69 | throw new UnsupportedOperationException("Not a constant: " + value); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/droid/dx/FieldId.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.droid.dx; 18 | 19 | import com.android.dx.rop.cst.CstFieldRef; 20 | import com.android.dx.rop.cst.CstNat; 21 | import com.android.dx.rop.cst.CstString; 22 | 23 | /** 24 | * Identifies a field. 25 | * 26 | * @param the type declaring this field 27 | * @param the type of value this field holds 28 | */ 29 | public final class FieldId { 30 | final TypeId declaringType; 31 | final TypeId type; 32 | final String name; 33 | 34 | /** cached converted state */ 35 | final CstNat nat; 36 | final CstFieldRef constant; 37 | 38 | FieldId(TypeId declaringType, TypeId type, String name) { 39 | if (declaringType == null || type == null || name == null) { 40 | throw new NullPointerException(); 41 | } 42 | this.declaringType = declaringType; 43 | this.type = type; 44 | this.name = name; 45 | this.nat = new CstNat(new CstString(name), new CstString(type.name)); 46 | this.constant = new CstFieldRef(declaringType.constant, nat); 47 | } 48 | 49 | public TypeId getDeclaringType() { 50 | return declaringType; 51 | } 52 | 53 | public TypeId getType() { 54 | return type; 55 | } 56 | 57 | public String getName() { 58 | return name; 59 | } 60 | 61 | @Override 62 | public boolean equals(Object o) { 63 | return o instanceof FieldId 64 | && ((FieldId) o).declaringType.equals(declaringType) 65 | && ((FieldId) o).name.equals(name); 66 | } 67 | 68 | @Override 69 | public int hashCode() { 70 | return declaringType.hashCode() + 37 * name.hashCode(); 71 | } 72 | 73 | @Override 74 | public String toString() { 75 | return declaringType + "." + name; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/com/droid/dx/Label.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.droid.dx; 18 | 19 | import com.android.dx.rop.code.BasicBlock; 20 | import com.android.dx.rop.code.Insn; 21 | import com.android.dx.rop.code.InsnList; 22 | import com.android.dx.util.IntList; 23 | 24 | import java.util.ArrayList; 25 | import java.util.Collections; 26 | import java.util.List; 27 | 28 | /** 29 | * A branch target in a list of instructions. 30 | */ 31 | public final class Label { 32 | 33 | final List instructions = new ArrayList<>(); 34 | 35 | Code code; 36 | 37 | boolean marked = false; 38 | 39 | /** an immutable list of labels corresponding to the types in the catch list */ 40 | List

Warning: Use care when dealing with boxed primitive 28 | * types. Java's lack of support for parameterized primitive types means that 29 | * a primitive type like {@code int} and its boxed type {@code 30 | * java.lang.Integer} have the same type parameter: {@code TypeId}. 31 | * These types are different and it will be a runtime error if the boxed type 32 | * {@code java.lang.Integer} is used where the primitive type {@code int} is 33 | * expected. 34 | */ 35 | public final class TypeId { 36 | /** The {@code boolean} primitive type. */ 37 | public static final TypeId BOOLEAN = new TypeId<>(com.android.dx.rop.type.Type.BOOLEAN); 38 | 39 | /** The {@code byte} primitive type. */ 40 | public static final TypeId BYTE = new TypeId<>(com.android.dx.rop.type.Type.BYTE); 41 | 42 | /** The {@code char} primitive type. */ 43 | public static final TypeId CHAR = new TypeId<>(com.android.dx.rop.type.Type.CHAR); 44 | 45 | /** The {@code double} primitive type. */ 46 | public static final TypeId DOUBLE = new TypeId<>(com.android.dx.rop.type.Type.DOUBLE); 47 | 48 | /** The {@code float} primitive type. */ 49 | public static final TypeId FLOAT = new TypeId<>(com.android.dx.rop.type.Type.FLOAT); 50 | 51 | /** The {@code int} primitive type. */ 52 | public static final TypeId INT = new TypeId<>(com.android.dx.rop.type.Type.INT); 53 | 54 | /** The {@code long} primitive type. */ 55 | public static final TypeId LONG = new TypeId<>(com.android.dx.rop.type.Type.LONG); 56 | 57 | /** The {@code short} primitive type. */ 58 | public static final TypeId SHORT = new TypeId<>(com.android.dx.rop.type.Type.SHORT); 59 | 60 | /** The {@code void} primitive type. Only used as a return type. */ 61 | public static final TypeId VOID = new TypeId<>(com.android.dx.rop.type.Type.VOID); 62 | 63 | /** The {@code Object} type. */ 64 | public static final TypeId OBJECT = new TypeId<>(com.android.dx.rop.type.Type.OBJECT); 65 | 66 | /** The {@code String} type. */ 67 | public static final TypeId STRING = new TypeId<>(com.android.dx.rop.type.Type.STRING); 68 | 69 | private static final Map, TypeId> PRIMITIVE_TO_TYPE = new HashMap<>(); 70 | static { 71 | PRIMITIVE_TO_TYPE.put(boolean.class, BOOLEAN); 72 | PRIMITIVE_TO_TYPE.put(byte.class, BYTE); 73 | PRIMITIVE_TO_TYPE.put(char.class, CHAR); 74 | PRIMITIVE_TO_TYPE.put(double.class, DOUBLE); 75 | PRIMITIVE_TO_TYPE.put(float.class, FLOAT); 76 | PRIMITIVE_TO_TYPE.put(int.class, INT); 77 | PRIMITIVE_TO_TYPE.put(long.class, LONG); 78 | PRIMITIVE_TO_TYPE.put(short.class, SHORT); 79 | PRIMITIVE_TO_TYPE.put(void.class, VOID); 80 | } 81 | 82 | final String name; 83 | 84 | /** cached converted values */ 85 | final com.android.dx.rop.type.Type ropType; 86 | final CstType constant; 87 | 88 | TypeId(com.android.dx.rop.type.Type ropType) { 89 | this(ropType.getDescriptor(), ropType); 90 | } 91 | 92 | TypeId(String name, com.android.dx.rop.type.Type ropType) { 93 | if (name == null || ropType == null) { 94 | throw new NullPointerException(); 95 | } 96 | this.name = name; 97 | this.ropType = ropType; 98 | this.constant = CstType.intern(ropType); 99 | } 100 | 101 | /** 102 | * @param name a descriptor like "Ljava/lang/Class;". 103 | */ 104 | public static TypeId get(String name) { 105 | return new TypeId<>(name, com.android.dx.rop.type.Type.internReturnType(name)); 106 | } 107 | 108 | public static TypeId get(Class type) { 109 | if (type.isPrimitive()) { 110 | // guarded by equals 111 | @SuppressWarnings("unchecked") 112 | TypeId result = (TypeId) PRIMITIVE_TO_TYPE.get(type); 113 | return result; 114 | } 115 | String name = type.getName().replace('.', '/'); 116 | return get(type.isArray() ? name : 'L' + name + ';'); 117 | } 118 | 119 | public FieldId getField(TypeId type, String name) { 120 | return new FieldId<>(this, type, name); 121 | } 122 | 123 | public MethodId getConstructor(TypeId... parameters) { 124 | return new MethodId<>(this, VOID, "", new TypeList(parameters)); 125 | } 126 | 127 | public MethodId getStaticInitializer() { 128 | return new MethodId<>(this, VOID, "", new TypeList(new TypeId[0])); 129 | } 130 | 131 | public MethodId getMethod(TypeId returnType, String name, TypeId... parameters) { 132 | return new MethodId<>(this, returnType, name, new TypeList(parameters)); 133 | } 134 | 135 | public String getName() { 136 | return name; 137 | } 138 | 139 | @Override 140 | public boolean equals(Object o) { 141 | return o instanceof TypeId 142 | && ((TypeId) o).name.equals(name); 143 | } 144 | 145 | @Override 146 | public int hashCode() { 147 | return name.hashCode(); 148 | } 149 | 150 | @Override 151 | public String toString() { 152 | return name; 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /app/src/main/java/com/droid/dx/TypeList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.droid.dx; 18 | 19 | import com.android.dx.rop.type.StdTypeList; 20 | 21 | import java.util.Arrays; 22 | import java.util.Collections; 23 | import java.util.List; 24 | 25 | /** 26 | * An immutable of types. 27 | */ 28 | final class TypeList { 29 | final TypeId[] types; 30 | final StdTypeList ropTypes; 31 | 32 | TypeList(TypeId[] types) { 33 | this.types = types.clone(); 34 | this.ropTypes = new StdTypeList(types.length); 35 | for (int i = 0; i < types.length; i++) { 36 | ropTypes.set(i, types[i].ropType); 37 | } 38 | } 39 | 40 | /** 41 | * Returns an immutable list. 42 | */ 43 | public List> asList() { 44 | return Collections.unmodifiableList(Arrays.asList(types)); 45 | } 46 | 47 | @Override 48 | public boolean equals(Object o) { 49 | return o instanceof TypeList && Arrays.equals(((TypeList) o).types, types); 50 | } 51 | 52 | @Override 53 | public int hashCode() { 54 | return Arrays.hashCode(types); 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | StringBuilder result = new StringBuilder(); 60 | for (int i = 0; i < types.length; i++) { 61 | if (i > 0) { 62 | result.append(", "); 63 | } 64 | result.append(types[i]); 65 | } 66 | return result.toString(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/droid/dx/UnaryOp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.droid.dx; 18 | 19 | import com.android.dx.rop.code.Rop; 20 | import com.android.dx.rop.code.Rops; 21 | 22 | /** 23 | * An operation on one value. 24 | */ 25 | public enum UnaryOp { 26 | 27 | /** {@code ~a}. Supports int and long. */ 28 | NOT() { 29 | @Override 30 | Rop rop(TypeId type) { 31 | return Rops.opNot(type.ropType); 32 | } 33 | }, 34 | 35 | /** {@code -a}. Supports int, long, float and double. */ 36 | NEGATE() { 37 | @Override 38 | Rop rop(TypeId type) { 39 | return Rops.opNeg(type.ropType); 40 | } 41 | }; 42 | 43 | abstract Rop rop(TypeId type); 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/droid/internal/util/XmlUtils.java: -------------------------------------------------------------------------------- 1 | package com.droid.internal.util; 2 | 3 | import org.xmlpull.v1.XmlPullParserException; 4 | 5 | import java.io.InputStream; 6 | import java.util.HashMap; 7 | 8 | public class XmlUtils { 9 | 10 | public static final HashMap readMapXml(InputStream in) throws XmlPullParserException, java.io.IOException { 11 | return null; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/swift/sandhook/FirstFragment.kt: -------------------------------------------------------------------------------- 1 | package com.swift.sandhook 2 | 3 | import android.os.Bundle 4 | import androidx.fragment.app.Fragment 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import android.widget.Button 9 | import androidx.navigation.fragment.findNavController 10 | 11 | /** 12 | * A simple [Fragment] subclass as the default destination in the navigation. 13 | */ 14 | class FirstFragment : Fragment() { 15 | 16 | override fun onCreateView( 17 | inflater: LayoutInflater, container: ViewGroup?, 18 | savedInstanceState: Bundle? 19 | ): View? { 20 | // Inflate the layout for this fragment 21 | return inflater.inflate(R.layout.fragment_first, container, false) 22 | } 23 | 24 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 25 | super.onViewCreated(view, savedInstanceState) 26 | 27 | view.findViewById