Last active
July 7, 2020 16:21
-
-
Save langston-barrett/5573d64ae0c9953e2fa0fe26847a5e1e to your computer and use it in GitHub Desktop.
Print a program's arguments, environment, and ELF aux vector with GDB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Print a program's arguments, environment, and ELF aux vector with GDB | |
Run with: | |
gdb-multiarch -n -q -batch -ex 'source showstack.py' | |
""" | |
from __future__ import print_function | |
import gdb | |
from gdb import Breakpoint | |
# From glibc/elf/elf.h | |
_ATS = { | |
"AT_NULL": 0, | |
"AT_IGNORE": 1, | |
"AT_EXECFD": 2, | |
"AT_PHDR": 3, | |
"AT_PHENT": 4, | |
"AT_PHNUM": 5, | |
"AT_PAGESZ": 6, | |
"AT_BASE": 7, | |
"AT_FLAGS": 8, | |
"AT_ENTRY": 9, | |
"AT_NOTELF": 10, | |
"AT_UID": 11, | |
"AT_EUID": 12, | |
"AT_GID": 13, | |
"AT_EGID": 14, | |
"AT_CLKTCK": 17, | |
"AT_PLATFORM": 15, | |
"AT_HWCAP": 16, | |
"AT_FPUCW": 18, | |
"AT_DCACHEBSIZE": 19, | |
"AT_ICACHEBSIZE": 20, | |
"AT_UCACHEBSIZE": 21, | |
"AT_IGNOREPPC": 22, | |
"AT_SECURE": 23, | |
"AT_BASE_PLATFORM": 24, | |
"AT_RANDOM": 25, | |
"AT_HWCAP2": 26, | |
"AT_EXECFN": 31, | |
"AT_SYSINFO": 32, | |
"AT_SYSINFO_EHDR": 33, | |
"AT_L1I_CACHESHAPE": 34, | |
"AT_L1D_CACHESHAPE": 35, | |
"AT_L2_CACHESHAPE": 36, | |
"AT_L3_CACHESHAPE": 37, | |
"AT_L1I_CACHESIZE": 40, | |
"AT_L1I_CACHEGEOMETRY": 41, | |
"AT_L1D_CACHESIZE": 42, | |
"AT_L1D_CACHEGEOMETRY": 43, | |
"AT_L2_CACHESIZE": 44, | |
"AT_L2_CACHEGEOMETRY": 45, | |
"AT_L3_CACHESIZE": 46, | |
"AT_L3_CACHEGEOMETRY": 47, | |
"AT_MINSIGSTKSZ": 51, | |
} | |
_ATS_REVERSE = {v: k for (k, v) in _ATS.items()} | |
_LIBC_START_MAIN = "__libc_start_main" | |
_CHAR_STAR = gdb.lookup_type("char").pointer() | |
_INT = gdb.lookup_type("int") | |
def header(s): | |
print() | |
print(s) | |
print("-"*len(s)) | |
def show_stack(): | |
frame = gdb.newest_frame() | |
assert frame.is_valid() | |
assert frame.type() == gdb.NORMAL_FRAME | |
header("ARGUMENTS") | |
argc = frame.read_register("r1") | |
argv = frame.read_register("r2").cast(_CHAR_STAR.pointer()) | |
print("argc", "=", argc) | |
for index in range(argc): | |
print("arg", index, "=", (argv + index).dereference().string()) | |
header("ENVIRONMENT") | |
envp = argv + argc + 1 | |
try: | |
while True: | |
envvar = envp.dereference().string() | |
assert "=" in envvar | |
print(envvar) | |
envp += 1 | |
except gdb.MemoryError: | |
pass | |
header("AUX VECTOR") | |
# 1 = inclusive upper bound, where lower bound is 0 | |
auxvp = (envp + 1).cast(_INT.array(1).pointer()) | |
while True: | |
auxv_entry = auxvp.dereference() | |
ty = int(auxv_entry[0]) | |
print(_ATS_REVERSE[ty], "=", "{0:#x}".format(int(auxv_entry[1]))) | |
auxvp += 1 | |
if ty == _ATS["AT_NULL"]: | |
break | |
gdb.execute("set arch arm") | |
gdb.execute("set endian little") | |
gdb.execute("target remote localhost:12345") | |
class MyBreakpoint(Breakpoint): | |
def stop(self): | |
show_stack() | |
breakpoint = MyBreakpoint(_LIBC_START_MAIN) | |
assert breakpoint.is_valid() | |
breakpoint.enabled = True | |
assert breakpoint.enabled is True | |
gdb.execute("continue") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment