Address types

joeq uses special types to represent raw addresses. The three types of addresses are:

All three are subclasses of a single type, Address.

You can obtain addresses via static methods in the above classes.

Furthermore, you can get addresses from other addresses. The "offset(int)" method returns a new address that is an offset from the given address. The "peek()" method dereferences the given address; that is, it returns the address that the given address points to. There are other methods in Address for peeking of other data types, finding the difference between two addresses, etc.

IMPORTANT POINT: Note that although the Address types are thought of as subclasses of java.lang.Object by the Java source compiler, they are NOT objects, and cannot be used as such. Therefore, it is illegal to call any of the java.lang.Object methods, such as equals, toString, hashCode, etc. on Address types. Less obviously, it is illegal to perform "instanceof" operations on them, or even pass them as "Objects" under any circumstances.

Operation Corresponding Address method
void* a = *p; Address a = p.peek();
byte b = *p; byte b = p.peek1();
short s = *p; short s = p.peek2();
int i = *p; int i = p.peek4();
long l = *p; long l = p.peek8();
*p1 = p2; p1.poke(p2);
*p = b; p.poke1(b);
*p = s; p.poke2(s);
*p = i; p.poke4(i);
*p = l; p.poke8(l);
p + c p.offset(c);
int i = p1 - p2; int i = p1.difference(p2);
p.toString(); p.stringRep();

"Unsafe" class

The Unsafe class has a very simple low level API consisting of a few essential operations:

  • floatToIntBits, intBitsToFloat, doubleToLongBits, longBitsToDouble - change data representations
  • EAX, get/setThreadBlock, switch register state - read/write the CPU register state
  • pushArg, invoke - push arguments and call an address in memory

Methods in the Unsafe class are implemented as native methods, which the compiler silently replaces with the corresponding low-level operations.