Skip to content

got ¤

Global Offset Table Tracker

Subsystem for tracking accesses to external function calls made through pointers in an inferior's Global Offset Table, such as those made by the stubs in the Procedure Linkage Table.

Currently, it does this by attatching watchpoints to the entries in the GOT and taking note of where the call came from, but it could be done much faster by injecting our own code into the program space to track this.

Classes:

  • RelocTypes

    This class contains all the relocation type constants so that one may

  • TrapAllocator

    Utility that allocates and manages executable addresses in the space of the

  • Patcher

    Watches for changes made by program code to the GOT and fixes them up.

  • Tracker

    Class that tracks the accesses made to the entries in the GOT.

Functions:

Attributes:

JUMP_SLOTS module-attribute ¤

JUMP_SLOTS = {
    "x86-64": {R_X86_64_JUMP_SLOT},
    "i386": {R_386_JMP_SLOT},
    "aarch64": {R_AARCH64_JUMP_SLOT},
    "mips": {R_MIPS_JUMP_SLOT},
    "powerpc": {R_PPC_JMP_SLOT},
    "sparc": {R_SPARC_JMP_SLOT},
    "arm": {R_ARM_JUMP_SLOT},
    "armcm": {R_ARM_JUMP_SLOT},
    "rv32": {R_RISCV_JUMP_SLOT},
    "rv64": {R_RISCV_JUMP_SLOT},
}

IRELATIVE_SLOTS module-attribute ¤

IRELATIVE_SLOTS = {
    "x86-64": {R_X86_64_IRELATIVE},
    "i386": {R_386_IRELATIVE},
    "aarch64": {R_AARCH64_P32_IRELATIVE, R_AARCH64_IRELATIVE},
    "mips": set(),
    "powerpc": {R_PPC_IRELATIVE},
    "sparc": {R_SPARC_IRELATIVE},
    "arm": {R_ARM_IRELATIVE},
    "armcm": {R_ARM_IRELATIVE},
    "rv32": {R_RISCV_IRELATIVE},
    "rv64": {R_RISCV_IRELATIVE},
}

TRAP_ALLOCATOR module-attribute ¤

TRAP_ALLOCATOR = TrapAllocator()

GOT_TRACKING module-attribute ¤

GOT_TRACKING = False

INSTALLED_WATCHPOINTS module-attribute ¤

INSTALLED_WATCHPOINTS: dict[int, tuple[Tracker, Patcher]] = {}

RelocTypes ¤

This class contains all the relocation type constants so that one may interpret the relocations types present in the DYNAMIC segment. These constants are defined in each of the processors' SystemV R4 psABI document, or equivalent, and should stay the same across all implementations of libc on systems that adhere to that ABI, such as Linux.

Most of these were sourced from GLibc, which conveniently lists all of the relocations types in a single file1.

Attributes:

R_RISCV_JUMP_SLOT class-attribute instance-attribute ¤

R_RISCV_JUMP_SLOT = 5

R_X86_64_JUMP_SLOT class-attribute instance-attribute ¤

R_X86_64_JUMP_SLOT = 7

R_386_JMP_SLOT class-attribute instance-attribute ¤

R_386_JMP_SLOT = 7

R_CRIS_JUMP_SLOT class-attribute instance-attribute ¤

R_CRIS_JUMP_SLOT = 11

R_390_JMP_SLOT class-attribute instance-attribute ¤

R_390_JMP_SLOT = 11

R_CKCORE_JUMP_SLOT class-attribute instance-attribute ¤

R_CKCORE_JUMP_SLOT = 12

R_TILEPRO_JMP_SLOT class-attribute instance-attribute ¤

R_TILEPRO_JMP_SLOT = 12

R_MICROBLAZE_JUMP_SLOT class-attribute instance-attribute ¤

R_MICROBLAZE_JUMP_SLOT = 17

R_TILEGX_JMP_SLOT class-attribute instance-attribute ¤

R_TILEGX_JMP_SLOT = 18

R_OR1K_JMP_SLOT class-attribute instance-attribute ¤

R_OR1K_JMP_SLOT = 20

R_68K_JMP_SLOT class-attribute instance-attribute ¤

R_68K_JMP_SLOT = 21

R_SPARC_JMP_SLOT class-attribute instance-attribute ¤

R_SPARC_JMP_SLOT = 21

R_PPC_JMP_SLOT class-attribute instance-attribute ¤

R_PPC_JMP_SLOT = 21

R_PPC64_JMP_SLOT class-attribute instance-attribute ¤

R_PPC64_JMP_SLOT = 21

R_ARM_JUMP_SLOT class-attribute instance-attribute ¤

R_ARM_JUMP_SLOT = 22

R_MN10300_JMP_SLOT class-attribute instance-attribute ¤

R_MN10300_JMP_SLOT = 22

R_ALPHA_JMP_SLOT class-attribute instance-attribute ¤

R_ALPHA_JMP_SLOT = 26

R_NIOS2_JUMP_SLOT class-attribute instance-attribute ¤

R_NIOS2_JUMP_SLOT = 38

R_NDS32_JMP_SLOT class-attribute instance-attribute ¤

R_NDS32_JMP_SLOT = 41

R_METAG_JMP_SLOT class-attribute instance-attribute ¤

R_METAG_JMP_SLOT = 44

R_M32R_JMP_SLOT class-attribute instance-attribute ¤

R_M32R_JMP_SLOT = 52

R_ARC_JMP_SLOT class-attribute instance-attribute ¤

R_ARC_JMP_SLOT = 55

R_MIPS_JUMP_SLOT class-attribute instance-attribute ¤

R_MIPS_JUMP_SLOT = 127

R_SH_JMP_SLOT class-attribute instance-attribute ¤

R_SH_JMP_SLOT = 164

R_AARCH64_JUMP_SLOT class-attribute instance-attribute ¤

R_AARCH64_JUMP_SLOT = 1026

R_X86_64_IRELATIVE class-attribute instance-attribute ¤

R_X86_64_IRELATIVE = 37

R_386_IRELATIVE class-attribute instance-attribute ¤

R_386_IRELATIVE = 42

R_RISCV_IRELATIVE class-attribute instance-attribute ¤

R_RISCV_IRELATIVE = 58

R_390_IRELATIVE class-attribute instance-attribute ¤

R_390_IRELATIVE = 61

R_ARM_IRELATIVE class-attribute instance-attribute ¤

R_ARM_IRELATIVE = 160

R_AARCH64_P32_IRELATIVE class-attribute instance-attribute ¤

R_AARCH64_P32_IRELATIVE = 188

R_PPC_IRELATIVE class-attribute instance-attribute ¤

R_PPC_IRELATIVE = 248

R_PPC64_IRELATIVE class-attribute instance-attribute ¤

R_PPC64_IRELATIVE = 248

R_SPARC_IRELATIVE class-attribute instance-attribute ¤

R_SPARC_IRELATIVE = 249

R_AARCH64_IRELATIVE class-attribute instance-attribute ¤

R_AARCH64_IRELATIVE = 1032

TrapAllocator ¤

TrapAllocator()

Utility that allocates and manages executable addresses in the space of the executing program that we can trap.

Methods:

  • alloc

    Allocates a new address to where program execution can be diverted.

  • free

    Indicates that an address obtained from alloc() can be recycled.

  • clear

    Deletes all memory mappings and frees all addresses.

Attributes:

block_capacity class-attribute instance-attribute ¤

block_capacity = 4096

slot_size class-attribute instance-attribute ¤

slot_size = 8

alloc ¤

alloc()

Allocates a new address to where program execution can be diverted.

free ¤

free(address) -> None

Indicates that an address obtained from alloc() can be recycled.

clear ¤

clear()

Deletes all memory mappings and frees all addresses.

Patcher ¤

Patcher(entry, tracker)

Bases: Breakpoint

Watches for changes made by program code to the GOT and fixes them up.

This class is paired with Tracker, and instances of both classes always function together.

Methods:

Attributes:

silent instance-attribute ¤

silent = True

entry class-attribute instance-attribute ¤

entry = entry

tracker class-attribute instance-attribute ¤

tracker = tracker

init instance-attribute ¤

init = True

should_stop ¤

should_stop() -> bool

stop ¤

stop() -> bool

Tracker ¤

Tracker()

Bases: Breakpoint

Class that tracks the accesses made to the entries in the GOT.

This class is paired with Patcher, and instances of both classes always function together.

Methods:

Attributes:

total_hits class-attribute instance-attribute ¤

total_hits = 0

target class-attribute instance-attribute ¤

target = 0

dynamic_section class-attribute instance-attribute ¤

dynamic_section = None

relocation_fn class-attribute instance-attribute ¤

relocation_fn = None

relocation_index class-attribute instance-attribute ¤

relocation_index = 0

link_map_entry class-attribute instance-attribute ¤

link_map_entry = None

trapped_address class-attribute instance-attribute ¤

trapped_address = alloc()

hits class-attribute instance-attribute ¤

hits: dict[tuple[int, ...], int] = {}

silent instance-attribute ¤

silent = True

delete ¤

delete() -> None

should_stop ¤

should_stop() -> bool

stop ¤

stop() -> bool

is_mmap_error ¤

is_mmap_error(ptr: int)

Checks whether the return value of an mmap of indicates an error.

display_name ¤

display_name(name, basename=False)

Return the display name for a symbol or objfile.

Ideally, we'd like to display all of the names of the symbols as text, but there is really nothing stopping symbol names from being stored in some fairly wacky encoding or really from having names that aren't text at all.

We should try our best to turn whatever the symbol name is into text, but not so much that non-text entries or entries in unknown encodings become unrecognizable.

all_tracked_entries ¤

all_tracked_entries()

Return an iterator over all of the GOT whose accesses are being tracked.

tracked_entry_by_address ¤

tracked_entry_by_address(address)

Return the tracker associated with the entry at the given address, if any.

enable_got_call_tracking ¤

enable_got_call_tracking(disable_hardware_whatchpoints=True) -> None

Enable the analysis of calls made through the GOT.

disable_got_call_tracking ¤

disable_got_call_tracking() -> None

Disable the analysis of calls made through the GOT.

jump_slots_for ¤

jump_slots_for(dynamic)

Returns the jump slot addresses described by the given dynamic section.