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.

GOT_TRACKING = False module-attribute

INSTALLED_WATCHPOINTS: Dict[int, Tuple[Tracker, Patcher]] = {} module-attribute

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

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

TRAP_ALLOCATOR = TrapAllocator() module-attribute

Patcher

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.

entry = entry class-attribute instance-attribute

init = True instance-attribute

silent = True instance-attribute

tracker = tracker class-attribute instance-attribute

__init__(entry, tracker)

should_stop()

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.

R_386_IRELATIVE = 42 class-attribute instance-attribute

R_386_JMP_SLOT = 7 class-attribute instance-attribute

R_390_IRELATIVE = 61 class-attribute instance-attribute

R_390_JMP_SLOT = 11 class-attribute instance-attribute

R_68K_JMP_SLOT = 21 class-attribute instance-attribute

R_AARCH64_IRELATIVE = 1032 class-attribute instance-attribute

R_AARCH64_JUMP_SLOT = 1026 class-attribute instance-attribute

R_AARCH64_P32_IRELATIVE = 188 class-attribute instance-attribute

R_ALPHA_JMP_SLOT = 26 class-attribute instance-attribute

R_ARC_JMP_SLOT = 55 class-attribute instance-attribute

R_ARM_IRELATIVE = 160 class-attribute instance-attribute

R_ARM_JUMP_SLOT = 22 class-attribute instance-attribute

R_CKCORE_JUMP_SLOT = 12 class-attribute instance-attribute

R_CRIS_JUMP_SLOT = 11 class-attribute instance-attribute

R_M32R_JMP_SLOT = 52 class-attribute instance-attribute

R_METAG_JMP_SLOT = 44 class-attribute instance-attribute

R_MICROBLAZE_JUMP_SLOT = 17 class-attribute instance-attribute

R_MIPS_JUMP_SLOT = 127 class-attribute instance-attribute

R_MN10300_JMP_SLOT = 22 class-attribute instance-attribute

R_NDS32_JMP_SLOT = 41 class-attribute instance-attribute

R_NIOS2_JUMP_SLOT = 38 class-attribute instance-attribute

R_OR1K_JMP_SLOT = 20 class-attribute instance-attribute

R_PPC64_IRELATIVE = 248 class-attribute instance-attribute

R_PPC64_JMP_SLOT = 21 class-attribute instance-attribute

R_PPC_IRELATIVE = 248 class-attribute instance-attribute

R_PPC_JMP_SLOT = 21 class-attribute instance-attribute

R_RISCV_IRELATIVE = 58 class-attribute instance-attribute

R_RISCV_JUMP_SLOT = 5 class-attribute instance-attribute

R_SH_JMP_SLOT = 164 class-attribute instance-attribute

R_SPARC_IRELATIVE = 249 class-attribute instance-attribute

R_SPARC_JMP_SLOT = 21 class-attribute instance-attribute

R_TILEGX_JMP_SLOT = 18 class-attribute instance-attribute

R_TILEPRO_JMP_SLOT = 12 class-attribute instance-attribute

R_X86_64_IRELATIVE = 37 class-attribute instance-attribute

R_X86_64_JUMP_SLOT = 7 class-attribute instance-attribute

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.

dynamic_section = None class-attribute instance-attribute

hits: Dict[Tuple[int, ...], int] = {} class-attribute instance-attribute

link_map_entry = None class-attribute instance-attribute

relocation_fn = None class-attribute instance-attribute

relocation_index = 0 class-attribute instance-attribute

silent = True instance-attribute

target = 0 class-attribute instance-attribute

total_hits = 0 class-attribute instance-attribute

trapped_address = TRAP_ALLOCATOR.alloc() class-attribute instance-attribute

__init__()

delete()

should_stop()

TrapAllocator

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

block_capacity = 4096 class-attribute instance-attribute

slot_size = 8 class-attribute instance-attribute

__init__()

alloc()

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

clear()

Deletes all memory mappings and frees all addresses.

free(address)

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

all_tracked_entries()

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

disable_got_call_tracking()

Disable the analysis of calls made through the GOT.

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.

enable_got_call_tracking(disable_hardware_whatchpoints=True)

Enable the analysis of calls made through the GOT.

is_mmap_error(ptr)

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

jump_slots_for(dynamic)

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

tracked_entry_by_address(address)

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