我有以下java代码:
class Father {
public void walk(int x) { System.out.format("Fwalk %d", x); }
public void run (int x) { System.out.format("Frun %d", x); }
public void swim(int x) { System.out.format("Fswim %d", x); }
}
class Son extends Father {
public void swim(int x) { System.out.format("Fswim %d", x); }
public void cook(int x) { System.out.format("Scook %d", x); }
public void run (int x) { System.out.format("Frun %d", x); }
}
class main {
public static void main(String[] args) {
Father f = new Father();
f.run(1);
f.swim(2);
Son s = new Son();
s.run(3);
s.swim(4);
}
}
我正在寻找虚函数表的实际偏移量。当我使用等效的 C++ 代码时,我可以使用objdump轻松做到这一点:swim
run
663 f->run(1);
664 8c3: 48 8b 45 e0 mov -0x20(%rbp),%rax
665 8c7: 48 8b 00 mov (%rax),%rax
666 8ca: 48 83 c0 08 add $0x8,%rax <------ offset 8 for father::run
继承类的相同偏移量:
689 s->run(3);
690 914: 48 8b 45 e8 mov -0x18(%rbp),%rax
691 918: 48 8b 00 mov (%rax),%rax
692 91b: 48 83 c0 08 add $0x8,%rax <------ offset 8 for son::run
当我使用Apache 的类实用程序时,我得到了一些接近的东西(池常量)
1)CONSTANT_Methodref[10](class_index = 11, name_and_type_index = 20)
2)CONSTANT_Class[7](name_index = 21)
3)CONSTANT_Methodref[10](class_index = 2, name_and_type_index = 20)
4)CONSTANT_Methodref[10](class_index = 2, name_and_type_index = 22)
5)CONSTANT_Methodref[10](class_index = 2, name_and_type_index = 23)
6)CONSTANT_Class[7](name_index = 24)
7)CONSTANT_Methodref[10](class_index = 6, name_and_type_index = 20)
8)CONSTANT_Methodref[10](class_index = 6, name_and_type_index = 22)
9)CONSTANT_Methodref[10](class_index = 6, name_and_type_index = 23)
10)CONSTANT_Class[7](name_index = 16)
11)CONSTANT_Class[7](name_index = 25)
12)CONSTANT_Utf8[1]("<init>")
13)CONSTANT_Utf8[1]("()V")
14)CONSTANT_Utf8[1]("Code")
15)CONSTANT_Utf8[1]("LineNumberTable")
16)CONSTANT_Utf8[1]("main")
17)CONSTANT_Utf8[1]("([Ljava/lang/String;)V")
18)CONSTANT_Utf8[1]("SourceFile")
19)CONSTANT_Utf8[1]("main.java")
20)CONSTANT_NameAndType[12](name_index = 12, signature_index = 13)
21)CONSTANT_Utf8[1]("Father")
22)CONSTANT_NameAndType[12](name_index = 26, signature_index = 27)
23)CONSTANT_NameAndType[12](name_index = 28, signature_index = 27)
24)CONSTANT_Utf8[1]("Son")
25)CONSTANT_Utf8[1]("java/lang/Object")
26)CONSTANT_Utf8[1]("run")
27)CONSTANT_Utf8[1]("(I)V")
28)CONSTANT_Utf8[1]("swim")
似乎虚函数表的条目是基于名称的(“run”、“swim”)。真的是这样吗?为了完成,这里是提取常量池的 Java 脚本。
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.ConstantPool;
class test
{
public static void main(String[] args)
{
try
{
ClassParser c = new ClassParser(args[0]);
JavaClass j = c.parse();
ConstantPool cp = j.getConstantPool();
System.out.format(cp.toString());
}
catch (Exception e) { return; }
}
}