使用ByteBuddy反射来绕过文件字符串检查。

huangapple go评论79阅读模式
英文:

Using bytebuddy reflection to bypass file string check

问题

以下是您要翻译的部分:

有一个问题涉及到 Codewars
https://www.codewars.com/kata/58a3fa665973c2a6e80000c4/train/java

我们只需对一个非常大的数开平方。当然,我们都会考虑使用 BigInteger.sqrt,但挑战本身拒绝使用这些词语:reflection、biginteger、bigdecimal、runtime、process、script。另外不能使用 Unicode。

更新:还阻止了 "newInstance" 和 "invoke"。

嗯,在按照任务的初衷去做没有乐趣,所以我目前正在尝试通过使用 bytebuddy 来绕过这个问题(幸运的是它们不会拒绝这个)。

这段代码的作用是强制 text() 方法返回拦截的内容。

这个解决方案本身可以解决问题,但正如您所看到的,拦截中仍然包含 "BigInteger"。

我对 bytebuddy 不太熟悉,所以有没有办法使用 bytebuddy 反射来解决这个问题,也许可以将拦截中的 BigInteger 更改为字符串(这样我就可以使用字符数组)来解决这个问题。

或者甚至使用 Nashorn 引擎来访问一些 JavaScript API。

请随时分享您的想法。

英文:

There's this problem in Codewars
https://www.codewars.com/kata/58a3fa665973c2a6e80000c4/train/java

We will have to just square root a very big number. Of course all of us would think about BigInteger.sqrt - but the challenge itself reject these words: reflection, biginteger, bigdecimal, runtime, process, script. (P/s you can't use unicode either).

Update: also blocked "newInstance", "invoke"

Well there's no fun in doing what intended for the task, so I currently trying to bypass this by using bytebuddy (luckily they don't reject this).

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.dynamic.DynamicType.Loaded;
import net.bytebuddy.dynamic.loading.ClassReloadingStrategy;
import net.bytebuddy.implementation.FixedValue;
import net.bytebuddy.matcher.ElementMatchers;

public class Kata {	
  public static String integerSquareRoot(String n) {
    ByteBuddyAgent.install();
		Loaded<Kata> dynamicType = new ByteBuddy().redefine(Kata.class).method(ElementMatchers.named("text"))
				.intercept(FixedValue.value(new java.math.BigInteger(n).sqrt().toString())).make()
				.load(Thread.currentThread().getContextClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
    return Kata.text("forsenCD");
	}
  
  public static String text(String n){
    return n;
  }
}

What it does here is to force the text() method to return what's in the intercept

This solution itself solve the task, but as you can see, it still have "BigInteger" in the intercept.

I'm noob at bytebuddy, so anyone have a way to solve this using bytebuddy reflection, that maybe can change the BigInteger in the intercept with a string (so I can use character array) to solve this.

Or maybe even using Nashorn engine to get to some JavaScript API.

Please feel free to share your thought.

答案1

得分: 1

  1. 不必直接调用 BigInteger 构造函数,使用反射调用它:Class.forName("java.math.BigInteger").newInstance(n) *
  2. 现在将该字符串文字应用您选择的编码。Base64 应该可以。将编码后的字符串保存为常量。
  3. 在运行时,解码字符串并将其传递给 Class.forName

* newInstance 有可变参数选项吗?如果没有,可以使用 getConstructors 替代,并调用正确的构造函数。

英文:

Sure, since we're hacking anyway, this should be fun:

  1. Instead of calling the BigInteger constructor directly, call it using reflection: Class.forName("java.math.BigInteger").newInstance(n) *
  2. Now take that String literal, and apply an encoding of your choice. Base64 should do. Save the encoded string as a constant.
  3. At runtime, decode the String and pass it to Class.forName.

* Does newInstance have a varargs option? If not, use getConstructors instead and call the right one.

huangapple
  • 本文由 发表于 2023年7月27日 19:08:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76779141.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定