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.
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.