Skip to content

Commit

Permalink
Spoof app version dynamically
Browse files Browse the repository at this point in the history
* As suggested in ElJaviLuki/GrindrPlus#55
  • Loading branch information
R0rt1z2 committed Dec 16, 2023
1 parent b7fefd6 commit ba81d86
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 3 deletions.
3 changes: 3 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,7 @@ dependencies {

//AndroidX Core
implementation 'androidx.core:core-ktx:1.8.0'

// OkHttp
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
}
1 change: 1 addition & 0 deletions app/src/main/java/com/grindrplus/Hooker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class Hooker : IXposedHookLoadPackage {
pkgParam = lpparam

try {
Logger.xLog("About to hook App Updates")
Hooks.hookAppUpdates()
} catch (e: Exception) {
e.message?.let { Logger.xLog(it) }
Expand Down
47 changes: 44 additions & 3 deletions app/src/main/java/com/grindrplus/Hooks.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ import de.robv.android.xposed.XC_MethodHook
import de.robv.android.xposed.XC_MethodReplacement
import de.robv.android.xposed.XposedBridge
import de.robv.android.xposed.XposedHelpers.*
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Call
import okhttp3.Callback
import okhttp3.Response
import java.io.IOException
import java.io.File
import java.lang.reflect.Proxy
import java.util.*
Expand Down Expand Up @@ -1066,6 +1072,41 @@ object Hooks {
* and spoof the app version. Inspired by @Tebbe's idea.
*/
fun hookAppUpdates() {
val client = OkHttpClient()
val request = Request.Builder()
.url("https://apkpure.com/grindr-gay-chat-for-android/com.grindrapp.android/download")
.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0")
.build()

client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
Logger.xLog("Fetch failed: ${e.message}")
}

override fun onResponse(call: Call, response: Response) {
response.use {
if (!response.isSuccessful)
return Logger.xLog("Received unexpected response code: ${response.code}")

val responseBody = response.body?.string() ?:
return Logger.xLog("Unable to get body from response!")
val versionName = """"versionName":"(.*?)",""".toRegex()
.find(responseBody)?.groups?.get(1)?.value
val versionCode = """"versionCode":(\d+),""".toRegex()
.find(responseBody)?.groups?.get(1)?.value

// If both are valid, spoof the app version to prevent the update dialog
// from showing up. This should be enough to disable forced updates.
if (versionName != null && versionCode != null) {
hookUpdateInfo(versionName, versionCode.toInt())
}
}
}
})
}

fun hookUpdateInfo(versionName: String, versionCode: Int) {
Logger.xLog("Hooking update info with version $versionName ($versionCode)")
findAndHookMethod(
"com.google.android.play.core.appupdate.AppUpdateInfo",
Hooker.pkgParam.classLoader,
Expand All @@ -1084,9 +1125,9 @@ object Hooks {
findClass("com.grindrapp.android.base.config.AppConfiguration.a", Hooker.pkgParam.classLoader),
object : XC_MethodHook() {
override fun afterHookedMethod(param: MethodHookParam) {
setObjectField(param.thisObject, "a", "9.17.4")
setObjectField(param.thisObject, "b", 118992)
setObjectField(param.thisObject, "u", "9.17.4.118992")
setObjectField(param.thisObject, "a", versionName)
setObjectField(param.thisObject, "b", versionCode)
setObjectField(param.thisObject, "u", "$versionName.$versionCode")
}
}
)
Expand Down

0 comments on commit ba81d86

Please sign in to comment.