2

我刚刚写了一些访问内存的代码。我用 CheatEngine 检查了地址(在代码中),然后用 打印了它System.out,它是不同的。我知道这是一个长值,但在十六进制中,值 2 是 00000002(这是 CheatEngine 中的结果),我用 java 得到 844287491178496。这是为什么?如何将值从地址转换为int?更重要的是,我刚刚用 java 从内存中读取的 long 值是多少?这是我的代码:

import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class Memory2 {
    public static void main(String args[]){
        Unsafe unsafe = getUnsafe();
        long address = 0x002005C;
    unsafe.getAddress(address);
    System.out.println(unsafe.getAddress(address));
}

public static Unsafe getUnsafe() {
try {
        Field f = Unsafe.class.getDeclaredField("theUnsafe");
            f.setAccessible(true);
        return (Unsafe)f.get(null);
    } catch (Exception e) {}
        return null;
}
}
4

2 回答 2

3

java中的long是8个字节,不是dword;您来自 CheatEngine 的值似乎是四个字节。我认为差异可能仅此而已。0000000200000000 十六进制是 8589934592;您使用 CheatEngine 检查的四个字节之外的字节可能解释了 Java 显示的值。

于 2012-12-04T19:34:29.117 回答
1

来自sun.misc.Unsafe的来源

/**
 * Fetches a native pointer from a given memory address.  If the address is
 * zero, or does not point into a block obtained from {@link
 * #allocateMemory}, the results are undefined.
 *
 * <p> If the native pointer is less than 64 bits wide, it is extended as
 * an unsigned number to a Java long.  The pointer may be indexed by any
 * given byte offset, simply by adding that offset (as a simple integer) to
 * the long representing the pointer.  The number of bytes actually read
 * from the target address maybe determined by consulting {@link
 * #addressSize}.
 *
 * @see #allocateMemory
 */
 public native long getAddress(long address);

简而言之,它将在 32 位 JVM 上读取 32 位(作为无符号值),在 64 位 JVM 上读取 64 位。

注意:大多数 64 位 JVM 将使用 32 位引用来表示典型的堆大小。

于 2012-12-05T09:46:26.503 回答