Skip to content

Commit

Permalink
弄了些和Test有关的事宜
Browse files Browse the repository at this point in the history
  • Loading branch information
EarzuChan committed Aug 26, 2024
1 parent 5334ed7 commit 5dd5c58
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 59 deletions.
8 changes: 7 additions & 1 deletion api/src/main/codes/Api.kt
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,11 @@ class HookConfig {
}

class HookContext(val args: Array<Any?>, val instance: Any) {
var result: Any? = null
var result: Any?
get() {
throw UnsupportedOperationException("Cannot get result in before hook")
}
set(value) {
throw UnsupportedOperationException("Cannot set result in before hook")
}
}
60 changes: 27 additions & 33 deletions loader/src/main/codes/Loader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,50 +13,44 @@ const val TAG = "SakikoLoader"
object LoaderEntry {
@JvmStatic
fun premain(agentArgs: String?, inst: Instrumentation) {
Log.info(TAG, "Loader Entry")
Log.info(TAG, "Loader Enter")

agentArgs?.let { arg ->
Log.info(TAG, "Agent Args: $arg")
Log.info(TAG, "Given Args: $arg")

// 按','分割参数
val jarPaths = arg.split(',')

val moduleClasses = mutableListOf<Class<out SakikoModule>>()

jarPaths.forEach {
File(it).let { file ->
if (file.exists()) {
Log.info(TAG, "Checking Jar: ${file.name}")

JarFile(file).use { jar ->
val entries = jar.entries()
while (entries.hasMoreElements()) {
val entry = entries.nextElement()
if (entry.name.endsWith(".class")) {
val classBytes = jar.getInputStream(entry).readBytes()
val className = entry.name.removeSuffix(".class").replace('/', '.')
val clazz = loadClassFromBytes(classBytes, className)

if (clazz != null && clazz.annotations.any { it.annotationClass == ExposedSakikoModule::class }
&& SakikoModule::class.java.isAssignableFrom(clazz)) {
Log.info(TAG, "Found Module Class: $className")

moduleClasses.add(clazz as Class<out SakikoModule>)
}
}
}
}
}
}
}
val moduleClasses = jarPaths.mapNotNull { processJarFile(it) }.flatten()

moduleClasses.forEach {
Log.info(TAG, "Loading Module: ${it.name}")
Runner.loadModule(it)
}
}
}

// 使用隔离的ClassLoader加载类
private fun processJarFile(jarPath: String): List<Class<out SakikoModule>>? {
val file = File(jarPath)
if (!file.exists()) {
Log.warn(TAG, "Jar file does not exist: $jarPath")
return null
}

Log.info(TAG, "Checking Jar: ${file.name}")
return JarFile(file).use { jar ->
jar.entries().asSequence().filter { it.name.endsWith(".class") }.mapNotNull { entry ->
val classBytes = jar.getInputStream(entry).readBytes()
val className = entry.name.removeSuffix(".class").replace('/', '.')
loadClassFromBytes(classBytes, className)
}.filter { clazz ->
clazz.annotations.any { it.annotationClass == ExposedSakikoModule::class }
&& SakikoModule::class.java.isAssignableFrom(clazz)
}.map {
Log.info(TAG, "Module Class Found: ${it.name}")
it as Class<out SakikoModule>
}.toList()
}
}

private fun loadClassFromBytes(classBytes: ByteArray, className: String): Class<*>? {
return try {
val classLoader = object : ClassLoader() {
Expand Down
5 changes: 3 additions & 2 deletions test/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
dependencies {
api(project(":api"))
implementation("org.junit.jupiter:junit-jupiter:5.8.1")
}

sourceSets {
Expand All @@ -10,7 +11,7 @@ sourceSets {
}
test {
kotlin {
srcDirs("src/test/codes")
srcDirs("src/test-module/codes")
}
}
}
Expand All @@ -26,7 +27,7 @@ tasks.register<JavaExec>("runTest") {
// dependsOn(":buildNativeOnMyPc")

classpath = sourceSets.main.get().runtimeClasspath
mainClass.set("me.earzuchan.sakiko.test.Main")
mainClass.set("me.earzuchan.sakiko.test.TestMain")

doFirst {
val agentJar = project(":loader").tasks.named<Jar>("agentJar").get().archiveFile.get().asFile
Expand Down
19 changes: 0 additions & 19 deletions test/src/main/codes/Main.kt

This file was deleted.

33 changes: 33 additions & 0 deletions test/src/main/codes/TestMain.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package me.earzuchan.sakiko.test

import me.earzuchan.sakiko.api.reflecting.method
import me.earzuchan.sakiko.api.utils.Log
import org.junit.jupiter.api.Assertions.assertEquals

const val TAG = "SakikoTestMain"

object TestMain {
@JvmStatic
fun main(args: Array<String>) {
Log.info(TAG, "Hello Sakiko, Let's rock!")

val testMethodClass = MethodsForTest::class.java

Log.info(TAG, "First")
assertEquals("kobe man", MethodsForTest.method1("man"))
testMethodClass.method {
name = "method1"
}.hook {
before {
result = "mamba"
}
}
}
}

object MethodsForTest {
@JvmStatic
fun method1(man: String): String {
return "kobe $man"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ class TestModule(moduleContext: ModuleContext) : SakikoModule(moduleContext) {
override fun onHook() {
Log.info("TestModule", "onHook")

"me.earzuchan.sakiko.test.Main".toClass().method {
name = "test"
param(StringClass)
"me.earzuchan.sakiko.test.MethodsForTest".toClass().method {
name = "method1"
}.hook {
before {
println("Before hook")
Expand All @@ -24,4 +23,4 @@ class TestModule(moduleContext: ModuleContext) : SakikoModule(moduleContext) {
}
}
}
}
}

0 comments on commit 5dd5c58

Please sign in to comment.