英文:
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
- 不必直接调用
BigInteger
构造函数,使用反射调用它:Class.forName("java.math.BigInteger").newInstance(n)
* - 现在将该字符串文字应用您选择的编码。Base64 应该可以。将编码后的字符串保存为常量。
- 在运行时,解码字符串并将其传递给
Class.forName
。
* newInstance
有可变参数选项吗?如果没有,可以使用 getConstructors
替代,并调用正确的构造函数。
英文:
Sure, since we're hacking anyway, this should be fun:
- Instead of calling the
BigInteger
constructor directly, call it using reflection:Class.forName("java.math.BigInteger").newInstance(n)
* - Now take that String literal, and apply an encoding of your choice. Base64 should do. Save the encoded string as a constant.
- 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论