我想使用字节码插装来访问我添加到类中的整数数组字段。为此,我需要类文件中字段的索引,但找不到它。
更详细地解释,而不是(所需的是声明的局部整数,我从局部变量表中获取了该整数的索引):
desired = Server.rand.nextInt(4);
我想做:
desired = _MyField[Server.rand.nextInt(_MyField.length)];
在贾斯姆,这将是:
// field reference to later access an index in the array
aload <local variable index of "this"> (push reference of class)
getfield <fieldindex> (pop reference, push field reference to stack)
// rand is a public static field in class Server
getstatic java.util.Random com.wurmonline.server.Server.rand
// field reference to pass to arraylength and the Random.nextInt(int) call
aload <local variable index of "this">
getfield <fieldindex> (push reference of array)
arraylength (pop reference, push array.length value)
invokevirtual int java.util.Random.nextInt(int) (pop length for rng, push index)
iaload (pop index, push integer value from array index)
istore <index of local variable "desired"> (pop value, store in variable)
该字段是使用javassist添加的,如果sb是一个包含字段初始值设定项的stringbuilder(例如,“new int[]{n,n,n,n};”):
ctClass.addField(
new CtField(
HookManager.getInstance().getClassPool().get("[I"),
"_OtherServerMissions",
ctClass),
sb.toString());
查看使用dirtyjoe的类文件,dirtyjoe是一个字节码编辑器,适用于java8/主类文件版本52,我找不到字段的索引值。我似乎也找不到一个使用ctfield或适用的attributeinfo的。
for (CtField ctField : ctClass.getDeclaredFields())
所以我想知道从哪里得到fieldindex。
我希望这个解释对那些熟悉这件事的可怜的人来说足够清楚。
1条答案
按热度按时间csbfibhn1#
有时它真的有助于把问题写出来,向别人解释。
传递给getfield操作码的fieldindex是对类的常量池的引用。您必须将fieldrefinfo添加到类的常量池中。addfieldrefinfo()的返回值是它在常量池中的索引。
您还必须确定“this”的索引,以便在使用getfield之前将类示例的引用(如果适用)推送到堆栈上。
如果它已经不在局部变量表中,我不知道如何在此时添加它。或者如何准确地添加到局部变量表中。如果你知道的话,请随时发表评论(如果你有足够的代表点,嗯…)。
修复的问题现在包含正确的java汇编代码,这些代码与这里列出的值一起使用。