Optimize code
This commit is contained in:
parent
650e7542ed
commit
8f753de854
@ -1,6 +1,8 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'kotlin-android'
|
||||
id 'top.niunaijun.blackobfuscator'
|
||||
id 'icu.nullptr.stringfuck'
|
||||
}
|
||||
|
||||
android {
|
||||
@ -8,7 +10,7 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId "xfk233.genshinproxy"
|
||||
minSdk 27
|
||||
minSdk 28
|
||||
targetSdk 32
|
||||
versionCode 5
|
||||
versionName "1.5"
|
||||
@ -16,8 +18,9 @@ android {
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro', 'proguard-log.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
@ -29,10 +32,23 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
BlackObfuscator {
|
||||
enabled true
|
||||
depth 3
|
||||
obfClass = ["xfk233.genshinproxy"]
|
||||
}
|
||||
|
||||
stringFuck {
|
||||
setKey "xfk2333"
|
||||
obfuscationList ["xfk233.genshinproxy"]
|
||||
workOnDebug true
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//API
|
||||
compileOnly 'de.robv.android.xposed:api:82'
|
||||
//带源码Api
|
||||
compileOnly 'de.robv.android.xposed:api:82:sources'
|
||||
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
|
||||
# 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
|
||||
|
||||
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.IXposedHookZygoteInit
|
||||
import de.robv.android.xposed.XC_MethodHook
|
||||
import de.robv.android.xposed.XposedBridge
|
||||
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 {
|
||||
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 hook = Hook()
|
||||
|
||||
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()
|
||||
}
|
||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
||||
hook.handleLoadPackage(lpparam)
|
||||
}
|
||||
|
||||
override fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam) {
|
||||
modulePath = startupParam.modulePath
|
||||
moduleRes = XModuleResources.createInstance(modulePath, null)
|
||||
TrustMeAlready().initZygote(startupParam)
|
||||
hook.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.*;
|
||||
|
||||
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_METHOD_NAME = "checkTrustedRecursive";
|
||||
private static final Class<?> SSL_RETURN_TYPE = List.class;
|
||||
private static final Class<?> SSL_RETURN_PARAM_TYPE = X509Certificate.class;
|
||||
|
||||
@Override
|
||||
public void initZygote(StartupParam startupParam) throws Throwable {
|
||||
public void initZygote() {
|
||||
XposedBridge.log("TrustMeAlready loading...");
|
||||
int hookedMethods = 0;
|
||||
|
||||
|
@ -1,6 +1,10 @@
|
||||
package xfk233.genshinproxy
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.util.Base64
|
||||
import android.widget.Toast
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
object Utils {
|
||||
var isInit = false
|
||||
@ -9,4 +13,14 @@ object Utils {
|
||||
val scale: Float = context.resources.displayMetrics.density
|
||||
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 {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
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 "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
|
||||
// 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
|
||||
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
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
Loading…
Reference in New Issue
Block a user