| import collections |
| import sys |
| import re |
| from util import * |
| |
| arch = get_exe_arch() |
| |
| ArchInfo = collections.namedtuple('ArchInfo', ['ip_name']) |
| regex_info = { |
| 'i386': ArchInfo('eip'), |
| 'i386:x86-64': ArchInfo('rip'), |
| 'aarch64': ArchInfo('pc'), |
| } |
| |
| syscall_re = re.compile("`SYSCALL: <unknown-syscall--1>' \\(state:EXITING_SYSCALL\\)") |
| sched_re = re.compile("`SCHED'") |
| eip_re = re.compile("%s:(0x[a-f0-9]+)" % regex_info[arch].ip_name) |
| |
| sched_enabled = False |
| eip_enabled = False |
| eip = None |
| while True: |
| line = sys.stdin.readline() |
| if not line: |
| break |
| if syscall_re.search(line): |
| sched_enabled = True |
| if sched_enabled and sched_re.search(line): |
| eip_enabled = True |
| if eip_enabled: |
| m = eip_re.search(line) |
| if m: |
| eip = m.group(1) |
| break |
| |
| if eip is None: |
| failed('%s not found' % regex_info[arch].ip_name) |
| |
| # The SCHED after getgid may land in libc, which might not be loaded yet, in |
| # which case setting a breakpoint there will cause gdb to barf. So run to |
| # 'main' at which point libc is definitely loaded. |
| send_gdb('b main') |
| expect_gdb('Breakpoint 1') |
| send_gdb('c') |
| expect_gdb('Breakpoint 1') |
| |
| send_gdb('b *%s'%eip) |
| expect_gdb('Breakpoint 2') |
| send_gdb('c') |
| expect_gdb('Breakpoint 2') |
| expect_gdb('(rr)') |
| |
| if arch == 'aarch64': |
| send_gdb('p/x *(uint32_t*)$pc') |
| expect_gdb('0x([a-f0-9]+)') |
| if last_match().group(1) == 'd4200000': |
| failed('saw breakpoint at current instruction') |
| elif arch == 'i386' or arch == 'i386:x86-64': |
| send_gdb('p/x *(char*)$pc') |
| expect_gdb('0x([a-f0-9]+)') |
| if last_match().group(1) == 'cc': |
| failed('saw breakpoint at current instruction') |
| else: |
| failed('Add check for this architecture') |
| |
| ok() |