Reading values or structs from registers or memory

REVEN v2.2.0

Common imports for easy access

from reven2.address import LinearAddress, LogicalAddress, LogicalAddressSegmentIndex, PhysicalAddress
from reven2.arch import x64 as regs
from reven2.types import *

Getting the current ring

def current_ring(ctx):
    return ctx.read(regs.cs) & 3

Reading as a type

Integer types

ctx.read(regs.rax, U8)
ctx.read(regs.rax, U16)
ctx.read(regs.rax, I16)
ctx.read(regs.rax, BigEndian(U16))

Sample output:

96
35680
-29856
24715

String

ctx.read(LogicalAddress(0xffffe00041cac2ea), CString(encoding=Encoding.Utf16,
                                                     max_character_count=1000))

Sample output:

u'Network Store Interface Service'

Array

list(ctx.read(LogicalAddress(0xffffe00041cac2ea), Array(U8, 4)))

Sample output:

[78, 0, 101, 0]

Dereferencing pointers, reading the stack

Reading [rsp+0x20] manually:

addr = LogicalAddress(0x20) + ctx.read(regs.rsp, USize)
ctx.read(addr, U64)

Reading [rsp+0x20] using deref:

ctx.deref(regs.rsp, Pointer(U64, base_address=LogicalAddress(0x20)))

Sample output:

10738

Reading struct values

REVEN v2.11.0
OS Windows 64-bit
OS Windows 32-bit

Getting a struct type from a binary:

object_attributes_ty = next(server.ossi.executed_binaries("ntoskrnl")).exact_type("_OBJECT_ATTRIBUTES")

Sample output of printing object_attributes_ty:

StructKind.Struct _OBJECT_ATTRIBUTES /* 0x30 */ {
    /* 0x0 */ Length : U32,
    /* 0x8 */ RootDirectory : void*,
    /* 0x10 */ ObjectName : _UNICODE_STRING*,
    /* 0x18 */ Attributes : U32,
    /* 0x20 */ SecurityDescriptor : void*,
    /* 0x28 */ SecurityQualityOfService : void*,
}

Reading a struct instance from a source (register, memory, etc):

# Reading structure from pointer stored in r8
object_attributes = ctx.read(reven2.address.LogicalAddress(0xffffe00041cac2ea), object_attributes_ty)

# Read one field according to declared type
object_attributes.field("Length").read()

Sample output:

48

You can also:

# Read one field, forcing its type to int-like. Useful for IDE type hints
object_attributes.field("Attributes").read_int()

# Get whole struct content as bytes
object_attributes.as_bytes()

# Dereferences a pointer-like field, read it as an inner struct, display its type
print(object_attributes.field("ObjectName").deref_struct().type)

Sample output:

0
b'0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\xd1]\x06\x00\x00\x00\x00B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
StructKind.Struct _UNICODE_STRING /* 0x10 */ {
    /* 0x0 */ Length : U16,
    /* 0x2 */ MaximumLength : U16,
    /* 0x8 */ Buffer : U16*,
}

Parsing a raw buffer as a type

U16.parse(b"\x10\x20")
BigEndian(U16).parse(b"\x10\x20")
Array(U8, 2).parse(b"\x10\x20")

Sample output:

8208
4128
[16, 32]