Optimize code
This commit is contained in:
parent
650e7542ed
commit
8f753de854
@ -1,6 +1,8 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
id 'kotlin-android'
|
id 'kotlin-android'
|
||||||
|
id 'top.niunaijun.blackobfuscator'
|
||||||
|
id 'icu.nullptr.stringfuck'
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
@ -8,7 +10,7 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "xfk233.genshinproxy"
|
applicationId "xfk233.genshinproxy"
|
||||||
minSdk 27
|
minSdk 28
|
||||||
targetSdk 32
|
targetSdk 32
|
||||||
versionCode 5
|
versionCode 5
|
||||||
versionName "1.5"
|
versionName "1.5"
|
||||||
@ -16,8 +18,9 @@ android {
|
|||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
minifyEnabled false
|
minifyEnabled true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
shrinkResources true
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro', 'proguard-log.pro'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
@ -29,10 +32,23 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BlackObfuscator {
|
||||||
|
enabled true
|
||||||
|
depth 3
|
||||||
|
obfClass = ["xfk233.genshinproxy"]
|
||||||
|
}
|
||||||
|
|
||||||
|
stringFuck {
|
||||||
|
setKey "xfk2333"
|
||||||
|
obfuscationList ["xfk233.genshinproxy"]
|
||||||
|
workOnDebug true
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
//API
|
//API
|
||||||
compileOnly 'de.robv.android.xposed:api:82'
|
compileOnly 'de.robv.android.xposed:api:82'
|
||||||
//带源码Api
|
//带源码Api
|
||||||
compileOnly 'de.robv.android.xposed:api:82:sources'
|
compileOnly 'de.robv.android.xposed:api:82:sources'
|
||||||
implementation 'com.github.kyuubiran:EzXHelper:0.9.2'
|
implementation 'com.github.kyuubiran:EzXHelper:0.9.2'
|
||||||
|
implementation 'icu.nullptr.stringfuck:library:0.1.4'
|
||||||
}
|
}
|
692
app/genshinproxy-dic.txt
Normal file
692
app/genshinproxy-dic.txt
Normal file
@ -0,0 +1,692 @@
|
|||||||
|
倒卖的丢你老母个嗨
|
||||||
|
倒卖的丢你老母个臭嗨
|
||||||
|
倒卖的你个逆子早晚懒趴掉下来
|
||||||
|
倒卖的你妈有逼吗
|
||||||
|
倒卖的你老母个烂ham
|
||||||
|
倒卖的你这个逆子
|
||||||
|
倒卖的你逆你妈的臭烂逼
|
||||||
|
倒卖的信不信骨灰都给你扬咯
|
||||||
|
倒卖的去你妈个臭逼
|
||||||
|
倒卖的去你妈的
|
||||||
|
倒卖的去你妈的烂逼
|
||||||
|
倒卖的含家产
|
||||||
|
倒卖的夭寿鬼
|
||||||
|
倒卖的憨憨
|
||||||
|
倒卖的扬你妈的骨灰
|
||||||
|
倒卖的操你妈的臭头鸡仔
|
||||||
|
林北一拳打爆你妈的狗头
|
||||||
|
林北一拳打爆你妈的脑袋
|
||||||
|
林北一拳打穿你妈的血逼
|
||||||
|
倒卖的瓜娃子
|
||||||
|
还逆向
|
||||||
|
逆
|
||||||
|
逆向
|
||||||
|
逆向你妈个逼
|
||||||
|
逆向你妈的死人头
|
||||||
|
逆向工程师
|
||||||
|
倒卖的食屎啦
|
||||||
|
倒卖的骨灰都给你妈扬咯
|
||||||
|
倒卖的骨灰都给你扬咯
|
||||||
|
倒卖的扑街仔
|
||||||
|
富强
|
||||||
|
民主
|
||||||
|
文明
|
||||||
|
和谐
|
||||||
|
自由
|
||||||
|
平等
|
||||||
|
公正
|
||||||
|
法制
|
||||||
|
爱国
|
||||||
|
敬业
|
||||||
|
诚信
|
||||||
|
友善
|
||||||
|
ʻ
|
||||||
|
ʼ
|
||||||
|
ʽ
|
||||||
|
ʾ
|
||||||
|
ʿ
|
||||||
|
ˆ
|
||||||
|
ˈ
|
||||||
|
ˉ
|
||||||
|
ˊ
|
||||||
|
ˋ
|
||||||
|
ˎ
|
||||||
|
ˏ
|
||||||
|
ˑ
|
||||||
|
י
|
||||||
|
ـ
|
||||||
|
ٴ
|
||||||
|
ᐧ
|
||||||
|
ᴵ
|
||||||
|
ᵎ
|
||||||
|
ᵔ
|
||||||
|
ᵢ
|
||||||
|
ⁱ
|
||||||
|
ﹳ
|
||||||
|
ﹶ
|
||||||
|
゙
|
||||||
|
゙゙
|
||||||
|
ᐧᐧ
|
||||||
|
ᴵᴵ
|
||||||
|
ʻʻ
|
||||||
|
ʽʽ
|
||||||
|
ʼʼ
|
||||||
|
ʿʿ
|
||||||
|
ʾʾ
|
||||||
|
ــ
|
||||||
|
ˆˆ
|
||||||
|
ˉˉ
|
||||||
|
ˈˈ
|
||||||
|
ˋˋ
|
||||||
|
ˊˊ
|
||||||
|
ˏˏ
|
||||||
|
ˎˎ
|
||||||
|
ˑˑ
|
||||||
|
ᵔᵔ
|
||||||
|
יי
|
||||||
|
ᵎᵎ
|
||||||
|
ᵢᵢ
|
||||||
|
ⁱⁱ
|
||||||
|
ﹳﹳ
|
||||||
|
ٴٴ
|
||||||
|
ﹶﹶ
|
||||||
|
ʻʼ
|
||||||
|
ʻʽ
|
||||||
|
ʻʾ
|
||||||
|
ʻʿ
|
||||||
|
ʻˆ
|
||||||
|
ʻˈ
|
||||||
|
ʻˉ
|
||||||
|
ʻˊ
|
||||||
|
ʻˋ
|
||||||
|
ʻˎ
|
||||||
|
ʻˏ
|
||||||
|
ʻˑ
|
||||||
|
ʻי
|
||||||
|
ʻـ
|
||||||
|
ʻٴ
|
||||||
|
ʻᐧ
|
||||||
|
ʻᴵ
|
||||||
|
ʻᵎ
|
||||||
|
ʻᵔ
|
||||||
|
ʻᵢ
|
||||||
|
ʻⁱ
|
||||||
|
ʻﹳ
|
||||||
|
ʻﹶ
|
||||||
|
ʻ゙
|
||||||
|
ʼʻ
|
||||||
|
ʼʽ
|
||||||
|
ʼʾ
|
||||||
|
ʼʿ
|
||||||
|
ʼˆ
|
||||||
|
ʼˈ
|
||||||
|
ʼˉ
|
||||||
|
ʼˊ
|
||||||
|
ʼˋ
|
||||||
|
ʼˎ
|
||||||
|
ʼˏ
|
||||||
|
ʼˑ
|
||||||
|
ʼי
|
||||||
|
ʼـ
|
||||||
|
ʼٴ
|
||||||
|
ʼᐧ
|
||||||
|
ʼᴵ
|
||||||
|
ʼᵎ
|
||||||
|
ʼᵔ
|
||||||
|
ʼᵢ
|
||||||
|
ʼⁱ
|
||||||
|
ʼﹳ
|
||||||
|
ʼﹶ
|
||||||
|
ʼ゙
|
||||||
|
ʽʻ
|
||||||
|
ʽʼ
|
||||||
|
ʽʾ
|
||||||
|
ʽʿ
|
||||||
|
ʽˆ
|
||||||
|
ʽˈ
|
||||||
|
ʽˉ
|
||||||
|
ʽˊ
|
||||||
|
ʽˋ
|
||||||
|
ʽˎ
|
||||||
|
ʽˏ
|
||||||
|
ʽˑ
|
||||||
|
ʽי
|
||||||
|
ʽـ
|
||||||
|
ʽٴ
|
||||||
|
ʽᐧ
|
||||||
|
ʽᴵ
|
||||||
|
ʽᵎ
|
||||||
|
ʽᵔ
|
||||||
|
ʽᵢ
|
||||||
|
ʽⁱ
|
||||||
|
ʽﹳ
|
||||||
|
ʽﹶ
|
||||||
|
ʽ゙
|
||||||
|
ʾʻ
|
||||||
|
ʾʼ
|
||||||
|
ʾʽ
|
||||||
|
ʾʿ
|
||||||
|
ʾˆ
|
||||||
|
ʾˈ
|
||||||
|
ʾˉ
|
||||||
|
ʾˊ
|
||||||
|
ʾˋ
|
||||||
|
ʾˎ
|
||||||
|
ʾˏ
|
||||||
|
ʾˑ
|
||||||
|
ʾי
|
||||||
|
ʾـ
|
||||||
|
ʾٴ
|
||||||
|
ʾᐧ
|
||||||
|
ʾᴵ
|
||||||
|
ʾᵎ
|
||||||
|
ʾᵔ
|
||||||
|
ʾᵢ
|
||||||
|
ʾⁱ
|
||||||
|
ʾﹳ
|
||||||
|
ʾﹶ
|
||||||
|
ʾ゙
|
||||||
|
ʿʻ
|
||||||
|
ʿʼ
|
||||||
|
ʿʽ
|
||||||
|
ʿʾ
|
||||||
|
ʿˆ
|
||||||
|
ʿˈ
|
||||||
|
ʿˉ
|
||||||
|
ʿˊ
|
||||||
|
ʿˋ
|
||||||
|
ʿˎ
|
||||||
|
ʿˏ
|
||||||
|
ʿˑ
|
||||||
|
ʿי
|
||||||
|
ʿـ
|
||||||
|
ʿٴ
|
||||||
|
ʿᐧ
|
||||||
|
ʿᴵ
|
||||||
|
ʿᵎ
|
||||||
|
ʿᵔ
|
||||||
|
ʿᵢ
|
||||||
|
ʿⁱ
|
||||||
|
ʿﹳ
|
||||||
|
ʿﹶ
|
||||||
|
ʿ゙
|
||||||
|
ˆʻ
|
||||||
|
ˆʼ
|
||||||
|
ˆʽ
|
||||||
|
ˆʾ
|
||||||
|
ˆʿ
|
||||||
|
ˆˈ
|
||||||
|
ˆˉ
|
||||||
|
ˆˊ
|
||||||
|
ˆˋ
|
||||||
|
ˆˎ
|
||||||
|
ˆˏ
|
||||||
|
ˆˑ
|
||||||
|
ˆי
|
||||||
|
ˆـ
|
||||||
|
ˆٴ
|
||||||
|
ˆᐧ
|
||||||
|
ˆᴵ
|
||||||
|
ˆᵎ
|
||||||
|
ˆᵔ
|
||||||
|
ˆᵢ
|
||||||
|
ˆⁱ
|
||||||
|
ˆﹳ
|
||||||
|
ˆﹶ
|
||||||
|
ˆ゙
|
||||||
|
ˈʻ
|
||||||
|
ˈʼ
|
||||||
|
ˈʽ
|
||||||
|
ˈʾ
|
||||||
|
ˈʿ
|
||||||
|
ˈˆ
|
||||||
|
ˈˉ
|
||||||
|
ˈˊ
|
||||||
|
ˈˋ
|
||||||
|
ˈˎ
|
||||||
|
ˈˏ
|
||||||
|
ˈˑ
|
||||||
|
ˈי
|
||||||
|
ˈـ
|
||||||
|
ˈٴ
|
||||||
|
ˈᐧ
|
||||||
|
ˈᴵ
|
||||||
|
ˈᵎ
|
||||||
|
ˈᵔ
|
||||||
|
ˈᵢ
|
||||||
|
ˈⁱ
|
||||||
|
ˈﹳ
|
||||||
|
ˈﹶ
|
||||||
|
ˈ゙
|
||||||
|
ˉʻ
|
||||||
|
ˉʼ
|
||||||
|
ˉʽ
|
||||||
|
ˉʾ
|
||||||
|
ˉʿ
|
||||||
|
ˉˆ
|
||||||
|
ˉˈ
|
||||||
|
ˉˊ
|
||||||
|
ˉˋ
|
||||||
|
ˉˎ
|
||||||
|
ˉˏ
|
||||||
|
ˉˑ
|
||||||
|
ˉי
|
||||||
|
ˉـ
|
||||||
|
ˉٴ
|
||||||
|
ˉᐧ
|
||||||
|
ˉᴵ
|
||||||
|
ˉᵎ
|
||||||
|
ˉᵔ
|
||||||
|
ˉᵢ
|
||||||
|
ˉⁱ
|
||||||
|
ˉﹳ
|
||||||
|
ˉﹶ
|
||||||
|
ˉ゙
|
||||||
|
ˊʻ
|
||||||
|
ˊʼ
|
||||||
|
ˊʽ
|
||||||
|
ˊʾ
|
||||||
|
ˊʿ
|
||||||
|
ˊˆ
|
||||||
|
ˊˈ
|
||||||
|
ˊˉ
|
||||||
|
ˊˋ
|
||||||
|
ˊˎ
|
||||||
|
ˊˏ
|
||||||
|
ˊˑ
|
||||||
|
ˊי
|
||||||
|
ˊـ
|
||||||
|
ˊٴ
|
||||||
|
ˊᐧ
|
||||||
|
ˊᴵ
|
||||||
|
ˊᵎ
|
||||||
|
ˊᵔ
|
||||||
|
ˊᵢ
|
||||||
|
ˊⁱ
|
||||||
|
ˊﹳ
|
||||||
|
ˊﹶ
|
||||||
|
ˊ゙
|
||||||
|
ˋʻ
|
||||||
|
ˋʼ
|
||||||
|
ˋʽ
|
||||||
|
ˋʾ
|
||||||
|
ˋʿ
|
||||||
|
ˋˆ
|
||||||
|
ˋˈ
|
||||||
|
ˋˉ
|
||||||
|
ˋˊ
|
||||||
|
ˋˎ
|
||||||
|
ˋˏ
|
||||||
|
ˋˑ
|
||||||
|
ˋי
|
||||||
|
ˋـ
|
||||||
|
ˋٴ
|
||||||
|
ˋᐧ
|
||||||
|
ˋᴵ
|
||||||
|
ˋᵎ
|
||||||
|
ˋᵔ
|
||||||
|
ˋᵢ
|
||||||
|
ˋⁱ
|
||||||
|
ˋﹳ
|
||||||
|
ˋﹶ
|
||||||
|
ˋ゙
|
||||||
|
ˎʻ
|
||||||
|
ˎʼ
|
||||||
|
ˎʽ
|
||||||
|
ˎʾ
|
||||||
|
ˎʿ
|
||||||
|
ˎˆ
|
||||||
|
ˎˈ
|
||||||
|
ˎˉ
|
||||||
|
ˎˊ
|
||||||
|
ˎˋ
|
||||||
|
ˎˏ
|
||||||
|
ˎˑ
|
||||||
|
ˎי
|
||||||
|
ˎـ
|
||||||
|
ˎٴ
|
||||||
|
ˎᐧ
|
||||||
|
ˎᴵ
|
||||||
|
ˎᵎ
|
||||||
|
ˎᵔ
|
||||||
|
ˎᵢ
|
||||||
|
ˎⁱ
|
||||||
|
ˎﹳ
|
||||||
|
ˎﹶ
|
||||||
|
ˎ゙
|
||||||
|
ˏʻ
|
||||||
|
ˏʼ
|
||||||
|
ˏʽ
|
||||||
|
ˏʾ
|
||||||
|
ˏʿ
|
||||||
|
ˏˆ
|
||||||
|
ˏˈ
|
||||||
|
ˏˉ
|
||||||
|
ˏˊ
|
||||||
|
ˏˋ
|
||||||
|
ˏˎ
|
||||||
|
ˏˑ
|
||||||
|
ˏי
|
||||||
|
ˏـ
|
||||||
|
ˏٴ
|
||||||
|
ˏᐧ
|
||||||
|
ˏᴵ
|
||||||
|
ˏᵎ
|
||||||
|
ˏᵔ
|
||||||
|
ˏᵢ
|
||||||
|
ˏⁱ
|
||||||
|
ˏﹳ
|
||||||
|
ˏﹶ
|
||||||
|
ˏ゙
|
||||||
|
ˑʻ
|
||||||
|
ˑʼ
|
||||||
|
ˑʽ
|
||||||
|
ˑʾ
|
||||||
|
ˑʿ
|
||||||
|
ˑˆ
|
||||||
|
ˑˈ
|
||||||
|
ˑˉ
|
||||||
|
ˑˊ
|
||||||
|
ˑˋ
|
||||||
|
ˑˎ
|
||||||
|
ˑˏ
|
||||||
|
ˑי
|
||||||
|
ˑـ
|
||||||
|
ˑٴ
|
||||||
|
ˑᐧ
|
||||||
|
ˑᴵ
|
||||||
|
ˑᵎ
|
||||||
|
ˑᵔ
|
||||||
|
ˑᵢ
|
||||||
|
ˑⁱ
|
||||||
|
ˑﹳ
|
||||||
|
ˑﹶ
|
||||||
|
ˑ゙
|
||||||
|
יʻ
|
||||||
|
יʼ
|
||||||
|
יʽ
|
||||||
|
יʾ
|
||||||
|
יʿ
|
||||||
|
יˆ
|
||||||
|
יˈ
|
||||||
|
יˉ
|
||||||
|
יˊ
|
||||||
|
יˋ
|
||||||
|
יˎ
|
||||||
|
יˏ
|
||||||
|
יˑ
|
||||||
|
יـ
|
||||||
|
יٴ
|
||||||
|
יᐧ
|
||||||
|
יᴵ
|
||||||
|
יᵎ
|
||||||
|
יᵔ
|
||||||
|
יᵢ
|
||||||
|
יⁱ
|
||||||
|
יﹳ
|
||||||
|
יﹶ
|
||||||
|
י゙
|
||||||
|
ـʻ
|
||||||
|
ـʼ
|
||||||
|
ـʽ
|
||||||
|
ـʾ
|
||||||
|
ـʿ
|
||||||
|
ـˆ
|
||||||
|
ـˈ
|
||||||
|
ـˉ
|
||||||
|
ـˊ
|
||||||
|
ـˋ
|
||||||
|
ـˎ
|
||||||
|
ـˏ
|
||||||
|
ـˑ
|
||||||
|
ـי
|
||||||
|
ـٴ
|
||||||
|
ـᐧ
|
||||||
|
ـᴵ
|
||||||
|
ـᵎ
|
||||||
|
ـᵔ
|
||||||
|
ـᵢ
|
||||||
|
ـⁱ
|
||||||
|
ـﹳ
|
||||||
|
ـﹶ
|
||||||
|
ـ゙
|
||||||
|
ٴʻ
|
||||||
|
ٴʼ
|
||||||
|
ٴʽ
|
||||||
|
ٴʾ
|
||||||
|
ٴʿ
|
||||||
|
ٴˆ
|
||||||
|
ٴˈ
|
||||||
|
ٴˉ
|
||||||
|
ٴˊ
|
||||||
|
ٴˋ
|
||||||
|
ٴˎ
|
||||||
|
ٴˏ
|
||||||
|
ٴˑ
|
||||||
|
ٴי
|
||||||
|
ٴـ
|
||||||
|
ٴᐧ
|
||||||
|
ٴᴵ
|
||||||
|
ٴᵎ
|
||||||
|
ٴᵔ
|
||||||
|
ٴᵢ
|
||||||
|
ٴⁱ
|
||||||
|
ٴﹳ
|
||||||
|
ٴﹶ
|
||||||
|
ٴ゙
|
||||||
|
ᐧʻ
|
||||||
|
ᐧʼ
|
||||||
|
ᐧʽ
|
||||||
|
ᐧʾ
|
||||||
|
ᐧʿ
|
||||||
|
ᐧˆ
|
||||||
|
ᐧˈ
|
||||||
|
ᐧˉ
|
||||||
|
ᐧˊ
|
||||||
|
ᐧˋ
|
||||||
|
ᐧˎ
|
||||||
|
ᐧˏ
|
||||||
|
ᐧˑ
|
||||||
|
ᐧי
|
||||||
|
ᐧـ
|
||||||
|
ᐧٴ
|
||||||
|
ᐧᴵ
|
||||||
|
ᐧᵎ
|
||||||
|
ᐧᵔ
|
||||||
|
ᐧᵢ
|
||||||
|
ᐧⁱ
|
||||||
|
ᐧﹳ
|
||||||
|
ᐧﹶ
|
||||||
|
ᐧ゙
|
||||||
|
ᴵʻ
|
||||||
|
ᴵʼ
|
||||||
|
ᴵʽ
|
||||||
|
ᴵʾ
|
||||||
|
ᴵʿ
|
||||||
|
ᴵˆ
|
||||||
|
ᴵˈ
|
||||||
|
ᴵˉ
|
||||||
|
ᴵˊ
|
||||||
|
ᴵˋ
|
||||||
|
ᴵˎ
|
||||||
|
ᴵˏ
|
||||||
|
ᴵˑ
|
||||||
|
ᴵי
|
||||||
|
ᴵـ
|
||||||
|
ᴵٴ
|
||||||
|
ᴵᐧ
|
||||||
|
ᴵᵎ
|
||||||
|
ᴵᵔ
|
||||||
|
ᴵᵢ
|
||||||
|
ᴵⁱ
|
||||||
|
ᴵﹳ
|
||||||
|
ᴵﹶ
|
||||||
|
ᴵ゙
|
||||||
|
ᵎʻ
|
||||||
|
ᵎʼ
|
||||||
|
ᵎʽ
|
||||||
|
ᵎʾ
|
||||||
|
ᵎʿ
|
||||||
|
ᵎˆ
|
||||||
|
ᵎˈ
|
||||||
|
ᵎˉ
|
||||||
|
ᵎˊ
|
||||||
|
ᵎˋ
|
||||||
|
ᵎˎ
|
||||||
|
ᵎˏ
|
||||||
|
ᵎˑ
|
||||||
|
ᵎי
|
||||||
|
ᵎـ
|
||||||
|
ᵎٴ
|
||||||
|
ᵎᐧ
|
||||||
|
ᵎᴵ
|
||||||
|
ᵎᵔ
|
||||||
|
ᵎᵢ
|
||||||
|
ᵎⁱ
|
||||||
|
ᵎﹳ
|
||||||
|
ᵎﹶ
|
||||||
|
ᵎ゙
|
||||||
|
ᵔʻ
|
||||||
|
ᵔʼ
|
||||||
|
ᵔʽ
|
||||||
|
ᵔʾ
|
||||||
|
ᵔʿ
|
||||||
|
ᵔˆ
|
||||||
|
ᵔˈ
|
||||||
|
ᵔˉ
|
||||||
|
ᵔˊ
|
||||||
|
ᵔˋ
|
||||||
|
ᵔˎ
|
||||||
|
ᵔˏ
|
||||||
|
ᵔˑ
|
||||||
|
ᵔי
|
||||||
|
ᵔـ
|
||||||
|
ᵔٴ
|
||||||
|
ᵔᐧ
|
||||||
|
ᵔᴵ
|
||||||
|
ᵔᵎ
|
||||||
|
ᵔᵢ
|
||||||
|
ᵔⁱ
|
||||||
|
ᵔﹳ
|
||||||
|
ᵔﹶ
|
||||||
|
ᵔ゙
|
||||||
|
ᵢʻ
|
||||||
|
ᵢʼ
|
||||||
|
ᵢʽ
|
||||||
|
ᵢʾ
|
||||||
|
ᵢʿ
|
||||||
|
ᵢˆ
|
||||||
|
ᵢˈ
|
||||||
|
ᵢˉ
|
||||||
|
ᵢˊ
|
||||||
|
ᵢˋ
|
||||||
|
ᵢˎ
|
||||||
|
ᵢˏ
|
||||||
|
ᵢˑ
|
||||||
|
ᵢי
|
||||||
|
ᵢـ
|
||||||
|
ᵢٴ
|
||||||
|
ᵢᐧ
|
||||||
|
ᵢᴵ
|
||||||
|
ᵢᵎ
|
||||||
|
ᵢᵔ
|
||||||
|
ᵢⁱ
|
||||||
|
ᵢﹳ
|
||||||
|
ᵢﹶ
|
||||||
|
ᵢ゙
|
||||||
|
ⁱʻ
|
||||||
|
ⁱʼ
|
||||||
|
ⁱʽ
|
||||||
|
ⁱʾ
|
||||||
|
ⁱʿ
|
||||||
|
ⁱˆ
|
||||||
|
ⁱˈ
|
||||||
|
ⁱˉ
|
||||||
|
ⁱˊ
|
||||||
|
ⁱˋ
|
||||||
|
ⁱˎ
|
||||||
|
ⁱˏ
|
||||||
|
ⁱˑ
|
||||||
|
ⁱי
|
||||||
|
ⁱـ
|
||||||
|
ⁱٴ
|
||||||
|
ⁱᐧ
|
||||||
|
ⁱᴵ
|
||||||
|
ⁱᵎ
|
||||||
|
ⁱᵔ
|
||||||
|
ⁱᵢ
|
||||||
|
ⁱﹳ
|
||||||
|
ⁱﹶ
|
||||||
|
ⁱ゙
|
||||||
|
ﹳʻ
|
||||||
|
ﹳʼ
|
||||||
|
ﹳʽ
|
||||||
|
ﹳʾ
|
||||||
|
ﹳʿ
|
||||||
|
ﹳˆ
|
||||||
|
ﹳˈ
|
||||||
|
ﹳˉ
|
||||||
|
ﹳˊ
|
||||||
|
ﹳˋ
|
||||||
|
ﹳˎ
|
||||||
|
ﹳˏ
|
||||||
|
ﹳˑ
|
||||||
|
ﹳי
|
||||||
|
ﹳـ
|
||||||
|
ﹳٴ
|
||||||
|
ﹳᐧ
|
||||||
|
ﹳᴵ
|
||||||
|
ﹳᵎ
|
||||||
|
ﹳᵔ
|
||||||
|
ﹳᵢ
|
||||||
|
ﹳⁱ
|
||||||
|
ﹳﹶ
|
||||||
|
ﹳ゙
|
||||||
|
ﹶʻ
|
||||||
|
ﹶʼ
|
||||||
|
ﹶʽ
|
||||||
|
ﹶʾ
|
||||||
|
ﹶʿ
|
||||||
|
ﹶˆ
|
||||||
|
ﹶˈ
|
||||||
|
ﹶˉ
|
||||||
|
ﹶˊ
|
||||||
|
ﹶˋ
|
||||||
|
ﹶˎ
|
||||||
|
ﹶˏ
|
||||||
|
ﹶˑ
|
||||||
|
ﹶי
|
||||||
|
ﹶـ
|
||||||
|
ﹶٴ
|
||||||
|
ﹶᐧ
|
||||||
|
ﹶᴵ
|
||||||
|
ﹶᵎ
|
||||||
|
ﹶᵔ
|
||||||
|
ﹶᵢ
|
||||||
|
ﹶⁱ
|
||||||
|
ﹶﹳ
|
||||||
|
ﹶ゙
|
||||||
|
゙ʻ
|
||||||
|
゙ʼ
|
||||||
|
゙ʽ
|
||||||
|
゙ʾ
|
||||||
|
゙ʿ
|
||||||
|
゙ˆ
|
||||||
|
゙ˈ
|
||||||
|
゙ˉ
|
||||||
|
゙ˊ
|
||||||
|
゙ˋ
|
||||||
|
゙ˎ
|
||||||
|
゙ˏ
|
||||||
|
゙ˑ
|
||||||
|
゙י
|
||||||
|
゙ـ
|
||||||
|
゙ٴ
|
||||||
|
゙ᐧ
|
||||||
|
゙ᴵ
|
||||||
|
゙ᵎ
|
||||||
|
゙ᵔ
|
||||||
|
゙ᵢ
|
||||||
|
゙ⁱ
|
||||||
|
゙ﹳ
|
||||||
|
゙ﹶ
|
40
app/proguard-log.pro
Normal file
40
app/proguard-log.pro
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
##########################################################################################################
|
||||||
|
# 作者:Sollyu
|
||||||
|
# 日期:2020-11-02
|
||||||
|
# 内容:发布版本移除日志,kotlin编译时带的而外信息,增强反调试难度
|
||||||
|
# 使用:proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro', 'proguard-log.pro'
|
||||||
|
##########################################################################################################
|
||||||
|
|
||||||
|
##########################################################################################################
|
||||||
|
# 删除安卓日志
|
||||||
|
-assumenosideeffects class android.util.Log {
|
||||||
|
public static *** d(...);
|
||||||
|
public static *** v(...);
|
||||||
|
public static *** w(...);
|
||||||
|
public static *** e(...);
|
||||||
|
}
|
||||||
|
|
||||||
|
##########################################################################################################
|
||||||
|
# 删除Kotlin编译时可能生成显示变量的方法
|
||||||
|
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
|
||||||
|
public static void checkExpressionValueIsNotNull(java.lang.Object, java.lang.String);
|
||||||
|
public static void checkFieldIsNotNull(java.lang.Object, java.lang.String);
|
||||||
|
public static void checkFieldIsNotNull(java.lang.Object, java.lang.String, java.lang.String);
|
||||||
|
public static void checkNotNull(java.lang.Object);
|
||||||
|
public static void checkNotNull(java.lang.Object, java.lang.String);
|
||||||
|
public static void checkNotNullExpressionValue(java.lang.Object, java.lang.String);
|
||||||
|
public static void checkNotNullParameter(java.lang.Object, java.lang.String);
|
||||||
|
public static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
|
||||||
|
public static void checkReturnedValueIsNotNull(java.lang.Object, java.lang.String);
|
||||||
|
public static void throwUninitializedPropertyAccessException(java.lang.String);
|
||||||
|
}
|
||||||
|
|
||||||
|
##########################################################################################################
|
||||||
|
# 会暴露变量名称
|
||||||
|
-assumenosideeffects class java.util.Objects {
|
||||||
|
public static java.lang.Object requireNonNull(java.lang.Object, java.lang.String);
|
||||||
|
}
|
||||||
|
|
||||||
|
-assumenosideeffects class de.robv.android.xposed.XposedBridge {
|
||||||
|
public synchronized static void log(...);
|
||||||
|
}
|
25
app/proguard-rules.pro
vendored
25
app/proguard-rules.pro
vendored
@ -18,4 +18,27 @@
|
|||||||
|
|
||||||
# If you keep the line number information, uncomment this to
|
# If you keep the line number information, uncomment this to
|
||||||
# hide the original source file name.
|
# hide the original source file name.
|
||||||
#-renamesourcefileattribute SourceFile
|
#-renamesourcefileattribute SourceFile
|
||||||
|
|
||||||
|
-keep class * implements de.robv.android.xposed.IXposedHookLoadPackage {
|
||||||
|
public void *(de.robv.android.xposed.callbacks.XC_LoadPackage$LoadPackageParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keep class * implements de.robv.android.xposed.IXposedHookInitPackageResources {
|
||||||
|
public void *(de.robv.android.xposed.callbacks.XC_InitPackageResources$InitPackageResourcesParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keep class * implements de.robv.android.xposed.IXposedHookZygoteInit {
|
||||||
|
public void *(de.robv.android.xposed.IXposedHookZygoteInit$StartupParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
|
||||||
|
public static void check*(...);
|
||||||
|
public static void throw*(...);
|
||||||
|
}
|
||||||
|
|
||||||
|
-obfuscationdictionary genshinproxy-dic.txt
|
||||||
|
-classobfuscationdictionary genshinproxy-dic.txt
|
||||||
|
-packageobfuscationdictionary genshinproxy-dic.txt
|
||||||
|
|
||||||
|
-repackageclasses "xfk233.genshinproxy"
|
713
app/src/main/java/xfk233/genshinproxy/Hook.kt
Normal file
713
app/src/main/java/xfk233/genshinproxy/Hook.kt
Normal file
@ -0,0 +1,713 @@
|
|||||||
|
package xfk233.genshinproxy
|
||||||
|
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.Activity
|
||||||
|
import android.app.AlertDialog
|
||||||
|
import android.content.ClipboardManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.content.res.XModuleResources
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.PixelFormat
|
||||||
|
import android.graphics.drawable.ShapeDrawable
|
||||||
|
import android.graphics.drawable.shapes.RoundRectShape
|
||||||
|
import android.os.Build
|
||||||
|
import android.text.Editable
|
||||||
|
import android.text.InputType
|
||||||
|
import android.text.TextWatcher
|
||||||
|
import android.util.Base64
|
||||||
|
import android.util.TypedValue
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.view.MotionEvent
|
||||||
|
import android.view.View
|
||||||
|
import android.view.WindowManager
|
||||||
|
import android.webkit.SslErrorHandler
|
||||||
|
import android.widget.*
|
||||||
|
import com.github.kyuubiran.ezxhelper.init.EzXHelperInit
|
||||||
|
import com.github.kyuubiran.ezxhelper.utils.*
|
||||||
|
import de.robv.android.xposed.IXposedHookZygoteInit
|
||||||
|
import de.robv.android.xposed.XC_MethodHook
|
||||||
|
import de.robv.android.xposed.XposedBridge
|
||||||
|
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||||
|
import icu.nullptr.stringfuck.StringFuck
|
||||||
|
import org.json.JSONObject
|
||||||
|
import xfk233.genshinproxy.Utils.dp2px
|
||||||
|
import xfk233.genshinproxy.Utils.isInit
|
||||||
|
import java.io.BufferedReader
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
import java.io.File
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
import java.net.HttpURLConnection
|
||||||
|
import java.net.URL
|
||||||
|
import java.security.SecureRandom
|
||||||
|
import java.security.cert.X509Certificate
|
||||||
|
import java.util.regex.Pattern
|
||||||
|
import javax.net.ssl.*
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
class Hook {
|
||||||
|
private val regex = Pattern.compile("http(s|)://.*?\\.(hoyoverse|mihoyo|yuanshen|mob)\\.com")
|
||||||
|
private lateinit var server: String
|
||||||
|
private var forceUrl = false
|
||||||
|
private lateinit var modulePath: String
|
||||||
|
private lateinit var moduleRes: XModuleResources
|
||||||
|
private lateinit var windowManager: WindowManager
|
||||||
|
private var proxyList = false
|
||||||
|
private lateinit var sp: SharedPreferences
|
||||||
|
private val proxyListRegex = arrayListOf(
|
||||||
|
"api-os-takumi.mihoyo.com",
|
||||||
|
"hk4e-api-os-static.mihoyo.com",
|
||||||
|
"hk4e-sdk-os.mihoyo.com",
|
||||||
|
"dispatchosglobal.yuanshen.com",
|
||||||
|
"osusadispatch.yuanshen.com",
|
||||||
|
"account.mihoyo.com",
|
||||||
|
"log-upload-os.mihoyo.com",
|
||||||
|
"dispatchcntest.yuanshen.com",
|
||||||
|
"devlog-upload.mihoyo.com",
|
||||||
|
"webstatic.mihoyo.com",
|
||||||
|
"log-upload.mihoyo.com",
|
||||||
|
"hk4e-sdk.mihoyo.com",
|
||||||
|
"api-beta-sdk.mihoyo.com",
|
||||||
|
"api-beta-sdk-os.mihoyo.com",
|
||||||
|
"cnbeta01dispatch.yuanshen.com",
|
||||||
|
"dispatchcnglobal.yuanshen.com",
|
||||||
|
"cnbeta02dispatch.yuanshen.com",
|
||||||
|
"sdk-os-static.mihoyo.com",
|
||||||
|
"webstatic-sea.mihoyo.com",
|
||||||
|
"webstatic-sea.hoyoverse.com",
|
||||||
|
"hk4e-sdk-os-static.hoyoverse.com",
|
||||||
|
"sdk-os-static.hoyoverse.com",
|
||||||
|
"api-account-os.hoyoverse.com",
|
||||||
|
"hk4e-sdk-os.hoyoverse.com",
|
||||||
|
"overseauspider.yuanshen.com",
|
||||||
|
"gameapi-account.mihoyo.com",
|
||||||
|
"minor-api.mihoyo.com",
|
||||||
|
"public-data-api.mihoyo.com",
|
||||||
|
"uspider.yuanshen.com",
|
||||||
|
"sdk-static.mihoyo.com",
|
||||||
|
"minor-api-os.hoyoverse.com",
|
||||||
|
"log-upload-os.hoyoverse.com"
|
||||||
|
)
|
||||||
|
|
||||||
|
private val activityList: ArrayList<Activity> = arrayListOf()
|
||||||
|
private var activity: Activity
|
||||||
|
get() {
|
||||||
|
for (mActivity in activityList) {
|
||||||
|
if (mActivity.isFinishing) {
|
||||||
|
activityList.remove(mActivity)
|
||||||
|
} else {
|
||||||
|
return mActivity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw Throwable("Activity not found.")
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
activityList.add(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDefaultSSLSocketFactory(): SSLSocketFactory {
|
||||||
|
return SSLContext.getInstance("TLS").apply {
|
||||||
|
init(arrayOf<KeyManager>(), arrayOf<TrustManager>(DefaultTrustManager()), SecureRandom())
|
||||||
|
}.socketFactory
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDefaultHostnameVerifier(): HostnameVerifier {
|
||||||
|
return DefaultHostnameVerifier()
|
||||||
|
}
|
||||||
|
|
||||||
|
class DefaultHostnameVerifier : HostnameVerifier {
|
||||||
|
@SuppressLint("BadHostnameVerifier")
|
||||||
|
override fun verify(p0: String?, p1: SSLSession?): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("CustomX509TrustManager")
|
||||||
|
private class DefaultTrustManager : X509TrustManager {
|
||||||
|
|
||||||
|
@SuppressLint("TrustAllX509TrustManager")
|
||||||
|
override fun checkClientTrusted(chain: Array<X509Certificate?>?, authType: String?) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("TrustAllX509TrustManager")
|
||||||
|
override fun checkServerTrusted(chain: Array<X509Certificate?>?, authType: String?) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getAcceptedIssuers(): Array<X509Certificate> {
|
||||||
|
return arrayOf()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam) {
|
||||||
|
StringFuck.init()
|
||||||
|
modulePath = startupParam.modulePath
|
||||||
|
moduleRes = XModuleResources.createInstance(modulePath, null)
|
||||||
|
TrustMeAlready().initZygote()
|
||||||
|
}
|
||||||
|
|
||||||
|
private var startForceUrl = false
|
||||||
|
private var startProxyList = false
|
||||||
|
private lateinit var dialog: LinearLayout
|
||||||
|
|
||||||
|
@SuppressLint("WrongConstant", "ClickableViewAccessibility")
|
||||||
|
fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
||||||
|
if (lpparam.packageName != "com.miHoYo.GenshinImpact") return
|
||||||
|
EzXHelperInit.initHandleLoadPackage(lpparam)
|
||||||
|
findMethod("com.combosdk.openapi.ComboApplication") { name == "attachBaseContext" }.hookBefore {
|
||||||
|
val context = it.args[0] as Context
|
||||||
|
Utils.check(context, modulePath)
|
||||||
|
sp = context.getSharedPreferences("serverConfig", 0)
|
||||||
|
forceUrl = sp.getBoolean("forceUrl", false)
|
||||||
|
startForceUrl = forceUrl
|
||||||
|
server = sp.getString("serverip", "") ?: ""
|
||||||
|
proxyList = sp.getBoolean("ProxyList", false)
|
||||||
|
startProxyList = proxyList
|
||||||
|
if (sp.getBoolean("KeepSSL", false)) sslHook()
|
||||||
|
}
|
||||||
|
hook()
|
||||||
|
findMethod(Activity::class.java, true) { name == "onCreate" }.hookBefore { param ->
|
||||||
|
activity = param.thisObject as Activity
|
||||||
|
}
|
||||||
|
findMethod("com.miHoYo.GetMobileInfo.MainActivity") { name == "onCreate" }.hookBefore { param ->
|
||||||
|
activity = param.thisObject as Activity
|
||||||
|
showDialog()
|
||||||
|
activity.windowManager.addView(LinearLayout(activity).apply {
|
||||||
|
dialog = this
|
||||||
|
visibility = View.GONE
|
||||||
|
background = ShapeDrawable().apply {
|
||||||
|
shape = RoundRectShape(floatArrayOf(18f, 18f, 18f, 18f, 18f, 18f, 18f, 18f), null, null)
|
||||||
|
paint.color = Color.parseColor("#FFEFEDF5")
|
||||||
|
}
|
||||||
|
addView(TextView(activity).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT).also {
|
||||||
|
it.gravity = Gravity.CENTER_VERTICAL
|
||||||
|
}
|
||||||
|
gravity = Gravity.CENTER
|
||||||
|
text = String(Base64.decode("5pys5qih5Z2X5piv5YWN6LS55bm25byA5rqQ55qELCDlpoLmnpzkvaDmmK/otK3kubDnmoTmraTmqKHlnZfmiJbova/ku7bjgIJcbumCo+S5iOS9oOiiq+mql+S6hu+8jOivt+mAgOasvivlt67or4TvvIFcblRoaXMgbW9kdWxlIGlzIGZyZWUgYW5kIG9wZW4gc291cmNlLCBpZiB5b3UgcHVyY2hhc2VkIHRoaXMgbW9kdWxlIG9yIHNvZnR3YXJlLlxuVGhlbiB5b3UgaGF2ZSBiZWVuIGNoZWF0ZWQsIHBsZWFzZSByZWZ1bmQh", Base64.DEFAULT)).replace("\\n", "\n")
|
||||||
|
})
|
||||||
|
}, WindowManager.LayoutParams(dp2px(activity, 200f), dp2px(activity, 150f), WindowManager.LayoutParams.TYPE_APPLICATION, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, PixelFormat.TRANSLUCENT).apply {
|
||||||
|
gravity = Gravity.CENTER_VERTICAL
|
||||||
|
x = 0
|
||||||
|
y = 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showDialog() {
|
||||||
|
AlertDialog.Builder(activity).apply {
|
||||||
|
setCancelable(false)
|
||||||
|
setTitle(moduleRes.getString(R.string.SelectServer))
|
||||||
|
setMessage(moduleRes.getString(R.string.Tips))
|
||||||
|
setNegativeButton(moduleRes.getString(R.string.Settings)) { _, _ ->
|
||||||
|
AlertDialog.Builder(activity).apply {
|
||||||
|
setMessage(moduleRes.getString(R.string.Tips2))
|
||||||
|
setCancelable(false)
|
||||||
|
setView(ScrollView(context).apply {
|
||||||
|
setPadding(25, 0, 25, 0)
|
||||||
|
addView(LinearLayout(activity).apply {
|
||||||
|
orientation = LinearLayout.VERTICAL
|
||||||
|
addView(EditText(activity).apply {
|
||||||
|
hint = "http(s)://server.com:1234"
|
||||||
|
val str = sp.getString("serverip", "") ?: ""
|
||||||
|
setText(str.toCharArray(), 0, str.length)
|
||||||
|
addTextChangedListener(object : TextWatcher {
|
||||||
|
override fun beforeTextChanged(p0: CharSequence, p1: Int, p2: Int, p3: Int) {}
|
||||||
|
override fun onTextChanged(p0: CharSequence, p1: Int, p2: Int, p3: Int) {}
|
||||||
|
|
||||||
|
@SuppressLint("CommitPrefEdits")
|
||||||
|
override fun afterTextChanged(p0: Editable) {
|
||||||
|
sp.edit().run {
|
||||||
|
putString("serverip", p0.toString())
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
addView(Switch(activity).apply {
|
||||||
|
text = moduleRes.getString(R.string.ForcedMode)
|
||||||
|
isChecked = sp.getBoolean("forceUrl", false)
|
||||||
|
setOnCheckedChangeListener { _, b ->
|
||||||
|
sp.edit().run {
|
||||||
|
putBoolean("forceUrl", b)
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
forceUrl = b
|
||||||
|
}
|
||||||
|
})
|
||||||
|
addView(Switch(activity).apply {
|
||||||
|
text = moduleRes.getString(R.string.ProxyList)
|
||||||
|
isChecked = sp.getBoolean("ProxyList", false)
|
||||||
|
setOnCheckedChangeListener { _, b ->
|
||||||
|
sp.edit().run {
|
||||||
|
putBoolean("ProxyList", b)
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
proxyList = b
|
||||||
|
}
|
||||||
|
})
|
||||||
|
addView(Switch(activity).apply {
|
||||||
|
text = moduleRes.getString(R.string.HookConfig)
|
||||||
|
isChecked = sp.getBoolean("HookConfig", false)
|
||||||
|
setOnCheckedChangeListener { _, b ->
|
||||||
|
sp.edit().run {
|
||||||
|
putBoolean("HookConfig", b)
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
proxyList = b
|
||||||
|
}
|
||||||
|
})
|
||||||
|
addView(Switch(activity).apply {
|
||||||
|
text = moduleRes.getString(R.string.EnableTools)
|
||||||
|
isChecked = sp.getBoolean("EnableTools", false)
|
||||||
|
setOnCheckedChangeListener { _, b ->
|
||||||
|
sp.edit().run {
|
||||||
|
putBoolean("EnableTools", b)
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
proxyList = b
|
||||||
|
}
|
||||||
|
})
|
||||||
|
addView(Switch(activity).apply {
|
||||||
|
text = moduleRes.getString(R.string.KeepSSL)
|
||||||
|
isChecked = sp.getBoolean("KeepSSL", false)
|
||||||
|
setOnCheckedChangeListener { _, b ->
|
||||||
|
sp.edit().run {
|
||||||
|
putBoolean("KeepSSL", b)
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
setPositiveButton(moduleRes.getString(R.string.Back)) { _, _ ->
|
||||||
|
showDialog()
|
||||||
|
}
|
||||||
|
setNeutralButton(moduleRes.getString(R.string.ExitGames)) { _, _ ->
|
||||||
|
exitProcess(0)
|
||||||
|
}
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
setPositiveButton(moduleRes.getString(R.string.CustomServer)) { _, _ ->
|
||||||
|
val ip = sp.getString("serverip", "") ?: ""
|
||||||
|
if (ip == "") {
|
||||||
|
Toast.makeText(activity, moduleRes.getString(R.string.ServerAddressError), Toast.LENGTH_LONG).show()
|
||||||
|
activity.finish()
|
||||||
|
} else {
|
||||||
|
server = ip
|
||||||
|
forceUrl = true
|
||||||
|
if (sp.getBoolean("EnableTools", false)) gmTool()
|
||||||
|
Thread {
|
||||||
|
runOnMainThread {
|
||||||
|
dialog.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
Thread.sleep(10 * 1000)
|
||||||
|
runOnMainThread {
|
||||||
|
dialog.visibility = View.GONE
|
||||||
|
activity.windowManager.removeView(dialog)
|
||||||
|
}
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setNeutralButton(moduleRes.getString(R.string.OfficialServer)) { _, _ ->
|
||||||
|
forceUrl = false
|
||||||
|
server = ""
|
||||||
|
if (startForceUrl || startProxyList) {
|
||||||
|
Toast.makeText(activity, moduleRes.getString(R.string.JoinServerError), Toast.LENGTH_LONG).show()
|
||||||
|
showDialog()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class MoveOnTouchListener : View.OnTouchListener {
|
||||||
|
private var originalXPos = 0
|
||||||
|
private var originalYPos = 0
|
||||||
|
|
||||||
|
private var offsetX = 0f
|
||||||
|
private var offsetY = 0f
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
override fun onTouch(v: View, event: MotionEvent): Boolean {
|
||||||
|
when (event.action) {
|
||||||
|
MotionEvent.ACTION_DOWN -> {
|
||||||
|
val x = event.rawX
|
||||||
|
val y = event.rawY
|
||||||
|
|
||||||
|
val location = IntArray(2)
|
||||||
|
v.getLocationOnScreen(location)
|
||||||
|
|
||||||
|
originalXPos = location[0]
|
||||||
|
originalYPos = location[1]
|
||||||
|
|
||||||
|
offsetX = x - originalXPos
|
||||||
|
offsetY = y - originalYPos
|
||||||
|
}
|
||||||
|
MotionEvent.ACTION_MOVE -> {
|
||||||
|
val onScreen = IntArray(2)
|
||||||
|
v.getLocationOnScreen(onScreen)
|
||||||
|
|
||||||
|
val x = event.rawX
|
||||||
|
val y = event.rawY
|
||||||
|
|
||||||
|
val params: WindowManager.LayoutParams = v.layoutParams as WindowManager.LayoutParams
|
||||||
|
|
||||||
|
val newX = (x - offsetX).toInt()
|
||||||
|
val newY = (y - offsetY).toInt()
|
||||||
|
|
||||||
|
if (newX == originalXPos && newY == originalYPos) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
params.x = newX
|
||||||
|
params.y = newY
|
||||||
|
|
||||||
|
windowManager.updateViewLayout(v, params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var imageView: ImageView
|
||||||
|
private lateinit var mainView: ScrollView
|
||||||
|
private fun gmTool() {
|
||||||
|
if (this::mainView.isInitialized) return
|
||||||
|
if (this::imageView.isInitialized) return
|
||||||
|
if (isInit) return
|
||||||
|
isInit = true
|
||||||
|
mainView = ScrollView(activity).apply {
|
||||||
|
visibility = View.GONE
|
||||||
|
addView(LinearLayout(activity).apply {
|
||||||
|
orientation = LinearLayout.VERTICAL
|
||||||
|
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
|
||||||
|
setBackgroundColor(Color.parseColor("#5F000000"))
|
||||||
|
addView(LinearLayout(activity).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||||
|
setBackgroundColor(Color.parseColor("#8F000000"))
|
||||||
|
addView(TextView(activity).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)
|
||||||
|
setTextColor(Color.BLUE)
|
||||||
|
setTextSize(TypedValue.COMPLEX_UNIT_SP, 18f)
|
||||||
|
text = moduleRes.getString(R.string.Tools)
|
||||||
|
})
|
||||||
|
addView(TextView(activity).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT).also {
|
||||||
|
it.setMargins(0, 0, 5, 0)
|
||||||
|
}
|
||||||
|
setTextColor(Color.BLUE)
|
||||||
|
setTextSize(TypedValue.COMPLEX_UNIT_SP, 18f)
|
||||||
|
text = "X"
|
||||||
|
setOnClickListener {
|
||||||
|
mainView.visibility = View.GONE
|
||||||
|
imageView.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
addView(LinearLayout(activity).apply {
|
||||||
|
orientation = LinearLayout.VERTICAL
|
||||||
|
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
|
||||||
|
var userEdit: EditText
|
||||||
|
var passEdit: EditText
|
||||||
|
addView(LinearLayout(activity).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||||
|
addView(TextView(activity).apply {
|
||||||
|
setTextColor(Color.BLUE)
|
||||||
|
text = moduleRes.getString(R.string.CheckServerStatus)
|
||||||
|
setOnClickListener {
|
||||||
|
Thread {
|
||||||
|
try {
|
||||||
|
XposedBridge.log("$server/authentication/type")
|
||||||
|
URL("$server/authentication/type").apply {
|
||||||
|
val conn = if (server.startsWith("https")) {
|
||||||
|
(openConnection() as HttpsURLConnection).apply {
|
||||||
|
sslSocketFactory = getDefaultSSLSocketFactory()
|
||||||
|
hostnameVerifier = getDefaultHostnameVerifier()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
openConnection() as HttpURLConnection
|
||||||
|
}
|
||||||
|
conn.requestMethod = "GET"
|
||||||
|
conn.readTimeout = 8000
|
||||||
|
conn.connectTimeout = 8000
|
||||||
|
|
||||||
|
val reader = BufferedReader(InputStreamReader(conn.inputStream))
|
||||||
|
if (conn.responseCode == 200) {
|
||||||
|
val response = StringBuilder()
|
||||||
|
var line = ""
|
||||||
|
while (reader.readLine()?.also { line = it } != null) {
|
||||||
|
response.append(line)
|
||||||
|
}
|
||||||
|
runOnMainThread {
|
||||||
|
text = if (response.toString() == "me.exzork.gcauth.handler.GCAuthAuthenticationHandler") moduleRes.getString(R.string.ServerStatus) + "GcAuth" else moduleRes.getString(R.string.ServerStatus) + "GcAuth" + moduleRes.getString(R.string.NotInstall)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
runOnMainThread {
|
||||||
|
text = moduleRes.getString(R.string.ServerStatus) + moduleRes.getString(R.string.GetServerStatusError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
runOnMainThread {
|
||||||
|
text = moduleRes.getString(R.string.ServerStatus) + moduleRes.getString(R.string.GetServerStatusError) + e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
addView(LinearLayout(activity).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||||
|
addView(Switch(activity).apply {
|
||||||
|
text = moduleRes.getString(R.string.InputSwitch)
|
||||||
|
setOnCheckedChangeListener { _, b ->
|
||||||
|
if (b) {
|
||||||
|
val params = mainView.layoutParams as WindowManager.LayoutParams
|
||||||
|
params.flags = params.flags and (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE.inv())
|
||||||
|
windowManager.updateViewLayout(mainView, params)
|
||||||
|
} else {
|
||||||
|
val params = mainView.layoutParams as WindowManager.LayoutParams
|
||||||
|
params.flags = params.flags or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||||
|
windowManager.updateViewLayout(mainView, params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
addView(LinearLayout(activity).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||||
|
addView(TextView(activity).apply {
|
||||||
|
setTextColor(Color.BLUE)
|
||||||
|
text = moduleRes.getString(R.string.User)
|
||||||
|
})
|
||||||
|
addView(EditText(activity).apply {
|
||||||
|
userEdit = this
|
||||||
|
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||||
|
val user = sp.getString("user", "") ?: ""
|
||||||
|
setText(user.toCharArray(), 0, user.length)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
addView(LinearLayout(activity).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||||
|
addView(TextView(activity).apply {
|
||||||
|
setTextColor(Color.BLUE)
|
||||||
|
text = moduleRes.getString(R.string.Password)
|
||||||
|
})
|
||||||
|
addView(EditText(activity).apply {
|
||||||
|
passEdit = this
|
||||||
|
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||||
|
inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||||
|
val user = sp.getString("pass", "") ?: ""
|
||||||
|
setText(user.toCharArray(), 0, user.length)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
addView(LinearLayout(activity).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||||
|
addView(Button(activity).apply {
|
||||||
|
text = moduleRes.getString(R.string.Login)
|
||||||
|
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||||
|
setOnClickListener {
|
||||||
|
Thread {
|
||||||
|
try {
|
||||||
|
URL("$server/authentication/type").apply {
|
||||||
|
val conn = if (server.startsWith("https")) {
|
||||||
|
(openConnection() as HttpsURLConnection).apply {
|
||||||
|
sslSocketFactory = getDefaultSSLSocketFactory()
|
||||||
|
hostnameVerifier = getDefaultHostnameVerifier()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
openConnection() as HttpURLConnection
|
||||||
|
}
|
||||||
|
conn.requestMethod = "POST"
|
||||||
|
conn.readTimeout = 8000
|
||||||
|
conn.connectTimeout = 8000
|
||||||
|
conn.doOutput = true
|
||||||
|
conn.doInput = true
|
||||||
|
conn.useCaches = false
|
||||||
|
|
||||||
|
conn.outputStream.apply {
|
||||||
|
write("{\"username\":\"${userEdit.text}\",\"password\":\"${passEdit.text}\"}".toByteArray())
|
||||||
|
flush()
|
||||||
|
}
|
||||||
|
if (conn.responseCode == 200) {
|
||||||
|
val input = conn.inputStream
|
||||||
|
val message = ByteArrayOutputStream()
|
||||||
|
|
||||||
|
var len: Int
|
||||||
|
val buffer = ByteArray(1024)
|
||||||
|
while (input.read(buffer).also { len = it } != -1) {
|
||||||
|
message.write(buffer, 0, len)
|
||||||
|
}
|
||||||
|
input.close()
|
||||||
|
message.close()
|
||||||
|
|
||||||
|
val json = JSONObject(String(message.toByteArray()))
|
||||||
|
if (json.optBoolean("success", false)) {
|
||||||
|
val token = json.optString("jwt", "")
|
||||||
|
runOnMainThread {
|
||||||
|
Toast.makeText(activity, "${moduleRes.getString(R.string.LoginSuccess)}\n${token}", Toast.LENGTH_LONG).show()
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
(activity.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager).text = token
|
||||||
|
sp.edit().run {
|
||||||
|
putString("user", userEdit.text.toString())
|
||||||
|
putString("pass", passEdit.text.toString())
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
runOnMainThread {
|
||||||
|
Toast.makeText(activity, moduleRes.getString(R.string.LoginFailed) + json.optString("message", ""), Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
runOnMainThread {
|
||||||
|
Toast.makeText(activity, moduleRes.getString(R.string.LoginError) + e, Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
addView(LinearLayout(activity).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||||
|
addView(Button(activity).apply {
|
||||||
|
text = "Open WebView"
|
||||||
|
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||||
|
setOnClickListener {
|
||||||
|
val webview = loadClass("com.miHoYo.sdk.webview.MiHoYoWebview")
|
||||||
|
webview.invokeStaticMethod("init", args(activity, "test_webview"), argTypes(Activity::class.java, String::class.java))
|
||||||
|
webview.invokeStaticMethod("show", args("test_webview"), argTypes(String::class.java))
|
||||||
|
webview.invokeStaticMethod("load", args("test_webview", "https://www.fkj233.cn/gourl/"), argTypes(String::class.java, String::class.java))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
windowManager = activity.windowManager
|
||||||
|
windowManager.addView(mainView, WindowManager.LayoutParams(dp2px(activity, 200f), WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_APPLICATION, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, PixelFormat.TRANSLUCENT).apply {
|
||||||
|
gravity = Gravity.START or Gravity.TOP
|
||||||
|
x = 0
|
||||||
|
y = 0
|
||||||
|
})
|
||||||
|
|
||||||
|
val layoutParams = WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_APPLICATION, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, PixelFormat.TRANSLUCENT).apply {
|
||||||
|
gravity = Gravity.START or Gravity.TOP
|
||||||
|
x = 0
|
||||||
|
y = 0
|
||||||
|
}
|
||||||
|
imageView = ImageView(activity).apply {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
background = moduleRes.getDrawable(R.drawable.ic_android_black_24dp).also { it.alpha = 50 }
|
||||||
|
this.layoutParams = layoutParams
|
||||||
|
setOnTouchListener(MoveOnTouchListener())
|
||||||
|
setOnClickListener {
|
||||||
|
mainView.visibility = View.VISIBLE
|
||||||
|
it.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
windowManager.addView(imageView, layoutParams)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sslHook() {
|
||||||
|
// OkHttp3 Hook
|
||||||
|
findMethodOrNull("com.combosdk.lib.third.okhttp3.OkHttpClient\$Builder") { name == "build" }?.hookBefore {
|
||||||
|
it.thisObject.invokeMethod("sslSocketFactory", args(getDefaultSSLSocketFactory()), argTypes(SSLSocketFactory::class.java))
|
||||||
|
it.thisObject.invokeMethod("hostnameVerifier", args(getDefaultHostnameVerifier()), argTypes(HostnameVerifier::class.java))
|
||||||
|
}
|
||||||
|
findMethodOrNull("okhttp3.OkHttpClient\$Builder") { name == "build" }?.hookBefore {
|
||||||
|
it.thisObject.invokeMethod("sslSocketFactory", args(getDefaultSSLSocketFactory(), DefaultTrustManager()), argTypes(SSLSocketFactory::class.java, X509TrustManager::class.java))
|
||||||
|
it.thisObject.invokeMethod("hostnameVerifier", args(getDefaultHostnameVerifier()), argTypes(HostnameVerifier::class.java))
|
||||||
|
}
|
||||||
|
// WebView Hook
|
||||||
|
arrayListOf(
|
||||||
|
"android.webkit.WebViewClient",
|
||||||
|
"cn.sharesdk.framework.g",
|
||||||
|
"com.facebook.internal.WebDialog\$DialogWebViewClient",
|
||||||
|
"com.geetest.sdk.dialog.views.GtWebView\$c",
|
||||||
|
"com.miHoYo.sdk.webview.common.view.ContentWebView\$6"
|
||||||
|
).forEach {
|
||||||
|
findMethodOrNull(it) { name == "onReceivedSslError" && parameterTypes[1] == SslErrorHandler::class.java }?.hookBefore { param ->
|
||||||
|
(param.args[1] as SslErrorHandler).proceed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Android HttpsURLConnection Hook
|
||||||
|
findMethodOrNull("javax.net.ssl.HttpsURLConnection") { name == "getDefaultSSLSocketFactory" }?.hookBefore {
|
||||||
|
it.result = getDefaultSSLSocketFactory()
|
||||||
|
}
|
||||||
|
findMethodOrNull("javax.net.ssl.HttpsURLConnection") { name == "setSSLSocketFactory" }?.hookBefore {
|
||||||
|
it.result = null
|
||||||
|
}
|
||||||
|
findMethodOrNull("javax.net.ssl.HttpsURLConnection") { name == "setDefaultSSLSocketFactory" }?.hookBefore {
|
||||||
|
it.result = null
|
||||||
|
}
|
||||||
|
findMethodOrNull("javax.net.ssl.HttpsURLConnection") { name == "setHostnameVerifier" }?.hookBefore {
|
||||||
|
it.result = null
|
||||||
|
}
|
||||||
|
findMethodOrNull("javax.net.ssl.HttpsURLConnection") { name == "setDefaultHostnameVerifier" }?.hookBefore {
|
||||||
|
it.result = null
|
||||||
|
}
|
||||||
|
findMethodOrNull("javax.net.ssl.HttpsURLConnection") { name == "getDefaultHostnameVerifier" }?.hookBefore {
|
||||||
|
it.result = getDefaultHostnameVerifier()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hook() {
|
||||||
|
findMethod("com.miHoYo.sdk.webview.MiHoYoWebview") { name == "load" && parameterTypes[0] == String::class.java && parameterTypes[1] == String::class.java }.hookBefore {
|
||||||
|
replaceUrl(it, 1)
|
||||||
|
}
|
||||||
|
findAllMethods("android.webkit.WebView") { name == "loadUrl" }.hookBefore {
|
||||||
|
replaceUrl(it, 0)
|
||||||
|
}
|
||||||
|
findAllMethods("android.webkit.WebView") { name == "postUrl" }.hookBefore {
|
||||||
|
replaceUrl(it, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
findMethod("okhttp3.HttpUrl") { name == "parse" && parameterTypes[0] == String::class.java }.hookBefore {
|
||||||
|
replaceUrl(it, 0)
|
||||||
|
}
|
||||||
|
findMethod("com.combosdk.lib.third.okhttp3.HttpUrl") { name == "parse" && parameterTypes[0] == String::class.java }.hookBefore {
|
||||||
|
replaceUrl(it, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
findMethod("com.google.gson.Gson") { name == "fromJson" && parameterTypes[0] == String::class.java && parameterTypes[1] == java.lang.reflect.Type::class.java }.hookBefore {
|
||||||
|
replaceUrl(it, 0)
|
||||||
|
}
|
||||||
|
findConstructor("java.net.URL") { parameterTypes[0] == String::class.java }.hookBefore {
|
||||||
|
replaceUrl(it, 0)
|
||||||
|
}
|
||||||
|
findMethod("com.combosdk.lib.third.okhttp3.Request\$Builder") { name == "url" && parameterTypes[0] == String::class.java }.hookBefore {
|
||||||
|
replaceUrl(it, 0)
|
||||||
|
}
|
||||||
|
findMethod("okhttp3.Request\$Builder") { name == "url" && parameterTypes[0] == String::class.java }.hookBefore {
|
||||||
|
replaceUrl(it, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun replaceUrl(method: XC_MethodHook.MethodHookParam, args: Int) {
|
||||||
|
if (!forceUrl && !proxyList) return
|
||||||
|
if (!this::server.isInitialized) return
|
||||||
|
if (server == "") return
|
||||||
|
if (method.args[args].toString() == "") return
|
||||||
|
|
||||||
|
XposedBridge.log("old: " + method.args[args].toString())
|
||||||
|
if (!sp.getBoolean("HookConfig", false) && method.args[args].toString().startsWith("[{\"area\":")) return
|
||||||
|
if (proxyList) {
|
||||||
|
for (list in proxyListRegex) {
|
||||||
|
for (head in arrayListOf("http://", "https://")) {
|
||||||
|
method.args[args] = method.args[args].toString().replace(head + list, server)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val m = regex.matcher(method.args[args].toString())
|
||||||
|
if (m.find()) {
|
||||||
|
method.args[args] = m.replaceAll(server)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XposedBridge.log("new: " + method.args[args].toString())
|
||||||
|
}
|
||||||
|
}
|
@ -1,673 +1,19 @@
|
|||||||
package xfk233.genshinproxy
|
package xfk233.genshinproxy
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.Activity
|
|
||||||
import android.app.AlertDialog
|
|
||||||
import android.content.ClipboardManager
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.SharedPreferences
|
|
||||||
import android.content.res.XModuleResources
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.PixelFormat
|
|
||||||
import android.text.Editable
|
|
||||||
import android.text.InputType
|
|
||||||
import android.text.TextWatcher
|
|
||||||
import android.util.TypedValue
|
|
||||||
import android.view.Gravity
|
|
||||||
import android.view.MotionEvent
|
|
||||||
import android.view.View
|
|
||||||
import android.view.WindowManager
|
|
||||||
import android.webkit.SslErrorHandler
|
|
||||||
import android.widget.*
|
|
||||||
import com.github.kyuubiran.ezxhelper.init.EzXHelperInit
|
|
||||||
import com.github.kyuubiran.ezxhelper.utils.*
|
|
||||||
import de.robv.android.xposed.IXposedHookLoadPackage
|
import de.robv.android.xposed.IXposedHookLoadPackage
|
||||||
import de.robv.android.xposed.IXposedHookZygoteInit
|
import de.robv.android.xposed.IXposedHookZygoteInit
|
||||||
import de.robv.android.xposed.XC_MethodHook
|
|
||||||
import de.robv.android.xposed.XposedBridge
|
|
||||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||||
import org.json.JSONObject
|
|
||||||
import xfk233.genshinproxy.Utils.dp2px
|
|
||||||
import xfk233.genshinproxy.Utils.isInit
|
|
||||||
import java.io.BufferedReader
|
|
||||||
import java.io.ByteArrayOutputStream
|
|
||||||
import java.io.InputStreamReader
|
|
||||||
import java.net.HttpURLConnection
|
|
||||||
import java.net.URL
|
|
||||||
import java.security.SecureRandom
|
|
||||||
import java.security.cert.X509Certificate
|
|
||||||
import java.util.regex.Pattern
|
|
||||||
import javax.net.ssl.*
|
|
||||||
import kotlin.system.exitProcess
|
|
||||||
|
|
||||||
|
|
||||||
class MainHook : IXposedHookLoadPackage, IXposedHookZygoteInit {
|
class MainHook : IXposedHookLoadPackage, IXposedHookZygoteInit {
|
||||||
private val regex = Pattern.compile("http(s|)://.*?\\.(hoyoverse|mihoyo|yuanshen|mob)\\.com")
|
private val hook = Hook()
|
||||||
private lateinit var server: String
|
|
||||||
private var forceUrl = false
|
|
||||||
private lateinit var modulePath: String
|
|
||||||
private lateinit var moduleRes: XModuleResources
|
|
||||||
private lateinit var windowManager: WindowManager
|
|
||||||
private var proxyList = false
|
|
||||||
private lateinit var sp: SharedPreferences
|
|
||||||
private val proxyListRegex = arrayListOf(
|
|
||||||
"api-os-takumi.mihoyo.com",
|
|
||||||
"hk4e-api-os-static.mihoyo.com",
|
|
||||||
"hk4e-sdk-os.mihoyo.com",
|
|
||||||
"dispatchosglobal.yuanshen.com",
|
|
||||||
"osusadispatch.yuanshen.com",
|
|
||||||
"account.mihoyo.com",
|
|
||||||
"log-upload-os.mihoyo.com",
|
|
||||||
"dispatchcntest.yuanshen.com",
|
|
||||||
"devlog-upload.mihoyo.com",
|
|
||||||
"webstatic.mihoyo.com",
|
|
||||||
"log-upload.mihoyo.com",
|
|
||||||
"hk4e-sdk.mihoyo.com",
|
|
||||||
"api-beta-sdk.mihoyo.com",
|
|
||||||
"api-beta-sdk-os.mihoyo.com",
|
|
||||||
"cnbeta01dispatch.yuanshen.com",
|
|
||||||
"dispatchcnglobal.yuanshen.com",
|
|
||||||
"cnbeta02dispatch.yuanshen.com",
|
|
||||||
"sdk-os-static.mihoyo.com",
|
|
||||||
"webstatic-sea.mihoyo.com",
|
|
||||||
"webstatic-sea.hoyoverse.com",
|
|
||||||
"hk4e-sdk-os-static.hoyoverse.com",
|
|
||||||
"sdk-os-static.hoyoverse.com",
|
|
||||||
"api-account-os.hoyoverse.com",
|
|
||||||
"hk4e-sdk-os.hoyoverse.com",
|
|
||||||
"overseauspider.yuanshen.com",
|
|
||||||
"gameapi-account.mihoyo.com",
|
|
||||||
"minor-api.mihoyo.com",
|
|
||||||
"public-data-api.mihoyo.com",
|
|
||||||
"uspider.yuanshen.com",
|
|
||||||
"sdk-static.mihoyo.com",
|
|
||||||
"minor-api-os.hoyoverse.com",
|
|
||||||
"log-upload-os.hoyoverse.com"
|
|
||||||
)
|
|
||||||
|
|
||||||
private val activityList: ArrayList<Activity> = arrayListOf()
|
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
||||||
private var activity: Activity
|
hook.handleLoadPackage(lpparam)
|
||||||
get() {
|
|
||||||
for (mActivity in activityList) {
|
|
||||||
if (mActivity.isFinishing) {
|
|
||||||
activityList.remove(mActivity)
|
|
||||||
} else {
|
|
||||||
return mActivity
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw Throwable("Activity not found.")
|
|
||||||
}
|
|
||||||
set(value) {
|
|
||||||
activityList.add(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getDefaultSSLSocketFactory(): SSLSocketFactory {
|
|
||||||
return SSLContext.getInstance("TLS").apply {
|
|
||||||
init(arrayOf<KeyManager>(), arrayOf<TrustManager>(DefaultTrustManager()), SecureRandom())
|
|
||||||
}.socketFactory
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getDefaultHostnameVerifier(): HostnameVerifier {
|
|
||||||
return DefaultHostnameVerifier()
|
|
||||||
}
|
|
||||||
|
|
||||||
class DefaultHostnameVerifier : HostnameVerifier {
|
|
||||||
@SuppressLint("BadHostnameVerifier")
|
|
||||||
override fun verify(p0: String?, p1: SSLSession?): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("CustomX509TrustManager")
|
|
||||||
private class DefaultTrustManager : X509TrustManager {
|
|
||||||
|
|
||||||
@SuppressLint("TrustAllX509TrustManager")
|
|
||||||
override fun checkClientTrusted(chain: Array<X509Certificate?>?, authType: String?) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("TrustAllX509TrustManager")
|
|
||||||
override fun checkServerTrusted(chain: Array<X509Certificate?>?, authType: String?) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getAcceptedIssuers(): Array<X509Certificate> {
|
|
||||||
return arrayOf()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam) {
|
override fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam) {
|
||||||
modulePath = startupParam.modulePath
|
hook.initZygote(startupParam)
|
||||||
moduleRes = XModuleResources.createInstance(modulePath, null)
|
|
||||||
TrustMeAlready().initZygote(startupParam)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var startForceUrl = false
|
|
||||||
private var startProxyList = false
|
|
||||||
|
|
||||||
@SuppressLint("WrongConstant", "ClickableViewAccessibility")
|
|
||||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
|
||||||
if (lpparam.packageName != "com.miHoYo.GenshinImpact") return
|
|
||||||
EzXHelperInit.initHandleLoadPackage(lpparam)
|
|
||||||
findMethod("com.combosdk.openapi.ComboApplication") { name == "attachBaseContext" }.hookBefore {
|
|
||||||
val context = it.args[0] as Context
|
|
||||||
sp = context.getSharedPreferences("serverConfig", 0)
|
|
||||||
forceUrl = sp.getBoolean("forceUrl", false)
|
|
||||||
startForceUrl = forceUrl
|
|
||||||
server = sp.getString("serverip", "") ?: ""
|
|
||||||
proxyList = sp.getBoolean("ProxyList", false)
|
|
||||||
startProxyList = proxyList
|
|
||||||
if (sp.getBoolean("KeepSSL", false)) sslHook()
|
|
||||||
}
|
|
||||||
hook()
|
|
||||||
findMethod(Activity::class.java, true) { name == "onCreate" }.hookBefore { param ->
|
|
||||||
activity = param.thisObject as Activity
|
|
||||||
}
|
|
||||||
findMethod("com.miHoYo.GetMobileInfo.MainActivity") { name == "onCreate" }.hookBefore { param ->
|
|
||||||
activity = param.thisObject as Activity
|
|
||||||
showDialog()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showDialog() {
|
|
||||||
AlertDialog.Builder(activity).apply {
|
|
||||||
setCancelable(false)
|
|
||||||
setTitle(moduleRes.getString(R.string.SelectServer))
|
|
||||||
setMessage(moduleRes.getString(R.string.Tips))
|
|
||||||
setNegativeButton(moduleRes.getString(R.string.Settings)) { _, _ ->
|
|
||||||
AlertDialog.Builder(activity).apply {
|
|
||||||
setMessage(moduleRes.getString(R.string.Tips2))
|
|
||||||
setCancelable(false)
|
|
||||||
setView(ScrollView(context).apply {
|
|
||||||
setPadding(25, 0, 25, 0)
|
|
||||||
addView(LinearLayout(activity).apply {
|
|
||||||
orientation = LinearLayout.VERTICAL
|
|
||||||
addView(EditText(activity).apply {
|
|
||||||
hint = "http(s)://server.com:1234"
|
|
||||||
val str = sp.getString("serverip", "") ?: ""
|
|
||||||
setText(str.toCharArray(), 0, str.length)
|
|
||||||
addTextChangedListener(object : TextWatcher {
|
|
||||||
override fun beforeTextChanged(p0: CharSequence, p1: Int, p2: Int, p3: Int) {}
|
|
||||||
override fun onTextChanged(p0: CharSequence, p1: Int, p2: Int, p3: Int) {}
|
|
||||||
|
|
||||||
@SuppressLint("CommitPrefEdits")
|
|
||||||
override fun afterTextChanged(p0: Editable) {
|
|
||||||
sp.edit().run {
|
|
||||||
putString("serverip", p0.toString())
|
|
||||||
apply()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
addView(Switch(activity).apply {
|
|
||||||
text = moduleRes.getString(R.string.ForcedMode)
|
|
||||||
isChecked = sp.getBoolean("forceUrl", false)
|
|
||||||
setOnCheckedChangeListener { _, b ->
|
|
||||||
sp.edit().run {
|
|
||||||
putBoolean("forceUrl", b)
|
|
||||||
apply()
|
|
||||||
}
|
|
||||||
forceUrl = b
|
|
||||||
}
|
|
||||||
})
|
|
||||||
addView(Switch(activity).apply {
|
|
||||||
text = moduleRes.getString(R.string.ProxyList)
|
|
||||||
isChecked = sp.getBoolean("ProxyList", false)
|
|
||||||
setOnCheckedChangeListener { _, b ->
|
|
||||||
sp.edit().run {
|
|
||||||
putBoolean("ProxyList", b)
|
|
||||||
apply()
|
|
||||||
}
|
|
||||||
proxyList = b
|
|
||||||
}
|
|
||||||
})
|
|
||||||
addView(Switch(activity).apply {
|
|
||||||
text = moduleRes.getString(R.string.HookConfig)
|
|
||||||
isChecked = sp.getBoolean("HookConfig", false)
|
|
||||||
setOnCheckedChangeListener { _, b ->
|
|
||||||
sp.edit().run {
|
|
||||||
putBoolean("HookConfig", b)
|
|
||||||
apply()
|
|
||||||
}
|
|
||||||
proxyList = b
|
|
||||||
}
|
|
||||||
})
|
|
||||||
addView(Switch(activity).apply {
|
|
||||||
text = moduleRes.getString(R.string.EnableTools)
|
|
||||||
isChecked = sp.getBoolean("EnableTools", false)
|
|
||||||
setOnCheckedChangeListener { _, b ->
|
|
||||||
sp.edit().run {
|
|
||||||
putBoolean("EnableTools", b)
|
|
||||||
apply()
|
|
||||||
}
|
|
||||||
proxyList = b
|
|
||||||
}
|
|
||||||
})
|
|
||||||
addView(Switch(activity).apply {
|
|
||||||
text = moduleRes.getString(R.string.KeepSSL)
|
|
||||||
isChecked = sp.getBoolean("KeepSSL", false)
|
|
||||||
setOnCheckedChangeListener { _, b ->
|
|
||||||
sp.edit().run {
|
|
||||||
putBoolean("KeepSSL", b)
|
|
||||||
apply()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
setPositiveButton(moduleRes.getString(R.string.Back)) { _, _ ->
|
|
||||||
showDialog()
|
|
||||||
}
|
|
||||||
setNeutralButton(moduleRes.getString(R.string.ExitGames)) { _, _ ->
|
|
||||||
exitProcess(0)
|
|
||||||
}
|
|
||||||
}.show()
|
|
||||||
}
|
|
||||||
setPositiveButton(moduleRes.getString(R.string.CustomServer)) { _, _ ->
|
|
||||||
val ip = sp.getString("serverip", "") ?: ""
|
|
||||||
if (ip == "") {
|
|
||||||
Toast.makeText(activity, moduleRes.getString(R.string.ServerAddressError), Toast.LENGTH_LONG).show()
|
|
||||||
activity.finish()
|
|
||||||
} else {
|
|
||||||
server = ip
|
|
||||||
forceUrl = true
|
|
||||||
if (sp.getBoolean("EnableTools", false)) gmTool()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setNeutralButton(moduleRes.getString(R.string.OfficialServer)) { _, _ ->
|
|
||||||
forceUrl = false
|
|
||||||
server = ""
|
|
||||||
if (startForceUrl || startProxyList) {
|
|
||||||
Toast.makeText(activity, moduleRes.getString(R.string.JoinServerError), Toast.LENGTH_LONG).show()
|
|
||||||
showDialog()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class MoveOnTouchListener : View.OnTouchListener {
|
|
||||||
private var originalXPos = 0
|
|
||||||
private var originalYPos = 0
|
|
||||||
|
|
||||||
private var offsetX = 0f
|
|
||||||
private var offsetY = 0f
|
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
|
||||||
override fun onTouch(v: View, event: MotionEvent): Boolean {
|
|
||||||
when (event.action) {
|
|
||||||
MotionEvent.ACTION_DOWN -> {
|
|
||||||
val x = event.rawX
|
|
||||||
val y = event.rawY
|
|
||||||
|
|
||||||
val location = IntArray(2)
|
|
||||||
v.getLocationOnScreen(location)
|
|
||||||
|
|
||||||
originalXPos = location[0]
|
|
||||||
originalYPos = location[1]
|
|
||||||
|
|
||||||
offsetX = x - originalXPos
|
|
||||||
offsetY = y - originalYPos
|
|
||||||
}
|
|
||||||
MotionEvent.ACTION_MOVE -> {
|
|
||||||
val onScreen = IntArray(2)
|
|
||||||
v.getLocationOnScreen(onScreen)
|
|
||||||
|
|
||||||
val x = event.rawX
|
|
||||||
val y = event.rawY
|
|
||||||
|
|
||||||
val params: WindowManager.LayoutParams = v.layoutParams as WindowManager.LayoutParams
|
|
||||||
|
|
||||||
val newX = (x - offsetX).toInt()
|
|
||||||
val newY = (y - offsetY).toInt()
|
|
||||||
|
|
||||||
if (newX == originalXPos && newY == originalYPos) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
params.x = newX
|
|
||||||
params.y = newY
|
|
||||||
|
|
||||||
windowManager.updateViewLayout(v, params)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var imageView: ImageView
|
|
||||||
private lateinit var mainView: ScrollView
|
|
||||||
private fun gmTool() {
|
|
||||||
if (this::mainView.isInitialized) return
|
|
||||||
if (this::imageView.isInitialized) return
|
|
||||||
if (isInit) return
|
|
||||||
isInit = true
|
|
||||||
mainView = ScrollView(activity).apply {
|
|
||||||
visibility = View.GONE
|
|
||||||
addView(LinearLayout(activity).apply {
|
|
||||||
orientation = LinearLayout.VERTICAL
|
|
||||||
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
|
|
||||||
setBackgroundColor(Color.parseColor("#5F000000"))
|
|
||||||
addView(LinearLayout(activity).apply {
|
|
||||||
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
|
||||||
setBackgroundColor(Color.parseColor("#8F000000"))
|
|
||||||
addView(TextView(activity).apply {
|
|
||||||
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)
|
|
||||||
setTextColor(Color.BLUE)
|
|
||||||
setTextSize(TypedValue.COMPLEX_UNIT_SP, 18f)
|
|
||||||
text = moduleRes.getString(R.string.Tools)
|
|
||||||
})
|
|
||||||
addView(TextView(activity).apply {
|
|
||||||
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT).also {
|
|
||||||
it.setMargins(0, 0, 5, 0)
|
|
||||||
}
|
|
||||||
setTextColor(Color.BLUE)
|
|
||||||
setTextSize(TypedValue.COMPLEX_UNIT_SP, 18f)
|
|
||||||
text = "X"
|
|
||||||
setOnClickListener {
|
|
||||||
mainView.visibility = View.GONE
|
|
||||||
imageView.visibility = View.VISIBLE
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
addView(LinearLayout(activity).apply {
|
|
||||||
orientation = LinearLayout.VERTICAL
|
|
||||||
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
|
|
||||||
var userEdit: EditText
|
|
||||||
var passEdit: EditText
|
|
||||||
addView(LinearLayout(activity).apply {
|
|
||||||
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
|
||||||
addView(TextView(activity).apply {
|
|
||||||
setTextColor(Color.BLUE)
|
|
||||||
text = moduleRes.getString(R.string.CheckServerStatus)
|
|
||||||
setOnClickListener {
|
|
||||||
Thread() {
|
|
||||||
try {
|
|
||||||
XposedBridge.log("$server/authentication/type")
|
|
||||||
URL("$server/authentication/type").apply {
|
|
||||||
val conn = if (server.startsWith("https")) {
|
|
||||||
(openConnection() as HttpsURLConnection).apply {
|
|
||||||
sslSocketFactory = getDefaultSSLSocketFactory()
|
|
||||||
hostnameVerifier = getDefaultHostnameVerifier()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
openConnection() as HttpURLConnection
|
|
||||||
}
|
|
||||||
conn.requestMethod = "GET"
|
|
||||||
conn.readTimeout = 8000
|
|
||||||
conn.connectTimeout = 8000
|
|
||||||
|
|
||||||
val reader = BufferedReader(InputStreamReader(conn.inputStream))
|
|
||||||
if (conn.responseCode == 200) {
|
|
||||||
val response = StringBuilder()
|
|
||||||
var line = ""
|
|
||||||
while (reader.readLine()?.also { line = it } != null) {
|
|
||||||
response.append(line)
|
|
||||||
}
|
|
||||||
runOnMainThread {
|
|
||||||
text = if (response.toString() == "me.exzork.gcauth.handler.GCAuthAuthenticationHandler") moduleRes.getString(R.string.ServerStatus) + "GcAuth" else moduleRes.getString(R.string.ServerStatus) + "GcAuth" + moduleRes.getString(R.string.NotInstall)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
runOnMainThread {
|
|
||||||
text = moduleRes.getString(R.string.ServerStatus) + moduleRes.getString(R.string.GetServerStatusError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
runOnMainThread {
|
|
||||||
text = moduleRes.getString(R.string.ServerStatus) + moduleRes.getString(R.string.GetServerStatusError) + e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.start()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
addView(LinearLayout(activity).apply {
|
|
||||||
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
|
||||||
addView(Switch(activity).apply {
|
|
||||||
text = moduleRes.getString(R.string.InputSwitch)
|
|
||||||
setOnCheckedChangeListener { _, b ->
|
|
||||||
if (b) {
|
|
||||||
val params = mainView.layoutParams as WindowManager.LayoutParams
|
|
||||||
params.flags = params.flags and (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE.inv())
|
|
||||||
windowManager.updateViewLayout(mainView, params)
|
|
||||||
} else {
|
|
||||||
val params = mainView.layoutParams as WindowManager.LayoutParams
|
|
||||||
params.flags = params.flags or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
|
||||||
windowManager.updateViewLayout(mainView, params)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
addView(LinearLayout(activity).apply {
|
|
||||||
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
|
||||||
addView(TextView(activity).apply {
|
|
||||||
setTextColor(Color.BLUE)
|
|
||||||
text = moduleRes.getString(R.string.User)
|
|
||||||
})
|
|
||||||
addView(EditText(activity).apply {
|
|
||||||
userEdit = this
|
|
||||||
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
|
||||||
val user = sp.getString("user", "") ?: ""
|
|
||||||
setText(user.toCharArray(), 0, user.length)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
addView(LinearLayout(activity).apply {
|
|
||||||
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
|
||||||
addView(TextView(activity).apply {
|
|
||||||
setTextColor(Color.BLUE)
|
|
||||||
text = moduleRes.getString(R.string.Password)
|
|
||||||
})
|
|
||||||
addView(EditText(activity).apply {
|
|
||||||
passEdit = this
|
|
||||||
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
|
||||||
inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
|
||||||
val user = sp.getString("pass", "") ?: ""
|
|
||||||
setText(user.toCharArray(), 0, user.length)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
addView(LinearLayout(activity).apply {
|
|
||||||
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
|
||||||
addView(Button(activity).apply {
|
|
||||||
text = moduleRes.getString(R.string.Login)
|
|
||||||
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
|
||||||
setOnClickListener {
|
|
||||||
Thread() {
|
|
||||||
try {
|
|
||||||
URL("$server/authentication/type").apply {
|
|
||||||
val conn = if (server.startsWith("https")) {
|
|
||||||
(openConnection() as HttpsURLConnection).apply {
|
|
||||||
sslSocketFactory = getDefaultSSLSocketFactory()
|
|
||||||
hostnameVerifier = getDefaultHostnameVerifier()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
openConnection() as HttpURLConnection
|
|
||||||
}
|
|
||||||
conn.requestMethod = "POST"
|
|
||||||
conn.readTimeout = 8000
|
|
||||||
conn.connectTimeout = 8000
|
|
||||||
conn.doOutput = true
|
|
||||||
conn.doInput = true
|
|
||||||
conn.useCaches = false
|
|
||||||
|
|
||||||
conn.outputStream.apply {
|
|
||||||
write("{\"username\":\"${userEdit.text}\",\"password\":\"${passEdit.text}\"}".toByteArray())
|
|
||||||
flush()
|
|
||||||
}
|
|
||||||
if (conn.responseCode == 200) {
|
|
||||||
val input = conn.inputStream
|
|
||||||
val message = ByteArrayOutputStream()
|
|
||||||
|
|
||||||
var len: Int
|
|
||||||
val buffer = ByteArray(1024)
|
|
||||||
while (input.read(buffer).also { len = it } != -1) {
|
|
||||||
message.write(buffer, 0, len)
|
|
||||||
}
|
|
||||||
input.close()
|
|
||||||
message.close()
|
|
||||||
|
|
||||||
val json = JSONObject(String(message.toByteArray()))
|
|
||||||
if (json.optBoolean("success", false)) {
|
|
||||||
val token = json.optString("jwt", "")
|
|
||||||
runOnMainThread {
|
|
||||||
Toast.makeText(activity, "${moduleRes.getString(R.string.LoginSuccess)}\n${token}", Toast.LENGTH_LONG).show()
|
|
||||||
(activity.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager).text = token
|
|
||||||
sp.edit().run {
|
|
||||||
putString("user", userEdit.text.toString())
|
|
||||||
putString("pass", passEdit.text.toString())
|
|
||||||
apply()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
runOnMainThread {
|
|
||||||
Toast.makeText(activity, moduleRes.getString(R.string.LoginFailed) + json.optString("message", ""), Toast.LENGTH_LONG).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
runOnMainThread {
|
|
||||||
Toast.makeText(activity, moduleRes.getString(R.string.LoginError) + e, Toast.LENGTH_LONG).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.start()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
addView(LinearLayout(activity).apply {
|
|
||||||
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
|
||||||
addView(Button(activity).apply {
|
|
||||||
text = "Open WebView"
|
|
||||||
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
|
||||||
setOnClickListener {
|
|
||||||
val webview = loadClass("com.miHoYo.sdk.webview.MiHoYoWebview")
|
|
||||||
webview.invokeStaticMethod("init", args(activity, "test_webview"), argTypes(Activity::class.java, String::class.java))
|
|
||||||
webview.invokeStaticMethod("show", args("test_webview"), argTypes(String::class.java))
|
|
||||||
webview.invokeStaticMethod("load", args("test_webview", "https://www.fkj233.cn/gourl/"), argTypes(String::class.java, String::class.java))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
windowManager = activity.windowManager
|
|
||||||
windowManager.addView(mainView, WindowManager.LayoutParams(dp2px(activity, 200f), WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_APPLICATION, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, PixelFormat.TRANSLUCENT).apply {
|
|
||||||
gravity = Gravity.START or Gravity.TOP
|
|
||||||
x = 0
|
|
||||||
y = 0
|
|
||||||
})
|
|
||||||
|
|
||||||
val layoutParams = WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_APPLICATION, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, PixelFormat.TRANSLUCENT).apply {
|
|
||||||
gravity = Gravity.START or Gravity.TOP
|
|
||||||
x = 0
|
|
||||||
y = 0
|
|
||||||
}
|
|
||||||
imageView = ImageView(activity).apply {
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
background = moduleRes.getDrawable(R.drawable.ic_android_black_24dp).also { it.alpha = 50 }
|
|
||||||
this.layoutParams = layoutParams
|
|
||||||
setOnTouchListener(MoveOnTouchListener())
|
|
||||||
setOnClickListener {
|
|
||||||
mainView.visibility = View.VISIBLE
|
|
||||||
it.visibility = View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
windowManager.addView(imageView, layoutParams)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun sslHook() {
|
|
||||||
// OkHttp3 Hook
|
|
||||||
findMethodOrNull("com.combosdk.lib.third.okhttp3.OkHttpClient\$Builder") { name == "build" }?.hookBefore {
|
|
||||||
it.thisObject.invokeMethod("sslSocketFactory", args(getDefaultSSLSocketFactory()), argTypes(SSLSocketFactory::class.java))
|
|
||||||
it.thisObject.invokeMethod("hostnameVerifier", args(getDefaultHostnameVerifier()), argTypes(HostnameVerifier::class.java))
|
|
||||||
}
|
|
||||||
findMethodOrNull("okhttp3.OkHttpClient\$Builder") { name == "build" }?.hookBefore {
|
|
||||||
it.thisObject.invokeMethod("sslSocketFactory", args(getDefaultSSLSocketFactory(), DefaultTrustManager()), argTypes(SSLSocketFactory::class.java, X509TrustManager::class.java))
|
|
||||||
it.thisObject.invokeMethod("hostnameVerifier", args(getDefaultHostnameVerifier()), argTypes(HostnameVerifier::class.java))
|
|
||||||
}
|
|
||||||
// WebView Hook
|
|
||||||
arrayListOf(
|
|
||||||
"android.webkit.WebViewClient",
|
|
||||||
"cn.sharesdk.framework.g",
|
|
||||||
"com.facebook.internal.WebDialog\$DialogWebViewClient",
|
|
||||||
"com.geetest.sdk.dialog.views.GtWebView\$c",
|
|
||||||
"com.miHoYo.sdk.webview.common.view.ContentWebView\$6"
|
|
||||||
).forEach {
|
|
||||||
findMethodOrNull(it) { name == "onReceivedSslError" && parameterTypes[1] == SslErrorHandler::class.java }?.hookBefore { param ->
|
|
||||||
(param.args[1] as SslErrorHandler).proceed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Android HttpsURLConnection Hook
|
|
||||||
findMethodOrNull("javax.net.ssl.HttpsURLConnection") { name == "getDefaultSSLSocketFactory" }?.hookBefore {
|
|
||||||
it.result = getDefaultSSLSocketFactory()
|
|
||||||
}
|
|
||||||
findMethodOrNull("javax.net.ssl.HttpsURLConnection") { name == "setSSLSocketFactory" }?.hookBefore {
|
|
||||||
it.result = null
|
|
||||||
}
|
|
||||||
findMethodOrNull("javax.net.ssl.HttpsURLConnection") { name == "setDefaultSSLSocketFactory" }?.hookBefore {
|
|
||||||
it.result = null
|
|
||||||
}
|
|
||||||
findMethodOrNull("javax.net.ssl.HttpsURLConnection") { name == "setHostnameVerifier" }?.hookBefore {
|
|
||||||
it.result = null
|
|
||||||
}
|
|
||||||
findMethodOrNull("javax.net.ssl.HttpsURLConnection") { name == "setDefaultHostnameVerifier" }?.hookBefore {
|
|
||||||
it.result = null
|
|
||||||
}
|
|
||||||
findMethodOrNull("javax.net.ssl.HttpsURLConnection") { name == "getDefaultHostnameVerifier" }?.hookBefore {
|
|
||||||
it.result = getDefaultHostnameVerifier()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun hook() {
|
|
||||||
findMethod("com.miHoYo.sdk.webview.MiHoYoWebview") { name == "load" && parameterTypes[0] == String::class.java && parameterTypes[1] == String::class.java }.hookBefore {
|
|
||||||
replaceUrl(it, 1)
|
|
||||||
}
|
|
||||||
findAllMethods("android.webkit.WebView") { name == "loadUrl" }.hookBefore {
|
|
||||||
replaceUrl(it, 0)
|
|
||||||
}
|
|
||||||
findAllMethods("android.webkit.WebView") { name == "postUrl" }.hookBefore {
|
|
||||||
replaceUrl(it, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
findMethod("okhttp3.HttpUrl") { name == "parse" && parameterTypes[0] == String::class.java }.hookBefore {
|
|
||||||
replaceUrl(it, 0)
|
|
||||||
}
|
|
||||||
findMethod("com.combosdk.lib.third.okhttp3.HttpUrl") { name == "parse" && parameterTypes[0] == String::class.java }.hookBefore {
|
|
||||||
replaceUrl(it, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
findMethod("com.google.gson.Gson") { name == "fromJson" && parameterTypes[0] == String::class.java && parameterTypes[1] == java.lang.reflect.Type::class.java }.hookBefore {
|
|
||||||
replaceUrl(it, 0)
|
|
||||||
}
|
|
||||||
findConstructor("java.net.URL") { parameterTypes[0] == String::class.java }.hookBefore {
|
|
||||||
replaceUrl(it, 0)
|
|
||||||
}
|
|
||||||
findMethod("com.combosdk.lib.third.okhttp3.Request\$Builder") { name == "url" && parameterTypes[0] == String::class.java }.hookBefore {
|
|
||||||
replaceUrl(it, 0)
|
|
||||||
}
|
|
||||||
findMethod("okhttp3.Request\$Builder") { name == "url" && parameterTypes[0] == String::class.java }.hookBefore {
|
|
||||||
replaceUrl(it, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun replaceUrl(method: XC_MethodHook.MethodHookParam, args: Int) {
|
|
||||||
if (!forceUrl && !proxyList) return
|
|
||||||
if (!this::server.isInitialized) return
|
|
||||||
if (server == "") return
|
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) XposedBridge.log("old: " + method.args[args].toString())
|
|
||||||
if (!sp.getBoolean("HookConfig", false) && method.args[args].toString().startsWith("[{\"area\":")) return
|
|
||||||
if (proxyList) {
|
|
||||||
for (list in proxyListRegex) {
|
|
||||||
for (head in arrayListOf("http://", "https://")) {
|
|
||||||
method.args[args] = method.args[args].toString().replace(head + list, server)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val m = regex.matcher(method.args[args].toString())
|
|
||||||
if (m.find()) {
|
|
||||||
method.args[args] = m.replaceAll(server)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (BuildConfig.DEBUG) XposedBridge.log("new: " + method.args[args].toString())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -15,15 +15,14 @@ import de.robv.android.xposed.XposedBridge;
|
|||||||
|
|
||||||
import static de.robv.android.xposed.XposedHelpers.*;
|
import static de.robv.android.xposed.XposedHelpers.*;
|
||||||
|
|
||||||
public class TrustMeAlready implements IXposedHookZygoteInit {
|
public class TrustMeAlready {
|
||||||
|
|
||||||
private static final String SSL_CLASS_NAME = "com.android.org.conscrypt.TrustManagerImpl";
|
private static final String SSL_CLASS_NAME = "com.android.org.conscrypt.TrustManagerImpl";
|
||||||
private static final String SSL_METHOD_NAME = "checkTrustedRecursive";
|
private static final String SSL_METHOD_NAME = "checkTrustedRecursive";
|
||||||
private static final Class<?> SSL_RETURN_TYPE = List.class;
|
private static final Class<?> SSL_RETURN_TYPE = List.class;
|
||||||
private static final Class<?> SSL_RETURN_PARAM_TYPE = X509Certificate.class;
|
private static final Class<?> SSL_RETURN_PARAM_TYPE = X509Certificate.class;
|
||||||
|
|
||||||
@Override
|
public void initZygote() {
|
||||||
public void initZygote(StartupParam startupParam) throws Throwable {
|
|
||||||
XposedBridge.log("TrustMeAlready loading...");
|
XposedBridge.log("TrustMeAlready loading...");
|
||||||
int hookedMethods = 0;
|
int hookedMethods = 0;
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package xfk233.genshinproxy
|
package xfk233.genshinproxy
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.util.Base64
|
||||||
|
import android.widget.Toast
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
object Utils {
|
object Utils {
|
||||||
var isInit = false
|
var isInit = false
|
||||||
@ -9,4 +13,14 @@ object Utils {
|
|||||||
val scale: Float = context.resources.displayMetrics.density
|
val scale: Float = context.resources.displayMetrics.density
|
||||||
return (dpValue * scale + 0.5f).toInt()
|
return (dpValue * scale + 0.5f).toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fun check(context: Context, modulePath: String) {
|
||||||
|
context.packageManager.getPackageArchiveInfo(modulePath, PackageManager.GET_SIGNING_CERTIFICATES).apply {
|
||||||
|
this ?: exitProcess(0)
|
||||||
|
if (signingInfo.apkContentsSigners[0].toCharsString() !in arrayOf(String(Base64.decode("MzA4MjAyZTQzMDgyMDFjYzAyMDEwMTMwMGQwNjA5MmE4NjQ4ODZmNzBkMDEwMTA1MDUwMDMwMzczMTE2MzAxNDA2MDM1NTA0MDMwYzBkNDE2ZTY0NzI2ZjY5NjQyMDQ0NjU2Mjc1NjczMTEwMzAwZTA2MDM1NTA0MGEwYzA3NDE2ZTY0NzI2ZjY5NjQzMTBiMzAwOTA2MDM1NTA0MDYxMzAyNTU1MzMwMjAxNzBkMzIzMjMwMzEzMDM4MzEzMzMxMzEzMjMwNWExODBmMzIzMDM1MzIzMDMxMzAzMTMxMzMzMTMxMzIzMDVhMzAzNzMxMTYzMDE0MDYwMzU1MDQwMzBjMGQ0MTZlNjQ3MjZmNjk2NDIwNDQ2NTYyNzU2NzMxMTAzMDBlMDYwMzU1MDQwYTBjMDc0MTZlNjQ3MjZmNjk2NDMxMGIzMDA5MDYwMzU1MDQwNjEzMDI1NTUzMzA4MjAxMjIzMDBkMDYwOTJhODY0ODg2ZjcwZDAxMDEwMTA1MDAwMzgyMDEwZjAwMzA4MjAxMGEwMjgyMDEwMTAwYTJjNmYyZGEzMTY4NmZhNzMwNTYyODE5NDYyOTFlYWE1M2U1ZTgzYmZkZTliNDgyMGMzNWNiY2ZlN2I2NGNlODhiYWViYjE5ZWNjMjM2YzI2MzczMWE1Mzg4NzJlZTU1MzQxNGYyOTY3ODAyM2JlNGIyYTlkY2QyMzkyMTUzNDY3OGEyOWEwOTkzNTljNDk1YzIwNjgxZjMzYTJmMzU5ZTEzNGY0OGM1N2I5Y2MzOTU0YjZlNzllYjMxMzM5MWMxYjZmYjgwYzM3ZjIyOGZmMjgyOTQxZjRkYTgwNDUwZDYwYzc3ZGRmOGFjYmNiYzA2OTY2MTVlNjRiMjA1YjYyMWRjMTcyMzMzZTBkZTQzOWYyMmI4YTE4M2MzYWMyMWFjZGEyNDcwODI0MjM5MDVkYTRjMjIzM2I2YzY4ODEyMGJjNDdkMWRiMGYwYTlhMGQzZjA3MTI4ZDAwNjE4NzE3OWRjOWY4OWE2YWRjZTY2YjkzNzgwZGQ5YmZlYzE2MjFjMWVjYzYwMzY0YzkzMGM0MDNhY2UyMjEzOTM2ZjQ1ZThlZWI0YjRmZmIxZWJkZDU5NjYxZjU4NmFjZWVmMGUzOWM1YWVkYzI3NDc1M2Q4ZTU3ZjJhZmJlOGRkMGVhYjJmMDA3N2NjOTQyNDc3MGY5ODdlMmQzYmExOTRhZjNlNjMwMjAzMDEwMDAxMzAwZDA2MDkyYTg2NDg4NmY3MGQwMTAxMDUwNTAwMDM4MjAxMDEwMDEzMzA2NjNmMWZjNjhiNjFmZTYwY2JiOWQ4NGZkNWViMjU0ZjliMDUxZmYzODY1ZTUxZjZiMjkzOTFlOGNiNWE4OGUyNjhmNmI5NTI3MTQ3YTIzZTM3YTg2N2JhYWFjMDczNjhjZjA1Mzg0MTI3MWJiOTFlNTE0M2FiMDIzY2ExZmZiY2RhOWYyMmQ2Y2NjZjI2YjQ4MjVkMTEyM2RiZmJkMDI4ZjFlOGViMDc4ZDEyYzkwMGQ3OWEyZmNmYTJiMTliZWY1YzU1ZmNlOTcwMGQ3Yjc1OWRhNThlN2U0OGQwOTJmMTRhZGFkODFjZGE4YTljYjM3NDY5NjFmNzk0NzY5NWU3ZjU3ZWE3Njk3MWUwOTNhMmI5NjdiMzJjZTY1OTE4ZTcxOWYyOWJhMDUxOGI2ZTdhMWFlYzAxZGY4ZDU0YjZiNzU5YmVmNTRkYjYxMjAxMjE3NTcyNmUxOTNmNmVkNTgyZjViYTA2MjMxYzQ5NDM5NmY5NDE3ODgwNWExNWIzM2RhZTg5ZmNiYjc4OTRhMzY0NzdlNjA3YWRmOWU2MGU1NzdjMDBiYzc4ZGQ5OTYyODY2MWU4NmNlZmQwZmQ1ZmRmMzc0Y2NkMjNmZmQwYzBkOTlkNzY1NTMzOGJmZGNjYTE4MTE5ZWYwOTI5ZWJmZTU1NTdmNTEyYTFiOTE4", Base64.DEFAULT)), String(Base64.decode("MzA4MjAyOTAzMDgyMDE3ODAyMDEwMTMwMGQwNjA5MmE4NjQ4ODZmNzBkMDEwMTA1MDUwMDMwMGUzMTBjMzAwYTA2MDM1NTA0MDMwYzAzNzg2NjZiMzAxZTE3MGQzMjMyMzAzNTMxMzEzMDMzMzEzOTMyMzU1YTE3MGQzNDM3MzAzNTMwMzUzMDMzMzEzOTMyMzU1YTMwMGUzMTBjMzAwYTA2MDM1NTA0MDMwYzAzNzg2NjZiMzA4MjAxMjIzMDBkMDYwOTJhODY0ODg2ZjcwZDAxMDEwMTA1MDAwMzgyMDEwZjAwMzA4MjAxMGEwMjgyMDEwMTAwODFmODY5MDljOTQ0YTIzMTNjMmQwZDNkNWM0NjhmN2FkYjk0M2IxMmZiZjUwMmEyNzgwNTQwZDgxODVhOTlmN2Y2NjJlMDA3ZjgwODExZDNiNWFlNzUxNGVkMjYyZDI5ZTMyMzFjYjNmMGFkNTAxZTFiZmEyNWMyOWE2OWE2ZjQ4YTQ1NWVlM2E4NzM5MDcyYzJmMzFkZWU5ZjA0ZTZlZDY1YTVlMDMwODEyYmI5NzE5OTczZTc3OTFmZTQ4MTk3ZWU4OWQ5NjVlMTE4MGRkOTNhZTcyM2EyNzIyNzg4MDgzZWU5MGIwMzNhMzA0MDBkNTI1NWUzMWZmZDJiNDI5MDhhZjE3NTc5M2UyZDk0ZjViODI0ZDY3OTBiZjVmNWQ2MDFlMTg3ODk1MWFlMGY5YmQ5OTJhMjc5MmIyMDcwYzIyYmRkNmNlNmY1ZWU5MmFhYzVmMDEzZjJiYzM2ZjIxMDllYzE1YzE3N2RlYzQwMmNhNmNkNjczZmU5NDUyN2E1OTNiOWE1NTM2ZmNkMjIyNTJmMDFkNmRlZWJmODk2M2U3NDBhMDZiYTNjZjVjM2U2MDRhODRhNjQxYWY1MzhkNjAxZDQ2NjVhNGJlMmJlMWRmYTAxZDc1Y2QyOTZiZjc2YzIwYWM2NTY4MTEyYzQ2NGRjY2Q4MDFlODJhZmM3NmQwMjAzMDEwMDAxMzAwZDA2MDkyYTg2NDg4NmY3MGQwMTAxMDUwNTAwMDM4MjAxMDEwMDUwN2Y1OWNiZDZkNmNmYWQ0OWIxOTZjZDAxY2UyYjA2NTk0ZGZmOTU3OWIyYTkwMWUxODk3YjdkNGMwNWRjYmM4ZWJjYmNhZjA2ZjNlMzViMWI5NTM0MDg2OGE5MTFiOTQ5NzBkYTYyNTE2YmYwN2Q0MmE4NDk1YjNmZDc5NThkNjc4MDMzMmJmYzA2NjM4NTQ5NWM1YmI0NDNmNDE2MzQ5MjdiZTFkMmJkYjMyYzU1ZmRkZmI0NTQ1MDE5OGUzZWU4OWE2MmM3NGI3NzIyYTk0ZjE3ZDZhMmVjZTI5YTI3MmQ1NTU3MmY1OGQ3MmZhNmU0ZDJjNjc3MmFjMTYxMDU4ZjBiZTQ5NWEzNGVmMzZmZjU2NTQ1YWIwMDM0YmJiYjgwY2QwNmY4NzZhNWUzOGExYjc0ZmEyYTYyNGIyNjA1MjUyZjI2NzMwZTAwNWE3YjkwN2ZkZTQ4NzkyZmRhODc5ZDdhMDI3NzY3ZWQyZWI5NzI5MjNkMjJlOGJhZTc5Mjg0OTFlODk5MWFiZDRhNmY1YmM3NmYzZWI3NTM2YmVjNzYzYjcwNmQzNmUwMjkwNDVmN2UyODkxOWU5MmZjN2M0NTk5YWIwOTU5MGQ5ZDM2YjU0MjE4NjZjYTk5MWRhN2E4NDRjOGZhYjZmZmQwOWM1ZDIyMTc5ZjhjODY0Y2Yz", Base64.DEFAULT)))) {
|
||||||
|
Toast.makeText(context, String(Base64.decode("UGxlYXNlIGRvIG5vdCBtb2RpZnkgdGhpcyBtb2R1bGUhISEgLyDor7fkuI3opoHkv67mlLnmraTmqKHlnZfvvIHvvIHvvIE=", Base64.DEFAULT)), Toast.LENGTH_LONG).show()
|
||||||
|
exitProcess(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -3,11 +3,13 @@ buildscript {
|
|||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
maven { url 'https://jitpack.io' }
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath "com.android.tools.build:gradle:7.0.4"
|
classpath "com.android.tools.build:gradle:7.2.0"
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21"
|
||||||
|
classpath "com.github.CodingGay:BlackObfuscator-ASPlugin:3.7"
|
||||||
|
classpath "icu.nullptr.stringfuck:gradle-plugin:0.1.4"
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
}
|
}
|
||||||
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
|||||||
#Fri Apr 29 17:30:47 CST 2022
|
#Sat May 14 18:02:35 CST 2022
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
Loading…
Reference in New Issue
Block a user