Skip to content

Commit cadfee7

Browse files
committed
ClassHunter
1 parent 19e57e9 commit cadfee7

File tree

7 files changed

+129
-0
lines changed

7 files changed

+129
-0
lines changed

ClassHunter/Readme.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# ClassHunter
2+
3+
Hunts for a Class.
4+
Chose which class you want to hunt for in `build.gradle.kts`:
5+
```kotlin
6+
buildConfigField("String", "targetClass", """"com.example.MyClass"""")
7+
```

ClassHunter/build.gradle.kts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
plugins {
2+
id("com.android.application")
3+
kotlin("android")
4+
}
5+
6+
android {
7+
namespace = "de.binarynoise.ClassHunter"
8+
9+
defaultConfig {
10+
minSdk = 26
11+
targetSdk = 33
12+
13+
buildConfigField("String", "targetClass", """"..."""")
14+
}
15+
16+
buildFeatures {
17+
buildConfig = true
18+
}
19+
}
20+
21+
dependencies {
22+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest
3+
xmlns:android="http://schemas.android.com/apk/res/android">
4+
5+
<application android:label="ClassHunter">
6+
<meta-data
7+
android:name="xposedmodule"
8+
android:value="true"
9+
/>
10+
<meta-data
11+
android:name="xposeddescription"
12+
android:value="Hunts for a Class"
13+
/>
14+
<meta-data
15+
android:name="xposedminversion"
16+
android:value="53"
17+
/>
18+
<meta-data
19+
android:name="xposedscope"
20+
android:resource="@array/scope"
21+
/>
22+
</application>
23+
24+
</manifest>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
de.binarynoise.ClassHunter.Hook
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package de.binarynoise.ClassHunter
2+
3+
import android.annotation.SuppressLint
4+
import android.util.Log
5+
import de.robv.android.xposed.IXposedHookLoadPackage
6+
import de.robv.android.xposed.callbacks.XC_LoadPackage
7+
8+
const val TAG = "Hook"
9+
10+
@SuppressLint("PrivateApi", "MissingPermission")
11+
class Hook : IXposedHookLoadPackage {
12+
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
13+
Log.i(TAG, "*".repeat(50))
14+
Log.i(TAG, "loading package: ${lpparam.packageName}")
15+
Log.i(TAG, "hunting for ${BuildConfig.targetClass}")
16+
17+
val classLoaders = mutableSetOf<ClassLoader>()
18+
19+
val packageClassLoader: ClassLoader = lpparam.classLoader
20+
collectParents(packageClassLoader, "packageClassLoader", classLoaders)
21+
22+
val moduleClassLoader: ClassLoader = this::class.java.classLoader!!
23+
collectParents(moduleClassLoader, "moduleClassLoader", classLoaders)
24+
25+
val systemClassLoader: ClassLoader = ClassLoader.getSystemClassLoader()
26+
collectParents(systemClassLoader, "systemClassLoader", classLoaders)
27+
28+
val bootClassLoader = classLoaders.find { it.javaClass.simpleName == "BootClassLoader" }!!
29+
collectParents(bootClassLoader, "bootClassLoader", classLoaders)
30+
31+
Log.i(TAG, "currently known classloaders:")
32+
classLoaders.forEach {
33+
Log.d(TAG, "${it.toObjectString()}" + " - " + it.toString())
34+
35+
try {
36+
val cls = Class.forName(BuildConfig.targetClass, false, it)
37+
Log.w(TAG, " - found class: ${cls.name}")
38+
39+
Log.i(TAG, " - methods:")
40+
cls.declaredMethods.forEach {
41+
Log.d(TAG, " - ${it.returnType.name} ${it.name}(${it.parameters.joinToString(", ") { it.name + " " + it.type.name }})")
42+
}
43+
44+
Log.i(TAG, " - fields:")
45+
cls.declaredFields.forEach {
46+
Log.d(TAG, " - ${it.type.name} ${it.name}")
47+
}
48+
} catch (_: Throwable) {
49+
50+
}
51+
}
52+
}
53+
54+
private fun collectParents(classLoader: ClassLoader, name: String, classLoaders: MutableSet<ClassLoader>) {
55+
generateSequence(classLoader) { it.parent }.forEach {
56+
Log.d(TAG, name + " - ${it.toObjectString()}")
57+
classLoaders.add(it)
58+
}
59+
}
60+
}
61+
62+
fun Any?.toObjectString(): String {
63+
if (this == null) return "null"
64+
return this::class.simpleName + "@" + Integer.toHexString(hashCode())
65+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<string-array name="scope">
4+
<item>android</item>
5+
<item>system</item>
6+
<item>com.android.systemui</item>
7+
<item>android.ext.services</item>
8+
</string-array>
9+
</resources>

settings.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ include(":AntiBrightnessChange")
2222
include(":AutomaticAdvancedSettingsExpander")
2323
include(":BetterVerboseWiFiLogging")
2424
include(":BetterBluetoothDeviceSort")
25+
include(":ClassHunter")
2526
include(":DontResetIfBootedAndConnected")
2627
include(":FreeNotifications")
2728
include(":MotionEventMod")

0 commit comments

Comments
 (0)