Skip to content

Commit

Permalink
Remove arguments with "javaagent" from RuntimeMXBean#getInputArguments
Browse files Browse the repository at this point in the history
  • Loading branch information
Candicey authored and Candicey committed Jan 3, 2024
1 parent b40f2ae commit a6da9ec
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 3 deletions.
3 changes: 2 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ val agent by tasks.registering(Jar::class) {
}

manifest.attributes(
"Premain-Class" to "net.weavemc.loader.bootstrap.AgentKt"
"Premain-Class" to "net.weavemc.loader.bootstrap.AgentKt",
"Can-Retransform-Classes" to "true",
)
}

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ kotlin.code.style = official
# Project properties
projectName = Weave-Loader
projectGroup = net.weavemc
projectVersion = 0.2.4
projectVersion = 0.2.5
70 changes: 69 additions & 1 deletion src/main/kotlin/net/weavemc/loader/bootstrap/Agent.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
package net.weavemc.loader.bootstrap

import java.lang.instrument.Instrumentation
import net.weavemc.loader.WeaveLoader
import net.weavemc.loader.api.util.asm
import org.objectweb.asm.ClassReader
import org.objectweb.asm.ClassWriter
import org.objectweb.asm.Opcodes
import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.LabelNode
import java.lang.instrument.ClassFileTransformer
import java.lang.instrument.Instrumentation
import java.security.ProtectionDomain

/**
* The JavaAgent's `premain()` method, this is where initialization of Weave Loader begins.
Expand All @@ -15,6 +23,66 @@ public fun premain(opt: String?, inst: Instrumentation) {
return
}

inst.addTransformer(object : ClassFileTransformer /*SafeTransformer*/ {
override fun transform(
loader: ClassLoader?,
className: String,
classBeingRedefined: Class<*>?,
protectionDomain: ProtectionDomain?,
classfileBuffer: ByteArray
): ByteArray? {
if (className != "sun/management/RuntimeImpl" || classBeingRedefined == null) return null
inst.removeTransformer(this)

val node = ClassNode().also { ClassReader(classfileBuffer).accept(it, 0) }
val writer = ClassWriter(ClassWriter.COMPUTE_FRAMES)

with(node.methods.first { it.name == "getInputArguments" }) {
val insn = instructions.first { it.opcode == Opcodes.ARETURN }
instructions.insertBefore(insn, asm {
invokeinterface("java/lang/Iterable", "iterator", "()Ljava/util/Iterator;")
astore(2)
new("java/util/ArrayList")
dup
invokespecial("java/util/ArrayList", "<init>", "()V")
astore(3)

val loop = LabelNode()
val end = LabelNode()

+loop
aload(2)
invokeinterface("java/util/Iterator", "hasNext", "()Z")
ifeq(end)

aload(2)
invokeinterface("java/util/Iterator", "next", "()Ljava/lang/Object;")
checkcast("java/lang/String")
dup
astore(4)
ldc("javaagent")
invokevirtual("java/lang/String", "contains", "(Ljava/lang/CharSequence;)Z")
ifne(loop)

aload(3)
aload(4)
invokeinterface("java/util/List", "add", "(Ljava/lang/Object;)Z")
pop

goto(loop)
+end

aload(3)
})
}

node.accept(writer)

return writer.toByteArray()
}
}, true)
inst.retransformClasses(Class.forName("sun.management.RuntimeImpl", false, ClassLoader.getSystemClassLoader()))

inst.addTransformer(object : SafeTransformer {
override fun transform(loader: ClassLoader, className: String, originalClass: ByteArray): ByteArray? {
// net/minecraft/ false flags on launchwrapper which gets loaded earlier
Expand Down

0 comments on commit a6da9ec

Please sign in to comment.