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

Retrieving struct definitions from PDB

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 struct values

Reven v2.11.0

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*,
}

Defining a struct manually

Reven v2.11.0

Creating a struct:

my_struct = Struct(
    StructKind.Struct, 10, "MyStruct", None,
    [
        RegularField("start", 0x0, Pointer(U16)),
        RegularField("value", 0x8, U16),
    ],
)

You can also create structs that contain forward mentions to yet-undefined structs (useful with recursive links for instance). In this case, you must use a TypeResolver:

type_resolver = TypeResolver()

struct_a_ty = Struct(
    StructKind.Struct, 10, "A", None,
    [
        RegularField("b", 0x0, Pointer(UnresolvedStruct(StructKind.Struct, "B", None))),
        RegularField("value", 0x8, U16),
    ],
    type_resolver,
)
type_resolver["A"] = struct_a_ty

struct_b_ty = Struct(
    StructKind.Struct, 10, "B", None,
    [
        RegularField("a", 0x0, Pointer(UnresolvedStruct(StructKind.Struct, "A", None))),
        RegularField("value", 0x8, U16),
    ],
    type_resolver,
)
type_resolver["B"] = struct_b_ty

Sample output of printing struct_a_ty:

struct A /* 0x8 */ {
    /* 0x0 */ b : B*,
    /* 0x8 */ value : 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]

Accessing the framebuffer memory to take a screenshot

Reven v2.12.0
image = ctx.framebuffer.image()

# save the screenshot as a png file
image.save("/tmp/framebuffer.png")

# display the screenshot in the default image viewer
image.show()

# display the screenshot in a Jupyter Notebook
display(image)

# access RGB values from a pixel as a tuple
image.getpixel((123, 42))