Здравствуйте. У меня есть тестовый игрок с позицией
static class Entity {
protected Position pos = new Position(0.0, 0.0, 0.0);
}
static class Player extends Entity {
private final UUID uuid;
private final String name;
public Player(UUID uuid, String name) {
this.uuid = uuid;
this.name = name;
}
}
static class Position {
private double x;
private double y;
private double z;
public Position(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
}
Путем отладки, я выяснил адрес игрока (пусть будет 0x621830180)
Затем при помощи следующего сооружения я высчитал оффсет в классе игрока до позиции:
public static long calculateFieldOffset(Class<?> clazz, String fieldName) throws Exception {
Unsafe unsafe = getUnsafe();
while (clazz != null) {
try {
Field field = clazz.getDeclaredField(fieldName);
return unsafe.objectFieldOffset(field);
} catch (NoSuchFieldException e) {
clazz = clazz.getSuperclass();
}
}
throw new NoSuchFieldException("Поле " + fieldName + " не найдено в классе " + clazz.getName());
}
Допустим, что до поля с позицией оффсет 12.
Я предположил, что по player_address + 12 (0x621830180 + 12 = 0x62183018C
) должен быть актуальный указатель на мой объект позиции, но нахожу я там что-то вроде
BF 99 5E C4 E4 96 5E C4 E8 96 5E C4 01 00 00 00 00 00 00 00 F0 E9 00 00 00 00 00 00 00 00 00 00 8A 12 5B C4 01 00 00 00 00 00 00 00 38 67
Что не похоже на указатель.
Как объекты внутри jvm по своим полям находят данные? Может тут есть какая-то мета, из-за которой я путаюсь?
Объект позиции в итоге находится на 0x6218df4f8, как этот адрес получить?
Зачем это все?
Просто хочу разобраться, как работает. А вообще стало интересно, как внешне влиять на java приложение без использования jni и подобного. GC производит много манипуляций с памятью, из-за чего искать актуальные адреса каждый раз по сигнатурам затруднительно.